cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
460 lines
19 KiB
C
460 lines
19 KiB
C
#ifndef LLVM_TOOLS_LLVM_BOLT_SYS_RISCV
|
|
#define LLVM_TOOLS_LLVM_BOLT_SYS_RISCV
|
|
|
|
// Save all registers while keeping 16B stack alignment
|
|
#define SAVE_ALL \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x0, 0(sp)\n" \
|
|
"sd x1, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x2, 0(sp)\n" \
|
|
"sd x3, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x4, 0(sp)\n" \
|
|
"sd x5, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x6, 0(sp)\n" \
|
|
"sd x7, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x8, 0(sp)\n" \
|
|
"sd x9, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x10, 0(sp)\n" \
|
|
"sd x11, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x12, 0(sp)\n" \
|
|
"sd x13, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x14, 0(sp)\n" \
|
|
"sd x15, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x16, 0(sp)\n" \
|
|
"sd x17, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x18, 0(sp)\n" \
|
|
"sd x19, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x20, 0(sp)\n" \
|
|
"sd x21, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x22, 0(sp)\n" \
|
|
"sd x23, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x24, 0(sp)\n" \
|
|
"sd x25, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x26, 0(sp)\n" \
|
|
"sd x27, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x28, 0(sp)\n" \
|
|
"sd x29, 8(sp)\n" \
|
|
"addi sp, sp, -16\n" \
|
|
"sd x30, 0(sp)\n" \
|
|
"sd x31, 8(sp)\n"
|
|
// Mirrors SAVE_ALL
|
|
#define RESTORE_ALL \
|
|
"ld x30, 0(sp)\n" \
|
|
"ld x31, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x28, 0(sp)\n" \
|
|
"ld x29, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x26, 0(sp)\n" \
|
|
"ld x27, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x24, 0(sp)\n" \
|
|
"ld x25, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x22, 0(sp)\n" \
|
|
"ld x23, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x20, 0(sp)\n" \
|
|
"ld x21, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x18, 0(sp)\n" \
|
|
"ld x19, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x16, 0(sp)\n" \
|
|
"ld x17, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x14, 0(sp)\n" \
|
|
"ld x15, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x12, 0(sp)\n" \
|
|
"ld x13, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x10, 0(sp)\n" \
|
|
"ld x11, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x8, 0(sp)\n" \
|
|
"ld x9, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x6, 0(sp)\n" \
|
|
"ld x7, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x4, 0(sp)\n" \
|
|
"ld x5, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x2, 0(sp)\n" \
|
|
"ld x3, 8(sp)\n" \
|
|
"addi sp, sp, 16\n" \
|
|
"ld x0, 0(sp)\n" \
|
|
"ld x1, 8(sp)\n" \
|
|
"addi sp, sp, 16\n"
|
|
|
|
// Anonymous namespace covering everything but our library entry point
|
|
namespace {
|
|
|
|
// Get the difference between runtime addrress of .text section and
|
|
// static address in section header table. Can be extracted from arbitrary
|
|
// pc value recorded at runtime to get the corresponding static address, which
|
|
// in turn can be used to search for indirect call description. Needed because
|
|
// indirect call descriptions are read-only non-relocatable data.
|
|
uint64_t getTextBaseAddress() {
|
|
uint64_t DynAddr;
|
|
uint64_t StaticAddr;
|
|
__asm__ volatile("lla %0, __hot_end\n\t"
|
|
"lui %1, %%hi(__hot_end)\n\t"
|
|
"addi %1, %1, %%lo(__hot_end)\n\t"
|
|
: "=r"(DynAddr), "=r"(StaticAddr));
|
|
return DynAddr - StaticAddr;
|
|
}
|
|
|
|
uint64_t __read(uint64_t fd, const void *buf, uint64_t count) {
|
|
uint64_t ret;
|
|
register uint64_t a0 __asm__("a0") = fd;
|
|
register const void *a1 __asm__("a1") = buf;
|
|
register uint64_t a2 __asm__("a2") = count;
|
|
register uint64_t a7 __asm__("a7") =
|
|
63; // Assuming 63 is the syscall number for read
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret)
|
|
: "r"(a0), "r"(a1), "r"(a2), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __write(uint64_t fd, const void *buf, uint64_t count) {
|
|
uint64_t ret;
|
|
register uint64_t a0 __asm__("a0") = fd;
|
|
register const void *a1 __asm__("a1") = buf;
|
|
register uint64_t a2 __asm__("a2") = count;
|
|
register uint32_t a7 __asm__("a7") =
|
|
64; // Assuming 64 is the syscall number for write
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret)
|
|
: "r"(a0), "r"(a1), "r"(a2), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
void *__mmap(uint64_t addr, uint64_t size, uint64_t prot, uint64_t flags,
|
|
uint64_t fd, uint64_t offset) {
|
|
void *ret;
|
|
register uint64_t a0 __asm__("a0") = addr;
|
|
register uint64_t a1 __asm__("a1") = size;
|
|
register uint64_t a2 __asm__("a2") = prot;
|
|
register uint64_t a3 __asm__("a3") = flags;
|
|
register uint64_t a4 __asm__("a4") = fd;
|
|
register uint64_t a5 __asm__("a5") = offset;
|
|
register uint32_t a7 __asm__("a7") =
|
|
222; // Assuming 222 is the syscall number for mmap
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret)
|
|
: "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5),
|
|
"r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __munmap(void *addr, uint64_t size) {
|
|
uint64_t ret;
|
|
register void *a0 __asm__("a0") = addr;
|
|
register uint64_t a1 __asm__("a1") = size;
|
|
register uint32_t a7 __asm__("a7") = 215;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __exit(uint64_t code) {
|
|
uint64_t ret;
|
|
register uint64_t a0 __asm__("a0") = code;
|
|
register uint32_t a7 __asm__("a7") = 94;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __open(const char *pathname, uint64_t flags, uint64_t mode) {
|
|
uint64_t ret;
|
|
register int a0 __asm__("a0") =
|
|
-100; // Assuming -100 is an invalid file descriptor
|
|
register const char *a1 __asm__("a1") = pathname;
|
|
register uint64_t a2 __asm__("a2") = flags;
|
|
register uint64_t a3 __asm__("a3") = mode;
|
|
register uint64_t a7 __asm__("a7") =
|
|
56; // Assuming 56 is the syscall number for open
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret)
|
|
: "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
long __getdents64(unsigned int fd, dirent64 *dirp, size_t count) {
|
|
long ret;
|
|
register unsigned int a0 __asm__("a0") = fd;
|
|
register dirent64 *a1 __asm__("a1") = dirp;
|
|
register size_t a2 __asm__("a2") = count;
|
|
register uint32_t a7 __asm__("a7") = 61;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a2), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __readlink(const char *pathname, char *buf, size_t bufsize) {
|
|
uint64_t ret;
|
|
register int a0 __asm__("a0") = -100;
|
|
register const char *a1 __asm__("a1") = pathname;
|
|
register char *a2 __asm__("a2") = buf;
|
|
register size_t a3 __asm__("a3") = bufsize;
|
|
register uint32_t a7 __asm__("a7") = 78; // readlinkat
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a2), "r"(a3), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __lseek(uint64_t fd, uint64_t pos, uint64_t whence) {
|
|
uint64_t ret;
|
|
register uint64_t a0 __asm__("a0") = fd;
|
|
register uint64_t a1 __asm__("a1") = pos;
|
|
register uint64_t a2 __asm__("a2") = whence;
|
|
register uint32_t a7 __asm__("a7") = 62;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a2), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
int __ftruncate(uint64_t fd, uint64_t length) {
|
|
int ret;
|
|
register uint64_t a0 __asm__("a0") = fd;
|
|
register uint64_t a1 __asm__("a1") = length;
|
|
register uint32_t a7 __asm__("a7") = 46;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
int __close(uint64_t fd) {
|
|
int ret;
|
|
register uint64_t a0 __asm__("a0") = fd;
|
|
register uint32_t a7 __asm__("a7") =
|
|
57; // Assuming 57 is the syscall number for close
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret)
|
|
: "r"(a0), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
int __madvise(void *addr, size_t length, int advice) {
|
|
int ret;
|
|
register void *a0 __asm__("a0") = addr;
|
|
register size_t a1 __asm__("a1") = length;
|
|
register int a2 __asm__("a2") = advice;
|
|
register uint32_t a7 __asm__("a7") = 233;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a2), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
int __uname(struct UtsNameTy *buf) {
|
|
int ret;
|
|
register UtsNameTy *a0 __asm__("a0") = buf;
|
|
register uint32_t a7 __asm__("a7") = 160;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __nanosleep(const timespec *req, timespec *rem) {
|
|
uint64_t ret;
|
|
register const timespec *a0 __asm__("a0") = req;
|
|
register timespec *a1 __asm__("a1") = rem;
|
|
register uint32_t a7 __asm__("a7") = 101;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
int64_t __fork() {
|
|
uint64_t ret;
|
|
// clone instead of fork with flags
|
|
// "CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD"
|
|
register uint64_t a0 __asm__("a0") = 0x1200011;
|
|
register uint64_t a1 __asm__("a1") = 0;
|
|
register uint64_t a2 __asm__("a2") = 0;
|
|
register uint64_t a3 __asm__("a3") = 0;
|
|
register uint64_t a4 __asm__("a4") = 0;
|
|
register uint32_t a7 __asm__("a7") = 220;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a2), "r"(a3), "r"(a4), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
int __mprotect(void *addr, size_t len, int prot) {
|
|
int ret;
|
|
register void *a0 __asm__("a0") = addr;
|
|
register size_t a1 __asm__("a1") = len;
|
|
register int a2 __asm__("a2") = prot;
|
|
register uint32_t a7 __asm__("a7") = 226;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a2), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __getpid() {
|
|
uint64_t ret;
|
|
register uint32_t a7 __asm__("a7") = 172;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __getppid() {
|
|
uint64_t ret;
|
|
register uint32_t a7 __asm__("a7") = 173;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
int __setpgid(uint64_t pid, uint64_t pgid) {
|
|
int ret;
|
|
register uint64_t a0 __asm__("a0") = pid;
|
|
register uint64_t a1 __asm__("a1") = pgid;
|
|
register uint32_t a7 __asm__("a7") = 154;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __getpgid(uint64_t pid) {
|
|
uint64_t ret;
|
|
register uint64_t a0 __asm__("a0") = pid;
|
|
register uint32_t a7 __asm__("a7") = 155;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
int __kill(uint64_t pid, int sig) {
|
|
int ret;
|
|
register uint64_t a0 __asm__("a0") = pid;
|
|
register int a1 __asm__("a1") = sig;
|
|
register uint32_t a7 __asm__("a7") = 129;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
int __fsync(int fd) {
|
|
int ret;
|
|
register int a0 __asm__("a0") = fd;
|
|
register uint32_t a7 __asm__("a7") = 82;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0)
|
|
: "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
uint64_t __sigprocmask(int how, const void *set, void *oldset) {
|
|
uint64_t ret;
|
|
register int a0 __asm__("a0") = how;
|
|
register const void *a1 __asm__("a1") = set;
|
|
register void *a2 __asm__("a2") = oldset;
|
|
register long a3 asm("a3") = 8;
|
|
register uint32_t a7 __asm__("a7") = 135;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a2), "r"(a3), "r"(a7)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
int __prctl(int option, unsigned long arg2, unsigned long arg3,
|
|
unsigned long arg4, unsigned long arg5) {
|
|
int ret;
|
|
register int a0 __asm__("a0") = option;
|
|
register unsigned long a1 __asm__("a1") = arg2;
|
|
register unsigned long a2 __asm__("a2") = arg3;
|
|
register unsigned long a3 __asm__("a3") = arg4;
|
|
register unsigned long a4 __asm__("a4") = arg5;
|
|
register uint32_t a7 __asm__("a7") = 167;
|
|
__asm__ __volatile__("ecall\n\t"
|
|
"mv %0, a0"
|
|
: "=r"(ret), "+r"(a0), "+r"(a1)
|
|
: "r"(a2), "r"(a3), "r"(a4), "r"(a7)
|
|
: "cc", "memory");
|
|
return ret;
|
|
}
|
|
} // anonymous namespace
|
|
|
|
#endif |