|
2 | 2 |
|
3 | 3 | #ifdef __x86_64__
|
4 | 4 | float ceilf(float x) {
|
5 |
| - float result; |
6 |
| - __asm__( |
7 |
| - "roundss $0x0A, %[x], %[result]" |
8 |
| - : [result] "=x" (result) |
9 |
| - : [x] "x" (x) |
10 |
| - ); |
11 |
| - return result; |
| 5 | + float result; |
| 6 | + __asm__("roundss $0x0A, %[x], %[result]" |
| 7 | + : [result] "=x"(result) |
| 8 | + : [x] "x"(x)); |
| 9 | + return result; |
12 | 10 | }
|
13 | 11 | double ceil(double x) {
|
14 |
| - double result; |
15 |
| - __asm__( |
16 |
| - "roundsd $0x0A, %[x], %[result]" |
17 |
| - : [result] "=x" (result) |
18 |
| - : [x] "x" (x) |
19 |
| - ); |
20 |
| - return result; |
| 12 | + double result; |
| 13 | + __asm__("roundsd $0x0A, %[x], %[result]" |
| 14 | + : [result] "=x"(result) |
| 15 | + : [x] "x"(x)); |
| 16 | + return result; |
21 | 17 | }
|
22 | 18 | #endif
|
23 | 19 |
|
24 | 20 | #ifdef __aarch64__
|
25 | 21 | float ceilf(float x) {
|
26 |
| - float result; |
27 |
| - __asm__( |
28 |
| - "frintp %s0, %s1\n" |
29 |
| - : "=w" (result) |
30 |
| - : "w" (x) |
31 |
| - ); |
32 |
| - return result; |
| 22 | + float result; |
| 23 | + __asm__("frintp %s0, %s1\n" : "=w"(result) : "w"(x)); |
| 24 | + return result; |
33 | 25 | }
|
34 | 26 | double ceil(double x) {
|
35 |
| - double result; |
36 |
| - __asm__( |
37 |
| - "frintp %d0, %d1\n" |
38 |
| - : "=w" (result) |
39 |
| - : "w" (x) |
40 |
| - ); |
41 |
| - return result; |
| 27 | + double result; |
| 28 | + __asm__("frintp %d0, %d1\n" : "=w"(result) : "w"(x)); |
| 29 | + return result; |
42 | 30 | }
|
43 | 31 | #endif
|
44 | 32 |
|
45 | 33 | int stat(const char *restrict path, void *restrict buf) {
|
46 |
| - int __xstat(int, const char *restrict, void *restrict); |
47 |
| - return __xstat(3, path, buf); |
| 34 | + int __xstat(int, const char *restrict, void *restrict); |
| 35 | + return __xstat(3, path, buf); |
48 | 36 | }
|
49 | 37 |
|
50 | 38 | int fstat(int fd, void *buf) {
|
51 |
| - int __fxstat(int, int, void *); |
52 |
| - return __fxstat(3, fd, buf); |
| 39 | + int __fxstat(int, int, void *); |
| 40 | + return __fxstat(3, fd, buf); |
53 | 41 | }
|
54 | 42 |
|
55 | 43 | // glibc doesn't define pthread_atfork on aarch64. We need to delegate to
|
@@ -80,45 +68,58 @@ int __register_atfork(void (*prepare)(void), void (*parent)(void),
|
80 | 68 |
|
81 | 69 | int pthread_atfork(void (*prepare)(void), void (*parent)(void),
|
82 | 70 | void (*child)(void)) {
|
83 |
| - // glibc |
84 |
| - if (__dso_handle && __register_atfork) { |
85 |
| - return __register_atfork(prepare, parent, child, __dso_handle); |
86 |
| - } |
| 71 | + // glibc |
| 72 | + if (__dso_handle && __register_atfork) { |
| 73 | + return __register_atfork(prepare, parent, child, __dso_handle); |
| 74 | + } |
87 | 75 |
|
88 |
| - static int (*real_atfork)(void (*)(void), void (*)(void), void (*)(void)); |
| 76 | + static int (*real_atfork)(void (*)(void), void (*)(void), void (*)(void)); |
89 | 77 |
|
90 |
| - if (!real_atfork) { |
91 |
| - // dlopen musl |
| 78 | + if (!real_atfork) { |
| 79 | + // dlopen musl |
92 | 80 | #ifdef __aarch64__
|
93 |
| - void *handle = dlopen("ld-musl-aarch64.so.1", RTLD_LAZY); |
94 |
| - if (!handle) { |
95 |
| - fprintf(stderr, "dlopen of ld-musl-aarch64.so.1 failed: %s\n", |
96 |
| - dlerror()); |
97 |
| - abort(); |
98 |
| - } |
| 81 | + void *handle = dlopen("ld-musl-aarch64.so.1", RTLD_LAZY); |
| 82 | + if (!handle) { |
| 83 | + fprintf(stderr, "dlopen of ld-musl-aarch64.so.1 failed: %s\n", dlerror()); |
| 84 | + abort(); |
| 85 | + } |
99 | 86 | #else
|
100 |
| - void *handle = dlopen("libc.musl-x86_64.so.1", RTLD_LAZY); |
101 |
| - if (!handle) { |
102 |
| - fprintf(stderr, "dlopen of libc.musl-x86_64.so.1 failed: %s\n", |
103 |
| - dlerror()); |
104 |
| - abort(); |
105 |
| - } |
| 87 | + void *handle = dlopen("libc.musl-x86_64.so.1", RTLD_LAZY); |
| 88 | + if (!handle) { |
| 89 | + fprintf(stderr, "dlopen of libc.musl-x86_64.so.1 failed: %s\n", |
| 90 | + dlerror()); |
| 91 | + abort(); |
| 92 | + } |
106 | 93 | #endif
|
107 |
| - real_atfork = dlsym(handle, "pthread_atfork"); |
108 |
| - if (!real_atfork) { |
109 |
| - fprintf(stderr, "dlsym of pthread_atfork failed: %s\n", dlerror()); |
110 |
| - abort(); |
111 |
| - } |
| 94 | + real_atfork = dlsym(handle, "pthread_atfork"); |
| 95 | + if (!real_atfork) { |
| 96 | + fprintf(stderr, "dlsym of pthread_atfork failed: %s\n", dlerror()); |
| 97 | + abort(); |
112 | 98 | }
|
| 99 | + } |
113 | 100 |
|
114 |
| - return real_atfork(prepare, parent, child); |
| 101 | + return real_atfork(prepare, parent, child); |
115 | 102 | }
|
116 | 103 |
|
117 | 104 | // the symbol strerror_r in glibc is not the POSIX version; it returns char *
|
118 | 105 | // __xpg_sterror_r is exported by both glibc and musl
|
119 | 106 | int strerror_r(int errnum, char *buf, size_t buflen) {
|
120 |
| - int __xpg_strerror_r(int, char *, size_t); |
121 |
| - return __xpg_strerror_r(errnum, buf, buflen); |
| 107 | + int __xpg_strerror_r(int, char *, size_t); |
| 108 | + return __xpg_strerror_r(errnum, buf, buflen); |
| 109 | +} |
| 110 | + |
| 111 | +// when compiling with --coverage, some references to atexit show up. |
| 112 | +// glibc doesn't provide atexit for similar reasons as pthread_atfork presumably |
| 113 | +int __cxa_atexit(void (*func)(void *), void *arg, void *dso_handle); |
| 114 | +int atexit(void (*function)(void)) { |
| 115 | + if (!__dso_handle) { |
| 116 | + fprintf(stderr, "Aborting because __dso_handle is NULL\n"); |
| 117 | + abort(); |
| 118 | + } |
| 119 | + |
| 120 | + // the cast is harmless on amd64 and aarch64. Passing an extra argument to a |
| 121 | + // function that expects none causes no problems |
| 122 | + return __cxa_atexit((void (*)(void *))function, 0, __dso_handle); |
122 | 123 | }
|
123 | 124 |
|
124 | 125 | #endif
|
0 commit comments