Skip to content

Commit 6c66c2b

Browse files
committed
Link DWARF types only when prototypes match ##analysis
1 parent b4b6253 commit 6c66c2b

2 files changed

Lines changed: 26 additions & 11 deletions

File tree

libr/anal/dwarf_process.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,27 +1614,35 @@ static bool dwarf_function_type_matches(Sdb *types, const char *name, const char
16141614
return true;
16151615
}
16161616

1617-
static char *dwarf_function_type_name(Context *ctx, const char *sname, const Function *dwarf_fcn, const char *ret_type, RList/*<Variable*>*/ *variables, bool has_unspecified_parameters) {
1618-
R_RETURN_VAL_IF_FAIL (ctx && ctx->anal && sname && dwarf_fcn && ret_type && variables, NULL);
1617+
static char *dwarf_function_type_name(Context *ctx, const char *sname, const Function *dwarf_fcn, const char *ret_type, RList/*<Variable*>*/ *variables, bool has_unspecified_parameters, bool *type_matches) {
1618+
R_RETURN_VAL_IF_FAIL (ctx && ctx->anal && sname && dwarf_fcn && ret_type && variables && type_matches, NULL);
1619+
*type_matches = false;
16191620
Sdb *types = ctx->anal->sdb_types;
16201621
const char *previous_name = sdb_const_getf (ctx->sdb, NULL, "fcn.%s.name", sname);
16211622
const char *previous = sdb_const_getf (ctx->sdb, NULL, "fcn.%s.typed_name", sname);
16221623
if (previous_name && !strcmp (previous_name, dwarf_fcn->name)
16231624
&& previous && dwarf_function_type_matches (types, previous,
16241625
ret_type, variables, has_unspecified_parameters)) {
1626+
*type_matches = true;
16251627
return strdup (previous);
16261628
}
16271629
char *name = sanitize_c_identifier (dwarf_fcn->name);
1628-
if (!name || !sdb_const_get (types, name, 0)
1629-
|| dwarf_function_type_matches (types, name, ret_type,
1630+
if (!name || !sdb_const_get (types, name, 0)) {
1631+
return name;
1632+
}
1633+
if (dwarf_function_type_matches (types, name, ret_type,
16301634
variables, has_unspecified_parameters)) {
1635+
*type_matches = true;
16311636
return name;
16321637
}
16331638
char *candidate = r_str_newf ("%s_%" PFMT64x, name, dwarf_fcn->addr);
16341639
int suffix = 2;
1635-
while (candidate && sdb_const_get (types, candidate, 0)
1636-
&& !dwarf_function_type_matches (types, candidate, ret_type,
1637-
variables, has_unspecified_parameters)) {
1640+
while (candidate && sdb_const_get (types, candidate, 0)) {
1641+
if (dwarf_function_type_matches (types, candidate, ret_type,
1642+
variables, has_unspecified_parameters)) {
1643+
*type_matches = true;
1644+
break;
1645+
}
16381646
free (candidate);
16391647
candidate = r_str_newf ("%s_%" PFMT64x "_%d", name, dwarf_fcn->addr, suffix++);
16401648
}
@@ -1705,7 +1713,7 @@ static bool import_dwarf_function_fallback(RAnal *anal, const char *typed_name,
17051713
return true;
17061714
}
17071715

1708-
static void import_dwarf_function_type(Context *ctx, const char *sname, const char *typed_name, Function *dwarf_fcn, const char *ret_type, RList/*<Variable*>*/ *variables, bool has_unspecified_parameters) {
1716+
static void import_dwarf_function_type(Context *ctx, const char *sname, const char *typed_name, Function *dwarf_fcn, const char *ret_type, RList/*<Variable*>*/ *variables, bool has_unspecified_parameters, bool type_matches) {
17091717
R_RETURN_IF_FAIL (ctx && ctx->anal && sname && typed_name && dwarf_fcn && ret_type && variables);
17101718
RAnal *anal = (RAnal *)ctx->anal;
17111719
sdb_setf (ctx->sdb, typed_name, 0, "fcn.%s.typed_name", sname);
@@ -1751,7 +1759,9 @@ static void import_dwarf_function_type(Context *ctx, const char *sname, const ch
17511759
(void)import_dwarf_function_fallback (anal, typed_name, ret_type, variables, has_unspecified_parameters);
17521760
}
17531761
}
1754-
if (dwarf_fcn->prototype_complete && r_type_func_exist (anal->sdb_types, typed_name)) {
1762+
if (dwarf_fcn->prototype_complete && r_type_func_exist (anal->sdb_types, typed_name)
1763+
&& (type_matches || dwarf_function_type_matches (anal->sdb_types, typed_name,
1764+
ret_type, variables, has_unspecified_parameters))) {
17551765
const char *linked = sdb_const_getf (anal->sdb_types, NULL,
17561766
"fcnlink.%08" PFMT64x, dwarf_fcn->addr);
17571767
if (!linked || !strcmp (linked, typed_name)) {
@@ -1771,8 +1781,9 @@ static void sdb_save_dwarf_function(Context *ctx, Function *dwarf_fcn, const cha
17711781
free (real_name);
17721782
return;
17731783
}
1784+
bool type_matches = false;
17741785
char *typed_name = dwarf_function_type_name (ctx, sname, dwarf_fcn,
1775-
ret_type, variables, has_unspecified_parameters);
1786+
ret_type, variables, has_unspecified_parameters, &type_matches);
17761787
sdb_set (sdb, sname, "fcn", 0);
17771788

17781789
char *addr_val = r_str_newf ("0x%" PFMT64x, dwarf_fcn->addr);
@@ -1824,7 +1835,7 @@ static void sdb_save_dwarf_function(Context *ctx, Function *dwarf_fcn, const cha
18241835
r_strbuf_fini (&vars_buf);
18251836
r_strbuf_fini (&args_buf);
18261837
if (typed_name) {
1827-
import_dwarf_function_type (ctx, sname, typed_name, dwarf_fcn, ret_type, variables, has_unspecified_parameters);
1838+
import_dwarf_function_type (ctx, sname, typed_name, dwarf_fcn, ret_type, variables, has_unspecified_parameters, type_matches);
18281839
}
18291840
free (typed_name);
18301841
free (real_name);

test/db/formats/dwarf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ FILE=bins/elf/dwarf3_cpp.elf
1515
CMDS=<<EOF
1616
e asm.dwarf=false
1717
aaa
18+
k anal/types/fcnlink.00001169
19+
afs @ 0x1169
1820
k anal/types/fcnlink.0000130e
1921
afs @ 0x130e
2022
aaa
@@ -24,6 +26,8 @@ tl overridden = 0x130e
2426
afs @ 0x130e
2527
EOF
2628
EXPECT=<<EOF
29+
main_1169
30+
int main_1169 ();
2731
Bird_Bird_
2832
void Bird_Bird_ (Bird * const this);
2933
void Bird_Bird_ (Bird * const this);

0 commit comments

Comments
 (0)