Rewrite C compiler code for rz-gg (#5761)
This commit is contained in:
parent
e4ed1d3436
commit
6926b6a65d
12 changed files with 623 additions and 506 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,341 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2011-2018 pancake <pancake@nopcode.org>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_egg.h>
|
||||
|
||||
// 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;
|
||||
}
|
||||
420
librz/egg/egg_c_compile.c
Normal file
420
librz/egg/egg_c_compile.c
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
// SPDX-FileCopyrightText: 2026 deroad <deroad@kumo.xn--q9jyb4c>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_egg.h>
|
||||
|
||||
typedef struct egg_c_config {
|
||||
const char *triplet; ///< <os>-<arch>-<bits>
|
||||
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/<section>" 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;
|
||||
}
|
||||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 /*<char *>*/ *str, const char *sep);
|
||||
RZ_API char *rz_str_array_join(const char **a, size_t n, const char *sep);
|
||||
RZ_API RzList /*<char *>*/ *rz_str_wrap(char *str, size_t width);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 /*<char *>*/ *str, const char *sep) {
|
||||
RzStrBuf *sb = rz_strbuf_new("");
|
||||
const char *p;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -566,6 +566,7 @@ ec diff.unmatch red | mismatch color
|
|||
[32m-s[0m [0mShow assembler
|
||||
[32m-S[0m[33m string [0m [0mAppend a string
|
||||
[32m-v[0m [0mShow version information
|
||||
[32m-V[0m [0mIncrease the verbosity
|
||||
[32m-w[0m[33m off:hex [0m [0mPatch hexpairs at given offset
|
||||
[32m-x[0m [0mExecute
|
||||
[32m-X[0m [0mExecute rop chain, using the stack provided
|
||||
|
|
|
|||
Loading…
Reference in a new issue