From 6926b6a65db1e6cc4db54475b6d3952bb86dffe7 Mon Sep 17 00:00:00 2001 From: Giovanni <561184+wargio@users.noreply.github.com> Date: Sat, 10 Jan 2026 13:36:51 +0800 Subject: [PATCH] Rewrite C compiler code for rz-gg (#5761) --- librz/egg/egg.c | 13 +- librz/egg/egg_Cfile.c | 341 ------------------ librz/egg/egg_c_compile.c | 420 ++++++++++++++++++++++ librz/egg/meson.build | 2 +- librz/include/rz_egg.h | 2 +- librz/include/rz_util/rz_str.h | 1 - librz/include/sflib/darwin-arm-64/sflib.h | 278 ++++++++------ librz/main/rz-gg.c | 6 +- librz/util/str.c | 36 -- librz/util/sys.c | 9 +- sys/clang-format.py | 20 +- test/db/tools/rz | 1 + 12 files changed, 623 insertions(+), 506 deletions(-) delete mode 100644 librz/egg/egg_Cfile.c create mode 100644 librz/egg/egg_c_compile.c diff --git a/librz/egg/egg.c b/librz/egg/egg.c index e73e878090..0ed4ac8bfa 100644 --- a/librz/egg/egg.c +++ b/librz/egg/egg.c @@ -178,6 +178,17 @@ RZ_API bool rz_egg_setup(RzEgg *egg, const char *arch, int bits, int endian, con egg->endian = endian; break; } + } else if (!strcmp(arch, "mips")) { + egg->arch = RZ_SYS_ARCH_MIPS; + switch (bits) { + case 16: + case 32: + case 64: + rz_syscall_setup(egg->syscall, egg->sys_path, arch, bits, asmcpu, os); + egg->bits = bits; + egg->endian = endian; + break; + } } else if (!strcmp(arch, "trace")) { // rz_syscall_setup (egg->syscall, arch, os, bits); egg->remit = &emit_trace; @@ -234,7 +245,7 @@ RZ_API bool rz_egg_load_file(RzEgg *egg, const char *file) { rz_str_sanitize(fileSanitized); const char *arch = rz_sys_arch_str(egg->arch); const char *os = rz_egg_os_as_string(egg->os); - char *textFile = rz_egg_Cfile_parser(egg->sys_path, fileSanitized, arch, os, egg->bits); + char *textFile = rz_egg_compile_c_source(fileSanitized, arch, os, egg->bits, egg->sys_path); if (!textFile) { RZ_LOG_ERROR("egg: failure while parsing '%s'\n", fileSanitized); free(fileSanitized); diff --git a/librz/egg/egg_Cfile.c b/librz/egg/egg_Cfile.c deleted file mode 100644 index 15fe5f395d..0000000000 --- a/librz/egg/egg_Cfile.c +++ /dev/null @@ -1,341 +0,0 @@ -// SPDX-FileCopyrightText: 2011-2018 pancake -// SPDX-License-Identifier: LGPL-3.0-only - -#include - -// compilation environment -struct cEnv_t { - char *SFLIBPATH; - char *CC; - const char *OBJCOPY; - char *CFLAGS; - char *LDFLAGS; - const char *JMP; - const char *FMT; - char *SHDR; - char *TRIPLET; - const char *TEXT; -}; - -static char *rz_egg_Cfile_getCompiler(void) { - size_t i; - const char *compilers[] = { "llvm-gcc", "clang", "gcc" }; - char *output = rz_sys_getenv("CC"); - - if (output) { - return output; - } - - for (i = 0; i < 3; i++) { - output = rz_file_path(compilers[i]); - if (strcmp(output, compilers[i])) { - free(output); - return rz_str_dup(compilers[i]); - } - free(output); - } - - eprintf("Couldn't find a compiler ! Please, set CC.\n"); - return NULL; -} - -static inline bool rz_egg_Cfile_armOrMips(const char *arch) { - return (!strcmp(arch, "arm") || !strcmp(arch, "arm64") || !strcmp(arch, "aarch64") || !strcmp(arch, "thumb") || !strcmp(arch, "arm32") || !strcmp(arch, "mips") || !strcmp(arch, "mips32") || !strcmp(arch, "mips64")); -} - -static void rz_egg_Cfile_free_cEnv(struct cEnv_t *cEnv) { - if (cEnv) { - free(cEnv->SFLIBPATH); - free(cEnv->CC); - free(cEnv->CFLAGS); - free(cEnv->LDFLAGS); - free(cEnv->SHDR); - free(cEnv->TRIPLET); - } - free(cEnv); -} - -static inline bool rz_egg_Cfile_check_cEnv(struct cEnv_t *cEnv) { - return (!cEnv->SFLIBPATH || !cEnv->CC || !cEnv->CFLAGS || !cEnv->LDFLAGS || !cEnv->SHDR || !cEnv->TRIPLET); -} - -static inline bool isXNU(const char *os) { - return (!strcmp(os, "darwin") || !strcmp(os, "macos") || !strcmp(os, "tvos") || !strcmp(os, "watchos") || !strcmp(os, "ios")); -} - -static struct cEnv_t *rz_egg_Cfile_set_cEnv(RZ_BORROW RZ_NONNULL RzPath *sys_path, const char *arch, const char *os, int bits) { - rz_return_val_if_fail(sys_path, NULL); - struct cEnv_t *cEnv = calloc(1, sizeof(struct cEnv_t)); - bool use_clang; - char *buffer = NULL; - char *incdir = NULL; - - if (!cEnv) { - return NULL; - } - - if (!(cEnv->CC = rz_egg_Cfile_getCompiler())) { - goto fail; - } - - cEnv->SFLIBPATH = rz_sys_getenv("SFLIBPATH"); - if (!cEnv->SFLIBPATH) { - incdir = rz_path_incdir(sys_path); - - if (!(cEnv->SFLIBPATH = rz_str_newf("%s/sflib", incdir))) { - goto fail; - } - } - - cEnv->JMP = rz_egg_Cfile_armOrMips(arch) ? "b" : "jmp"; - - // TODO: Missing -Os .. caused some rip-relative LEA to be MOVQ on PIE in CLANG.. so sad - if (isXNU(os)) { - cEnv->OBJCOPY = "gobjcopy"; - cEnv->FMT = "mach0"; - if (!strcmp(arch, "x86")) { - if (bits == 32) { - cEnv->CFLAGS = rz_str_dup("-arch i386 -fPIC -fPIE"); - cEnv->LDFLAGS = rz_str_dup("-arch i386 -shared -c -fPIC -fPIE -pie"); - } else { - cEnv->CFLAGS = rz_str_dup("-arch x86_64 -fPIC -fPIE"); - cEnv->LDFLAGS = rz_str_dup("-arch x86_64 -shared -c -fPIC -fPIE -pie"); - } - } else { - cEnv->CFLAGS = rz_str_dup("-shared -c -fPIC -pie -fPIE"); - cEnv->LDFLAGS = rz_str_dup("-shared -c -fPIC -pie -fPIE"); - } - cEnv->SHDR = rz_str_newf("\n.text\n%s _main\n", cEnv->JMP); - } else { - cEnv->OBJCOPY = "objcopy"; - cEnv->FMT = "elf"; - cEnv->SHDR = rz_str_newf("\n.section .text\n.globl main\n" - "// .type main, @function\n%s main\n", - cEnv->JMP); - if (!strcmp(arch, "x86")) { - if (bits == 32) { - cEnv->CFLAGS = rz_str_dup("-fPIC -fPIE -pie -fpic -m32"); - cEnv->LDFLAGS = rz_str_dup("-fPIC -fPIE -pie -fpic -m32"); - } else { - cEnv->CFLAGS = rz_str_dup("-fPIC -fPIE -pie -fpic -m64"); - cEnv->LDFLAGS = rz_str_dup("-fPIC -fPIE -pie -fpic -m64"); - } - } else { - cEnv->CFLAGS = rz_str_dup("-fPIC -fPIE -pie -fpic -nostartfiles"); - cEnv->LDFLAGS = rz_str_dup("-fPIC -fPIE -pie -fpic -nostartfiles"); - } - } - - cEnv->TRIPLET = rz_str_newf("%s-%s-%d", os, arch, bits); - - if (!strcmp(os, "windows")) { - cEnv->TEXT = ".text"; - cEnv->FMT = "pe"; - } else if (isXNU(os)) { - // cEnv->TEXT = "0.__TEXT.__text"; - cEnv->TEXT = "0..__text"; - } else { - cEnv->TEXT = ".text"; - } - - use_clang = false; - if (!strcmp(cEnv->TRIPLET, "darwin-arm-64")) { - free(cEnv->CC); - cEnv->CC = rz_str_dup("xcrun --sdk iphoneos gcc -arch arm64 -miphoneos-version-min=0.0"); - use_clang = true; - cEnv->TEXT = "0.__TEXT.__text"; - } else if (!strcmp(cEnv->TRIPLET, "darwin-arm-32")) { - free(cEnv->CC); - cEnv->CC = rz_str_dup("xcrun --sdk iphoneos gcc -arch armv7 -miphoneos-version-min=0.0"); - use_clang = true; - cEnv->TEXT = "0.__TEXT.__text"; - } - - buffer = rz_str_newf("%s -fno-stack-protector -nostdinc -include '%s'/'%s'/sflib.h", - cEnv->CFLAGS, cEnv->SFLIBPATH, cEnv->TRIPLET); - if (!buffer) { - goto fail; - } - free(cEnv->CFLAGS); - cEnv->CFLAGS = rz_str_dup(buffer); - - if (use_clang) { - free(buffer); - buffer = rz_str_newf("%s -fomit-frame-pointer" - " -fno-zero-initialized-in-bss", - cEnv->CFLAGS); - if (!buffer) { - goto fail; - } - free(cEnv->CFLAGS); - cEnv->CFLAGS = rz_str_dup(buffer); - } else { - free(buffer); - buffer = rz_str_newf("%s -z execstack -fomit-frame-pointer" - " -finline-functions -fno-zero-initialized-in-bss", - cEnv->CFLAGS); - if (!buffer) { - goto fail; - } - free(cEnv->CFLAGS); - cEnv->CFLAGS = rz_str_dup(buffer); - } - free(buffer); - buffer = rz_str_newf("%s -nostdlib", cEnv->LDFLAGS); - if (!buffer) { - goto fail; - } - free(cEnv->LDFLAGS); - cEnv->LDFLAGS = rz_str_dup(buffer); - - if (rz_egg_Cfile_check_cEnv(cEnv)) { - eprintf("Error with cEnv allocation!\n"); - goto fail; - } - - free(buffer); - free(incdir); - return cEnv; - -fail: - free(buffer); - free(incdir); - rz_egg_Cfile_free_cEnv(cEnv); - return NULL; -} - -static bool rz_egg_Cfile_parseCompiled(const char *file) { - char *fileExt = rz_str_newf("%s.tmp", file); - char *buffer = rz_file_slurp(fileExt, NULL); - if (!buffer) { - eprintf("Could not open '%s'.\n", fileExt); - goto fail; - } - - buffer = rz_str_replace(buffer, "rdata", "text", false); - buffer = rz_str_replace(buffer, "rodata", "text", false); - buffer = rz_str_replace(buffer, "get_pc_thunk.bx", "__getesp__", true); - - const char *words[] = { ".cstring", "size", "___main", "section", "__alloca", "zero", "cfi" }; - size_t i; - for (i = 0; i < 7; i++) { - rz_str_stripLine(buffer, words[i]); - } - - free(fileExt); - fileExt = rz_str_newf("%s.s", file); - if (!rz_file_dump(fileExt, (const ut8 *)buffer, strlen(buffer), true)) { - eprintf("Error while opening %s.s\n", file); - goto fail; - } - - free(buffer); - free(fileExt); - return true; - -fail: - free(buffer); - free(fileExt); - return false; -} - -RZ_API char *rz_egg_Cfile_parser(RZ_BORROW RZ_NONNULL RzPath *sys_path, const char *file, const char *arch, const char *os, int bits) { - rz_return_val_if_fail(sys_path, NULL); - char *output = NULL; - char *fileExt = NULL; // "file" with extension (.s, .text, ...) - struct cEnv_t *cEnv = rz_egg_Cfile_set_cEnv(sys_path, arch, os, bits); - - if (!cEnv) { - goto fail; - } - - rz_str_sanitize(cEnv->CC); - - // Compile - char *cmd = rz_str_newf("'%s' %s -o '%s.tmp' -S '%s'\n", cEnv->CC, cEnv->CFLAGS, file, file); - eprintf("%s\n", cmd); - int rc = rz_sys_system(cmd); - free(cmd); - if (rc != 0) { - goto fail; - } - if (!(fileExt = rz_str_newf("%s.s", file))) { - goto fail; - } - - if (!rz_file_dump(fileExt, (const ut8 *)cEnv->SHDR, strlen(cEnv->SHDR), false)) { - eprintf("Error while opening %s.s\n", file); - goto fail; - } - - if (!rz_egg_Cfile_parseCompiled(file)) { - goto fail; - } - // Assemble - cmd = rz_str_newf("'%s' %s -o '%s.o' '%s.s'", cEnv->CC, cEnv->LDFLAGS, file, file); - eprintf("%s\n", cmd); - rc = rz_sys_system(cmd); - free(cmd); - if (rc != 0) { - goto fail; - } - - // Link - printf("rz-bin -o '%s.text' -O d/S/'%s' '%s.o'\n", file, cEnv->TEXT, file); - output = rz_sys_cmd_strf("rz-bin -o '%s.text' -O d/S/'%s' '%s'.o", - file, cEnv->TEXT, file); - if (!output) { - eprintf("Linkage failed!\n"); - goto fail; - } - - free(fileExt); - if (!(fileExt = rz_str_newf("%s.o", file))) { - goto fail; - } - - if (!rz_file_exists(fileExt)) { - eprintf("Cannot find %s.o\n", file); - goto fail; - } - - free(fileExt); - if (!(fileExt = rz_str_newf("%s.text", file))) { - goto fail; - } - if (rz_file_size(fileExt) == 0) { - eprintf("FALLBACK: Using objcopy instead of rz_bin"); - free(output); - output = rz_sys_cmd_strf("'%s' -j .text -O binary '%s.o' '%s.text'", - cEnv->OBJCOPY, file, file); - if (!output) { - eprintf("objcopy failed!\n"); - goto fail; - } - } - - size_t i; - const char *extArray[] = { "bin", "tmp", "s", "o" }; - for (i = 0; i < 4; i++) { - free(fileExt); - if (!(fileExt = rz_str_newf("%s.%s", file, extArray[i]))) { - goto fail; - } - rz_file_rm(fileExt); - } - - free(fileExt); - if ((fileExt = rz_str_newf("%s.text", file)) == NULL) { - goto fail; - } - - free(output); - rz_egg_Cfile_free_cEnv(cEnv); - return fileExt; - -fail: - free(fileExt); - free(output); - rz_egg_Cfile_free_cEnv(cEnv); - return NULL; -} diff --git a/librz/egg/egg_c_compile.c b/librz/egg/egg_c_compile.c new file mode 100644 index 0000000000..258fbada15 --- /dev/null +++ b/librz/egg/egg_c_compile.c @@ -0,0 +1,420 @@ +// SPDX-FileCopyrightText: 2026 deroad +// SPDX-License-Identifier: LGPL-3.0-only + +#include + +typedef struct egg_c_config { + const char *triplet; ///< -- + const char *exe_compiler; ///< special compiler to override the normal one. + const char *add_cflags; ///< CFLAGS to append + const char *add_ldflags; ///< LDFLAGS to append + const char *asm_text_segment; ///< hardcoded `.text` segment name to use for dumping the compiled code. + const char *asm_text_header; ///< hardcoded header of the assembly. +} egg_c_config_t; + +// compilation environment +typedef struct c_env_s { + const char *asm_text_segment; ///< hardcoded `.text` segment name to use for dumping the compiled code. + const char *asm_text_header; ///< hardcoded header of the assembly. + char *exe_objcopy; ///< objcopy exec + char *exe_compiler; ///< compiler exec + char *cflags; ///< compiler CFLAGS + char *ldflags; ///< compiler LDFLAGS +} c_env_t; + +const egg_c_config_t c_configs[] = { + { + /* triplet */ "ios-arm-32", + /* exe_compiler */ "xcrun --sdk iphoneos gcc -arch armv7 -miphoneos-version-min=0.0", + /* add_cflags */ "-shared -c -pie -fomit-frame-pointer -fno-zero-initialized-in-bss", + /* add_ldflags */ "-shared -c -pie", + /* asm_text_segment */ "0.__TEXT.__text", + /* asm_text_header */ "\n" + ".text\n" + "b _main\n", + }, + { + /* triplet */ "ios-arm-64", + /* exe_compiler */ "xcrun --sdk iphoneos gcc -arch arm64 -miphoneos-version-min=0.0", + /* add_cflags */ "-shared -c -pie -fomit-frame-pointer -fno-zero-initialized-in-bss", + /* add_ldflags */ "-shared -c -pie", + /* asm_text_segment */ "0.__TEXT.__text", + /* asm_text_header */ "\n" + ".text\n" + "b _main\n", + }, + { + /* triplet */ "darwin-arm-64", + /* exe_compiler */ NULL, + /* add_cflags */ "-O1 -fomit-frame-pointer -fno-zero-initialized-in-bss", + /* add_ldflags */ "-shared -c -pie", + /* asm_text_segment */ "0..__text", + /* asm_text_header */ "\n" + ".text\n" + "b _main\n", + }, + { + /* triplet */ "darwin-x86-32", + /* exe_compiler */ NULL, + /* add_cflags */ "-arch i386 -fomit-frame-pointer -fno-zero-initialized-in-bss", + /* add_ldflags */ "-arch i386 -shared -c -pie", + /* asm_text_segment */ "0..__text", + /* asm_text_header */ "\n" + ".text\n" + "jmp _main\n", + }, + { + /* triplet */ "darwin-x86-64", + /* exe_compiler */ NULL, + /* add_cflags */ "-arch x86_64 -fomit-frame-pointer -fno-zero-initialized-in-bss", + /* add_ldflags */ "-arch x86_64 -shared -c -pie", + /* asm_text_segment */ "0..__text", + /* asm_text_header */ "\n" + ".text\n" + "jmp _main\n", + }, + { + /* triplet */ "linux-arm-32", + /* exe_compiler */ NULL, + /* add_cflags */ "-pie -fpic -nostartfiles -z execstack -fomit-frame-pointer -finline-functions -fno-zero-initialized-in-bss", + /* add_ldflags */ "-pie -fpic -nostartfiles", + /* asm_text_segment */ ".text", + /* asm_text_header */ "\n" + ".section .text\n" + ".globl main\n" + "b main\n", + }, + { + /* triplet */ "linux-arm-64", + /* exe_compiler */ NULL, + /* add_cflags */ "-pie -fpic -nostartfiles -z execstack -fomit-frame-pointer -finline-functions -fno-zero-initialized-in-bss", + /* add_ldflags */ "-pie -fpic -nostartfiles", + /* asm_text_segment */ ".text", + /* asm_text_header */ "\n" + ".section .text\n" + ".globl main\n" + "b main\n", + }, + { + /* triplet */ "linux-x86-32", + /* exe_compiler */ NULL, + /* add_cflags */ "-pie -fpic -m32 -z execstack -fomit-frame-pointer -finline-functions -fno-zero-initialized-in-bss", + /* add_ldflags */ "-pie -fpic -m32", + /* asm_text_segment */ ".text", + /* asm_text_header */ "\n" + ".section .text\n" + ".globl main\n" + "jmp main\n", + }, + { + /* triplet */ "linux-x86-64", + /* exe_compiler */ NULL, + /* add_cflags */ "-pie -fpic -m64 -z execstack -fomit-frame-pointer -finline-functions -fno-zero-initialized-in-bss", + /* add_ldflags */ "-pie -fpic -m64", + /* asm_text_segment */ ".text", + /* asm_text_header */ "\n" + ".section .text\n" + ".globl main\n" + "jmp main\n", + }, +}; + +static char *egg_find_executable(const char *env_name, const char *exes[], const size_t length) { + char *output = rz_sys_getenv(env_name); + if (RZ_STR_ISNOTEMPTY(output)) { + return output; + } + + for (size_t i = 0; i < length; i++) { + output = rz_file_path(exes[i]); + if (!output || RZ_STR_EQ(output, exes[i])) { + free(output); + continue; + } + return output; + } + return NULL; +} + +static char *egg_find_compiler(const egg_c_config_t *config) { + if (config->exe_compiler) { + return rz_str_dup(config->exe_compiler); + } + + const char *cc_exes[] = { "llvm-gcc", "clang", "gcc" }; + char *found = egg_find_executable("CC", cc_exes, RZ_ARRAY_SIZE(cc_exes)); + if (found) { + return found; + } + RZ_LOG_ERROR("egg: Couldn't find a compiler! Please, set the 'CC' environment variable.\n"); + return NULL; +} + +static char *egg_find_objcopy(void) { + const char *objcopy_exes[] = { "objcopy", "gobjcopy" }; + char *found = egg_find_executable("OBJCOPY", objcopy_exes, RZ_ARRAY_SIZE(objcopy_exes)); + if (found) { + return found; + } + RZ_LOG_WARN("egg: Couldn't find a objcopy! You can set the 'OBJCOPY' environment variable.\n"); + return NULL; +} + +static char *egg_find_sflib(RzPath *sys_path, const char *triplet) { + char *sflib_path = rz_sys_getenv("SFLIBPATH"); + if (RZ_STR_ISNOTEMPTY(sflib_path)) { + return sflib_path; + } + RZ_FREE(sflib_path); + char *incdir = rz_path_incdir(sys_path); + sflib_path = rz_str_newf(RZ_JOIN_4_PATHS("%s", "sflib", "%s", "sflib.h"), incdir, triplet); + free(incdir); + + return sflib_path; +} + +static char *egg_get_cflags(const egg_c_config_t *config, RzPath *sys_path, const char *triplet) { + char *sflib_path = egg_find_sflib(sys_path, triplet); + char *env_cflags = rz_sys_getenv("CFLAGS"); + char *cflags = rz_str_newf("%s %s" + " -fno-stack-protector" + " -nostdinc" + " -fPIC" + " -fPIE" + " -include '%s'", + rz_str_get(env_cflags), rz_str_get(config->add_cflags), rz_str_get(sflib_path)); + free(sflib_path); + free(env_cflags); + return cflags; +} + +static char *egg_get_ldflags(const egg_c_config_t *config, RzPath *sys_path) { + char *env_ldflags = rz_sys_getenv("LDFLAGS"); + char *ldflags = rz_str_newf("%s %s" + " -fno-stack-protector" + " -nostdlib" + " -fPIC" + " -fPIE", + rz_str_get(env_ldflags), rz_str_get(config->add_ldflags)); + free(env_ldflags); + return ldflags; +} + +static void egg_c_env_free(c_env_t *env) { + if (!env) { + return; + } + + free(env->exe_objcopy); + free(env->exe_compiler); + free(env->cflags); + free(env->ldflags); + free(env); +} + +static c_env_t *egg_c_env_new(RzPath *sys_path, const char *arch, const char *os, int bits) { + char triplet[256] = { 0 }; + const egg_c_config_t *config = NULL; + + rz_strf(triplet, "%s-%s-%d", os, arch, bits); + + for (size_t i = 0; i < RZ_ARRAY_SIZE(c_configs); ++i) { + config = &c_configs[i]; + if (RZ_STR_EQ(triplet, config->triplet)) { + break; + } + config = NULL; + } + + if (!config) { + return NULL; + } + + c_env_t *env = RZ_NEW0(c_env_t); + if (!env) { + return NULL; + } + + env->asm_text_segment = config->asm_text_segment; + env->asm_text_header = config->asm_text_header; + // heap allocated below + env->exe_objcopy = egg_find_objcopy(); + env->exe_compiler = egg_find_compiler(config); + env->cflags = egg_get_cflags(config, sys_path, triplet); + env->ldflags = egg_get_ldflags(config, sys_path); + + if (!env->exe_compiler || + !env->cflags || + !env->ldflags) { + egg_c_env_free(env); + return NULL; + } + + rz_str_sanitize(env->exe_compiler); + return env; +} + +// strips any line containing the keyword +static void egg_str_strip_line(char *input, size_t input_len, const char *key) { + size_t klen = strlen(key); + const char *end = input + input_len; + const char *cur = input; + while (cur < end) { + const char *newline = strchr(cur, '\n'); + if (!newline) { + newline = end; + } + + const char *found = (const char *)rz_mem_mem((const ut8 *)cur, newline - cur, (const ut8 *)key, klen); + if (found) { + memset((char *)cur, ' ', newline - cur); + } + cur = newline + 1; + } +} + +static bool egg_append_tmp_to_assembly_file(const char *outfile_tmp, const char *assembly_file) { + size_t buffer_size = 0; + char *buffer = rz_file_slurp(outfile_tmp, &buffer_size); + if (!buffer) { + RZ_LOG_ERROR("egg: Could not open '%s'.\n", outfile_tmp); + goto fail; + } + buffer = rz_str_replace(buffer, "rdata", "text", false); + buffer = rz_str_replace(buffer, "rodata", "text", false); + buffer = rz_str_replace(buffer, "get_pc_thunk.bx", "__getesp__", true); + + const char *words[] = { ".cstring", "size", "___main", "section", "__alloca", "zero", "cfi" }; + for (size_t i = 0; i < RZ_ARRAY_SIZE(words); i++) { + egg_str_strip_line(buffer, buffer_size, words[i]); + } + + // the buffer size contains also the `\0` char + if (!rz_file_dump(assembly_file, (const ut8 *)buffer, buffer_size - 1, true)) { + RZ_LOG_ERROR("egg: Error while opening %s\n", assembly_file); + goto fail; + } + + free(buffer); + return true; + +fail: + free(buffer); + return false; +} + +static bool egg_compile_c_source_to_assembly(const c_env_t *env, const char *infile_C, const char *outfile_tmp) { + char *cmd = rz_str_newf("'%s' %s -o '%s' -S '%s'", env->exe_compiler, env->cflags, outfile_tmp, infile_C); + RZ_LOG_INFO("egg: executing sys command: %s\n", cmd); + int rc = rz_sys_system(cmd); + free(cmd); + // when zero, then no error. + return !rc; +} + +static bool egg_compile_assembly_to_object(const c_env_t *env, const char *infile_asm, const char *outfile_obj) { + char *cmd = rz_str_newf("'%s' %s -o '%s' '%s'", env->exe_compiler, env->ldflags, outfile_obj, infile_asm); + RZ_LOG_INFO("egg: executing command: %s\n", cmd); + int rc = rz_sys_system(cmd); + free(cmd); + // when zero, then no error. + return !rc; +} + +static bool egg_link_object_via_rz_bin(const c_env_t *env, const char *infile_obj, const char *outfile_text) { + // "d/S/
" is a command of rz-bin to dump a specific section + char *cmd = rz_str_newf("rz-bin -o '%s' -O 'd/S/%s' '%s'", outfile_text, env->asm_text_segment, infile_obj); + RZ_LOG_INFO("egg: executing command: %s\n", cmd); + int rc = rz_sys_system(cmd); + free(cmd); + // when zero, then no error. + return !rc; +} + +static bool egg_link_object_via_objdump(const c_env_t *env, const char *infile_obj, const char *outfile_text) { + char *cmd = rz_str_newf("'%s' -j .text -O binary '%s' '%s'", env->exe_objcopy, infile_obj, outfile_text); + RZ_LOG_INFO("egg: executing command: %s\n", cmd); + int rc = rz_sys_system(cmd); + free(cmd); + // when zero, then no error. + return !rc; +} + +static bool egg_link_object(const c_env_t *env, const char *infile_obj, const char *outfile_text) { + if (!egg_link_object_via_rz_bin(env, infile_obj, outfile_text)) { + return false; + } else if (rz_file_size(outfile_text) > 0) { + return true; + } else if (RZ_STR_ISEMPTY(env->exe_objcopy)) { + return false; + } + RZ_LOG_WARN("egg: linked file generated by rz-bin is empty, using objcopy instead.\n"); + return egg_link_object_via_objdump(env, infile_obj, outfile_text); +} + +/** + * \brief Compiles a given C source and returns the file path hexdump of the compiled code. + * + * \param[in] source_file The file + * \param[in] arch The arch name + * \param[in] os The operating system + * \param[in] bits The arch bits + * \param sys_path The system path + * + * \return { description_of_the_return_value } + */ +RZ_API RZ_OWN char *rz_egg_compile_c_source(RZ_NONNULL const char *source_file, RZ_NONNULL const char *arch, RZ_NONNULL const char *os, int bits, RZ_BORROW RZ_NONNULL RzPath *sys_path) { + rz_return_val_if_fail(sys_path && source_file && arch && os, NULL); + + bool ok = true; + c_env_t *env = NULL; + char *outfile_tmp = rz_str_newf("%s.tmp", source_file); + char *outfile_asm = rz_str_newf("%s.s", source_file); + char *outfile_obj = rz_str_newf("%s.o", source_file); + char *outfile_text = rz_str_newf("%s.text", source_file); + if (!outfile_tmp || !outfile_asm || !outfile_obj || !outfile_text) { + RZ_LOG_ERROR("egg: failed to allocate memory\n"); + ok = false; + goto fail; + } + + if (!(env = egg_c_env_new(sys_path, arch, os, bits))) { + RZ_LOG_ERROR("egg: failed to initialize C environment for '%s-%s-%d'\n", os, arch, bits); + ok = false; + goto fail; + } + + // prepare assembly file. + if (!rz_file_dump(outfile_asm, (const ut8 *)env->asm_text_header, strlen(env->asm_text_header), false)) { + RZ_LOG_ERROR("egg: Error while opening %s\n", outfile_asm); + ok = false; + } else if (!egg_compile_c_source_to_assembly(env, source_file, outfile_tmp)) { + RZ_LOG_ERROR("egg: failed to compile source file: %s\n", source_file); + ok = false; + } else if (!egg_append_tmp_to_assembly_file(outfile_tmp, outfile_asm)) { + RZ_LOG_ERROR("egg: failed to append '%s' to %s\n", outfile_tmp, outfile_asm); + ok = false; + } else if (!egg_compile_assembly_to_object(env, outfile_asm, outfile_obj)) { + RZ_LOG_ERROR("egg: failed to compile to object file: %s\n", outfile_asm); + ok = false; + } else if (!egg_link_object(env, outfile_obj, outfile_text)) { + RZ_LOG_ERROR("egg: failed to link object: %s\n", outfile_obj); + ok = false; + } + + // cleanup. + rz_file_rm(outfile_tmp); + rz_file_rm(outfile_asm); + rz_file_rm(outfile_obj); + +fail: + free(outfile_tmp); + free(outfile_asm); + free(outfile_obj); + if (!ok) { + RZ_FREE(outfile_text) + } + egg_c_env_free(env); + + return outfile_text; +} diff --git a/librz/egg/meson.build b/librz/egg/meson.build index c635865847..8cc2d2723e 100644 --- a/librz/egg/meson.build +++ b/librz/egg/meson.build @@ -16,7 +16,7 @@ egg_plugins = { rz_egg_sources = [ 'egg.c', - 'egg_Cfile.c', + 'egg_c_compile.c', 'egg_lang.c', 'emit_arm.c', 'emit_trace.c', diff --git a/librz/include/rz_egg.h b/librz/include/rz_egg.h index 5742cc9c24..c2145638b2 100644 --- a/librz/include/rz_egg.h +++ b/librz/include/rz_egg.h @@ -226,7 +226,7 @@ RZ_API bool rz_egg_patch_num(RzEgg *egg, int off, ut64 val, ut32 bits); RZ_API void rz_egg_finalize(RzEgg *egg); /* rz_egg_Cfile.c */ -RZ_API char *rz_egg_Cfile_parser(RZ_BORROW RZ_NONNULL RzPath *sys_path, const char *file, const char *arch, const char *os, int bits); +RZ_API RZ_OWN char *rz_egg_compile_c_source(RZ_NONNULL const char *source_file, RZ_NONNULL const char *arch, RZ_NONNULL const char *os, int bits, RZ_BORROW RZ_NONNULL RzPath *sys_path); /* lang.c */ RZ_API char *rz_egg_mkvar(RzEgg *egg, char *out, const char *_str, int delta); diff --git a/librz/include/rz_util/rz_str.h b/librz/include/rz_util/rz_str.h index 27fa1d4cec..4e619cdb73 100644 --- a/librz/include/rz_util/rz_str.h +++ b/librz/include/rz_util/rz_str.h @@ -270,7 +270,6 @@ RZ_API bool rz_str_isnumber(const char *str); RZ_API const char *rz_str_last(const char *in, const char *ch); RZ_API char *rz_str_highlight(char *str, const char *word, const char *color, const char *color_reset); RZ_API char *rz_str_from_ut64(ut64 val); -RZ_API void rz_str_stripLine(char *str, const char *key); RZ_API char *rz_str_list_join(RzList /**/ *str, const char *sep); RZ_API char *rz_str_array_join(const char **a, size_t n, const char *sep); RZ_API RzList /**/ *rz_str_wrap(char *str, size_t width); diff --git a/librz/include/sflib/darwin-arm-64/sflib.h b/librz/include/sflib/darwin-arm-64/sflib.h index 749dcf7e19..4eccee4257 100644 --- a/librz/include/sflib/darwin-arm-64/sflib.h +++ b/librz/include/sflib/darwin-arm-64/sflib.h @@ -30,119 +30,177 @@ #include "../common/sftypes.h" // syscall -static inline _sfsyscall1(void, exit, int, status) static inline _sfsyscall0(pid_t, fork) static inline _sfsyscall3(ssize_t, read, int, fd, void *, buf, size_t, count) static inline _sfsyscall3(ssize_t, write, int, fd, const void *, buf, size_t, count) static inline _sfsyscall3(int, open, const char *, pathname, int, flags, mode_t, mode) static inline _sfsyscall1(int, close, int, fd) static inline _sfsyscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, struct rusage *, rusage) static inline _sfsyscall2(int, link, const char *, oldpath, const char *, newpath) static inline _sfsyscall1(int, unlink, const char *, pathname) static inline _sfsyscall1(int, chdir, const char *, path) - // fchdir - static inline _sfsyscall3(int, mknod, const char *, pathname, mode_t, mode, dev_t, dev) static inline _sfsyscall2(int, chmod, const char *, path, mode_t, mode) static inline _sfsyscall3(int, chown, const char *, path, uid_t, owner, gid_t, group) - // break - static inline _sfsyscall0(pid_t, getpid) - // mount - // unmount - // setuid - static inline _sfsyscall1(int, setuid, uid_t, uid) static inline _sfsyscall1(int, setgid, gid_t, gid) static inline _sfsyscall0(uid_t, getuid) static inline _sfsyscall0(uid_t, geteuid) static inline _sfsyscall4(long, ptrace, int, request, pid_t, pid, void *, addr, void *, data) - // recvmsg - // sendmsg - static inline _sfsyscall6(ssize_t, recvfrom, int, s, void *, buf, size_t, len, int, flags, struct sockaddr *, from, socklen_t *, fromlen) static inline _sfsyscall3(int, accept, int, s, struct sockaddr *, addr, socklen_t *, addrlen); +static inline _sfsyscall1(void, exit, int, status) +static inline _sfsyscall0(pid_t, fork) +static inline _sfsyscall3(ssize_t, read, int, fd, void *, buf, size_t, count) +static inline _sfsyscall3(ssize_t, write, int, fd, const void *, buf, size_t, count) +static inline _sfsyscall3(int, open, const char *, pathname, int, flags, mode_t, mode) +static inline _sfsyscall1(int, close, int, fd) +static inline _sfsyscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, struct rusage *, rusage) +static inline _sfsyscall2(int, link, const char *, oldpath, const char *, newpath) +static inline _sfsyscall1(int, unlink, const char *, pathname) +static inline _sfsyscall1(int, chdir, const char *, path) +// fchdir +static inline _sfsyscall3(int, mknod, const char *, pathname, mode_t, mode, dev_t, dev) +static inline _sfsyscall2(int, chmod, const char *, path, mode_t, mode) +static inline _sfsyscall3(int, chown, const char *, path, uid_t, owner, gid_t, group) +// break +static inline _sfsyscall0(pid_t, getpid) +// mount +// unmount +// setuid +static inline _sfsyscall1(int, setuid, uid_t, uid) +static inline _sfsyscall1(int, setgid, gid_t, gid) +static inline _sfsyscall0(uid_t, getuid) +static inline _sfsyscall0(uid_t, geteuid) +static inline _sfsyscall4(long, ptrace, int, request, pid_t, pid, void *, addr, void *, data) +// recvmsg +// sendmsg +static inline _sfsyscall6(ssize_t, recvfrom, int, s, void *, buf, size_t, len, int, flags, struct sockaddr *, from, socklen_t *, fromlen) +static inline _sfsyscall3(int, accept, int, s, struct sockaddr *, addr, socklen_t *, addrlen); // getpeername // getsockname static inline _sfsyscall2(int, access, const char *, pathname, int, mode) - // chflags - // fchflags - static inline _sfsyscall0(int, sync) static inline _sfsyscall2(int, kill, pid_t, pid, int, sig) static inline _sfsyscall0(pid_t, getppid) static inline _sfsyscall1(int, dup, int, oldfd) - // opipe - static inline _sfsyscall0(gid_t, getegid) - // profil - // ktrace - // sigaction - static inline _sfsyscall0(gid_t, getgid) - // sigprocmask - // getlogin - // setlogin - static inline _sfsyscall1(int, acct, const char *, filename) static inline _sfsyscall1(int, sigpending, sigset_t *, set) - // sigaltstack - static inline _sfsyscall4(int, ioctl, int, d, int, request, char *, argp, int, len) - // reboot - // revoke - static inline _sfsyscall2(int, symlink, const char *, oldpath, const char *, newpath) static inline _sfsyscall3(int, readlink, const char *, path, char *, buf, size_t, bufsiz) static inline _sfsyscall3(int, execve, char *, s, char **, argv, char **, envp) static inline _sfsyscall1(mode_t, umask, mode_t, mask) static inline _sfsyscall1(int, chroot, const char *, path) - // omsync - static inline _sfsyscall0(pid_t, vfork) - // sbrk - // sstk - // vadvise - static inline _sfsyscall2(int, munmap, void *, start, size_t, length) static inline _sfsyscall3(int, mprotect, const void *, addr, size_t, len, int, prot) - // madvise - // mincore - // getgroups - static inline _sfsyscall2(int, setgroups, size_t, size, const gid_t *, list) static inline _sfsyscall0(pid_t, getpgrp) static inline _sfsyscall2(int, setpgid, pid_t, pid, pid_t, pgid) - // setitimer - static inline _sfsyscall2(int, swapon, const char *, path, int, swapflags) - // getitimer - static inline _sfsyscall2(int, dup2, int, oldfd, int, newfd) static inline _sfsyscall3(int, fcntl, int, fd, int, cmd, long, arg) static inline _sfsyscall5(int, select, int, n, fd_set *, readfds, fd_set *, writefds, fd_set *, exceptfds, struct timeval *, timeout) static inline _sfsyscall1(int, fsync, int, fd) static inline _sfsyscall3(int, setpriority, int, which, int, who, int, prio) static inline _sfsyscall3(int, socket, int, domain, int, type, int, protocol) static inline _sfsyscall3(int, connect, int, sockfd, const struct sockaddr *, serv_addr, socklen_t, addrlen) static inline _sfsyscall2(int, getpriority, int, which, int, who) static inline _sfsyscall1(int, sigreturn, unsigned long, __unused) static inline _sfsyscall3(int, bind, int, sockfd, struct sockaddr *, my_addr, socklen_t, addrlen) static inline _sfsyscall5(int, setsockopt, int, s, int, level, int, optname, void *, optval, socklen_t, optlen) static inline _sfsyscall2(int, listen, int, s, int, backlog) static inline _sfsyscall1(int, sigsuspend, const sigset_t *, mask) static inline _sfsyscall2(int, gettimeofday, struct timeval *, tv, struct timezone *, tz) - // getrusage - // getsockopt - static inline _sfsyscall3(int, readv, int, fd, const struct iovec *, vector, int, count) static inline _sfsyscall3(int, writev, int, fd, const struct iovec *, vector, int, count) - // settimeofday - static inline _sfsyscall3(int, fchown, int, fd, uid_t, owner, gid_t, group) static inline _sfsyscall2(int, fchmod, int, fildes, mode_t, mode) static inline _sfsyscall2(int, rename, const char *, oldpath, const char *, newpath) - // flock - // mkfifo - static inline _sfsyscall6(ssize_t, sendto, int, s, const void *, msg, size_t, len, int, flags, const struct sockaddr *, to, socklen_t, tolen) - // shutdown - // socketpair - static inline _sfsyscall2(int, mkdir, const char *, pathname, mode_t, mode) static inline _sfsyscall1(int, rmdir, const char *, pathname) - // utimes - // adjtime - static inline _sfsyscall0(pid_t, setsid) - // quotactl - // nfssvc - // getfh - // sysarch - static inline _sfsyscall4(ssize_t, pread, int, fd, void *, buf, size_t, count, off_t, offset) - // pwrite - // setgid - // setegid - // seteuid - // lfs_bmapv - // lfs_markv - // lfs_segclean - // lfs_segwait - static inline _sfsyscall2(int, stat, const char *, file_name, struct stat *, buf) static inline _sfsyscall2(int, fstat, int, filedes, struct stat *, buf) static inline _sfsyscall2(int, lstat, const char *, file_name, struct stat *, buf) - // pathconf - // fpathconf - // swapctl - // getrlimit - // setrlimit - static inline _sfsyscall4(int, getdirentries, int, fd, void *, buf, int, nbytes, long *, basep) static inline _sfsyscall6(void *, mmap, void *, start, size_t, length, int, prot, int, flags, int, fd, off_t, offset) static inline _sfsyscall3(off_t, lseek, int, fildes, off_t, offset, int, whence) static inline _sfsyscall2(int, truncate, const char *, path, off_t, length) static inline _sfsyscall2(int, ftruncate, int, fd, off_t, length) static inline _sfsyscall2(int, mlock, const void *, addr, size_t, len) static inline _sfsyscall2(int, munlock, const void *, addr, size_t, len) - // undelete - // futimes - static inline _sfsyscall1(pid_t, getpgid, pid_t, pid) - // xfspioctl - static inline _sfsyscall3(int, semget, long, key, int, nsems, int, semflg) static inline _sfsyscall3(int, semop, int, semid, struct sembuf *, sops, unsigned, nsops) - // msgget - // msgsnd - // msgrcv - static inline _sfsyscall3(void *, shmat, int, shmid, const void *, shmaddr, int, shmflg) - // shmdt - static inline _sfsyscall3(int, shmget, long, key, int, size, int, flags) - // clock_gettime - // clock_settime - // clock_getres - static inline _sfsyscall2(int, nanosleep, const struct timespec *, req, struct timespec *, rem) - // minherit - // rfork - static inline _sfsyscall3(int, poll, struct pollfd *, ufds, unsigned int, nfds, int, timeout) - // issetugid - static inline _sfsyscall3(int, lchown, const char *, path, uid_t, owner, gid_t, group) static inline _sfsyscall1(pid_t, getsid, pid_t, pid) static inline _sfsyscall3(int, msync, const void *, start, size_t, length, int, flags) - // shmctl - // msgctl - // getfsstat - static inline _sfsyscall2(int, statfs, const char *, path, struct statfs *, buf) static inline _sfsyscall2(int, fstatfs, int, fd, struct statfs *, buf) static inline _sfsyscall1(int, pipe, unsigned long *, filedes) - // fhopen - // fhstat - // fhstatfs - // preadv - // pwritev - // kqueue - // kevent - static inline _sfsyscall1(int, mlockall, int, flags) static inline _sfsyscall0(int, munlockall) +// chflags +// fchflags +static inline _sfsyscall0(int, sync) +static inline _sfsyscall2(int, kill, pid_t, pid, int, sig) +static inline _sfsyscall0(pid_t, getppid) +static inline _sfsyscall1(int, dup, int, oldfd) +// opipe +static inline _sfsyscall0(gid_t, getegid) +// profil +// ktrace +// sigaction +static inline _sfsyscall0(gid_t, getgid) +// sigprocmask +// getlogin +// setlogin +static inline _sfsyscall1(int, acct, const char *, filename) +static inline _sfsyscall1(int, sigpending, sigset_t *, set) +// sigaltstack +static inline _sfsyscall4(int, ioctl, int, d, int, request, char *, argp, int, len) +// reboot +// revoke +static inline _sfsyscall2(int, symlink, const char *, oldpath, const char *, newpath) +static inline _sfsyscall3(int, readlink, const char *, path, char *, buf, size_t, bufsiz) +static inline _sfsyscall3(int, execve, char *, s, char **, argv, char **, envp) +static inline _sfsyscall1(mode_t, umask, mode_t, mask) +static inline _sfsyscall1(int, chroot, const char *, path) +// omsync +static inline _sfsyscall0(pid_t, vfork) +// sbrk +// sstk +// vadvise +static inline _sfsyscall2(int, munmap, void *, start, size_t, length) +static inline _sfsyscall3(int, mprotect, const void *, addr, size_t, len, int, prot) +// madvise +// mincore +// getgroups +static inline _sfsyscall2(int, setgroups, size_t, size, const gid_t *, list) +static inline _sfsyscall0(pid_t, getpgrp) +static inline _sfsyscall2(int, setpgid, pid_t, pid, pid_t, pgid) +// setitimer +static inline _sfsyscall2(int, swapon, const char *, path, int, swapflags) +// getitimer +static inline _sfsyscall2(int, dup2, int, oldfd, int, newfd) +static inline _sfsyscall3(int, fcntl, int, fd, int, cmd, long, arg) +static inline _sfsyscall5(int, select, int, n, fd_set *, readfds, fd_set *, writefds, fd_set *, exceptfds, struct timeval *, timeout) +static inline _sfsyscall1(int, fsync, int, fd) +static inline _sfsyscall3(int, setpriority, int, which, int, who, int, prio) +static inline _sfsyscall3(int, socket, int, domain, int, type, int, protocol) +static inline _sfsyscall3(int, connect, int, sockfd, const struct sockaddr *, serv_addr, socklen_t, addrlen) +static inline _sfsyscall2(int, getpriority, int, which, int, who) +static inline _sfsyscall1(int, sigreturn, unsigned long, __unused) +static inline _sfsyscall3(int, bind, int, sockfd, struct sockaddr *, my_addr, socklen_t, addrlen) +static inline _sfsyscall5(int, setsockopt, int, s, int, level, int, optname, void *, optval, socklen_t, optlen) +static inline _sfsyscall2(int, listen, int, s, int, backlog) +static inline _sfsyscall1(int, sigsuspend, const sigset_t *, mask) +static inline _sfsyscall2(int, gettimeofday, struct timeval *, tv, struct timezone *, tz) +// getrusage +// getsockopt +static inline _sfsyscall3(int, readv, int, fd, const struct iovec *, vector, int, count) +static inline _sfsyscall3(int, writev, int, fd, const struct iovec *, vector, int, count) +// settimeofday +static inline _sfsyscall3(int, fchown, int, fd, uid_t, owner, gid_t, group) +static inline _sfsyscall2(int, fchmod, int, fildes, mode_t, mode) +static inline _sfsyscall2(int, rename, const char *, oldpath, const char *, newpath) +// flock +// mkfifo +static inline _sfsyscall6(ssize_t, sendto, int, s, const void *, msg, size_t, len, int, flags, const struct sockaddr *, to, socklen_t, tolen) +// shutdown +// socketpair +static inline _sfsyscall2(int, mkdir, const char *, pathname, mode_t, mode) +static inline _sfsyscall1(int, rmdir, const char *, pathname) +// utimes +// adjtime +static inline _sfsyscall0(pid_t, setsid) +// quotactl +// nfssvc +// getfh +// sysarch +static inline _sfsyscall4(ssize_t, pread, int, fd, void *, buf, size_t, count, off_t, offset) +// pwrite +// setgid +// setegid +// seteuid +// lfs_bmapv +// lfs_markv +// lfs_segclean +// lfs_segwait +static inline _sfsyscall2(int, stat, const char *, file_name, struct stat *, buf) +static inline _sfsyscall2(int, fstat, int, filedes, struct stat *, buf) +static inline _sfsyscall2(int, lstat, const char *, file_name, struct stat *, buf) +// pathconf +// fpathconf +// swapctl +// getrlimit +// setrlimit +static inline _sfsyscall4(int, getdirentries, int, fd, void *, buf, int, nbytes, long *, basep) +static inline _sfsyscall6(void *, mmap, void *, start, size_t, length, int, prot, int, flags, int, fd, off_t, offset) +static inline _sfsyscall3(off_t, lseek, int, fildes, off_t, offset, int, whence) +static inline _sfsyscall2(int, truncate, const char *, path, off_t, length) +static inline _sfsyscall2(int, ftruncate, int, fd, off_t, length) +static inline _sfsyscall2(int, mlock, const void *, addr, size_t, len) +static inline _sfsyscall2(int, munlock, const void *, addr, size_t, len) +// undelete +// futimes +static inline _sfsyscall1(pid_t, getpgid, pid_t, pid) +// xfspioctl +static inline _sfsyscall3(int, semget, long, key, int, nsems, int, semflg) +static inline _sfsyscall3(int, semop, int, semid, struct sembuf *, sops, unsigned, nsops) +// msgget +// msgsnd +// msgrcv +static inline _sfsyscall3(void *, shmat, int, shmid, const void *, shmaddr, int, shmflg) +// shmdt +static inline _sfsyscall3(int, shmget, long, key, int, size, int, flags) +// clock_gettime +// clock_settime +// clock_getres +static inline _sfsyscall2(int, nanosleep, const struct timespec *, req, struct timespec *, rem) +// minherit +// rfork +static inline _sfsyscall3(int, poll, struct pollfd *, ufds, unsigned int, nfds, int, timeout) +// issetugid +static inline _sfsyscall3(int, lchown, const char *, path, uid_t, owner, gid_t, group) +static inline _sfsyscall1(pid_t, getsid, pid_t, pid) +static inline _sfsyscall3(int, msync, const void *, start, size_t, length, int, flags) +// shmctl +// msgctl +// getfsstat +static inline _sfsyscall2(int, statfs, const char *, path, struct statfs *, buf) +static inline _sfsyscall2(int, fstatfs, int, fd, struct statfs *, buf) +static inline _sfsyscall1(int, pipe, unsigned long *, filedes) +// fhopen +// fhstat +// fhstatfs +// preadv +// pwritev +// kqueue +// kevent +static inline _sfsyscall1(int, mlockall, int, flags) +static inline _sfsyscall0(int, munlockall) // getpeereid // extattrctl // extattr_set_file diff --git a/librz/main/rz-gg.c b/librz/main/rz-gg.c index 63986d8a9c..7dada5f118 100644 --- a/librz/main/rz-gg.c +++ b/librz/main/rz-gg.c @@ -44,6 +44,7 @@ static int usage(int v) { "-s", "" ,"Show assembler", "-S", "string" ,"Append a string", "-v", "" ,"Show version information", + "-V", "" ,"Increase the verbosity", "-w", "off:hex" ,"Patch hexpairs at given offset", "-x", "" ,"Execute", "-X", "" ,"Execute rop chain, using the stack provided", @@ -163,7 +164,7 @@ RZ_API int rz_main_rz_gg(int argc, const char **argv) { RzEgg *egg = rz_egg_new(); RzGetopt opt; - rz_getopt_init(&opt, argc, argv, "n:N:he:a:b:f:o:sxXrk:FOI:Li:c:p:P:B:C:vd:D:w:zq:S:"); + rz_getopt_init(&opt, argc, argv, "n:N:he:a:b:f:o:sVxXrk:FOI:Li:c:p:P:B:C:vd:D:w:zq:S:"); while ((c = rz_getopt_next(&opt)) != -1) { switch (c) { case 'a': @@ -324,6 +325,9 @@ RZ_API int rz_main_rz_gg(int argc, const char **argv) { rz_egg_free(egg); return print_val; } + case 'V': + rz_log_set_level(RZ_LOGLVL_DEBUG); + break; case 'z': show_str = 1; break; diff --git a/librz/util/str.c b/librz/util/str.c index ced155c1b2..5332b540c9 100644 --- a/librz/util/str.c +++ b/librz/util/str.c @@ -3919,42 +3919,6 @@ RZ_API int rz_snprintf(char *string, int len, const char *fmt, ...) { return ret; } -// Strips all the lines in str that contain key -RZ_API void rz_str_stripLine(char *str, const char *key) { - size_t i, j, klen, slen, off; - const char *ptr; - - if (!str || !key) { - return; - } - klen = strlen(key); - slen = strlen(str); - - for (i = 0; i < slen;) { - ptr = (char *)rz_mem_mem((ut8 *)str + i, slen - i, (ut8 *)"\n", 1); - if (!ptr) { - ptr = (char *)rz_mem_mem((ut8 *)str + i, slen - i, (ut8 *)key, klen); - if (ptr) { - str[i] = '\0'; - break; - } - break; - } - - off = (size_t)(ptr - (str + i)) + 1; - - ptr = (char *)rz_mem_mem((ut8 *)str + i, off, (ut8 *)key, klen); - if (ptr) { - for (j = i; j < slen - off + 1; j++) { - str[j] = str[j + off]; - } - slen -= off; - } else { - i += off; - } - } -} - RZ_API char *rz_str_list_join(RzList /**/ *str, const char *sep) { RzStrBuf *sb = rz_strbuf_new(""); const char *p; diff --git a/librz/util/sys.c b/librz/util/sys.c index 9769176a5d..43bd2e8c30 100644 --- a/librz/util/sys.c +++ b/librz/util/sys.c @@ -176,7 +176,6 @@ static const struct { { "lm32", RZ_SYS_ARCH_LM32 }, { "v850", RZ_SYS_ARCH_V850 }, { "tricore", RZ_SYS_ARCH_TRICORE }, - { NULL, 0 } }; #if __WINDOWS__ @@ -926,8 +925,7 @@ RZ_API bool rz_sys_arch_match(const char *archstr, const char *arch) { } RZ_API int rz_sys_arch_id(const char *arch) { - int i; - for (i = 0; arch_bit_array[i].name; i++) { + for (size_t i = 0; i < RZ_ARRAY_SIZE(arch_bit_array); i++) { if (!strcmp(arch, arch_bit_array[i].name)) { return arch_bit_array[i].bit; } @@ -936,9 +934,8 @@ RZ_API int rz_sys_arch_id(const char *arch) { } RZ_API const char *rz_sys_arch_str(int arch) { - int i; - for (i = 0; arch_bit_array[i].name; i++) { - if (arch & arch_bit_array[i].bit) { + for (size_t i = 0; i < RZ_ARRAY_SIZE(arch_bit_array); i++) { + if (arch == arch_bit_array[i].bit) { return arch_bit_array[i].name; } } diff --git a/sys/clang-format.py b/sys/clang-format.py index 1ef9f4ee19..276b986f5c 100755 --- a/sys/clang-format.py +++ b/sys/clang-format.py @@ -83,12 +83,14 @@ def format_files(args, files): sys.exit(r.returncode) -def get_file(args): - filename = args.file - if should_scan(filename) and not skip(filename): - return [filename] - - return [] +def get_files_from_arg_option(args): + files = [] + for filename in args.file: + if should_scan(filename) and not skip(filename): + files.append(filename) + else: + print(f"{filename} will be skipped.") + return files def get_files(args): @@ -96,7 +98,7 @@ def get_files(args): return get_edited_files(args) if args.file: - return get_file(args) + return get_files_from_arg_option(args) return get_matching_files() @@ -118,7 +120,9 @@ def parse(): parser.add_argument( "-v", "--verbose", action="store_true", help="use verbose output" ) - parser.add_argument("-f", "--file", help="formats (or checks) only the given file") + parser.add_argument( + "-f", "--file", action="append", help="formats (or checks) only the given file" + ) parser.add_argument( "-d", "--diff", diff --git a/test/db/tools/rz b/test/db/tools/rz index a1d7409235..f79a8d4180 100644 --- a/test/db/tools/rz +++ b/test/db/tools/rz @@ -566,6 +566,7 @@ ec diff.unmatch red | mismatch color -s Show assembler -S string  Append a string -v Show version information + -V Increase the verbosity -w off:hex  Patch hexpairs at given offset -x Execute -X Execute rop chain, using the stack provided