diff --git a/util/build.c b/util/build.c index 28d8ca9..3770ff8 100644 --- a/util/build.c +++ b/util/build.c @@ -1589,20 +1589,8 @@ void DoCommand(const char *l) { } else if (0 == strcmp(l, "setup-pre-built-toolchain")) { CallSystem("mv bin/source cross"); CallSystem("mkdir -p cross/bin2"); - CallSystem("gcc -o bin/change_sysroot util/change_sysroot.c -Wall -Wextra"); - CallSystem("cross/bin/" TOOLCHAIN_PREFIX "-gcc --verbose 2> bin/temp.txt"); - char *configureFlags = (char *) LoadFile("bin/temp.txt", NULL); - char *sysrootPath = strstr(configureFlags, "--with-sysroot="); - sysrootPath += 15; - char *sysrootPathEnd = strchr(sysrootPath, ' '); - if (sysrootPathEnd) *sysrootPathEnd = 0; - free(configureFlags); - CallSystem("rm bin/temp.txt"); - fprintf(stderr, "Detected sysroot from gcc as \"%s\".\n", sysrootPath); #define MAKE_TOOLCHAIN_WRAPPER(tool) \ - CallSystemF("gcc -o cross/bin2/" TOOLCHAIN_PREFIX "-" tool \ - " util/toolchain_wrapper.c -Wall -Wextra -g " \ - " -DCONFIGURE_SYSROOT=\"%s\" -DTOOL=" TOOLCHAIN_PREFIX "-" tool, sysrootPath) + CallSystem("gcc -o cross/bin2/" TOOLCHAIN_PREFIX "-" tool " util/toolchain_wrapper.c -Wall -Wextra -Wno-format-truncation -g -DTOOL=" TOOLCHAIN_PREFIX "-" tool) MAKE_TOOLCHAIN_WRAPPER("addr2line"); MAKE_TOOLCHAIN_WRAPPER("ar"); MAKE_TOOLCHAIN_WRAPPER("as"); diff --git a/util/change_sysroot.c b/util/change_sysroot.c deleted file mode 100644 index 00f5e75..0000000 --- a/util/change_sysroot.c +++ /dev/null @@ -1,184 +0,0 @@ -// gcc -o bin/change_sysroot util/change_sysroot.c -Wall -Wextra -// ./change_sysroot "/home/runner/work/build-gcc-x86_64-essence/build-gcc-x86_64-essence/essence/root/" $SYSROOT ... - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char *needle; -const char *replaceWith; - -bool GetReplacement(const char *original, char *buffer) { - if (0 == memcmp(needle, original, strlen(needle))) { - strcpy(buffer, replaceWith); - strcat(buffer, original + strlen(needle)); - // fprintf(stderr, "'%s' -> '%s'\n", original, buffer); - return true; - } else { - return false; - } -} - -char *ReadString(pid_t pid, uintptr_t address) { - char *buffer = NULL; - uintptr_t position = 0; - uintptr_t capacity = 0; - - while (true) { - char b = ptrace(PTRACE_PEEKDATA, pid, address, 0); - - if (position == capacity) { - capacity = (capacity + 8) * 2; - buffer = realloc(buffer, capacity); - } - - buffer[position] = b; - position++, address++; - - if (b == 0) { - break; - } - } - - return realloc(buffer, position); -} - -uintptr_t WriteString(pid_t pid, uintptr_t rsp, const char *string) { - uintptr_t address = rsp - 128 /* red zone */ - strlen(string) - sizeof(uintptr_t) /* POKEDATA writes words */; - - for (int i = 0; true; i++) { - uintptr_t c = string[i]; - ptrace(PTRACE_POKEDATA, pid, (void *) (address + i), (void *) c); - if (!c) break; - } - - return address; -} - -bool ReplaceString(pid_t pid, uintptr_t rsp, uintptr_t *address) { - char *original = ReadString(pid, *address); - char buffer[PATH_MAX]; - bool modified = GetReplacement(original, buffer); - if (modified) *address = WriteString(pid, rsp, buffer); - free(original); - return modified; -} - -int main(int argc, char **argv) { - if (argc < 4) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - needle = argv[1]; - replaceWith = argv[2]; - - pid_t basePID; - - { - pid_t pid = vfork(); - - if (pid == 0) { - ptrace(PTRACE_TRACEME, 0, 0, 0); - execvp(argv[3], &argv[3]); - } - - waitpid(pid, 0, 0); - ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_EXITKILL | PTRACE_O_TRACEVFORK); - ptrace(PTRACE_SYSCALL, pid, 0, 0); - basePID = pid; - } - - while (true) { - struct user_regs_struct registers = { 0 }; - int status; - pid_t pid = waitpid(-1, &status, 0); - - if (ptrace(PTRACE_GETREGS, pid, 0, ®isters) == -1) { - if (pid == basePID) { - return WEXITSTATUS(status); - } else { - continue; - } - } - - if (registers.orig_rax == SYS_access - || registers.orig_rax == SYS_chown - || registers.orig_rax == SYS_lstat - || registers.orig_rax == SYS_readlink - || registers.orig_rax == SYS_stat - || registers.orig_rax == SYS_unlink) { - if (ReplaceString(pid, registers.rsp, (uintptr_t *) ®isters.rdi)) { - ptrace(PTRACE_SETREGS, pid, 0, ®isters); - } - } else if (registers.orig_rax == 439 /* faccessat2 */ - || registers.orig_rax == SYS_faccessat - || registers.orig_rax == SYS_newfstatat - || registers.orig_rax == SYS_openat) { - if (ReplaceString(pid, registers.rsp, (uintptr_t *) ®isters.rsi)) { - ptrace(PTRACE_SETREGS, pid, 0, ®isters); - } - } else if (registers.orig_rax == SYS_arch_prctl - || registers.orig_rax == SYS_brk - || registers.orig_rax == SYS_chmod - || registers.orig_rax == SYS_close - || registers.orig_rax == SYS_exit_group - || registers.orig_rax == SYS_execve - || registers.orig_rax == SYS_fcntl - || registers.orig_rax == SYS_fstat - || registers.orig_rax == SYS_getcwd - || registers.orig_rax == SYS_getdents64 - || registers.orig_rax == SYS_getpid - || registers.orig_rax == SYS_getrandom - || registers.orig_rax == SYS_getrusage - || registers.orig_rax == SYS_ioctl - || registers.orig_rax == SYS_lseek - || registers.orig_rax == SYS_madvise - || registers.orig_rax == SYS_mmap - || registers.orig_rax == SYS_mprotect - || registers.orig_rax == SYS_mremap - || registers.orig_rax == SYS_munmap - || registers.orig_rax == SYS_pipe2 - || registers.orig_rax == SYS_pread64 - || registers.orig_rax == SYS_prlimit64 - || registers.orig_rax == SYS_read - || registers.orig_rax == SYS_rename - || registers.orig_rax == SYS_rt_sigaction - || registers.orig_rax == SYS_rt_sigprocmask - || registers.orig_rax == SYS_set_robust_list - || registers.orig_rax == SYS_set_tid_address - || registers.orig_rax == SYS_sysinfo - || registers.orig_rax == SYS_umask - || registers.orig_rax == SYS_vfork - || registers.orig_rax == SYS_wait4 - || registers.orig_rax == SYS_write) { - // Allow through. - } else { - printf("unhandled syscall %llu\n", registers.orig_rax); - } - - ptrace(PTRACE_SYSCALL, pid, 0, 0); - waitpid(pid, &status, 0); - - if (ptrace(PTRACE_GETREGS, pid, 0, ®isters) == -1) { - // The process has exited. - - if (pid == basePID) { - return WEXITSTATUS(status); - } - } else { - ptrace(PTRACE_SYSCALL, pid, 0, 0); - } - } -} diff --git a/util/toolchain_wrapper.c b/util/toolchain_wrapper.c index 151168c..f74e5be 100644 --- a/util/toolchain_wrapper.c +++ b/util/toolchain_wrapper.c @@ -8,8 +8,9 @@ #define STRING(x) _STRING(x) int main(int argc, char **argv) { - char buffer[PATH_MAX] = {}, change[PATH_MAX] = {}, sysroot[PATH_MAX] = {}, tool[PATH_MAX] = {}; + char buffer[PATH_MAX] = {}, sysroot[PATH_MAX] = {}, tool[PATH_MAX] = {}; readlink("/proc/self/exe", buffer, sizeof(buffer)); + int directoryPosition = 0; for (int i = 0; buffer[i]; i++) if (buffer[i] == '/') directoryPosition = i; buffer[directoryPosition] = 0; @@ -17,21 +18,20 @@ int main(int argc, char **argv) { buffer[directoryPosition] = 0; for (int i = 0; buffer[i]; i++) if (buffer[i] == '/') directoryPosition = i; buffer[directoryPosition] = 0; - strcpy(change, buffer); - strcpy(sysroot, buffer); - strcpy(tool, buffer); - strcat(change, "/bin/change_sysroot"); - strcat(sysroot, "/root/"); - strcat(tool, "/cross/bin/" STRING(TOOL)); - // printf("'%s'\n", change); - // printf("'%s'\n", sysroot); - // printf("'%s'\n", tool); - char **newArgv = (char **) calloc(sizeof(char *), (argc + 4)); - newArgv[0] = change; - newArgv[1] = STRING(CONFIGURE_SYSROOT); - newArgv[2] = sysroot; - newArgv[3] = tool; - memcpy(newArgv + 4, argv + 1, (argc - 1) * sizeof(char *)); - execv(newArgv[0], newArgv); - return 0; + + snprintf(sysroot, sizeof(sysroot), "%s/root/", buffer); + snprintf(tool, sizeof(tool), "%s/cross/bin/%s", buffer, STRING(TOOL)); + char *toolEnd = tool + strlen(tool); + + char **newArgv = (char **) calloc(sizeof(char *), (argc + 16)); + int index = 0; + newArgv[index++] = tool; + + if (0 == strcmp(toolEnd - 3, "g++") || 0 == strcmp(toolEnd - 3, "gcc") || 0 == strcmp(toolEnd - 2, "ld")) { + newArgv[index++] = "--sysroot"; + newArgv[index++] = sysroot; + } + + memcpy(newArgv + index, argv + 1, (argc - 1) * sizeof(char *)); + return execv(newArgv[0], newArgv); }