397 lines · c
1#ifndef LLVM_TOOLS_LLVM_BOLT_SYS_AARCH642#define LLVM_TOOLS_LLVM_BOLT_SYS_AARCH643 4// Save all registers while keeping 16B stack alignment5#define SAVE_ALL \6 "stp x0, x1, [sp, #-16]!\n" \7 "stp x2, x3, [sp, #-16]!\n" \8 "stp x4, x5, [sp, #-16]!\n" \9 "stp x6, x7, [sp, #-16]!\n" \10 "stp x8, x9, [sp, #-16]!\n" \11 "stp x10, x11, [sp, #-16]!\n" \12 "stp x12, x13, [sp, #-16]!\n" \13 "stp x14, x15, [sp, #-16]!\n" \14 "stp x16, x17, [sp, #-16]!\n" \15 "stp x18, x19, [sp, #-16]!\n" \16 "stp x20, x21, [sp, #-16]!\n" \17 "stp x22, x23, [sp, #-16]!\n" \18 "stp x24, x25, [sp, #-16]!\n" \19 "stp x26, x27, [sp, #-16]!\n" \20 "stp x28, x29, [sp, #-16]!\n" \21 "mrs x29, nzcv\n" \22 "stp x29, x30, [sp, #-16]!\n"23// Mirrors SAVE_ALL24#define RESTORE_ALL \25 "ldp x29, x30, [sp], #16\n" \26 "msr nzcv, x29\n" \27 "ldp x28, x29, [sp], #16\n" \28 "ldp x26, x27, [sp], #16\n" \29 "ldp x24, x25, [sp], #16\n" \30 "ldp x22, x23, [sp], #16\n" \31 "ldp x20, x21, [sp], #16\n" \32 "ldp x18, x19, [sp], #16\n" \33 "ldp x16, x17, [sp], #16\n" \34 "ldp x14, x15, [sp], #16\n" \35 "ldp x12, x13, [sp], #16\n" \36 "ldp x10, x11, [sp], #16\n" \37 "ldp x8, x9, [sp], #16\n" \38 "ldp x6, x7, [sp], #16\n" \39 "ldp x4, x5, [sp], #16\n" \40 "ldp x2, x3, [sp], #16\n" \41 "ldp x0, x1, [sp], #16\n"42 43// Anonymous namespace covering everything but our library entry point44namespace {45 46// Get the difference between runtime address of .text section and47// static address in section header table. Can be extracted from arbitrary48// pc value recorded at runtime to get the corresponding static address, which49// in turn can be used to search for indirect call description. Needed because50// indirect call descriptions are read-only non-relocatable data.51uint64_t getTextBaseAddress() {52 uint64_t DynAddr;53 uint64_t StaticAddr;54 __asm__ volatile("b .instr%=\n\t"55 ".StaticAddr%=:\n\t"56 ".dword __hot_end\n\t"57 ".instr%=:\n\t"58 "ldr %0, .StaticAddr%=\n\t"59 "adrp %1, __hot_end\n\t"60 "add %1, %1, :lo12:__hot_end\n\t"61 : "=r"(StaticAddr), "=r"(DynAddr));62 return DynAddr - StaticAddr;63}64 65uint64_t __read(uint64_t fd, const void *buf, uint64_t count) {66 uint64_t ret;67 register uint64_t x0 __asm__("x0") = fd;68 register const void *x1 __asm__("x1") = buf;69 register uint64_t x2 __asm__("x2") = count;70 register uint32_t w8 __asm__("w8") = 63;71 __asm__ __volatile__("svc #0\n"72 "mov %0, x0"73 : "=r"(ret), "+r"(x0), "+r"(x1)74 : "r"(x2), "r"(w8)75 : "cc", "memory");76 return ret;77}78 79uint64_t __write(uint64_t fd, const void *buf, uint64_t count) {80 uint64_t ret;81 register uint64_t x0 __asm__("x0") = fd;82 register const void *x1 __asm__("x1") = buf;83 register uint64_t x2 __asm__("x2") = count;84 register uint32_t w8 __asm__("w8") = 64;85 __asm__ __volatile__("svc #0\n"86 "mov %0, x0"87 : "=r"(ret), "+r"(x0), "+r"(x1)88 : "r"(x2), "r"(w8)89 : "cc", "memory");90 return ret;91}92 93void *__mmap(uint64_t addr, uint64_t size, uint64_t prot, uint64_t flags,94 uint64_t fd, uint64_t offset) {95 void *ret;96 register uint64_t x0 __asm__("x0") = addr;97 register uint64_t x1 __asm__("x1") = size;98 register uint64_t x2 __asm__("x2") = prot;99 register uint64_t x3 __asm__("x3") = flags;100 register uint64_t x4 __asm__("x4") = fd;101 register uint64_t x5 __asm__("x5") = offset;102 register uint32_t w8 __asm__("w8") = 222;103 __asm__ __volatile__("svc #0\n"104 "mov %0, x0"105 : "=r"(ret), "+r"(x0), "+r"(x1)106 : "r"(x2), "r"(x3), "r"(x4), "r"(x5), "r"(w8)107 : "cc", "memory");108 return ret;109}110 111uint64_t __munmap(void *addr, uint64_t size) {112 uint64_t ret;113 register void *x0 __asm__("x0") = addr;114 register uint64_t x1 __asm__("x1") = size;115 register uint32_t w8 __asm__("w8") = 215;116 __asm__ __volatile__("svc #0\n"117 "mov %0, x0"118 : "=r"(ret), "+r"(x0), "+r"(x1)119 : "r"(w8)120 : "cc", "memory");121 return ret;122}123 124uint64_t __exit(uint64_t code) {125 uint64_t ret;126 register uint64_t x0 __asm__("x0") = code;127 register uint32_t w8 __asm__("w8") = 94;128 __asm__ __volatile__("svc #0\n"129 "mov %0, x0"130 : "=r"(ret), "+r"(x0)131 : "r"(w8)132 : "cc", "memory", "x1");133 return ret;134}135 136uint64_t __open(const char *pathname, uint64_t flags, uint64_t mode) {137 uint64_t ret;138 register int x0 __asm__("x0") = -100;139 register const char *x1 __asm__("x1") = pathname;140 register uint64_t x2 __asm__("x2") = flags;141 register uint64_t x3 __asm__("x3") = mode;142 register uint32_t w8 __asm__("w8") = 56;143 __asm__ __volatile__("svc #0\n"144 "mov %0, x0"145 : "=r"(ret), "+r"(x0), "+r"(x1)146 : "r"(x2), "r"(x3), "r"(w8)147 : "cc", "memory");148 return ret;149}150 151long __getdents64(unsigned int fd, dirent64 *dirp, size_t count) {152 long ret;153 register unsigned int x0 __asm__("x0") = fd;154 register dirent64 *x1 __asm__("x1") = dirp;155 register size_t x2 __asm__("x2") = count;156 register uint32_t w8 __asm__("w8") = 61;157 __asm__ __volatile__("svc #0\n"158 "mov %0, x0"159 : "=r"(ret), "+r"(x0), "+r"(x1)160 : "r"(x2), "r"(w8)161 : "cc", "memory");162 return ret;163}164 165uint64_t __readlink(const char *pathname, char *buf, size_t bufsize) {166 uint64_t ret;167 register int x0 __asm__("x0") = -100;168 register const char *x1 __asm__("x1") = pathname;169 register char *x2 __asm__("x2") = buf;170 register size_t x3 __asm__("x3") = bufsize;171 register uint32_t w8 __asm__("w8") = 78; // readlinkat172 __asm__ __volatile__("svc #0\n"173 "mov %0, x0"174 : "=r"(ret), "+r"(x0), "+r"(x1)175 : "r"(x2), "r"(x3), "r"(w8)176 : "cc", "memory");177 return ret;178}179 180uint64_t __lseek(uint64_t fd, uint64_t pos, uint64_t whence) {181 uint64_t ret;182 register uint64_t x0 __asm__("x0") = fd;183 register uint64_t x1 __asm__("x1") = pos;184 register uint64_t x2 __asm__("x2") = whence;185 register uint32_t w8 __asm__("w8") = 62;186 __asm__ __volatile__("svc #0\n"187 "mov %0, x0"188 : "=r"(ret), "+r"(x0), "+r"(x1)189 : "r"(x2), "r"(w8)190 : "cc", "memory");191 return ret;192}193 194int __ftruncate(uint64_t fd, uint64_t length) {195 int ret;196 register uint64_t x0 __asm__("x0") = fd;197 register uint64_t x1 __asm__("x1") = length;198 register uint32_t w8 __asm__("w8") = 46;199 __asm__ __volatile__("svc #0\n"200 "mov %w0, w0"201 : "=r"(ret), "+r"(x0), "+r"(x1)202 : "r"(w8)203 : "cc", "memory");204 return ret;205}206 207int __close(uint64_t fd) {208 int ret;209 register uint64_t x0 __asm__("x0") = fd;210 register uint32_t w8 __asm__("w8") = 57;211 __asm__ __volatile__("svc #0\n"212 "mov %w0, w0"213 : "=r"(ret), "+r"(x0)214 : "r"(w8)215 : "cc", "memory", "x1");216 return ret;217}218 219int __madvise(void *addr, size_t length, int advice) {220 int ret;221 register void *x0 __asm__("x0") = addr;222 register size_t x1 __asm__("x1") = length;223 register int x2 __asm__("x2") = advice;224 register uint32_t w8 __asm__("w8") = 233;225 __asm__ __volatile__("svc #0\n"226 "mov %w0, w0"227 : "=r"(ret), "+r"(x0), "+r"(x1)228 : "r"(x2), "r"(w8)229 : "cc", "memory");230 return ret;231}232 233int __uname(struct UtsNameTy *buf) {234 int ret;235 register UtsNameTy *x0 __asm__("x0") = buf;236 register uint32_t w8 __asm__("w8") = 160;237 __asm__ __volatile__("svc #0\n"238 "mov %w0, w0"239 : "=r"(ret), "+r"(x0)240 : "r"(w8)241 : "cc", "memory", "x1");242 return ret;243}244 245uint64_t __nanosleep(const timespec *req, timespec *rem) {246 uint64_t ret;247 register const timespec *x0 __asm__("x0") = req;248 register timespec *x1 __asm__("x1") = rem;249 register uint32_t w8 __asm__("w8") = 101;250 __asm__ __volatile__("svc #0\n"251 "mov %0, x0"252 : "=r"(ret), "+r"(x0), "+r"(x1)253 : "r"(w8)254 : "cc", "memory");255 return ret;256}257 258int64_t __fork() {259 uint64_t ret;260 // clone instead of fork with flags261 // "CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD"262 register uint64_t x0 __asm__("x0") = 0x1200011;263 register uint64_t x1 __asm__("x1") = 0;264 register uint64_t x2 __asm__("x2") = 0;265 register uint64_t x3 __asm__("x3") = 0;266 register uint64_t x4 __asm__("x4") = 0;267 register uint32_t w8 __asm__("w8") = 220;268 __asm__ __volatile__("svc #0\n"269 "mov %0, x0"270 : "=r"(ret), "+r"(x0), "+r"(x1)271 : "r"(x2), "r"(x3), "r"(x4), "r"(w8)272 : "cc", "memory");273 return ret;274}275 276int __mprotect(void *addr, size_t len, int prot) {277 int ret;278 register void *x0 __asm__("x0") = addr;279 register size_t x1 __asm__("x1") = len;280 register int x2 __asm__("x2") = prot;281 register uint32_t w8 __asm__("w8") = 226;282 __asm__ __volatile__("svc #0\n"283 "mov %w0, w0"284 : "=r"(ret), "+r"(x0), "+r"(x1)285 : "r"(x2), "r"(w8)286 : "cc", "memory");287 return ret;288}289 290uint64_t __getpid() {291 uint64_t ret;292 register uint32_t w8 __asm__("w8") = 172;293 __asm__ __volatile__("svc #0\n"294 "mov %0, x0"295 : "=r"(ret)296 : "r"(w8)297 : "cc", "memory", "x0", "x1");298 return ret;299}300 301uint64_t __getppid() {302 uint64_t ret;303 register uint32_t w8 __asm__("w8") = 173;304 __asm__ __volatile__("svc #0\n"305 "mov %0, x0"306 : "=r"(ret)307 : "r"(w8)308 : "cc", "memory", "x0", "x1");309 return ret;310}311 312int __setpgid(uint64_t pid, uint64_t pgid) {313 int ret;314 register uint64_t x0 __asm__("x0") = pid;315 register uint64_t x1 __asm__("x1") = pgid;316 register uint32_t w8 __asm__("w8") = 154;317 __asm__ __volatile__("svc #0\n"318 "mov %w0, w0"319 : "=r"(ret), "+r"(x0), "+r"(x1)320 : "r"(w8)321 : "cc", "memory");322 return ret;323}324 325uint64_t __getpgid(uint64_t pid) {326 uint64_t ret;327 register uint64_t x0 __asm__("x0") = pid;328 register uint32_t w8 __asm__("w8") = 155;329 __asm__ __volatile__("svc #0\n"330 "mov %0, x0"331 : "=r"(ret), "+r"(x0)332 : "r"(w8)333 : "cc", "memory", "x1");334 return ret;335}336 337int __kill(uint64_t pid, int sig) {338 int ret;339 register uint64_t x0 __asm__("x0") = pid;340 register int x1 __asm__("x1") = sig;341 register uint32_t w8 __asm__("w8") = 129;342 __asm__ __volatile__("svc #0\n"343 "mov %w0, w0"344 : "=r"(ret), "+r"(x0), "+r"(x1)345 : "r"(w8)346 : "cc", "memory");347 return ret;348}349 350int __fsync(int fd) {351 int ret;352 register int x0 __asm__("x0") = fd;353 register uint32_t w8 __asm__("w8") = 82;354 __asm__ __volatile__("svc #0\n"355 "mov %w0, w0"356 : "=r"(ret), "+r"(x0)357 : "r"(w8)358 : "cc", "memory", "x1");359 return ret;360}361 362uint64_t __sigprocmask(int how, const void *set, void *oldset) {363 uint64_t ret;364 register int x0 __asm__("x0") = how;365 register const void *x1 __asm__("x1") = set;366 register void *x2 __asm__("x2") = oldset;367 register long x3 asm("x3") = 8;368 register uint32_t w8 __asm__("w8") = 135;369 __asm__ __volatile__("svc #0\n"370 "mov %0, x0"371 : "=r"(ret), "+r"(x0), "+r"(x1)372 : "r"(x2), "r"(x3), "r"(w8)373 : "cc", "memory");374 return ret;375}376 377int __prctl(int option, unsigned long arg2, unsigned long arg3,378 unsigned long arg4, unsigned long arg5) {379 int ret;380 register int x0 __asm__("x0") = option;381 register unsigned long x1 __asm__("x1") = arg2;382 register unsigned long x2 __asm__("x2") = arg3;383 register unsigned long x3 __asm__("x3") = arg4;384 register unsigned long x4 __asm__("x4") = arg5;385 register uint32_t w8 __asm__("w8") = 167;386 __asm__ __volatile__("svc #0\n"387 "mov %w0, w0"388 : "=r"(ret), "+r"(x0), "+r"(x1)389 : "r"(x2), "r"(x3), "r"(x4), "r"(w8)390 : "cc", "memory");391 return ret;392}393 394} // anonymous namespace395 396#endif397