362 lines · c
1#ifndef LLVM_TOOLS_LLVM_BOLT_SYS_X86_642#define LLVM_TOOLS_LLVM_BOLT_SYS_X86_643 4// Save all registers while keeping 16B stack alignment5#define SAVE_ALL \6 "push %%rax\n" \7 "push %%rbx\n" \8 "push %%rcx\n" \9 "push %%rdx\n" \10 "push %%rdi\n" \11 "push %%rsi\n" \12 "push %%rbp\n" \13 "push %%r8\n" \14 "push %%r9\n" \15 "push %%r10\n" \16 "push %%r11\n" \17 "push %%r12\n" \18 "push %%r13\n" \19 "push %%r14\n" \20 "push %%r15\n" \21 "sub $8, %%rsp\n"22// Mirrors SAVE_ALL23#define RESTORE_ALL \24 "add $8, %%rsp\n" \25 "pop %%r15\n" \26 "pop %%r14\n" \27 "pop %%r13\n" \28 "pop %%r12\n" \29 "pop %%r11\n" \30 "pop %%r10\n" \31 "pop %%r9\n" \32 "pop %%r8\n" \33 "pop %%rbp\n" \34 "pop %%rsi\n" \35 "pop %%rdi\n" \36 "pop %%rdx\n" \37 "pop %%rcx\n" \38 "pop %%rbx\n" \39 "pop %%rax\n"40 41namespace {42 43// Get the difference between runtime address of .text section and44// static address in section header table. Can be extracted from arbitrary45// pc value recorded at runtime to get the corresponding static address, which46// in turn can be used to search for indirect call description. Needed because47// indirect call descriptions are read-only non-relocatable data.48uint64_t getTextBaseAddress() {49 uint64_t DynAddr;50 uint64_t StaticAddr;51 __asm__ volatile("leaq __hot_end(%%rip), %0\n\t"52 "movabsq $__hot_end, %1\n\t"53 : "=r"(DynAddr), "=r"(StaticAddr));54 return DynAddr - StaticAddr;55}56 57#define _STRINGIFY(x) #x58#define STRINGIFY(x) _STRINGIFY(x)59 60uint64_t __read(uint64_t fd, const void *buf, uint64_t count) {61 uint64_t ret;62#if defined(__APPLE__)63#define READ_SYSCALL 0x200000364#else65#define READ_SYSCALL 066#endif67 __asm__ __volatile__("movq $" STRINGIFY(READ_SYSCALL) ", %%rax\n"68 "syscall\n"69 : "=a"(ret)70 : "D"(fd), "S"(buf), "d"(count)71 : "cc", "rcx", "r11", "memory");72 return ret;73}74 75uint64_t __write(uint64_t fd, const void *buf, uint64_t count) {76 uint64_t ret;77#if defined(__APPLE__)78#define WRITE_SYSCALL 0x200000479#else80#define WRITE_SYSCALL 181#endif82 __asm__ __volatile__("movq $" STRINGIFY(WRITE_SYSCALL) ", %%rax\n"83 "syscall\n"84 : "=a"(ret)85 : "D"(fd), "S"(buf), "d"(count)86 : "cc", "rcx", "r11", "memory");87 return ret;88}89 90void *__mmap(uint64_t addr, uint64_t size, uint64_t prot, uint64_t flags,91 uint64_t fd, uint64_t offset) {92#if defined(__APPLE__)93#define MMAP_SYSCALL 0x20000c594#else95#define MMAP_SYSCALL 996#endif97 void *ret;98 register uint64_t r8 asm("r8") = fd;99 register uint64_t r9 asm("r9") = offset;100 register uint64_t r10 asm("r10") = flags;101 __asm__ __volatile__("movq $" STRINGIFY(MMAP_SYSCALL) ", %%rax\n"102 "syscall\n"103 : "=a"(ret)104 : "D"(addr), "S"(size), "d"(prot), "r"(r10), "r"(r8),105 "r"(r9)106 : "cc", "rcx", "r11", "memory");107 return ret;108}109 110uint64_t __munmap(void *addr, uint64_t size) {111#if defined(__APPLE__)112#define MUNMAP_SYSCALL 0x2000049113#else114#define MUNMAP_SYSCALL 11115#endif116 uint64_t ret;117 __asm__ __volatile__("movq $" STRINGIFY(MUNMAP_SYSCALL) ", %%rax\n"118 "syscall\n"119 : "=a"(ret)120 : "D"(addr), "S"(size)121 : "cc", "rcx", "r11", "memory");122 return ret;123}124 125uint64_t __sigprocmask(int how, const void *set, void *oldset) {126#if defined(__APPLE__)127#define SIGPROCMASK_SYSCALL 0x2000030128#else129#define SIGPROCMASK_SYSCALL 14130#endif131 uint64_t ret;132 register long r10 asm("r10") = sizeof(uint64_t);133 __asm__ __volatile__("movq $" STRINGIFY(SIGPROCMASK_SYSCALL) ", %%rax\n"134 "syscall\n"135 : "=a"(ret)136 : "D"(how), "S"(set), "d"(oldset), "r"(r10)137 : "cc", "rcx", "r11", "memory");138 return ret;139}140 141uint64_t __getpid() {142 uint64_t ret;143#if defined(__APPLE__)144#define GETPID_SYSCALL 20145#else146#define GETPID_SYSCALL 39147#endif148 __asm__ __volatile__("movq $" STRINGIFY(GETPID_SYSCALL) ", %%rax\n"149 "syscall\n"150 : "=a"(ret)151 :152 : "cc", "rcx", "r11", "memory");153 return ret;154}155 156uint64_t __exit(uint64_t code) {157#if defined(__APPLE__)158#define EXIT_SYSCALL 0x2000001159#else160#define EXIT_SYSCALL 231161#endif162 uint64_t ret;163 __asm__ __volatile__("movq $" STRINGIFY(EXIT_SYSCALL) ", %%rax\n"164 "syscall\n"165 : "=a"(ret)166 : "D"(code)167 : "cc", "rcx", "r11", "memory");168 return ret;169}170 171#if !defined(__APPLE__)172// We use a stack-allocated buffer for string manipulation in many pieces of173// this code, including the code that prints each line of the fdata file. This174// buffer needs to accommodate large function names, but shouldn't be175// arbitrarily large (dynamically allocated) for simplicity of our memory space176// usage.177 178// Declare some syscall wrappers we use throughout this code to avoid linking179// against system libc.180uint64_t __open(const char *pathname, uint64_t flags, uint64_t mode) {181 uint64_t ret;182 __asm__ __volatile__("movq $2, %%rax\n"183 "syscall"184 : "=a"(ret)185 : "D"(pathname), "S"(flags), "d"(mode)186 : "cc", "rcx", "r11", "memory");187 return ret;188}189 190long __getdents64(unsigned int fd, dirent64 *dirp, size_t count) {191 long ret;192 __asm__ __volatile__("movq $217, %%rax\n"193 "syscall"194 : "=a"(ret)195 : "D"(fd), "S"(dirp), "d"(count)196 : "cc", "rcx", "r11", "memory");197 return ret;198}199 200uint64_t __readlink(const char *pathname, char *buf, size_t bufsize) {201 uint64_t ret;202 __asm__ __volatile__("movq $89, %%rax\n"203 "syscall"204 : "=a"(ret)205 : "D"(pathname), "S"(buf), "d"(bufsize)206 : "cc", "rcx", "r11", "memory");207 return ret;208}209 210uint64_t __lseek(uint64_t fd, uint64_t pos, uint64_t whence) {211 uint64_t ret;212 __asm__ __volatile__("movq $8, %%rax\n"213 "syscall\n"214 : "=a"(ret)215 : "D"(fd), "S"(pos), "d"(whence)216 : "cc", "rcx", "r11", "memory");217 return ret;218}219 220int __ftruncate(uint64_t fd, uint64_t length) {221 int ret;222 __asm__ __volatile__("movq $77, %%rax\n"223 "syscall\n"224 : "=a"(ret)225 : "D"(fd), "S"(length)226 : "cc", "rcx", "r11", "memory");227 return ret;228}229 230int __close(uint64_t fd) {231 uint64_t ret;232 __asm__ __volatile__("movq $3, %%rax\n"233 "syscall\n"234 : "=a"(ret)235 : "D"(fd)236 : "cc", "rcx", "r11", "memory");237 return ret;238}239 240int __madvise(void *addr, size_t length, int advice) {241 int ret;242 __asm__ __volatile__("movq $28, %%rax\n"243 "syscall\n"244 : "=a"(ret)245 : "D"(addr), "S"(length), "d"(advice)246 : "cc", "rcx", "r11", "memory");247 return ret;248}249 250int __uname(struct UtsNameTy *Buf) {251 int Ret;252 __asm__ __volatile__("movq $63, %%rax\n"253 "syscall\n"254 : "=a"(Ret)255 : "D"(Buf)256 : "cc", "rcx", "r11", "memory");257 return Ret;258}259 260uint64_t __nanosleep(const timespec *req, timespec *rem) {261 uint64_t ret;262 __asm__ __volatile__("movq $35, %%rax\n"263 "syscall\n"264 : "=a"(ret)265 : "D"(req), "S"(rem)266 : "cc", "rcx", "r11", "memory");267 return ret;268}269 270int64_t __fork() {271 uint64_t ret;272 __asm__ __volatile__("movq $57, %%rax\n"273 "syscall\n"274 : "=a"(ret)275 :276 : "cc", "rcx", "r11", "memory");277 return ret;278}279 280int __mprotect(void *addr, size_t len, int prot) {281 int ret;282 __asm__ __volatile__("movq $10, %%rax\n"283 "syscall\n"284 : "=a"(ret)285 : "D"(addr), "S"(len), "d"(prot)286 : "cc", "rcx", "r11", "memory");287 return ret;288}289 290uint64_t __getppid() {291 uint64_t ret;292 __asm__ __volatile__("movq $110, %%rax\n"293 "syscall\n"294 : "=a"(ret)295 :296 : "cc", "rcx", "r11", "memory");297 return ret;298}299 300int __setpgid(uint64_t pid, uint64_t pgid) {301 int ret;302 __asm__ __volatile__("movq $109, %%rax\n"303 "syscall\n"304 : "=a"(ret)305 : "D"(pid), "S"(pgid)306 : "cc", "rcx", "r11", "memory");307 return ret;308}309 310uint64_t __getpgid(uint64_t pid) {311 uint64_t ret;312 __asm__ __volatile__("movq $121, %%rax\n"313 "syscall\n"314 : "=a"(ret)315 : "D"(pid)316 : "cc", "rcx", "r11", "memory");317 return ret;318}319 320int __kill(uint64_t pid, int sig) {321 int ret;322 __asm__ __volatile__("movq $62, %%rax\n"323 "syscall\n"324 : "=a"(ret)325 : "D"(pid), "S"(sig)326 : "cc", "rcx", "r11", "memory");327 return ret;328}329 330int __fsync(int fd) {331 int ret;332 __asm__ __volatile__("movq $74, %%rax\n"333 "syscall\n"334 : "=a"(ret)335 : "D"(fd)336 : "cc", "rcx", "r11", "memory");337 return ret;338}339 340// %rdi %rsi %rdx %r10 %r8341// sys_prctl int option unsigned unsigned unsigned unsigned342// long arg2 long arg3 long arg4 long arg5343int __prctl(int Option, unsigned long Arg2, unsigned long Arg3,344 unsigned long Arg4, unsigned long Arg5) {345 int Ret;346 register long rdx asm("rdx") = Arg3;347 register long r8 asm("r8") = Arg5;348 register long r10 asm("r10") = Arg4;349 __asm__ __volatile__("movq $157, %%rax\n"350 "syscall\n"351 : "=a"(Ret)352 : "D"(Option), "S"(Arg2), "d"(rdx), "r"(r10), "r"(r8)353 :);354 return Ret;355}356 357#endif358 359} // anonymous namespace360 361#endif362