Skip to content

Commit

Permalink
DWARF: fix type process with the same name (#4454)
Browse files Browse the repository at this point in the history
* DWARF: Remove memory allocation for RzBinDwarfLocListEntry->range
* DWARF: fix type process with the same name
  • Loading branch information
imbillow authored Apr 21, 2024
1 parent 87a0da8 commit ea460e5
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 91 deletions.
28 changes: 12 additions & 16 deletions librz/arch/dwarf_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,8 @@ static RzBaseType *RzBaseType_from_die(DwContext *ctx, const RzBinDwarfDie *die)
btype->name, die->offset);
}

RzPVector *btypes = ht_sp_find(ctx->analysis->debug_info->base_types_by_name, btype->name, NULL);
RzPVector *btypes = ht_sp_find(
ctx->analysis->debug_info->base_types_by_name, btype->name, NULL);
if (!btypes) {
btypes = rz_pvector_new(NULL);
ht_sp_insert(ctx->analysis->debug_info->base_types_by_name, btype->name, btypes);
Expand Down Expand Up @@ -1336,13 +1337,9 @@ static RzBinDwarfLocation *location_list_parse(
entry->location = RzBinDwarfLocation_with_kind(RzBinDwarfLocationKind_EMPTY);
continue;
}
if (!rz_bin_dwarf_block_valid(entry->expression)) {
entry->location = RzBinDwarfLocation_with_kind(RzBinDwarfLocationKind_DECODE_ERROR);
continue;
}
entry->location = rz_bin_dwarf_location_from_block(entry->expression, ctx->dw, ctx->unit, fn);
if (!entry->location) {
RzBinDwarfBlock_log(ctx, entry->expression, loclist->offset, entry->range);
RzBinDwarfBlock_log(ctx, entry->expression, loclist->offset, &entry->range);
entry->location = RzBinDwarfLocation_with_kind(RzBinDwarfLocationKind_DECODE_ERROR);
continue;
}
Expand Down Expand Up @@ -1814,16 +1811,15 @@ static bool store_base_type(void *u, const char *k, const void *v) {
RZ_LOG_WARN("BaseType: type of typedef [%s] is not RZ_TYPE_KIND_IDENTIFIER\n", name);
goto beach;
}
if (RZ_STR_NE(a->type->identifier.name, name)) {
RZ_LOG_WARN("BaseType: type name [%s] of typedef [%s] is not valid\n",
a->type->identifier.name, name);
goto beach;
}
free(a->type->identifier.name);
char *newname = rz_str_newf("%s_0", name);
a->type->identifier.name = rz_str_dup(newname);
update_base_type(analysis->typedb, a);

// typedef a and type b have the same name
// 1. b is not the target of a, so rename b.
// 2. b is the target of a, so rename b and a->type->identifier.name
if (RZ_STR_EQ(a->type->identifier.name, name)) {
free(a->type->identifier.name);
a->type->identifier.name = rz_str_dup(newname);
update_base_type(analysis->typedb, a);
}
db_save_renamed(analysis->typedb, rz_base_type_clone(b), newname);
} else {
RZ_LOG_WARN("BaseType: same name [%s] type count is more than 3\n", name);
Expand Down Expand Up @@ -1915,7 +1911,7 @@ static RzBinDwarfLocation *location_by_biggest_range(const RzBinDwarfLocList *lo
void **it;
rz_pvector_foreach (&loclist->entries, it) {
RzBinDwarfLocListEntry *entry = *it;
ut64 range = entry->range->begin - entry->range->end;
ut64 range = entry->range.begin - entry->range.end;
if (range > biggest_range && entry->location &&
(entry->location->kind == RzBinDwarfLocationKind_REGISTER_OFFSET ||
entry->location->kind == RzBinDwarfLocationKind_REGISTER ||
Expand Down
13 changes: 2 additions & 11 deletions librz/bin/dwarf/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,8 @@ RZ_API RZ_BORROW const ut8 *rz_bin_dwarf_block_data(RZ_NONNULL const RzBinDwarfB
return self->data;
}

RZ_API bool rz_bin_dwarf_block_valid(RZ_NONNULL const RzBinDwarfBlock *self) {
rz_return_val_if_fail(self, false);
if (self->length == 0) {
return true;
}
return self->data != NULL;
}

RZ_API bool rz_bin_dwarf_block_empty(RZ_NONNULL const RzBinDwarfBlock *self) {
rz_return_val_if_fail(self, false);
return self->length == 0;
RZ_API bool rz_bin_dwarf_block_empty(RZ_NULLABLE const RzBinDwarfBlock *self) {
return !self || self->length == 0;
}

RZ_API void rz_bin_dwarf_block_dump(RZ_NONNULL const RzBinDwarfBlock *self, RZ_NONNULL RzStrBuf *sb) {
Expand Down
2 changes: 2 additions & 0 deletions librz/bin/dwarf/enum.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,8 @@ static const char *dwarf_op[] = {
[DW_OP_xderef_type] = "DW_OP_xderef_type",
[DW_OP_convert] = "DW_OP_convert",
[DW_OP_reinterpret] = "DW_OP_reinterpret",
[DW_OP_GNU_uninit] = "DW_OP_GNU_uninit",
[DW_OP_GNU_encoded_addr] = "DW_OP_GNU_encoded_addr",
[DW_OP_GNU_push_tls_address] = "DW_OP_GNU_push_tls_address",
[DW_OP_GNU_implicit_pointer] = "DW_OP_GNU_implicit_pointer",
[DW_OP_GNU_entry_value] = "DW_OP_GNU_entry_value",
Expand Down
75 changes: 32 additions & 43 deletions librz/bin/dwarf/loclists.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ static void RawLocListEntry_free(RzBinDwarfRawLocListEntry *self) {
}

static void LocListEntry_fini(RzBinDwarfLocListEntry *self) {
Range_free(self->range);
rz_bin_dwarf_location_free(self->location);
}

Expand Down Expand Up @@ -123,101 +122,90 @@ static bool convert_raw(
: (~0ULL >> (64 - encoding->address_size * 8));
ut64 tombstone = encoding->version <= 4 ? mask - 1
: mask;
RzBinDwarfRange *range = NULL;
const RzBinDwarfBlock *data = NULL;
RzBinDwarfRange range = { 0 };
const RzBinDwarfBlock *blk = NULL;
if (raw->is_address_or_offset_pair) {
if (self->base_address == tombstone) {
*entry = NULL;
return true;
}
range = RZ_NEW0(RzBinDwarfRange);
ERR_IF_FAIL(range);
range->begin = raw->address_or_offset_pair.begin;
range->end = raw->address_or_offset_pair.end;
Range_add_base_address(range, self->base_address, encoding->address_size);
data = &raw->address_or_offset_pair.data;
range.begin = raw->address_or_offset_pair.begin;
range.end = raw->address_or_offset_pair.end;
Range_add_base_address(&range, self->base_address, encoding->address_size);
blk = &raw->address_or_offset_pair.data;
} else {
switch (raw->encoding) {
case DW_LLE_end_of_list: break;
case DW_LLE_base_address:
self->base_address = raw->base_address.addr;
*entry = NULL;
*entry = NULL;
*entry = NULL;
return true;
case DW_LLE_base_addressx:
ERR_IF_FAIL(rz_bin_dwarf_addr_get(
addr, &self->base_address,
encoding->address_size, cu->addr_base, raw->base_addressx.addr));
return true;
case DW_LLE_startx_endx:
range = RZ_NEW0(RzBinDwarfRange);
ERR_IF_FAIL(range);
ERR_IF_FAIL(rz_bin_dwarf_addr_get(
addr, &range->begin,
addr, &range.begin,
encoding->address_size, cu->addr_base, raw->startx_endx.begin));
ERR_IF_FAIL(rz_bin_dwarf_addr_get(
addr, &range->end,
addr, &range.end,
encoding->address_size, cu->addr_base, raw->startx_endx.end));
blk = &raw->startx_endx.data;
break;
case DW_LLE_startx_length:
range = RZ_NEW0(RzBinDwarfRange);
ERR_IF_FAIL(range);
ERR_IF_FAIL(rz_bin_dwarf_addr_get(
addr, &range->begin,
addr, &range.begin,
encoding->address_size, cu->addr_base, raw->startx_length.begin));
range->end = (raw->startx_length.length + raw->startx_length.begin) & mask;
range.end = (raw->startx_length.length + raw->startx_length.begin) & mask;
blk = &raw->startx_length.data;
break;
case DW_LLE_offset_pair:
if (self->base_address == tombstone) {
*entry = NULL;
return true;
}
range = RZ_NEW0(RzBinDwarfRange);
ERR_IF_FAIL(range);
range->begin = raw->address_or_offset_pair.begin;
range->end = raw->address_or_offset_pair.end;
Range_add_base_address(range, self->base_address, encoding->address_size);
data = &raw->address_or_offset_pair.data;
ERR_IF_FAIL(data);
range.begin = raw->address_or_offset_pair.begin;
range.end = raw->address_or_offset_pair.end;
Range_add_base_address(&range, self->base_address, encoding->address_size);
blk = &raw->address_or_offset_pair.data;
break;
case DW_LLE_default_location:
blk = &raw->default_location.data;
break;
case DW_LLE_default_location: break;
case DW_LLE_start_end:
range = RZ_NEW0(RzBinDwarfRange);
ERR_IF_FAIL(range);
range->begin = raw->startx_endx.begin;
range->end = raw->startx_endx.end;
range.begin = raw->startx_endx.begin;
range.end = raw->startx_endx.end;
blk = &raw->start_length.data;
break;
case DW_LLE_start_length:
range = RZ_NEW0(RzBinDwarfRange);
ERR_IF_FAIL(range);
range->begin = raw->startx_length.begin;
range->end = (raw->startx_length.length + raw->startx_length.begin) & mask;
range.begin = raw->startx_length.begin;
range.end = (raw->startx_length.length + raw->startx_length.begin) & mask;
blk = &raw->start_length.data;
break;
case DW_LLE_GNU_view_pair:
rz_warn_if_reached();
break;
}
}

ERR_IF_FAIL(range);
if (range->begin == tombstone) {
Range_free(range);
if (range.begin == tombstone) {
*entry = NULL;
return true;
}
if (range->begin > range->end) {
RZ_LOG_VERBOSE("Invalid Address Range (0x%" PFMT64x ",0x%" PFMT64x ")\n", range->begin, range->end);
if (range.begin > range.end) {
RZ_LOG_VERBOSE("Invalid Address Range (0x%" PFMT64x ",0x%" PFMT64x ")\n",
range.begin, range.end);
goto err;
}

*entry = RZ_NEW0(RzBinDwarfLocListEntry);
ERR_IF_FAIL(*entry);
(*entry)->range = range;
(*entry)->expression = data;
(*entry)->expression = blk;
return true;
err:
Range_free(range);
return false;
}

Expand Down Expand Up @@ -438,7 +426,8 @@ static bool cb_loclist_dump(void *u, ut64 k, const void *v) {
void **it;
rz_pvector_foreach (&loclist->entries, it) {
RzBinDwarfLocListEntry *entry = *it;
rz_strbuf_appendf(sb, "\t(0x%" PFMT64x ", 0x%" PFMT64x ")\t", entry->range->begin, entry->range->end);
rz_strbuf_appendf(sb, "\t(0x%" PFMT64x ", 0x%" PFMT64x ")\t",
entry->range.begin, entry->range.end);
if (entry->expression) {
const RzBinDwarfEncoding *enc = ht_up_find(
ctx->dw->info->location_encoding, k, NULL);
Expand Down
6 changes: 3 additions & 3 deletions librz/bin/dwarf/op.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,8 @@ RZ_IPI bool Operation_parse(Operation *self, RzBinEndianReader *R, const RzBinDw
}
break;
}
case DW_OP_GNU_uninit:
case DW_OP_GNU_encoded_addr:
case DW_OP_hi_user:
default:
RZ_LOG_WARN("Unsupported opcode %s 0x%" PFMT32x "\n",
Expand Down Expand Up @@ -1421,8 +1423,6 @@ RZ_API RZ_OWN RzBinDwarfLocation *rz_bin_dwarf_location_from_block(

if (rz_bin_dwarf_block_empty(block)) {
loc->kind = RzBinDwarfLocationKind_EMPTY;
} else if (!rz_bin_dwarf_block_valid(block)) {
loc->kind = RzBinDwarfLocationKind_DECODE_ERROR;
} else {
RzBinDwarfEvaluationResult *result = RZ_NEW0(RzBinDwarfEvaluationResult);
RET_NULL_IF_FAIL(result);
Expand Down Expand Up @@ -1639,7 +1639,7 @@ RZ_API void rz_bin_dwarf_loclist_dump(
rz_pvector_foreach (&loclist->entries, it) {
const RzBinDwarfLocListEntry *entry = *it;
rz_strbuf_appendf(sb, "%s(0x%" PFMT64x ", %" PFMT64d "):",
rz_str_get(opt->loclist_indent), entry->range->begin, entry->range->end - entry->range->begin);
rz_str_get(opt->loclist_indent), entry->range.begin, entry->range.end - entry->range.begin);

if (entry->location) {
rz_strbuf_append(sb, " ");
Expand Down
7 changes: 4 additions & 3 deletions librz/include/rz_bin_dwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@ typedef enum {

// GNU extensions
DW_OP_GNU_push_tls_address = 0xe0,
DW_OP_GNU_uninit = 0xf0,
DW_OP_GNU_encoded_addr = 0xf1,
DW_OP_GNU_implicit_pointer = 0xf2,
DW_OP_GNU_entry_value = 0xf3,
DW_OP_GNU_const_type = 0xf4,
Expand Down Expand Up @@ -1403,7 +1405,7 @@ typedef struct {
struct rz_bin_dwarf_location_t;

typedef struct {
RzBinDwarfRange *range;
RzBinDwarfRange range;
const RzBinDwarfBlock *expression;
struct rz_bin_dwarf_location_t *location;
} RzBinDwarfLocListEntry;
Expand Down Expand Up @@ -1820,8 +1822,7 @@ RZ_API RZ_OWN RzBinDwarfRngLists *rz_bin_dwarf_rnglists_new_from_file(
RZ_BORROW RZ_NONNULL RzBinFile *bf, bool is_dwo);

/// Block
RZ_API bool rz_bin_dwarf_block_valid(RZ_NONNULL const RzBinDwarfBlock *self);
RZ_API bool rz_bin_dwarf_block_empty(RZ_NONNULL const RzBinDwarfBlock *self);
RZ_API bool rz_bin_dwarf_block_empty(RZ_NULLABLE const RzBinDwarfBlock *self);
RZ_API void rz_bin_dwarf_block_dump(RZ_NONNULL const RzBinDwarfBlock *self, RZ_NONNULL RzStrBuf *sb);
RZ_API RZ_BORROW const ut8 *rz_bin_dwarf_block_data(RZ_NONNULL const RzBinDwarfBlock *self);

Expand Down
24 changes: 12 additions & 12 deletions test/integration/test_dwarf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1373,8 +1373,8 @@ bool test_dwarf5_loclists(void) {
{
RzBinDwarfLocListEntry *entry = rz_pvector_at(&loclist->entries, 0);
mu_assert_notnull(entry, "entry");
mu_assert_eq(entry->range->begin, 0x4c0, "entry begin");
mu_assert_eq(entry->range->end, 0x4de, "entry end");
mu_assert_eq(entry->range.begin, 0x4c0, "entry begin");
mu_assert_eq(entry->range.end, 0x4de, "entry end");

RzBinDwarfLocation *loc = rz_bin_dwarf_location_from_block(entry->expression, dw, cu, NULL);
mu_assert_notnull(loc, "location");
Expand All @@ -1386,8 +1386,8 @@ bool test_dwarf5_loclists(void) {
{
RzBinDwarfLocListEntry *entry = rz_pvector_at(&loclist->entries, 1);
mu_assert_notnull(entry, "entry");
mu_assert_eq(entry->range->begin, 0x4de, "entry begin");
mu_assert_eq(entry->range->end, 0x4e1, "entry end");
mu_assert_eq(entry->range.begin, 0x4de, "entry begin");
mu_assert_eq(entry->range.end, 0x4e1, "entry end");

RzBinDwarfLocation *loc = rz_bin_dwarf_location_from_block(entry->expression, dw, cu, NULL);
mu_assert_notnull(loc, "location");
Expand All @@ -1400,8 +1400,8 @@ bool test_dwarf5_loclists(void) {
{
RzBinDwarfLocListEntry *entry = rz_pvector_at(&loclist->entries, 2);
mu_assert_notnull(entry, "entry");
mu_assert_eq(entry->range->begin, 0x4e1, "entry begin");
mu_assert_eq(entry->range->end, 0x4f8, "entry end");
mu_assert_eq(entry->range.begin, 0x4e1, "entry begin");
mu_assert_eq(entry->range.end, 0x4f8, "entry end");

RzBinDwarfLocation *loc = rz_bin_dwarf_location_from_block(entry->expression, dw, cu, NULL);
mu_assert_notnull(loc, "location");
Expand Down Expand Up @@ -1438,8 +1438,8 @@ bool test_dwarf4_loclists(void) {
{
RzBinDwarfLocListEntry *entry = rz_pvector_at(&loclist->entries, 0);
mu_assert_notnull(entry, "entry");
mu_assert_eq(entry->range->begin, 0x4013b0, "entry begin");
mu_assert_eq(entry->range->end, 0x4013b4, "entry end");
mu_assert_eq(entry->range.begin, 0x4013b0, "entry begin");
mu_assert_eq(entry->range.end, 0x4013b4, "entry end");

RzBinDwarfLocation *loc = rz_bin_dwarf_location_from_block(entry->expression, dw, cu, NULL);
mu_assert_notnull(loc, "location");
Expand All @@ -1452,8 +1452,8 @@ bool test_dwarf4_loclists(void) {
{
RzBinDwarfLocListEntry *entry = rz_pvector_at(&loclist->entries, 1);
mu_assert_notnull(entry, "entry");
mu_assert_eq(entry->range->begin, 0x4013b4, "entry begin");
mu_assert_eq(entry->range->end, 0x4013c0, "entry end");
mu_assert_eq(entry->range.begin, 0x4013b4, "entry begin");
mu_assert_eq(entry->range.end, 0x4013c0, "entry end");

RzBinDwarfLocation *loc = rz_bin_dwarf_location_from_block(entry->expression, dw, cu, NULL);
mu_assert_notnull(loc, "location");
Expand All @@ -1465,8 +1465,8 @@ bool test_dwarf4_loclists(void) {
{
RzBinDwarfLocListEntry *entry = rz_pvector_at(&loclist->entries, 2);
mu_assert_notnull(entry, "entry");
mu_assert_eq(entry->range->begin, 0x4013c0, "entry begin");
mu_assert_eq(entry->range->end, 0x401728, "entry end");
mu_assert_eq(entry->range.begin, 0x4013c0, "entry begin");
mu_assert_eq(entry->range.end, 0x401728, "entry end");

RzBinDwarfLocation *loc = rz_bin_dwarf_location_from_block(entry->expression, dw, cu, NULL);
mu_assert_notnull(loc, "location");
Expand Down
5 changes: 2 additions & 3 deletions test/integration/test_dwarf_integration.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,9 @@ static bool test_dwarf_function_parsing_rust(void) {
mu_assert_notnull(loclist, "Couldn't get loclist");
RzBinDwarfLocListEntry *entry = rz_pvector_at(&loclist->entries, 0);
mu_assert_notnull(entry, "Couldn't get entry");
mu_assert_notnull(entry->range, "Couldn't get entry range");
mu_assert_notnull(entry->expression, "Couldn't get entry expression");
mu_assert_eq(entry->range->begin, 0x84e1, "Err entry begin");
mu_assert_eq(entry->range->end, 0x84fc, "Err entry end");
mu_assert_eq(entry->range.begin, 0x84e1, "Err entry begin");
mu_assert_eq(entry->range.end, 0x84fc, "Err entry end");
RzBinDwarfLocation *loc = rz_bin_dwarf_location_from_block(entry->expression, dw, cu, NULL);
mu_assert_notnull(loc, "Couldn't get location");
RzBinDWARFDumpOption dump_option = {
Expand Down

0 comments on commit ea460e5

Please sign in to comment.