460 lines · c
1#ifndef LLVM_TOOLS_LLVM_BOLT_SYS_RISCV2#define LLVM_TOOLS_LLVM_BOLT_SYS_RISCV3 4// Save all registers while keeping 16B stack alignment5#define SAVE_ALL \6 "addi sp, sp, -16\n" \7 "sd x0, 0(sp)\n" \8 "sd x1, 8(sp)\n" \9 "addi sp, sp, -16\n" \10 "sd x2, 0(sp)\n" \11 "sd x3, 8(sp)\n" \12 "addi sp, sp, -16\n" \13 "sd x4, 0(sp)\n" \14 "sd x5, 8(sp)\n" \15 "addi sp, sp, -16\n" \16 "sd x6, 0(sp)\n" \17 "sd x7, 8(sp)\n" \18 "addi sp, sp, -16\n" \19 "sd x8, 0(sp)\n" \20 "sd x9, 8(sp)\n" \21 "addi sp, sp, -16\n" \22 "sd x10, 0(sp)\n" \23 "sd x11, 8(sp)\n" \24 "addi sp, sp, -16\n" \25 "sd x12, 0(sp)\n" \26 "sd x13, 8(sp)\n" \27 "addi sp, sp, -16\n" \28 "sd x14, 0(sp)\n" \29 "sd x15, 8(sp)\n" \30 "addi sp, sp, -16\n" \31 "sd x16, 0(sp)\n" \32 "sd x17, 8(sp)\n" \33 "addi sp, sp, -16\n" \34 "sd x18, 0(sp)\n" \35 "sd x19, 8(sp)\n" \36 "addi sp, sp, -16\n" \37 "sd x20, 0(sp)\n" \38 "sd x21, 8(sp)\n" \39 "addi sp, sp, -16\n" \40 "sd x22, 0(sp)\n" \41 "sd x23, 8(sp)\n" \42 "addi sp, sp, -16\n" \43 "sd x24, 0(sp)\n" \44 "sd x25, 8(sp)\n" \45 "addi sp, sp, -16\n" \46 "sd x26, 0(sp)\n" \47 "sd x27, 8(sp)\n" \48 "addi sp, sp, -16\n" \49 "sd x28, 0(sp)\n" \50 "sd x29, 8(sp)\n" \51 "addi sp, sp, -16\n" \52 "sd x30, 0(sp)\n" \53 "sd x31, 8(sp)\n"54// Mirrors SAVE_ALL55#define RESTORE_ALL \56 "ld x30, 0(sp)\n" \57 "ld x31, 8(sp)\n" \58 "addi sp, sp, 16\n" \59 "ld x28, 0(sp)\n" \60 "ld x29, 8(sp)\n" \61 "addi sp, sp, 16\n" \62 "ld x26, 0(sp)\n" \63 "ld x27, 8(sp)\n" \64 "addi sp, sp, 16\n" \65 "ld x24, 0(sp)\n" \66 "ld x25, 8(sp)\n" \67 "addi sp, sp, 16\n" \68 "ld x22, 0(sp)\n" \69 "ld x23, 8(sp)\n" \70 "addi sp, sp, 16\n" \71 "ld x20, 0(sp)\n" \72 "ld x21, 8(sp)\n" \73 "addi sp, sp, 16\n" \74 "ld x18, 0(sp)\n" \75 "ld x19, 8(sp)\n" \76 "addi sp, sp, 16\n" \77 "ld x16, 0(sp)\n" \78 "ld x17, 8(sp)\n" \79 "addi sp, sp, 16\n" \80 "ld x14, 0(sp)\n" \81 "ld x15, 8(sp)\n" \82 "addi sp, sp, 16\n" \83 "ld x12, 0(sp)\n" \84 "ld x13, 8(sp)\n" \85 "addi sp, sp, 16\n" \86 "ld x10, 0(sp)\n" \87 "ld x11, 8(sp)\n" \88 "addi sp, sp, 16\n" \89 "ld x8, 0(sp)\n" \90 "ld x9, 8(sp)\n" \91 "addi sp, sp, 16\n" \92 "ld x6, 0(sp)\n" \93 "ld x7, 8(sp)\n" \94 "addi sp, sp, 16\n" \95 "ld x4, 0(sp)\n" \96 "ld x5, 8(sp)\n" \97 "addi sp, sp, 16\n" \98 "ld x2, 0(sp)\n" \99 "ld x3, 8(sp)\n" \100 "addi sp, sp, 16\n" \101 "ld x0, 0(sp)\n" \102 "ld x1, 8(sp)\n" \103 "addi sp, sp, 16\n"104 105// Anonymous namespace covering everything but our library entry point106namespace {107 108// Get the difference between runtime address of .text section and109// static address in section header table. Can be extracted from arbitrary110// pc value recorded at runtime to get the corresponding static address, which111// in turn can be used to search for indirect call description. Needed because112// indirect call descriptions are read-only non-relocatable data.113uint64_t getTextBaseAddress() {114 uint64_t DynAddr;115 uint64_t StaticAddr;116 __asm__ volatile("lla %0, __hot_end\n\t"117 "lui %1, %%hi(__hot_end)\n\t"118 "addi %1, %1, %%lo(__hot_end)\n\t"119 : "=r"(DynAddr), "=r"(StaticAddr));120 return DynAddr - StaticAddr;121}122 123uint64_t __read(uint64_t fd, const void *buf, uint64_t count) {124 uint64_t ret;125 register uint64_t a0 __asm__("a0") = fd;126 register const void *a1 __asm__("a1") = buf;127 register uint64_t a2 __asm__("a2") = count;128 register uint64_t a7 __asm__("a7") =129 63; // Assuming 63 is the syscall number for read130 __asm__ __volatile__("ecall\n\t"131 "mv %0, a0"132 : "=r"(ret)133 : "r"(a0), "r"(a1), "r"(a2), "r"(a7)134 : "memory");135 return ret;136}137 138uint64_t __write(uint64_t fd, const void *buf, uint64_t count) {139 uint64_t ret;140 register uint64_t a0 __asm__("a0") = fd;141 register const void *a1 __asm__("a1") = buf;142 register uint64_t a2 __asm__("a2") = count;143 register uint32_t a7 __asm__("a7") =144 64; // Assuming 64 is the syscall number for write145 __asm__ __volatile__("ecall\n\t"146 "mv %0, a0"147 : "=r"(ret)148 : "r"(a0), "r"(a1), "r"(a2), "r"(a7)149 : "memory");150 return ret;151}152 153void *__mmap(uint64_t addr, uint64_t size, uint64_t prot, uint64_t flags,154 uint64_t fd, uint64_t offset) {155 void *ret;156 register uint64_t a0 __asm__("a0") = addr;157 register uint64_t a1 __asm__("a1") = size;158 register uint64_t a2 __asm__("a2") = prot;159 register uint64_t a3 __asm__("a3") = flags;160 register uint64_t a4 __asm__("a4") = fd;161 register uint64_t a5 __asm__("a5") = offset;162 register uint32_t a7 __asm__("a7") =163 222; // Assuming 222 is the syscall number for mmap164 __asm__ __volatile__("ecall\n\t"165 "mv %0, a0"166 : "=r"(ret)167 : "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5),168 "r"(a7)169 : "memory");170 return ret;171}172 173uint64_t __munmap(void *addr, uint64_t size) {174 uint64_t ret;175 register void *a0 __asm__("a0") = addr;176 register uint64_t a1 __asm__("a1") = size;177 register uint32_t a7 __asm__("a7") = 215;178 __asm__ __volatile__("ecall\n\t"179 "mv %0, a0"180 : "=r"(ret), "+r"(a0), "+r"(a1)181 : "r"(a7)182 : "memory");183 return ret;184}185 186uint64_t __exit(uint64_t code) {187 uint64_t ret;188 register uint64_t a0 __asm__("a0") = code;189 register uint32_t a7 __asm__("a7") = 94;190 __asm__ __volatile__("ecall\n\t"191 "mv %0, a0"192 : "=r"(ret), "+r"(a0)193 : "r"(a7)194 : "memory");195 return ret;196}197 198uint64_t __open(const char *pathname, uint64_t flags, uint64_t mode) {199 uint64_t ret;200 register int a0 __asm__("a0") =201 -100; // Assuming -100 is an invalid file descriptor202 register const char *a1 __asm__("a1") = pathname;203 register uint64_t a2 __asm__("a2") = flags;204 register uint64_t a3 __asm__("a3") = mode;205 register uint64_t a7 __asm__("a7") =206 56; // Assuming 56 is the syscall number for open207 __asm__ __volatile__("ecall\n\t"208 "mv %0, a0"209 : "=r"(ret)210 : "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a7)211 : "memory");212 return ret;213}214 215long __getdents64(unsigned int fd, dirent64 *dirp, size_t count) {216 long ret;217 register unsigned int a0 __asm__("a0") = fd;218 register dirent64 *a1 __asm__("a1") = dirp;219 register size_t a2 __asm__("a2") = count;220 register uint32_t a7 __asm__("a7") = 61;221 __asm__ __volatile__("ecall\n\t"222 "mv %0, a0"223 : "=r"(ret), "+r"(a0), "+r"(a1)224 : "r"(a2), "r"(a7)225 : "memory");226 return ret;227}228 229uint64_t __readlink(const char *pathname, char *buf, size_t bufsize) {230 uint64_t ret;231 register int a0 __asm__("a0") = -100;232 register const char *a1 __asm__("a1") = pathname;233 register char *a2 __asm__("a2") = buf;234 register size_t a3 __asm__("a3") = bufsize;235 register uint32_t a7 __asm__("a7") = 78; // readlinkat236 __asm__ __volatile__("ecall\n\t"237 "mv %0, a0"238 : "=r"(ret), "+r"(a0), "+r"(a1)239 : "r"(a2), "r"(a3), "r"(a7)240 : "memory");241 return ret;242}243 244uint64_t __lseek(uint64_t fd, uint64_t pos, uint64_t whence) {245 uint64_t ret;246 register uint64_t a0 __asm__("a0") = fd;247 register uint64_t a1 __asm__("a1") = pos;248 register uint64_t a2 __asm__("a2") = whence;249 register uint32_t a7 __asm__("a7") = 62;250 __asm__ __volatile__("ecall\n\t"251 "mv %0, a0"252 : "=r"(ret), "+r"(a0), "+r"(a1)253 : "r"(a2), "r"(a7)254 : "memory");255 return ret;256}257 258int __ftruncate(uint64_t fd, uint64_t length) {259 int ret;260 register uint64_t a0 __asm__("a0") = fd;261 register uint64_t a1 __asm__("a1") = length;262 register uint32_t a7 __asm__("a7") = 46;263 __asm__ __volatile__("ecall\n\t"264 "mv %0, a0"265 : "=r"(ret), "+r"(a0), "+r"(a1)266 : "r"(a7)267 : "memory");268 return ret;269}270 271int __close(uint64_t fd) {272 int ret;273 register uint64_t a0 __asm__("a0") = fd;274 register uint32_t a7 __asm__("a7") =275 57; // Assuming 57 is the syscall number for close276 __asm__ __volatile__("ecall\n\t"277 "mv %0, a0"278 : "=r"(ret)279 : "r"(a0), "r"(a7)280 : "memory");281 return ret;282}283 284int __madvise(void *addr, size_t length, int advice) {285 int ret;286 register void *a0 __asm__("a0") = addr;287 register size_t a1 __asm__("a1") = length;288 register int a2 __asm__("a2") = advice;289 register uint32_t a7 __asm__("a7") = 233;290 __asm__ __volatile__("ecall\n\t"291 "mv %0, a0"292 : "=r"(ret), "+r"(a0), "+r"(a1)293 : "r"(a2), "r"(a7)294 : "memory");295 return ret;296}297 298int __uname(struct UtsNameTy *buf) {299 int ret;300 register UtsNameTy *a0 __asm__("a0") = buf;301 register uint32_t a7 __asm__("a7") = 160;302 __asm__ __volatile__("ecall\n\t"303 "mv %0, a0"304 : "=r"(ret), "+r"(a0)305 : "r"(a7)306 : "memory");307 return ret;308}309 310uint64_t __nanosleep(const timespec *req, timespec *rem) {311 uint64_t ret;312 register const timespec *a0 __asm__("a0") = req;313 register timespec *a1 __asm__("a1") = rem;314 register uint32_t a7 __asm__("a7") = 101;315 __asm__ __volatile__("ecall\n\t"316 "mv %0, a0"317 : "=r"(ret), "+r"(a0), "+r"(a1)318 : "r"(a7)319 : "memory");320 return ret;321}322 323int64_t __fork() {324 uint64_t ret;325 // clone instead of fork with flags326 // "CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD"327 register uint64_t a0 __asm__("a0") = 0x1200011;328 register uint64_t a1 __asm__("a1") = 0;329 register uint64_t a2 __asm__("a2") = 0;330 register uint64_t a3 __asm__("a3") = 0;331 register uint64_t a4 __asm__("a4") = 0;332 register uint32_t a7 __asm__("a7") = 220;333 __asm__ __volatile__("ecall\n\t"334 "mv %0, a0"335 : "=r"(ret), "+r"(a0), "+r"(a1)336 : "r"(a2), "r"(a3), "r"(a4), "r"(a7)337 : "memory");338 return ret;339}340 341int __mprotect(void *addr, size_t len, int prot) {342 int ret;343 register void *a0 __asm__("a0") = addr;344 register size_t a1 __asm__("a1") = len;345 register int a2 __asm__("a2") = prot;346 register uint32_t a7 __asm__("a7") = 226;347 __asm__ __volatile__("ecall\n\t"348 "mv %0, a0"349 : "=r"(ret), "+r"(a0), "+r"(a1)350 : "r"(a2), "r"(a7)351 : "memory");352 return ret;353}354 355uint64_t __getpid() {356 uint64_t ret;357 register uint32_t a7 __asm__("a7") = 172;358 __asm__ __volatile__("ecall\n\t"359 "mv %0, a0"360 : "=r"(ret)361 : "r"(a7)362 : "memory");363 return ret;364}365 366uint64_t __getppid() {367 uint64_t ret;368 register uint32_t a7 __asm__("a7") = 173;369 __asm__ __volatile__("ecall\n\t"370 "mv %0, a0"371 : "=r"(ret)372 : "r"(a7)373 : "memory");374 return ret;375}376 377int __setpgid(uint64_t pid, uint64_t pgid) {378 int ret;379 register uint64_t a0 __asm__("a0") = pid;380 register uint64_t a1 __asm__("a1") = pgid;381 register uint32_t a7 __asm__("a7") = 154;382 __asm__ __volatile__("ecall\n\t"383 "mv %0, a0"384 : "=r"(ret), "+r"(a0), "+r"(a1)385 : "r"(a7)386 : "memory");387 return ret;388}389 390uint64_t __getpgid(uint64_t pid) {391 uint64_t ret;392 register uint64_t a0 __asm__("a0") = pid;393 register uint32_t a7 __asm__("a7") = 155;394 __asm__ __volatile__("ecall\n\t"395 "mv %0, a0"396 : "=r"(ret), "+r"(a0)397 : "r"(a7)398 : "memory");399 return ret;400}401 402int __kill(uint64_t pid, int sig) {403 int ret;404 register uint64_t a0 __asm__("a0") = pid;405 register int a1 __asm__("a1") = sig;406 register uint32_t a7 __asm__("a7") = 129;407 __asm__ __volatile__("ecall\n\t"408 "mv %0, a0"409 : "=r"(ret), "+r"(a0), "+r"(a1)410 : "r"(a7)411 : "memory");412 return ret;413}414 415int __fsync(int fd) {416 int ret;417 register int a0 __asm__("a0") = fd;418 register uint32_t a7 __asm__("a7") = 82;419 __asm__ __volatile__("ecall\n\t"420 "mv %0, a0"421 : "=r"(ret), "+r"(a0)422 : "r"(a7)423 : "memory");424 return ret;425}426 427uint64_t __sigprocmask(int how, const void *set, void *oldset) {428 uint64_t ret;429 register int a0 __asm__("a0") = how;430 register const void *a1 __asm__("a1") = set;431 register void *a2 __asm__("a2") = oldset;432 register long a3 asm("a3") = 8;433 register uint32_t a7 __asm__("a7") = 135;434 __asm__ __volatile__("ecall\n\t"435 "mv %0, a0"436 : "=r"(ret), "+r"(a0), "+r"(a1)437 : "r"(a2), "r"(a3), "r"(a7)438 : "memory");439 return ret;440}441 442int __prctl(int option, unsigned long arg2, unsigned long arg3,443 unsigned long arg4, unsigned long arg5) {444 int ret;445 register int a0 __asm__("a0") = option;446 register unsigned long a1 __asm__("a1") = arg2;447 register unsigned long a2 __asm__("a2") = arg3;448 register unsigned long a3 __asm__("a3") = arg4;449 register unsigned long a4 __asm__("a4") = arg5;450 register uint32_t a7 __asm__("a7") = 167;451 __asm__ __volatile__("ecall\n\t"452 "mv %0, a0"453 : "=r"(ret), "+r"(a0), "+r"(a1)454 : "r"(a2), "r"(a3), "r"(a4), "r"(a7)455 : "cc", "memory");456 return ret;457}458} // anonymous namespace459 460#endif