|
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