librz/bin/elf: improve ARM Thumb symbols detection (#6502)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
This commit is contained in:
parent
3aebd94478
commit
323e707114
3 changed files with 45 additions and 11 deletions
|
|
@ -98,22 +98,20 @@ static Elf_(Word) get_number_of_symbols_from_section(ELFOBJ *bin) {
|
|||
}
|
||||
|
||||
static bool is_special_arm_symbol(ELFOBJ *bin, Elf_(Sym) * sym, const char *name) {
|
||||
if (!name) {
|
||||
// ARM/AArch64 mapping symbols are named "$<char>" optionally followed by
|
||||
// ".<suffix>" (e.g. "$t", "$d.realdata"). The ABI specifies STT_NOTYPE, but
|
||||
// some toolchains emit them as STT_FUNC/STT_OBJECT (e.g. Motorola P2K
|
||||
// firmware), so only the name shape and local binding are checked, like
|
||||
// binutils' bfd_is_arm_special_symbol_name() with BFD_ARM_SPECIAL_SYM_TYPE_ANY.
|
||||
if (!name || name[0] != '$' || !name[1]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name[0] != '$') {
|
||||
if (name[2] != '\0' && name[2] != '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name[1] == 'a' || name[1] == 't' || name[1] == 'd' || name[1] == 'x') {
|
||||
return (name[2] == '\0' || name[2] == '.') &&
|
||||
ELF_ST_TYPE(sym->st_info) == STT_NOTYPE &&
|
||||
ELF_ST_BIND(sym->st_info) == STB_LOCAL &&
|
||||
ELF_ST_VISIBILITY(sym->st_info) == STV_DEFAULT;
|
||||
}
|
||||
|
||||
return false;
|
||||
return ELF_ST_BIND(sym->st_info) == STB_LOCAL;
|
||||
}
|
||||
|
||||
static bool is_special_symbol(ELFOBJ *bin, Elf_(Sym) * sym, const char *name) {
|
||||
|
|
|
|||
|
|
@ -1469,6 +1469,18 @@ static void select_flag_space(RzCore *core, RzBinSymbol *symbol) {
|
|||
}
|
||||
}
|
||||
|
||||
// True if the binary carries ARM/AArch64 mapping symbols ($a/$t/$d/$x).
|
||||
static bool has_arm_mapping_symbols(RzPVector /*<RzBinSymbol *>*/ *symbols) {
|
||||
void **it;
|
||||
rz_pvector_foreach (symbols, it) {
|
||||
RzBinSymbol *symbol = *it;
|
||||
if (symbol->name && is_special_symbol(symbol)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RZ_API bool rz_core_bin_apply_symbols(RzCore *core, RzBinFile *binfile, bool va) {
|
||||
rz_return_val_if_fail(core && binfile, false);
|
||||
RzBinObject *o = binfile->o;
|
||||
|
|
@ -1488,6 +1500,13 @@ RZ_API bool rz_core_bin_apply_symbols(RzCore *core, RzBinFile *binfile, bool va)
|
|||
void **iter;
|
||||
void **it;
|
||||
RzBinSymbol *symbol;
|
||||
|
||||
// Mapping symbols authoritatively describe the instruction set of each code
|
||||
// region, so when present the address-parity heuristic in handle_arm_symbol()
|
||||
// must be disabled: such binaries place Thumb functions at even addresses,
|
||||
// where the heuristic would wrongly force ARM mode (see issue #4357).
|
||||
bool arm_mapping_symbols = is_arm && has_arm_mapping_symbols(symbols);
|
||||
|
||||
rz_pvector_foreach (symbols, it) {
|
||||
symbol = *it;
|
||||
if (!symbol->name) {
|
||||
|
|
@ -1512,7 +1531,8 @@ RZ_API bool rz_core_bin_apply_symbols(RzCore *core, RzBinFile *binfile, bool va)
|
|||
// applied to FUNC symbols by handle_arm_symbol().
|
||||
} else {
|
||||
// TODO: provide separate API in RzBinPlugin to let plugins handle analysis hints/metadata
|
||||
if (is_arm) {
|
||||
// Address-parity heuristic only when no mapping symbols (see above).
|
||||
if (is_arm && !arm_mapping_symbols) {
|
||||
handle_arm_symbol(core, o, symbol, va);
|
||||
}
|
||||
select_flag_space(core, symbol);
|
||||
|
|
|
|||
|
|
@ -119,3 +119,19 @@ str r1, [r7]
|
|||
ldr r3, [r7, 4]
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=ELF: big-endian ARM, mapping symbols typed STT_FUNC/STT_OBJECT
|
||||
FILE=bins/elf/analysis/2048-P2K-AHI_EP1.elf
|
||||
CMDS=<<EOF
|
||||
s 0x81f0
|
||||
pi 6
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
movs r1, 0
|
||||
lsls r2, r1, 2
|
||||
ldr r3, [r0, r2]
|
||||
ldr r2, [r5, r2]
|
||||
cmp r3, r2
|
||||
beq 0x8200
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
Loading…
Reference in a new issue