Skip to content

Commit

Permalink
Add r2ghidra.compiler variable to list and use compiler profiles
Browse files Browse the repository at this point in the history
* Honor RBinInfo.compiler and the hardcoded list
  • Loading branch information
radare committed Jul 26, 2022
1 parent a8b4767 commit 957eed5
Show file tree
Hide file tree
Showing 2 changed files with 264 additions and 5 deletions.
247 changes: 243 additions & 4 deletions src/ArchMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,25 +172,264 @@ static const std::map<std::string, ArchMapper> arch_map = {
}}
};

#if 0
Supported compiler profiles. r2 should have a configuration option for that:

For X86:
* default
* clang
* gcc
* Borland C++
* Visual Studio
* Delphi

```
# list all arch.compiler from ghidra
$ cd ghidra-native
$ git grep 'compiler name=' | grep ldefs| cut -d '"' -f 1,2 |cut -d '/' -f 6- |sed -e 's,",.,' | cut -d . -f1,3|sort -u

6502.default
68000.default
6805.default
8048.default
8051.Archimedes
8051.default
8085.default
AARCH64.Visual Studio
AARCH64.default
ARM.Visual Studio
ARM.default
AppleSilicon.default
CP1600.default
CR16.default
Dalvik.default
HC05.default
HC08.default
HCS08.default
HCS12.default
JVM.default
MCS96.default
PIC24.default
STM8.default
SparcV9.default
SuperH4.Visual Studio
SuperH4.default
TI_MSP430.default
V850.default
avr32a.default
avr8.gcc
avr8.iarV1
avr8.imgCraftV8
hexagon.default
m8c.default
mips.Visual Studio
mips.default
mips.n32
mips.o32
mips.o64
old/v01stuff/toy.default
pa-risc.default
pic12c5xx.default
pic16.default
pic16c5x.default
pic17c7xx.default
pic18.default
ppc.Mac OS X
ppc.Visual Studio
ppc.default
riscv.gcc
superh.default
toy.default
toy.posStack
tricore.default
x86.Borland C++
x86.Delphi
x86.Visual Studio
x86.clang
x86.default
x86.gcc
z80.default


# list all compiler support from ghidra

$ git grep compiler' name=' | cut -d '"' -f 2|sort -u
Archimedes
Borland C++
Delphi
Mac OS X
Sleigh-PowerPC 32-bit
Visual Studio
clang
default
gcc
iarV1
imgCraftV8
n32
o32
o64
pointer16
pointer32
pointer64
posStack
```
#endif
const char *ghidraCompilers[] = {
"6502.default",
"68000.default",
"6805.default",
"8048.default",
"8051.Archimedes",
"8051.default",
"8085.default",
"AARCH64.Visual Studio",
"AARCH64.default",
"ARM.Visual Studio",
"ARM.default",
"AppleSilicon.default",
"CP1600.default",
"CR16.default",
"Dalvik.default",
"HC05.default",
"HC08.default",
"HCS08.default",
"HCS12.default",
"JVM.default",
"MCS96.default",
"PIC24.default",
"STM8.default",
"SparcV9.default",
"SuperH4.Visual Studio",
"SuperH4.default",
"TI_MSP430.default",
"V850.default",
"avr32a.default",
"avr8.gcc",
"avr8.iarV1",
"avr8.imgCraftV8",
"hexagon.default",
"m8c.default",
"mips.Visual Studio",
"mips.default",
"mips.n32",
"mips.o32",
"mips.o64",
"old/v01stuff/toy.default",
"pa-risc.default",
"pic12c5xx.default",
"pic16.default",
"pic16c5x.default",
"pic17c7xx.default",
"pic18.default",
"ppc.Mac OS X",
"ppc.Visual Studio",
"ppc.default",
"riscv.gcc",
"superh.default",
"toy.default",
"toy.posStack",
"tricore.default",
"x86.Borland C++",
"x86.Delphi",
"x86.Visual Studio",
"x86.clang",
"x86.default",
"x86.gcc",
"z80.default",
NULL
};

static const std::map<std::string, std::string> compiler_alias = {
{ "vs", "Visual Studio" },
{ "mach0", "Mac OS X" },
};

static const std::map<std::string, std::string> compiler_map = {
{ "elf", "gcc" },
{ "pe", "windows" },
{ "mach0", "clang" }
{ "pe", "Visual Studio" },
// { "mach0", "clang" },
{ "mach0", "clang" },
};

std::string findGhidraCompiler(RCore *core, const char *bin_compiler) {
const char *arch = r_config_get (core->config, "asm.arch");
if (R_STR_ISEMPTY (arch)) {
return std::string("default");
}
if (!strcmp (arch, "r2ghidra")) {
arch = r_config_get (core->config, "asm.cpu");
}

char *a = strdup (arch);
// take arch name by splitting by the dot.
char *dot = strchr (a, '.');
if (dot) {
*dot = 0;
}
char *b = r_str_newf ("%s.", a);
const char *uc = bin_compiler; // r_config_get (core->config, "r2ghidra.compiler");
if (!strcmp (uc, "?")) {
for (int i = 0; ghidraCompilers[i]; i++) {
if (r_str_startswith (ghidraCompilers[i], b)) {
const char *c = ghidraCompilers[i] + strlen (b);
r_cons_printf ("%s\n", c);
}
}
free (b);
return std::string("default");
}
if (R_STR_ISEMPTY (bin_compiler) || !strcmp (uc, "default")) {
bin_compiler = uc;
}
const char *goodcompiler = NULL;
for (int i = 0; ghidraCompilers[i]; i++) {
if (r_str_startswith (ghidraCompilers[i], b)) {
const char *c = ghidraCompilers[i] + strlen (b);
goodcompiler = c;
if (R_STR_ISEMPTY (bin_compiler) || !r_str_casecmp (c, bin_compiler)) {
break;
}
//eprintf ("-> %s\n", c);
}
}
free (b);
free (a);
if (goodcompiler != NULL) {
return std::string(goodcompiler);
}
if (r_str_startswith (arch, "x86")) {
return std::string("gcc");
}
return std::string("default");
/*
if (!r_str_startswith (arch, "x86")) {
"x86.Borland C++",
"x86.Delphi",
"x86.Visual Studio",
"x86.clang",
"x86.default",
"x86.gcc",
"z80.default",
}
*/
}

std::string CompilerFromCore(RCore *core) {
if (!core) {
return "gcc";
}
RBinInfo *info = r_bin_get_info(core->bin);
RBinInfo *info = r_bin_get_info (core->bin);
if (!info || !info->rclass) {
return std::string ();
}
if (R_STR_ISNOTEMPTY (info->compiler)) {
auto gcompiler = findGhidraCompiler(core, info->compiler);
return std::string(info->compiler);
}
auto comp_it = compiler_map.find (info->rclass);
if (comp_it == compiler_map.end ()) {
return std::string ();
}

return comp_it->second;
}

Expand Down
22 changes: 21 additions & 1 deletion src/core_ghidra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ struct ConfigVar {

std::vector<const ConfigVar *> ConfigVar::vars_all;

std::string findGhidraCompiler(RCore *core, const char *bin_compiler);
bool SleighHomeConfig(void *user, void *data);
bool ConfigCompiler(void *user, void *data);

static const ConfigVar cfg_var_sleighhome ("sleighhome", "", "SLEIGHHOME", SleighHomeConfig);
static const ConfigVar cfg_var_sleighid ("lang", "", "Custom Sleigh ID to override auto-detection (e.g. x86:LE:32:default)");
Expand All @@ -67,7 +69,7 @@ static const ConfigVar cfg_var_rawptr ("rawptr", "true", "Show un
static const ConfigVar cfg_var_verbose ("verbose", "false", "Show verbose warning messages while decompiling");
static const ConfigVar cfg_var_casts ("casts", "false", "Show type casts where needed");
static const ConfigVar cfg_var_ropropagate ("roprop", "true", "Propagate read-only constants");

static const ConfigVar cfg_var_compiler ("compiler", "default", "Select compiler for calling conventions", ConfigCompiler);


static std::recursive_mutex decompiler_mutex;
Expand Down Expand Up @@ -533,6 +535,24 @@ extern "C" int r2ghidra_core_cmd(void *user, const char *input) {
return false;
}

bool ConfigCompiler(void *user, void *data) {
RCore *core = (RCore *) user;
std::lock_guard<std::recursive_mutex> lock(decompiler_mutex);
auto node = reinterpret_cast<RConfigNode *>(data);
if (!strcmp (node->value, "?")) {
auto c = findGhidraCompiler (core, node->value);
// eprintf ("list compilers%c", 10);
return false;
} else {
auto c = findGhidraCompiler (core, node->value);
free (node->value);
node->value = strdup (c.c_str());
// eprintf ("%s%c", c.c_str(), 10);
// print c.c_str()
}
return true;
}

bool SleighHomeConfig(void */* user */, void *data) {
std::lock_guard<std::recursive_mutex> lock(decompiler_mutex);
auto node = reinterpret_cast<RConfigNode *>(data);
Expand Down

0 comments on commit 957eed5

Please sign in to comment.