rubycc 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +56 -0
  3. data/LICENSE.txt +21 -0
  4. data/NOTICE +52 -0
  5. data/README.md +208 -0
  6. data/data/README.md +117 -0
  7. data/data/r10_corpus_scan.json +4082 -0
  8. data/data/r10_manual_classification.json +5342 -0
  9. data/data/r10_verification_m4a.json +1531 -0
  10. data/data/r10_verification_m4b.json +1818 -0
  11. data/data/r10_verification_m4c.json +1489 -0
  12. data/data/r10_verification_m4d.json +318 -0
  13. data/data/r10_verification_rbs.json +192 -0
  14. data/data/verified_gems.json +397 -0
  15. data/exe/rmake +16 -0
  16. data/exe/rubycc +9 -0
  17. data/exe/rubycc-ar +114 -0
  18. data/exe/rubycc-doctor +14 -0
  19. data/exe/rubycc-pkgconf +8 -0
  20. data/include/float.h +87 -0
  21. data/include/iso646.h +18 -0
  22. data/include/libc/alloca.h +18 -0
  23. data/include/libc/arpa/inet.h +61 -0
  24. data/include/libc/assert.h +43 -0
  25. data/include/libc/dirent.h +72 -0
  26. data/include/libc/dlfcn.h +58 -0
  27. data/include/libc/features.h +205 -0
  28. data/include/libc/glibc/aarch64/ctype.h +108 -0
  29. data/include/libc/glibc/aarch64/endian.h +54 -0
  30. data/include/libc/glibc/aarch64/errno.h +154 -0
  31. data/include/libc/glibc/aarch64/fcntl.h +144 -0
  32. data/include/libc/glibc/aarch64/inttypes.h +182 -0
  33. data/include/libc/glibc/aarch64/limits.h +63 -0
  34. data/include/libc/glibc/aarch64/pthread.h +131 -0
  35. data/include/libc/glibc/aarch64/setjmp.h +84 -0
  36. data/include/libc/glibc/aarch64/stdint.h +174 -0
  37. data/include/libc/glibc/aarch64/sys/epoll.h +88 -0
  38. data/include/libc/glibc/aarch64/sys/fcntl.h +19 -0
  39. data/include/libc/glibc/aarch64/sys/select.h +75 -0
  40. data/include/libc/glibc/aarch64/sys/stat.h +136 -0
  41. data/include/libc/glibc/aarch64/sys/syscall.h +167 -0
  42. data/include/libc/glibc/aarch64/sys/time.h +74 -0
  43. data/include/libc/glibc/aarch64/sys/types.h +127 -0
  44. data/include/libc/glibc/aarch64/time.h +113 -0
  45. data/include/libc/glibc/x86_64/ctype.h +108 -0
  46. data/include/libc/glibc/x86_64/endian.h +54 -0
  47. data/include/libc/glibc/x86_64/errno.h +154 -0
  48. data/include/libc/glibc/x86_64/fcntl.h +134 -0
  49. data/include/libc/glibc/x86_64/inttypes.h +182 -0
  50. data/include/libc/glibc/x86_64/limits.h +61 -0
  51. data/include/libc/glibc/x86_64/pthread.h +111 -0
  52. data/include/libc/glibc/x86_64/setjmp.h +82 -0
  53. data/include/libc/glibc/x86_64/stdint.h +163 -0
  54. data/include/libc/glibc/x86_64/sys/epoll.h +91 -0
  55. data/include/libc/glibc/x86_64/sys/fcntl.h +19 -0
  56. data/include/libc/glibc/x86_64/sys/select.h +75 -0
  57. data/include/libc/glibc/x86_64/sys/stat.h +130 -0
  58. data/include/libc/glibc/x86_64/sys/syscall.h +188 -0
  59. data/include/libc/glibc/x86_64/sys/time.h +74 -0
  60. data/include/libc/glibc/x86_64/sys/types.h +123 -0
  61. data/include/libc/glibc/x86_64/time.h +113 -0
  62. data/include/libc/grp.h +50 -0
  63. data/include/libc/langinfo.h +126 -0
  64. data/include/libc/link.h +18 -0
  65. data/include/libc/locale.h +83 -0
  66. data/include/libc/math.h +191 -0
  67. data/include/libc/netinet/in.h +126 -0
  68. data/include/libc/netinet/tcp.h +44 -0
  69. data/include/libc/poll.h +46 -0
  70. data/include/libc/pwd.h +58 -0
  71. data/include/libc/regex.h +53 -0
  72. data/include/libc/sched.h +35 -0
  73. data/include/libc/signal.h +204 -0
  74. data/include/libc/stdio.h +157 -0
  75. data/include/libc/stdlib.h +92 -0
  76. data/include/libc/string.h +74 -0
  77. data/include/libc/strings.h +25 -0
  78. data/include/libc/sys/cdefs.h +126 -0
  79. data/include/libc/sys/inotify.h +111 -0
  80. data/include/libc/sys/ioctl.h +36 -0
  81. data/include/libc/sys/mman.h +65 -0
  82. data/include/libc/sys/param.h +41 -0
  83. data/include/libc/sys/resource.h +109 -0
  84. data/include/libc/sys/socket.h +167 -0
  85. data/include/libc/sys/statfs.h +82 -0
  86. data/include/libc/sys/timerfd.h +55 -0
  87. data/include/libc/sys/uio.h +40 -0
  88. data/include/libc/sys/un.h +25 -0
  89. data/include/libc/sys/utsname.h +35 -0
  90. data/include/libc/sys/wait.h +135 -0
  91. data/include/libc/termios.h +179 -0
  92. data/include/libc/unistd.h +194 -0
  93. data/include/stdalign.h +16 -0
  94. data/include/stdarg.h +31 -0
  95. data/include/stdatomic.h +158 -0
  96. data/include/stdbool.h +15 -0
  97. data/include/stdckdint.h +28 -0
  98. data/include/stddef.h +60 -0
  99. data/include/stdnoreturn.h +18 -0
  100. data/include/x86intrin.h +16 -0
  101. data/lib/rubycc/backend/aarch64.rb +1724 -0
  102. data/lib/rubycc/backend/x86_64.rb +1369 -0
  103. data/lib/rubycc/compile_error.rb +36 -0
  104. data/lib/rubycc/compiler.rb +305 -0
  105. data/lib/rubycc/doctor/builder.rb +151 -0
  106. data/lib/rubycc/doctor/cli.rb +190 -0
  107. data/lib/rubycc/doctor/fetcher.rb +84 -0
  108. data/lib/rubycc/doctor/gemfile.rb +115 -0
  109. data/lib/rubycc/doctor/verified_gems.rb +114 -0
  110. data/lib/rubycc/doctor.rb +16 -0
  111. data/lib/rubycc/driver.rb +463 -0
  112. data/lib/rubycc/front/ast.rb +528 -0
  113. data/lib/rubycc/front/constant_evaluator.rb +631 -0
  114. data/lib/rubycc/front/initializer_resolver.rb +592 -0
  115. data/lib/rubycc/front/lexeme_reader.rb +460 -0
  116. data/lib/rubycc/front/lexer.rb +232 -0
  117. data/lib/rubycc/front/parser.rb +4122 -0
  118. data/lib/rubycc/front/token.rb +49 -0
  119. data/lib/rubycc/ir/call_convention.rb +486 -0
  120. data/lib/rubycc/ir/generator.rb +6036 -0
  121. data/lib/rubycc/ir/ir.rb +417 -0
  122. data/lib/rubycc/link/compat_runtime.rb +89 -0
  123. data/lib/rubycc/link/errors.rb +13 -0
  124. data/lib/rubycc/link/executable_linker.rb +405 -0
  125. data/lib/rubycc/link/library_resolver.rb +437 -0
  126. data/lib/rubycc/link/partial_linker.rb +546 -0
  127. data/lib/rubycc/link/shared_linker.rb +1732 -0
  128. data/lib/rubycc/mkmf_shim.rb +83 -0
  129. data/lib/rubycc/objfile/ar_archive.rb +437 -0
  130. data/lib/rubycc/objfile/elf_reader.rb +646 -0
  131. data/lib/rubycc/objfile/elf_writer.rb +891 -0
  132. data/lib/rubycc/objfile/relocatable_writer.rb +376 -0
  133. data/lib/rubycc/pkgconf/cli.rb +139 -0
  134. data/lib/rubycc/pkgconf/errors.rb +39 -0
  135. data/lib/rubycc/pkgconf/model.rb +28 -0
  136. data/lib/rubycc/pkgconf/parser.rb +109 -0
  137. data/lib/rubycc/pkgconf/pkgconf.rb +15 -0
  138. data/lib/rubycc/pkgconf/resolver.rb +70 -0
  139. data/lib/rubycc/pkgconf/search_path.rb +38 -0
  140. data/lib/rubycc/pkgconf/system_path_filter.rb +131 -0
  141. data/lib/rubycc/preprocess/constant_expression.rb +219 -0
  142. data/lib/rubycc/preprocess/glibc_version.rb +124 -0
  143. data/lib/rubycc/preprocess/pp_token.rb +62 -0
  144. data/lib/rubycc/preprocess/preprocessor.rb +2020 -0
  145. data/lib/rubycc/preprocess/scanner.rb +290 -0
  146. data/lib/rubycc/preprocess/token_converter.rb +157 -0
  147. data/lib/rubycc/rmake/cli.rb +143 -0
  148. data/lib/rubycc/rmake/errors.rb +71 -0
  149. data/lib/rubycc/rmake/executor.rb +818 -0
  150. data/lib/rubycc/rmake/expander.rb +251 -0
  151. data/lib/rubycc/rmake/makefile.rb +352 -0
  152. data/lib/rubycc/rmake/model.rb +137 -0
  153. data/lib/rubycc/rmake/parser.rb +226 -0
  154. data/lib/rubycc/rmake/rmake.rb +15 -0
  155. data/lib/rubycc/type.rb +1236 -0
  156. data/lib/rubycc/version.rb +5 -0
  157. data/lib/rubycc.rb +36 -0
  158. data/lib/rubygems_plugin.rb +102 -0
  159. metadata +219 -0
@@ -0,0 +1,111 @@
1
+ /* rubycc bundled <sys/inotify.h>: the Linux inotify(7) filesystem-change
2
+ notification interface. Provenance: clean room against the Linux kernel
3
+ UAPI (linux/inotify.h) and the glibc call surface, not derived from musl or
4
+ glibc source. The event-mask bits, the two init flags and struct
5
+ inotify_event's layout are that ABI reproduced as measured integer
6
+ constants and measured field offsets (an ABI fact, not copied text -- see
7
+ docs/HEADER-LICENSING.md sec. 4), the same treatment as poll.h and
8
+ sys/epoll.h.
9
+
10
+ Common layer, and that was measured rather than assumed. struct
11
+ inotify_event ends in a flexible array member, which is exactly the shape
12
+ where a wrong tail assumption would be invisible in a member-by-member
13
+ read, so its size and every offset were printed from the glibc oracle on
14
+ both targets and came back identical:
15
+
16
+ sizeof 16, _Alignof 4, wd @ 0, mask @ 4, cookie @ 8, len @ 12,
17
+ name @ 16 (the flexible member contributes nothing to sizeof, so the
18
+ 16-byte size is the header alone -- which is what makes libev's
19
+ `ofs += sizeof (struct inotify_event) + ev->len` walk correct)
20
+
21
+ The member widths and signedness were measured too: wd is a signed 4-byte
22
+ int (it is a watch descriptor, and -1 is the error return of
23
+ inotify_add_watch), while mask, cookie and len are unsigned 4-byte. Since
24
+ nothing here differs between the targets, the header is arch neutral,
25
+ unlike sys/epoll.h whose struct packing does differ.
26
+
27
+ IN_CLOEXEC and IN_NONBLOCK share bits with the open(2) flags, and some O_*
28
+ names do differ between the targets (that is why fcntl.h is an arch-layer
29
+ header), so those two were measured on both as well: 0x80000 and 0x800 on
30
+ each.
31
+
32
+ inotify_init/inotify_init1/inotify_add_watch/inotify_rm_watch are
33
+ Linux/glibc declarations whose bodies resolve from the host libc at link
34
+ time.
35
+
36
+ Not included: the IN_ALL_EVENTS convenience mask is provided, but glibc's
37
+ internal aliases beyond it are not, and NAME_MAX (which callers sizing a
38
+ read buffer want next to this header) is left to <limits.h>, which already
39
+ provides it. nio4r, the gem that put this header on the list, reaches
40
+ inotify_init1 / inotify_add_watch / inotify_rm_watch and the mask bits
41
+ through libev's ev_stat backend. */
42
+
43
+ #ifndef _RUBYCC_SYS_INOTIFY_H
44
+ #define _RUBYCC_SYS_INOTIFY_H
45
+
46
+ #include <stdint.h>
47
+
48
+ /* Flags for inotify_init1; they share O_CLOEXEC's and O_NONBLOCK's bits
49
+ (measured, both arches). */
50
+ #define IN_CLOEXEC 0x80000
51
+ #define IN_NONBLOCK 0x800
52
+
53
+ /* The events a watch can ask for (measured, both arches). */
54
+ #define IN_ACCESS 0x00000001 /* file was read */
55
+ #define IN_MODIFY 0x00000002 /* file was written */
56
+ #define IN_ATTRIB 0x00000004 /* metadata changed */
57
+ #define IN_CLOSE_WRITE 0x00000008 /* writable descriptor closed */
58
+ #define IN_CLOSE_NOWRITE 0x00000010 /* read-only descriptor closed */
59
+ #define IN_OPEN 0x00000020 /* file was opened */
60
+ #define IN_MOVED_FROM 0x00000040 /* renamed out of the watched directory */
61
+ #define IN_MOVED_TO 0x00000080 /* renamed into the watched directory */
62
+ #define IN_CREATE 0x00000100 /* entry created in the directory */
63
+ #define IN_DELETE 0x00000200 /* entry deleted from the directory */
64
+ #define IN_DELETE_SELF 0x00000400 /* the watched file itself was deleted */
65
+ #define IN_MOVE_SELF 0x00000800 /* the watched file itself was renamed */
66
+
67
+ /* The two pairs above that callers usually want together. */
68
+ #define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
69
+ #define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO)
70
+
71
+ /* Everything a watch may be asked for, i.e. the twelve bits above
72
+ (measured: 0xfff on both arches). */
73
+ #define IN_ALL_EVENTS 0x00000fff
74
+
75
+ /* Events the kernel reports without being asked (measured, both arches). */
76
+ #define IN_UNMOUNT 0x00002000 /* the backing filesystem was unmounted */
77
+ #define IN_Q_OVERFLOW 0x00004000 /* the event queue overflowed */
78
+ #define IN_IGNORED 0x00008000 /* the watch was removed */
79
+
80
+ /* Bits that modify how inotify_add_watch installs the watch (measured, both
81
+ arches). IN_ISDIR is not one of these: it is set by the kernel on a
82
+ reported event whose subject is a directory. */
83
+ #define IN_ONLYDIR 0x01000000 /* fail unless the path is a directory */
84
+ #define IN_DONT_FOLLOW 0x02000000 /* do not dereference a symbolic link */
85
+ #define IN_EXCL_UNLINK 0x04000000 /* stop reporting unlinked children */
86
+ #define IN_MASK_CREATE 0x10000000 /* fail if a watch already exists */
87
+ #define IN_MASK_ADD 0x20000000 /* add to, not replace, the existing mask */
88
+ #define IN_ISDIR 0x40000000 /* reported: the subject is a directory */
89
+ #define IN_ONESHOT 0x80000000 /* remove the watch after one event */
90
+
91
+ /* One queued event, as read(2) hands it over. Measured: 16 bytes, 4-byte
92
+ aligned, with the four fixed members packed end to end and the name
93
+ starting immediately after them. `name` is a flexible array member: when
94
+ `len` is non-zero the kernel writes `len` bytes there (a NUL-terminated
95
+ name plus enough NUL padding to keep the next event 4-byte aligned), so
96
+ consecutive events in a read buffer are `sizeof(struct inotify_event) +
97
+ len` bytes apart. */
98
+ struct inotify_event {
99
+ int wd; /* offset 0: the watch this event belongs to */
100
+ uint32_t mask; /* offset 4: the IN_ bits that fired */
101
+ uint32_t cookie; /* offset 8: pairs a MOVED_FROM with its MOVED_TO */
102
+ uint32_t len; /* offset 12: bytes of `name`, including padding */
103
+ char name[]; /* offset 16: present only when len is non-zero */
104
+ };
105
+
106
+ int inotify_init(void);
107
+ int inotify_init1(int __flags);
108
+ int inotify_add_watch(int __fd, const char *__pathname, uint32_t __mask);
109
+ int inotify_rm_watch(int __fd, int __wd);
110
+
111
+ #endif /* _RUBYCC_SYS_INOTIFY_H */
@@ -0,0 +1,36 @@
1
+ /* rubycc bundled <sys/ioctl.h>: the ioctl(2) declaration and terminal window
2
+ size query (POSIX does not standardize ioctl at all; this is a Linux/glibc
3
+ ABI surface). Provenance: clean room against the glibc/Linux ABI (glibc's
4
+ bits/ioctl-types.h plus the kernel UAPI's asm-generic/ioctls.h request
5
+ numbers), not derived from musl. Narrowed to the surface io-console's
6
+ corpus sample actually reaches (Step 124, M5 H2): on the HAVE_TERMIOS_H
7
+ path (see termios.h's provenance note) the only ioctl requests it issues
8
+ are TIOCGWINSZ/TIOCSWINSZ against a `struct winsize`; the TCGETA/TCSETAF/
9
+ TIOCGETP/TIOCSETP requests belong to the termio.h/sgtty.h fallback paths
10
+ that HAVE_TERMIOS_H skips on Linux, so they are not reproduced here (the
11
+ same "corpus-reached surface only" scoping sched.h and poll.h used).
12
+ struct winsize is a struct callers read/write members of directly, so it
13
+ cannot be an opaque byte blob; its size (8) and every member's offset, and
14
+ the TIOCGWINSZ/TIOCSWINSZ request numbers, were measured against the glibc
15
+ oracle on both x86-64 and aarch64 (see test/test_header_abi.rb's IOCTL
16
+ case) and the two agreed exactly, so this header lives in the common
17
+ layer. */
18
+
19
+ #ifndef _RUBYCC_SYS_IOCTL_H
20
+ #define _RUBYCC_SYS_IOCTL_H
21
+
22
+ /* struct winsize: 8 bytes, 2-byte aligned (measured, both arches). */
23
+ struct winsize {
24
+ unsigned short ws_row; /* offset 0: rows, in characters */
25
+ unsigned short ws_col; /* offset 2: columns, in characters */
26
+ unsigned short ws_xpixel; /* offset 4: horizontal size, pixels */
27
+ unsigned short ws_ypixel; /* offset 6: vertical size, pixels */
28
+ };
29
+
30
+ /* Terminal window size ioctl requests (measured, both arches agree). */
31
+ #define TIOCGWINSZ 0x5413
32
+ #define TIOCSWINSZ 0x5414
33
+
34
+ int ioctl(int __fd, unsigned long __request, ...);
35
+
36
+ #endif /* _RUBYCC_SYS_IOCTL_H */
@@ -0,0 +1,65 @@
1
+ /* rubycc bundled <sys/mman.h>: the memory-mapping calls and the PROT_/MAP_/MS_/
2
+ MADV_ flag macros (POSIX plus Linux extensions). Provenance: clean room
3
+ against the Linux kernel UAPI (asm-generic/mman-common.h and mman.h), not
4
+ derived from musl. The flag values and MAP_FAILED are that ABI reproduced as
5
+ measured integer constants (an ABI fact, not copied text -- see
6
+ docs/HEADER-LICENSING.md), the same treatment as errno.h and fcntl.h. mmap,
7
+ munmap and kin are POSIX declarations. Common layer: every flag value is
8
+ identical on x86-64 and aarch64 (both use the asm-generic assignments). */
9
+
10
+ #ifndef _RUBYCC_SYS_MMAN_H
11
+ #define _RUBYCC_SYS_MMAN_H
12
+
13
+ #ifndef _RUBYCC_SIZE_T
14
+ #define _RUBYCC_SIZE_T
15
+ typedef unsigned long size_t;
16
+ #endif
17
+ #ifndef _RUBYCC_OFF_T
18
+ #define _RUBYCC_OFF_T
19
+ typedef long off_t;
20
+ #endif
21
+
22
+ /* Memory protection bits (for mmap/mprotect). */
23
+ #define PROT_NONE 0x0
24
+ #define PROT_READ 0x1
25
+ #define PROT_WRITE 0x2
26
+ #define PROT_EXEC 0x4
27
+
28
+ /* mmap flags. MAP_SHARED/MAP_PRIVATE are the required sharing mode; the rest
29
+ are Linux extensions. */
30
+ #define MAP_SHARED 0x00001
31
+ #define MAP_PRIVATE 0x00002
32
+ #define MAP_FIXED 0x00010
33
+ #define MAP_ANONYMOUS 0x00020
34
+ #define MAP_ANON MAP_ANONYMOUS
35
+ #define MAP_GROWSDOWN 0x00100
36
+ #define MAP_LOCKED 0x02000
37
+ #define MAP_NORESERVE 0x04000
38
+ #define MAP_POPULATE 0x08000
39
+ #define MAP_STACK 0x20000
40
+
41
+ /* mmap failure sentinel: the return value on error. */
42
+ #define MAP_FAILED ((void *) -1)
43
+
44
+ /* msync flags. */
45
+ #define MS_ASYNC 0x1
46
+ #define MS_INVALIDATE 0x2
47
+ #define MS_SYNC 0x4
48
+
49
+ /* madvise advice values. */
50
+ #define MADV_NORMAL 0
51
+ #define MADV_RANDOM 1
52
+ #define MADV_SEQUENTIAL 2
53
+ #define MADV_WILLNEED 3
54
+ #define MADV_DONTNEED 4
55
+ #define MADV_FREE 8
56
+
57
+ void *mmap(void *__addr, size_t __len, int __prot, int __flags, int __fd, off_t __offset);
58
+ int munmap(void *__addr, size_t __len);
59
+ int mprotect(void *__addr, size_t __len, int __prot);
60
+ int msync(void *__addr, size_t __len, int __flags);
61
+ int madvise(void *__addr, size_t __len, int __advice);
62
+ int mlock(const void *__addr, size_t __len);
63
+ int munlock(const void *__addr, size_t __len);
64
+
65
+ #endif /* _RUBYCC_SYS_MMAN_H */
@@ -0,0 +1,41 @@
1
+ /* rubycc bundled <sys/param.h>: BSD-heritage traditional Unix parameter
2
+ macros. Provenance: clean room. glibc's own <sys/param.h> is itself only a
3
+ compatibility shim (its own comment header calls it "Compatibility header
4
+ for old-style Unix parameters and limits") that pulls in sys/types.h,
5
+ limits.h, endian.h and signal.h to synthesize BSD-named aliases
6
+ (MAXPATHLEN, NOFILE, ...) and a handful of bit-twiddling macros
7
+ (setbit/isset/howmany/roundup/MIN/MAX); it was inspected on the host
8
+ (x86-64 and aarch64 glibc, both agree) to confirm what it actually emits,
9
+ but no macro *body* is copied from it -- MIN/MAX/howmany/roundup below are
10
+ rubycc's own phrasing of the same well-known formulas (an ABI/behavioral
11
+ fact -- the value MIN(a,b)/roundup(x,y) etc. must produce -- not a
12
+ creative expression; see docs/HEADER-LICENSING.md Sec 4). Narrowed to the
13
+ surface digest's corpus sample actually reaches (Step 124, M5 H2): sha1.c's
14
+ `#include <sys/param.h>` is itself gated behind `defined(_KERNEL) ||
15
+ defined(_STANDALONE)`, neither of which a userspace Ruby extension build
16
+ ever defines, so the include is unreachable dead code for this gem in
17
+ practice -- and no digest source references MIN/MAX/howmany/roundup or any
18
+ other sys/param.h name either. This header ships only the traditional
19
+ four macros a "sys/param.h" compatibility shim is expected to carry
20
+ (matching the header's own docs above); the BSD name aliases (MAXPATHLEN,
21
+ NOFILE, ...), the setbit/isset bitmap macros and the endian.h/signal.h
22
+ pull-ins are not reproduced (no corpus sample needs them, and re-adding
23
+ them would just re-derive limits.h/endian.h under new names). */
24
+
25
+ #ifndef _RUBYCC_SYS_PARAM_H
26
+ #define _RUBYCC_SYS_PARAM_H
27
+
28
+ #ifndef MIN
29
+ #define MIN(a, b) ((a) < (b) ? (a) : (b))
30
+ #endif
31
+ #ifndef MAX
32
+ #define MAX(a, b) ((a) > (b) ? (a) : (b))
33
+ #endif
34
+ #ifndef howmany
35
+ #define howmany(x, y) (((x) + ((y) - 1)) / (y))
36
+ #endif
37
+ #ifndef roundup
38
+ #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
39
+ #endif
40
+
41
+ #endif /* _RUBYCC_SYS_PARAM_H */
@@ -0,0 +1,109 @@
1
+ /* rubycc bundled <sys/resource.h>: resource limits and usage (POSIX.1).
2
+ Provenance: clean room against the POSIX public interface and the Linux
3
+ kernel UAPI (asm-generic/resource.h); struct rlimit's and struct rusage's
4
+ member names, types and order are that ABI's own public contract, not
5
+ glibc implementation detail. Every member is used directly by callers, so
6
+ neither struct can be an opaque byte blob; both structs' sizes and every
7
+ member's offset were measured against the glibc oracle on both x86-64 and
8
+ aarch64 (see test/test_header_abi.rb's RESOURCE case) and the two agreed
9
+ exactly (rlim_t is `unsigned long` and struct timeval's members are both
10
+ `long` on either LP64 target, so neither struct has an arch-dependent
11
+ field width), so this header lives in the common layer. The C libraries do
12
+ differ, though: struct rusage is larger on musl, which is carried below
13
+ under __RUBYCC_LIBC_MUSL__ (see the preprocessor's LIBCS). struct timeval
14
+ reuses the __timeval_defined guard sys/time.h also defines it under, so the
15
+ two headers agree rather than redefine when both are included.
16
+ The RLIMIT_* enumerators and RUSAGE_* constants are the standard Linux/
17
+ glibc values (measured, both arches agree). getrlimit/setrlimit/getrusage
18
+ are POSIX declarations whose bodies resolve from the host libc at link time
19
+ (Step 123, M5 H2). */
20
+
21
+ #ifndef _RUBYCC_SYS_RESOURCE_H
22
+ #define _RUBYCC_SYS_RESOURCE_H
23
+
24
+ #ifndef _RUBYCC_TIME_T
25
+ #define _RUBYCC_TIME_T
26
+ typedef long time_t;
27
+ #endif
28
+ #ifndef _RUBYCC_SUSECONDS_T
29
+ #define _RUBYCC_SUSECONDS_T
30
+ typedef long suseconds_t;
31
+ #endif
32
+
33
+ #ifndef __timeval_defined
34
+ #define __timeval_defined 1
35
+ struct timeval {
36
+ time_t tv_sec;
37
+ suseconds_t tv_usec;
38
+ };
39
+ #endif
40
+
41
+ typedef unsigned long rlim_t;
42
+
43
+ /* struct rlimit: 16 bytes, 8-byte aligned (measured, both arches). */
44
+ struct rlimit {
45
+ rlim_t rlim_cur; /* Soft limit. offset 0 */
46
+ rlim_t rlim_max; /* Hard limit. offset 8 */
47
+ };
48
+
49
+ /* struct rusage: 144 bytes, 8-byte aligned on glibc and 272 bytes, 8-byte
50
+ aligned on musl (both sizeof/_Alignof pairs measured with the ABI harness,
51
+ glibc's on this host and musl's on the CI musl run, docs/STEPS.md Step 193).
52
+ Every member offset below was probed on both and agreed, so the two libraries
53
+ differ only in what follows the last member: musl reserves a further 128
54
+ bytes there. Those bytes are reproduced as one opaque trailing array rather
55
+ than as named fields, because only their extent was measured -- the same
56
+ treatment sys/stat.h gives struct stat's reserved slots. The
57
+ ru_ixrss/ru_idrss/ru_isrss/ru_nswap fields are unused by Linux but kept for
58
+ the standard layout. */
59
+ struct rusage {
60
+ struct timeval ru_utime; /* offset 0: user CPU time used */
61
+ struct timeval ru_stime; /* offset 16: system CPU time used */
62
+ long ru_maxrss; /* offset 32: maximum resident set size */
63
+ long ru_ixrss; /* offset 40: integral shared memory size */
64
+ long ru_idrss; /* offset 48: integral unshared data size */
65
+ long ru_isrss; /* offset 56: integral unshared stack size */
66
+ long ru_minflt; /* offset 64: page reclaims */
67
+ long ru_majflt; /* offset 72: page faults */
68
+ long ru_nswap; /* offset 80: swaps */
69
+ long ru_inblock; /* offset 88: block input operations */
70
+ long ru_oublock; /* offset 96: block output operations */
71
+ long ru_msgsnd; /* offset 104: messages sent */
72
+ long ru_msgrcv; /* offset 112: messages received */
73
+ long ru_nsignals; /* offset 120: signals received */
74
+ long ru_nvcsw; /* offset 128: voluntary context switches */
75
+ long ru_nivcsw; /* offset 136: involuntary context switches */
76
+ #if defined(__RUBYCC_LIBC_MUSL__)
77
+ long __reserved[16]; /* offset 144: musl's trailing 128 bytes (measured) */
78
+ #endif
79
+ };
80
+
81
+ #define RLIMIT_CPU 0
82
+ #define RLIMIT_FSIZE 1
83
+ #define RLIMIT_DATA 2
84
+ #define RLIMIT_STACK 3
85
+ #define RLIMIT_CORE 4
86
+ #define RLIMIT_RSS 5
87
+ #define RLIMIT_NPROC 6
88
+ #define RLIMIT_NOFILE 7
89
+ #define RLIMIT_MEMLOCK 8
90
+ #define RLIMIT_AS 9
91
+ #define RLIMIT_LOCKS 10
92
+ #define RLIMIT_SIGPENDING 11
93
+ #define RLIMIT_MSGQUEUE 12
94
+ #define RLIMIT_NICE 13
95
+ #define RLIMIT_RTPRIO 14
96
+ #define RLIMIT_RTTIME 15
97
+ #define RLIMIT_NLIMITS 16
98
+
99
+ #define RLIM_INFINITY ((rlim_t)-1)
100
+
101
+ #define RUSAGE_SELF 0
102
+ #define RUSAGE_CHILDREN (-1)
103
+ #define RUSAGE_THREAD 1
104
+
105
+ int getrlimit(int __resource, struct rlimit *__rlimits);
106
+ int setrlimit(int __resource, const struct rlimit *__rlimits);
107
+ int getrusage(int __who, struct rusage *__usage);
108
+
109
+ #endif /* _RUBYCC_SYS_RESOURCE_H */
@@ -0,0 +1,167 @@
1
+ /* rubycc bundled <sys/socket.h>: the socket address family / type / option
2
+ macros, the socket address structs (sockaddr, sockaddr_storage, msghdr,
3
+ iovec, cmsghdr, linger) and the POSIX socket calls. Provenance: clean room
4
+ against the Linux kernel UAPI (linux/socket.h, asm-generic/socket.h,
5
+ linux/uio.h) and the glibc socket ABI, not derived from musl. The AF_/PF_/
6
+ SOCK_/SOL_/SO_/MSG_/SHUT_ values and the struct layouts are that ABI
7
+ reproduced as measured integer constants and measured field offsets (an ABI
8
+ fact, not copied text -- see docs/HEADER-LICENSING.md), the same treatment
9
+ as errno.h and fcntl.h. socket, bind, connect and kin are POSIX declarations
10
+ whose bodies resolve from the host libc at link time. Common layer: every
11
+ macro value and every struct layout below (struct sockaddr, sockaddr_storage,
12
+ msghdr, iovec, cmsghdr and linger all included) is identical on x86-64 and
13
+ aarch64. */
14
+
15
+ #ifndef _RUBYCC_SYS_SOCKET_H
16
+ #define _RUBYCC_SYS_SOCKET_H
17
+
18
+ #ifndef _RUBYCC_SIZE_T
19
+ #define _RUBYCC_SIZE_T
20
+ typedef unsigned long size_t;
21
+ #endif
22
+ #ifndef _RUBYCC_SSIZE_T
23
+ #define _RUBYCC_SSIZE_T
24
+ typedef long ssize_t;
25
+ #endif
26
+ #ifndef _RUBYCC_SOCKLEN_T
27
+ #define _RUBYCC_SOCKLEN_T
28
+ typedef unsigned int socklen_t;
29
+ #endif
30
+ #ifndef _RUBYCC_SA_FAMILY_T
31
+ #define _RUBYCC_SA_FAMILY_T
32
+ typedef unsigned short sa_family_t;
33
+ #endif
34
+
35
+ /* struct iovec: 16 bytes, 8-byte aligned (measured, both arches). */
36
+ #ifndef _RUBYCC_STRUCT_IOVEC
37
+ #define _RUBYCC_STRUCT_IOVEC
38
+ struct iovec {
39
+ void *iov_base; /* offset 0 */
40
+ size_t iov_len; /* offset 8 */
41
+ };
42
+ #endif
43
+
44
+ /* struct sockaddr: 16 bytes, the generic socket address (POSIX/glibc). */
45
+ struct sockaddr {
46
+ sa_family_t sa_family; /* offset 0 */
47
+ char sa_data[14]; /* offset 2 */
48
+ };
49
+
50
+ /* struct sockaddr_storage: 128 bytes, 8-byte aligned (measured, both arches),
51
+ large and aligned enough to hold any of the protocol-specific sockaddr_*
52
+ structs. __ss_align forces the 8-byte alignment and pads the struct out to
53
+ the full 128 bytes. */
54
+ struct sockaddr_storage {
55
+ sa_family_t ss_family; /* offset 0 */
56
+ char __ss_padding[118]; /* offset 2 */
57
+ unsigned long __ss_align; /* offset 120 */
58
+ };
59
+
60
+ /* struct msghdr: 56 bytes (measured, both arches), the sendmsg/recvmsg
61
+ scatter-gather message descriptor. */
62
+ struct msghdr {
63
+ void *msg_name; /* offset 0 */
64
+ socklen_t msg_namelen; /* offset 8 */
65
+ struct iovec *msg_iov; /* offset 16 */
66
+ size_t msg_iovlen; /* offset 24 */
67
+ void *msg_control; /* offset 32 */
68
+ size_t msg_controllen; /* offset 40 */
69
+ int msg_flags; /* offset 48 */
70
+ };
71
+
72
+ /* struct cmsghdr: 16 bytes, one ancillary-data record header. */
73
+ struct cmsghdr {
74
+ size_t cmsg_len; /* offset 0 */
75
+ int cmsg_level; /* offset 8 */
76
+ int cmsg_type; /* offset 12 */
77
+ };
78
+
79
+ /* struct linger: 8 bytes, the SO_LINGER option payload. */
80
+ struct linger {
81
+ int l_onoff;
82
+ int l_linger;
83
+ };
84
+
85
+ /* Address / protocol families (Linux kernel UAPI). */
86
+ #define AF_UNSPEC 0
87
+ #define AF_UNIX 1
88
+ #define AF_LOCAL AF_UNIX
89
+ #define AF_INET 2
90
+ #define AF_INET6 10
91
+ /* AF_NETLINK is the kernel-configuration socket family. It is here because a
92
+ corpus gem asked for it by name (raindrops' linux_inet_diag.c opens one to
93
+ read TCP listen queues) and for no other reason: the families are a numbered
94
+ space with dozens of members, and adding the ones nobody has reached for
95
+ would be values nobody has measured. */
96
+ #define AF_NETLINK 16
97
+
98
+ #define PF_UNSPEC AF_UNSPEC
99
+ #define PF_UNIX AF_UNIX
100
+ #define PF_LOCAL AF_UNIX
101
+ #define PF_INET AF_INET
102
+ #define PF_INET6 AF_INET6
103
+ #define PF_NETLINK AF_NETLINK
104
+
105
+ /* Socket types. SOCK_CLOEXEC/SOCK_NONBLOCK are Linux extensions that may be
106
+ OR'd into the type argument of socket()/socketpair(). */
107
+ #define SOCK_STREAM 1
108
+ #define SOCK_DGRAM 2
109
+ #define SOCK_RAW 3
110
+ #define SOCK_SEQPACKET 5
111
+ #define SOCK_NONBLOCK 0x800
112
+ #define SOCK_CLOEXEC 0x80000
113
+
114
+ /* getsockopt/setsockopt level and SO_* option names (asm-generic/socket.h). */
115
+ #define SOL_SOCKET 1
116
+
117
+ #define SO_REUSEADDR 2
118
+ #define SO_TYPE 3
119
+ #define SO_ERROR 4
120
+ #define SO_BROADCAST 6
121
+ #define SO_SNDBUF 7
122
+ #define SO_RCVBUF 8
123
+ #define SO_KEEPALIVE 9
124
+ #define SO_LINGER 13
125
+ #define SO_REUSEPORT 15
126
+
127
+ /* send/recv message flags. */
128
+ #define MSG_OOB 1
129
+ #define MSG_PEEK 2
130
+ #define MSG_TRUNC 0x20
131
+ #define MSG_DONTWAIT 0x40
132
+ #define MSG_WAITALL 0x100
133
+ #define MSG_NOSIGNAL 0x4000
134
+
135
+ /* shutdown() how. */
136
+ #define SHUT_RD 0
137
+ #define SHUT_WR 1
138
+ #define SHUT_RDWR 2
139
+
140
+ int socket(int __domain, int __type, int __protocol);
141
+ int socketpair(int __domain, int __type, int __protocol, int __fds[2]);
142
+ int bind(int __fd, const struct sockaddr *__addr, socklen_t __len);
143
+ int getsockname(int __fd, struct sockaddr *__addr, socklen_t *__len);
144
+ int connect(int __fd, const struct sockaddr *__addr, socklen_t __len);
145
+ int getpeername(int __fd, struct sockaddr *__addr, socklen_t *__len);
146
+ ssize_t send(int __fd, const void *__buf, size_t __n, int __flags);
147
+ ssize_t recv(int __fd, void *__buf, size_t __n, int __flags);
148
+ ssize_t sendto(int __fd, const void *__buf, size_t __n, int __flags,
149
+ const struct sockaddr *__addr, socklen_t __addr_len);
150
+ ssize_t recvfrom(int __fd, void *__buf, size_t __n, int __flags,
151
+ struct sockaddr *__addr, socklen_t *__addr_len);
152
+ ssize_t sendmsg(int __fd, const struct msghdr *__message, int __flags);
153
+ ssize_t recvmsg(int __fd, struct msghdr *__message, int __flags);
154
+ int getsockopt(int __fd, int __level, int __optname, void *__optval, socklen_t *__optlen);
155
+ int setsockopt(int __fd, int __level, int __optname, const void *__optval, socklen_t __optlen);
156
+ int listen(int __fd, int __n);
157
+ int accept(int __fd, struct sockaddr *__addr, socklen_t *__addr_len);
158
+ /* accept4 is the Linux extension that folds SOCK_CLOEXEC / SOCK_NONBLOCK into
159
+ the accept itself, closing the race a separate fcntl leaves open. glibc gates
160
+ it behind _GNU_SOURCE; this header exposes SOCK_CLOEXEC unconditionally
161
+ already (see the socket types above), so the declaration follows the same
162
+ rule rather than growing a feature-test macro of its own. kgio's accept.c
163
+ calls it whenever its extconf found it. */
164
+ int accept4(int __fd, struct sockaddr *__addr, socklen_t *__addr_len, int __flags);
165
+ int shutdown(int __fd, int __how);
166
+
167
+ #endif /* _RUBYCC_SYS_SOCKET_H */
@@ -0,0 +1,82 @@
1
+ /* rubycc bundled <sys/statfs.h>: the Linux statfs(2) filesystem-statistics
2
+ interface. Provenance: clean room against the Linux kernel UAPI
3
+ (the statfs(2) argument layout) and the glibc call surface, not derived
4
+ from musl or glibc source. struct statfs's size, member widths, signedness
5
+ and offsets are that ABI reproduced from measurement (an ABI fact, not
6
+ copied text -- see docs/HEADER-LICENSING.md sec. 4), the same treatment as
7
+ sys/stat.h and dirent.h.
8
+
9
+ Common layer, and this one is worth spelling out because the naive guess
10
+ is the other way. The kernel has two statfs layouts -- a legacy one whose
11
+ counters are 32-bit and a 64-bit one -- and glibc's member types are
12
+ written in terms of word-sized typedefs, so it would be reasonable to
13
+ expect the two targets to disagree the way sys/stat.h's struct stat does.
14
+ Measured with the glibc oracle, they do not: both x86-64 and aarch64
15
+ report
16
+
17
+ sizeof 120, _Alignof 8, and every member 8 bytes wide at
18
+ f_type 0, f_bsize 8, f_blocks 16, f_bfree 24, f_bavail 32,
19
+ f_files 40, f_ffree 48, f_fsid 56, f_namelen 64, f_frsize 72,
20
+ f_flags 80, f_spare 88 (4 x 8 = 32 bytes, running to 120)
21
+
22
+ i.e. both LP64 targets land on the all-64-bit layout with no padding
23
+ anywhere, so one arch-neutral definition serves. The signedness was
24
+ measured member by member as well, and is not uniform: f_type, f_bsize,
25
+ f_namelen, f_frsize, f_flags and f_spare are signed, while the six
26
+ counters f_blocks / f_bfree / f_bavail / f_files / f_ffree are unsigned.
27
+ That asymmetry is why signedness was probed rather than assumed -- libev
28
+ compares f_type against magic numbers as large as 0x9123683e, which only
29
+ behaves as intended because the field is a signed 64-bit word rather than
30
+ a 32-bit one.
31
+
32
+ f_fsid's type: glibc gets __fsid_t from its bits/types.h layer and spells
33
+ the fsid_t alias in <sys/types.h> under __USE_MISC; measured, <sys/statfs.h>
34
+ alone gives only the __fsid_t spelling. rubycc has no split types layer to
35
+ reach for and its bundled <sys/types.h> does not carry the type, so both
36
+ names are defined here under one guard. The type itself measured 8 bytes
37
+ with 4-byte alignment -- two 4-byte ints, not one 8-byte word, which is
38
+ why f_fsid cannot simply be written as a long.
39
+
40
+ Not included: struct statfs64 / statfs64 / fstatfs64 (measured, statfs64
41
+ is byte-for-byte the same 120-byte layout on both LP64 targets, so the
42
+ plain names already are the 64-bit interface here), and the ST_* mount
43
+ flag names, which measurement confirms <sys/statfs.h> does not define at
44
+ all -- they belong to <sys/statvfs.h>, which rubycc does not bundle. nio4r,
45
+ the gem that put this header on the list, reaches statfs and f_type only,
46
+ from libev's ev_stat backend deciding whether a filesystem is local enough
47
+ for inotify to be trusted. */
48
+
49
+ #ifndef _RUBYCC_SYS_STATFS_H
50
+ #define _RUBYCC_SYS_STATFS_H
51
+
52
+ /* The filesystem identifier statfs reports. Measured: 8 bytes, 4-byte
53
+ aligned, i.e. a pair of 4-byte ints rather than one 8-byte word. */
54
+ #ifndef _RUBYCC_FSID_T
55
+ #define _RUBYCC_FSID_T
56
+ typedef struct {
57
+ int __val[2];
58
+ } __fsid_t;
59
+ typedef __fsid_t fsid_t;
60
+ #endif
61
+
62
+ /* Measured: 120 bytes, 8-byte aligned, every member one 8-byte word and no
63
+ padding. Signedness is per member -- see the header note. */
64
+ struct statfs {
65
+ long f_type; /* offset 0: filesystem magic number */
66
+ long f_bsize; /* offset 8: optimal transfer block size */
67
+ unsigned long f_blocks; /* offset 16: total blocks, in f_frsize units */
68
+ unsigned long f_bfree; /* offset 24: free blocks */
69
+ unsigned long f_bavail; /* offset 32: free blocks available to non-root */
70
+ unsigned long f_files; /* offset 40: total file nodes */
71
+ unsigned long f_ffree; /* offset 48: free file nodes */
72
+ __fsid_t f_fsid; /* offset 56: filesystem id */
73
+ long f_namelen; /* offset 64: maximum filename length */
74
+ long f_frsize; /* offset 72: fragment size */
75
+ long f_flags; /* offset 80: mount flags */
76
+ long f_spare[4];/* offset 88: reserved, runs to 120 */
77
+ };
78
+
79
+ int statfs(const char *__path, struct statfs *__buf);
80
+ int fstatfs(int __fd, struct statfs *__buf);
81
+
82
+ #endif /* _RUBYCC_SYS_STATFS_H */
@@ -0,0 +1,55 @@
1
+ /* rubycc bundled <sys/timerfd.h>: the Linux timerfd(2) family, which delivers
2
+ POSIX timer expirations as readable events on a file descriptor.
3
+ Provenance: clean room against the Linux kernel UAPI
4
+ (linux/timerfd.h) and the glibc call surface, not derived from musl or
5
+ glibc source. The four TFD_* values are that ABI reproduced as measured
6
+ integer constants (an ABI fact, not copied text -- see
7
+ docs/HEADER-LICENSING.md sec. 4), printed from the glibc oracle on x86-64
8
+ and on aarch64 (cross gcc + qemu).
9
+
10
+ Common layer. Both TFD_CLOEXEC and TFD_NONBLOCK share bits with the
11
+ open(2) flags, which do differ between the two targets for some O_* names
12
+ (that is why fcntl.h is an arch-layer header), so this was measured rather
13
+ than assumed. It measured identical on both:
14
+
15
+ TFD_CLOEXEC 0x80000, TFD_NONBLOCK 0x800,
16
+ TFD_TIMER_ABSTIME 1, TFD_TIMER_CANCEL_ON_SET 2
17
+
18
+ and so did everything the interface's types rest on -- struct itimerspec
19
+ is 32 bytes with it_interval at 0 and it_value at 16, struct timespec is
20
+ 16 bytes, clockid_t is 4 -- so no arch split is needed here.
21
+
22
+ struct itimerspec is NOT duplicated below: the bundled <time.h> already
23
+ defines it (next to struct timespec, which it is built from), so this
24
+ header includes <time.h> and lets the one definition serve, the same
25
+ judgement <sys/wait.h> makes about siginfo_t. That include also supplies
26
+ the CLOCK_* ids timerfd_create's first argument takes.
27
+
28
+ Not included: timerfd_settime64/timerfd_gettime64 (the 32-bit-time_t
29
+ compatibility entry points; on LP64 targets glibc resolves the plain names
30
+ to the 64-bit implementation already). nio4r, the gem that put this header
31
+ on the list, reaches timerfd_create and timerfd_settime through libev's
32
+ periodic-timer backend. */
33
+
34
+ #ifndef _RUBYCC_SYS_TIMERFD_H
35
+ #define _RUBYCC_SYS_TIMERFD_H
36
+
37
+ #include <time.h>
38
+
39
+ /* timerfd_create flags (measured, both arches). */
40
+ #define TFD_CLOEXEC 0x80000
41
+ #define TFD_NONBLOCK 0x800
42
+
43
+ /* timerfd_settime flags (measured, both arches). ABSTIME reads the value as
44
+ an absolute time on the chosen clock; CANCEL_ON_SET additionally makes a
45
+ discontinuous change of CLOCK_REALTIME cancel the timer, which is how a
46
+ reader learns the wall clock was stepped. */
47
+ #define TFD_TIMER_ABSTIME 1
48
+ #define TFD_TIMER_CANCEL_ON_SET 2
49
+
50
+ int timerfd_create(int __clock_id, int __flags);
51
+ int timerfd_settime(int __fd, int __flags, const struct itimerspec *__new_value,
52
+ struct itimerspec *__old_value);
53
+ int timerfd_gettime(int __fd, struct itimerspec *__curr_value);
54
+
55
+ #endif /* _RUBYCC_SYS_TIMERFD_H */