Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DWARF: fix type process with the same name #4454

Merged
merged 3 commits into from
Apr 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
wargio marked this conversation as resolved.
Show resolved Hide resolved
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
Loading