R_API char *r_str_unscape(char *buf) { char *ptr, *ret; int len = strlen (buf); ptr = ret = malloc (1+len*2); if (ptr == NULL) return NULL; for (;*buf;buf++,ptr++) { if (*buf=='\n') { *ptr = '\\'; ptr++; *ptr = 'n'; } else if (*buf=='\t') { *ptr = '\\'; ptr++; *ptr = 't'; } else if (IS_PRINTABLE (*buf)) { *ptr = *buf; } else break; } *ptr = 0; r_str_sanitize (ret); return ret; }
R_API char* r_egg_Cfile_parser(const char *file, const char *arch, const char *os, int bits) { char *output = NULL; char *fileExt = NULL; // "file" with extension (.s, .text, ...) struct cEnv_t *cEnv = r_egg_Cfile_set_cEnv (arch, os, bits); if (!cEnv) { goto fail; } r_str_sanitize (cEnv->CC); //printf ("==> Compile\n"); printf ("'%s' %s -o '%s.tmp' -S -Os '%s'\n", cEnv->CC, cEnv->CFLAGS, file, file); output = r_sys_cmd_strf ("('%s' %s -o '%s.tmp' -S -Os '%s') 2>&1", cEnv->CC, cEnv->CFLAGS, file, file); if (output == NULL) { eprintf ("Compilation failed!\n"); goto fail; } printf ("%s", output); if (!(fileExt = r_str_newf ("%s.s", file))) { goto fail; } if (!r_file_dump (fileExt, (const ut8*) cEnv->SHDR, strlen (cEnv->SHDR), false)) { eprintf ("Error while opening %s.s\n", file); goto fail; } if (!r_egg_Cfile_parseCompiled (file)) { goto fail; } //printf ("==> Assemble\n"); printf ("'%s' %s -Os -o '%s.o' '%s.s'\n", cEnv->CC, cEnv->LDFLAGS, file, file); free (output); output = r_sys_cmd_strf ("'%s' %s -Os -o '%s.o' '%s.s'", cEnv->CC, cEnv->LDFLAGS, file, file); if (!output) { eprintf ("Assembly failed!\n"); goto fail; } printf ("%s", output); //printf ("==> Link\n"); printf ("rabin2 -o '%s.text' -O d/S/'%s' '%s.o'\n", file, cEnv->TEXT, file); free (output); output = r_sys_cmd_strf ("rabin2 -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 = r_str_newf ("%s.o", file))) { goto fail; } if (!r_file_exists (fileExt)) { eprintf ("Cannot find %s.o\n", file); goto fail; } free (fileExt); if (!(fileExt = r_str_newf ("%s.text", file))) { goto fail; } if (r_file_size (fileExt) == 0) { printf ("FALLBACK: Using objcopy instead of rabin2"); free (output); output = r_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 = r_str_newf ("%s.%s", file, extArray[i]))) { goto fail; } r_file_rm (fileExt); } free (fileExt); if ((fileExt = r_str_newf ("%s.text", file)) == NULL) { goto fail; } free (output); r_egg_Cfile_free_cEnv (cEnv); return fileExt; fail: free (fileExt); free (output); r_egg_Cfile_free_cEnv (cEnv); return NULL; }