+2018-05-21 Mark Wielaard <mark@klomp.org>
+
+ * dwarf_begin_elf.c (valid_p): Add a fake_addr_cu to the result.
+ * dwarf_end.c (cu_free): Disconnect the fake_addr_cu from the split
+ dwarf if shared with skeleton.
+ (dwarf_end): release fake_addr_cu.
+ * dwarf_formaddr.c (__libdw_cu_addr_base): Move to...
+ * libdwP.h (__libdw_cu_addr_base): ... here.
+ (struct Dwarf): Add fake_addr_cu field.
+ * dwarf_formudata.c (dwarf_formudata): Handle
+ DW_FORM_GNU_addr_index and DW_FORM_addrx[1234].
+ * dwarf_getlocation_attr.c (addr_valp): New static function.
+ (dwarf_getlocation_attr): Create attribute for values of
+ DW_OP_GNU_const_index, DW_OP_constx and DW_OP_GNU_addr_index and
+ DW_OP_addrx.
+ * libdw_find_split_unit.c (__libdw_find_split_unit): Connect
+ IDX_debug_addr sectiondata and fake_addr_cu between split and
+ skeleton.
+
2018-05-20 Mark Wielaard <mark@klomp.org>
* dwarf_cu_info.c: New file.
}
}
+ /* For DW_OP_constx/GNU_const_index and DW_OP_addrx/GNU_addr_index
+ the dwarf_location_attr () will need a "fake" address CU to
+ indicate where the attribute data comes from. This is a just
+ inside the .debug_addr section, if it exists. */
+ if (result != NULL && result->sectiondata[IDX_debug_addr] != NULL)
+ {
+ result->fake_addr_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
+ if (unlikely (result->fake_addr_cu == NULL))
+ {
+ Dwarf_Sig8_Hash_free (&result->sig8_hash);
+ __libdw_seterrno (DWARF_E_NOMEM);
+ free (result->fake_loc_cu);
+ free (result);
+ result = NULL;
+ }
+ else
+ {
+ result->fake_addr_cu->sec_idx = IDX_debug_addr;
+ result->fake_addr_cu->dbg = result;
+ result->fake_addr_cu->startp
+ = result->sectiondata[IDX_debug_addr]->d_buf;
+ result->fake_addr_cu->endp
+ = (result->sectiondata[IDX_debug_addr]->d_buf
+ + result->sectiondata[IDX_debug_addr]->d_size);
+ }
+ }
+
if (result != NULL)
result->debugdir = __libdw_debugdir (result->elf->fildes);
/* Free split dwarf one way (from skeleton to split). */
if (p->unit_type == DW_UT_skeleton
&& p->split != NULL && p->split != (void *)-1)
- INTUSE(dwarf_end) (p->split->dbg);
+ {
+ /* The fake_addr_cu might be shared, only release one. */
+ if (p->dbg->fake_addr_cu == p->split->dbg->fake_addr_cu)
+ p->split->dbg->fake_addr_cu = NULL;
+ INTUSE(dwarf_end) (p->split->dbg);
+ }
}
cu_free (dwarf->fake_loc_cu);
free (dwarf->fake_loc_cu);
}
+ if (dwarf->fake_addr_cu != NULL)
+ {
+ cu_free (dwarf->fake_addr_cu);
+ free (dwarf->fake_addr_cu);
+ }
/* Did we find and allocate the alt Dwarf ourselves? */
if (dwarf->alt_fd != -1)
return 0;
}
INTDEF(dwarf_formaddr)
-
-Dwarf_Off __libdw_cu_addr_base (Dwarf_CU *cu)
-{
- if (cu->addr_base == (Dwarf_Off) -1)
- {
- Dwarf_Die cu_die = CUDIE(cu);
- Dwarf_Attribute attr;
- if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
- || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
- {
- Dwarf_Word off;
- if (dwarf_formudata (&attr, &off) == 0)
- cu->addr_base = off;
- }
- }
-
- return cu->addr_base;
-}
get_sleb128_unchecked (*return_uval, datap);
break;
+ /* These are indexes into the .debug_addr section, normally resolved
+ with dwarf_formaddr. Here treat as constants. */
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_addrx:
+ if (datap >= endp)
+ goto invalid;
+ get_uleb128 (*return_uval, datap, endp);
+ break;
+
+ case DW_FORM_addrx1:
+ if (datap >= endp - 1)
+ goto invalid;
+ *return_uval = *datap;
+ break;
+
+ case DW_FORM_addrx2:
+ if (datap >= endp - 2)
+ goto invalid;
+ *return_uval = read_2ubyte_unaligned (attr->cu->dbg, datap);
+ break;
+
+ case DW_FORM_addrx3:
+ if (datap >= endp - 3)
+ goto invalid;
+ *return_uval = read_3ubyte_unaligned (attr->cu->dbg, datap);
+ break;
+
+ case DW_FORM_addrx4:
+ if (datap >= endp - 4)
+ goto invalid;
+ *return_uval = read_4ubyte_unaligned (attr->cu->dbg, datap);
+ break;
+
default:
__libdw_seterrno (DWARF_E_NO_CONSTANT);
return -1;
}
}
+static unsigned char *
+addr_valp (Dwarf_CU *cu, Dwarf_Word index)
+{
+ Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
+ Dwarf_Word offset = __libdw_cu_addr_base (cu) + (index * cu->address_size);
+ if (debug_addr == NULL)
+ /* This is really an error, will trigger with dwarf_formaddr. */
+ return (unsigned char *) offset;
+
+ return (unsigned char *) debug_addr->d_buf + offset;
+}
+
int
dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribute *result)
{
result->cu = attr_form_cu (attr);
break;
+ case DW_OP_GNU_const_index:
+ case DW_OP_constx:
+ result->code = DW_AT_const_value;
+ if (attr->cu->address_size == 4)
+ result->form = DW_FORM_data4;
+ else
+ result->form = DW_FORM_data8;
+ result->valp = addr_valp (attr->cu, op->number);
+ result->cu = attr->cu->dbg->fake_addr_cu;
+ break;
+
+ case DW_OP_GNU_addr_index:
+ case DW_OP_addrx:
+ result->code = DW_AT_low_pc;
+ result->form = DW_FORM_addr;
+ result->valp = addr_valp (attr->cu, op->number);
+ result->cu = attr->cu->dbg->fake_addr_cu;
+ break;
+
case DW_OP_call2:
case DW_OP_call4:
case DW_OP_call_ref:
came from a location list entry in dwarf_getlocation_attr. */
struct Dwarf_CU *fake_loc_cu;
+ /* Similar for addrx/constx, which will come from .debug_addr section. */
+ struct Dwarf_CU *fake_addr_cu;
+
/* Internal memory handling. This is basically a simplified
reimplementation of obstacks. Unfortunately the standard obstack
implementation is not usable in libraries. */
Dwarf_Addr __libdw_cu_base_address (Dwarf_CU *cu);
/* Get the address base for the CU, fetches it when not yet set. */
-Dwarf_Off __libdw_cu_addr_base (Dwarf_CU *cu);
+static inline Dwarf_Off
+__libdw_cu_addr_base (Dwarf_CU *cu)
+{
+ if (cu->addr_base == (Dwarf_Off) -1)
+ {
+ Dwarf_Die cu_die = CUDIE(cu);
+ Dwarf_Attribute attr;
+ Dwarf_Off offset = 0;
+ if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
+ || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
+ {
+ Dwarf_Word off;
+ if (dwarf_formudata (&attr, &off) == 0)
+ offset = off;
+ }
+ cu->addr_base = offset;
+ }
+
+ return cu->addr_base;
+}
/* Gets the .debug_str_offsets base offset to use. static inline to
be shared between libdw and eu-readelf. */
cu->split = split;
split->split = cu;
+ /* Get .debug_addr and addr_base greedy.
+ We also need it for the fake addr cu.
+ There is only one per split debug. */
+ Dwarf *dbg = cu->dbg;
+ Dwarf *sdbg = split->dbg;
+ if (sdbg->sectiondata[IDX_debug_addr] == NULL
+ && dbg->sectiondata[IDX_debug_addr] != NULL)
+ {
+ sdbg->sectiondata[IDX_debug_addr]
+ = dbg->sectiondata[IDX_debug_addr];
+ split->addr_base = __libdw_cu_addr_base (cu);
+ sdbg->fake_addr_cu = dbg->fake_addr_cu;
+ }
+
/* We have everything we need from this
ELF file. And we are going to close
the fd to not run out of file
+2018-01-21 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (get_indexed_addr): New function.
+ (print_ops): Handle DW_OP_addrx, DW_OP_GNU_addr_index,
+ DW_OP_constx, DW_OP_GNU_const_index separately and resolve
+ address.
+ (attr_callback): Print index and address for
+ DW_FORM_GNU_addr_index and DW_FORM_addrx[1234].
+
2018-01-19 Mark Wielaard <mark@klomp.org>
* readelf.c (options): Add info+.
}
}
+static int
+get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
+{
+ Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
+ if (debug_addr == NULL)
+ return -1;
+
+ Dwarf_Off base = __libdw_cu_addr_base (cu);
+ Dwarf_Word off = idx * cu->address_size;
+ if (base > debug_addr->d_size
+ || off > debug_addr->d_size - base
+ || cu->address_size > debug_addr->d_size - base - off)
+ return -1;
+
+ const unsigned char *addrp = debug_addr->d_buf + base + off;
+ if (cu->address_size == 4)
+ *addr = read_4ubyte_unaligned (cu->dbg, addrp);
+ else
+ *addr = read_8ubyte_unaligned (cu->dbg, addrp);
+
+ return 0;
+}
+
static void
print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
unsigned int vers, unsigned int addrsize, unsigned int offset_size,
case DW_OP_piece:
case DW_OP_regx:
case DW_OP_plus_uconst:
- case DW_OP_constu:
+ case DW_OP_constu:;
+ const unsigned char *start = data;
+ uint64_t uleb;
+ NEED (1);
+ get_uleb128 (uleb, data, data + len);
+ printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
+ indent, "", (uintmax_t) offset, op_name, uleb);
+ CONSUME (data - start);
+ offset += 1 + (data - start);
+ break;
+
case DW_OP_addrx:
case DW_OP_GNU_addr_index:
case DW_OP_constx:
case DW_OP_GNU_const_index:;
- const unsigned char *start = data;
- uint64_t uleb;
+ start = data;
NEED (1);
get_uleb128 (uleb, data, data + len);
- printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
+ printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
indent, "", (uintmax_t) offset, op_name, uleb);
CONSUME (data - start);
offset += 1 + (data - start);
+ if (get_indexed_addr (cu, uleb, &addr) != 0)
+ printf ("???\n");
+ else
+ {
+ a = format_dwarf_addr (dwflmod, 0, addr, addr);
+ printf ("%s\n", a);
+ free (a);
+ }
break;
case DW_OP_bit_piece:
}
char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
addr, addr);
- printf (" %*s%-20s (%s) %s\n",
- (int) (level * 2), "", dwarf_attr_name (attr),
- dwarf_form_name (form), a);
+ if (form != DW_FORM_addr )
+ {
+ Dwarf_Word index;
+ if (dwarf_formudata (attrp, &index) != 0)
+ goto attrval_out;
+ printf (" %*s%-20s (%s) [%" PRIx64 "] %s\n",
+ (int) (level * 2), "", dwarf_attr_name (attr),
+ dwarf_form_name (form), index, a);
+ }
+ else
+ printf (" %*s%-20s (%s) %s\n",
+ (int) (level * 2), "", dwarf_attr_name (attr),
+ dwarf_form_name (form), a);
free (a);
}
break;
+2018-05-21 Mark Wielaard <mark@klomp.org>
+
+ * addrx_constx-4.dwo.bz2: New testfile.
+ * addrx_constx-5.dwo.bz2: Likewise.
+ * testfile-addrx_constx-4.bz2: Likewise.
+ * testfile-addrx_constx-5.bz2: Likewise
+ * Makefile.am (EXTRA_DIST): Add addrx_constx-5.dwo.bz2
+ testfile-addrx_constx-4\ .bz2 testfile-addrx_constx-5.bz2.
+ * run-varlocs.sh: Add addrx_constx tests for DWARF4 and DWARF5.
+ * varlocx.c (print_expr): Handle DW_OP_GNU_addr_index,
+ DW_OP_addrx, DW_OP_GNU_const_index and DW_OP_constx.
+ (main): Handle split DWARF.
+ * run-all-dwarf-ranges.sh: Add new ranges for addrx low/highpc.
+
2018-05-20 Mark Wielaard <mark@klomp.org>
* unit-info.c: New test.
testfile_entry_value.c testfile_entry_value.bz2 \
testfile_implicit_value.c testfile_implicit_value.bz2 \
testfile_aarch64_core.bz2 testfile_i686_core.bz2 \
+ addrx_constx-4.dwo.bz2 addrx_constx-5.dwo.bz2 \
+ testfile-addrx_constx-4.bz2 testfile-addrx_constx-5.bz2 \
run-funcretval.sh funcretval_test.c funcretval_test_aarch64.bz2 \
run-backtrace-data.sh run-backtrace-dwarf.sh cleanup-13.c \
run-backtrace-native.sh run-backtrace-native-biarch.sh \
4004e0..4004ff
4003e0..4003f7
+die: no_say (2e)
+ 4004f0..4004ff
+
+die: main (2e)
+ 4003e0..4003f7
+
+die: subject (1d)
+ 4003e3..4003ef
+
+die: subject (2e)
+ 4004e0..4004f0
+
die: world.c (11)
400500..400567
+die: no_main (2e)
+ 400550..400567
+
+die: no_subject (1d)
+ 400553..40055f
+
+die: say (2e)
+ 400500..400540
+
die: happy (1d)
40051c..400526
400530..400534
40051c..400526
400535..40053f
+die: no_subject (2e)
+ 400540..400550
+
EOF
exit 0
EOF
+# DW_OP_addrx and DW_OP_constx testcases.
+#
+# int i, j, k;
+# __thread int l, m, n;
+#
+# int main ()
+# {
+# int r1 = i + j + k;
+# int r2 = l + m + n;
+# int res = r1 + r2;
+#
+# return res;
+# }
+#
+# gcc -O2 -gdwarf-5 -gsplit-dwarf -o addrx_constx-5.o -c addrx_constx.c
+# gcc -O2 -gdwarf-5 -gsplit-dwarf -o testfile-addrx_constx-5 addrx_constx-5.o
+# gcc -O2 -gdwarf-4 -gsplit-dwarf -o addrx_constx-4.o -c addrx_constx.c
+# gcc -O2 -gdwarf-4 -gsplit-dwarf -o testfile-addrx_constx-4 addrx_constx-4.o
+
+testfiles testfile-addrx_constx-5 addrx_constx-5.dwo
+testrun_compare ${abs_top_builddir}/tests/varlocs --exprlocs -e testfile-addrx_constx-5 <<\EOF
+module 'testfile-addrx_constx-5'
+[14] CU 'addrx_constx.c'
+ producer (strx)
+ language (data1)
+ name (strx)
+ comp_dir (strx)
+ [19] variable "i"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x404038}
+ [25] base_type "int"
+ byte_size (data1)
+ encoding (data1)
+ name (string)
+ [2c] variable "j"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x404034}
+ [38] variable "k"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x40403c}
+ [44] variable "l"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e10, form_tls_address}
+ [51] variable "m"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e0c, form_tls_address}
+ [5e] variable "n"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e08, form_tls_address}
+ [6b] subprogram "main"
+ external (flag_present)
+ name (strx)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ low_pc (addrx)
+ high_pc (data8)
+ frame_base (exprloc) {call_frame_cfa {bregx(7,8)}}
+ call_all_calls (flag_present)
+ [7f] variable "r1"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (implicit_const)
+ type (ref4)
+ location (exprloc) {addr: 0x404038, deref_size(4), addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+ [98] variable "r2"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (implicit_const)
+ type (ref4)
+ location (exprloc) {form_tls_address, const: 0x403e10, deref_size(4), form_tls_address, const: 0x403e0c, deref_size(4), plus, form_tls_address, const: 0x403e08, deref_size(4), plus, stack_value}
+ [b4] variable "res"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (implicit_const)
+ type (ref4)
+ location (exprloc) {addr: 0x404038, deref_size(4), form_tls_address, const: 0x403e08, deref_size(4), plus, form_tls_address, const: 0x403e0c, deref_size(4), plus, form_tls_address, const: 0x403e10, deref_size(4), plus, addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+EOF
+
+testfiles testfile-addrx_constx-4 addrx_constx-4.dwo
+testrun_compare ${abs_top_builddir}/tests/varlocs --exprlocs -e testfile-addrx_constx-4 <<\EOF
+module 'testfile-addrx_constx-4'
+[b] CU 'addrx_constx.c'
+ producer (GNU_str_index)
+ language (data1)
+ name (GNU_str_index)
+ comp_dir (GNU_str_index)
+ GNU_dwo_id (data8)
+ [18] variable "i"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x404038}
+ [25] base_type "int"
+ byte_size (data1)
+ encoding (data1)
+ name (string)
+ [2c] variable "j"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x404034}
+ [39] variable "k"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x40403c}
+ [46] variable "l"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e10, GNU_push_tls_address}
+ [54] variable "m"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e0c, GNU_push_tls_address}
+ [62] variable "n"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e08, GNU_push_tls_address}
+ [70] subprogram "main"
+ external (flag_present)
+ name (GNU_str_index)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ low_pc (GNU_addr_index)
+ high_pc (data8)
+ frame_base (exprloc) {call_frame_cfa {bregx(7,8)}}
+ GNU_all_call_sites (flag_present)
+ [84] variable "r1"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ location (exprloc) {addr: 0x404038, deref_size(4), addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+ [9f] variable "r2"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ location (exprloc) {GNU_push_tls_address, const: 0x403e10, deref_size(4), GNU_push_tls_address, const: 0x403e0c, deref_size(4), plus, GNU_push_tls_address, const: 0x403e08, deref_size(4), plus, stack_value}
+ [bd] variable "res"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ location (exprloc) {addr: 0x404038, deref_size(4), GNU_push_tls_address, const: 0x403e08, deref_size(4), plus, GNU_push_tls_address, const: 0x403e0c, deref_size(4), plus, GNU_push_tls_address, const: 0x403e10, deref_size(4), plus, addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+EOF
+
exit 0
}
break;
+ case DW_OP_GNU_addr_index:
+ case DW_OP_addrx:
+ /* Address from the .debug_addr section (indexed based on CU). */
+ {
+ Dwarf_Attribute addr_attr;
+ if (dwarf_getlocation_attr (attr, expr, &addr_attr) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for addr: %s",
+ dwarf_errmsg (-1));
+
+ Dwarf_Addr address;
+ if (dwarf_formaddr (&addr_attr, &address) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_formaddr address failed: %s",
+ dwarf_errmsg (-1));
+
+ printf ("addr: 0x%" PRIx64, address);
+ }
+ break;
+
+ case DW_OP_GNU_const_index:
+ case DW_OP_constx:
+ /* Constant from the .debug_addr section (indexed based on CU). */
+ {
+ Dwarf_Attribute addr_attr;
+ if (dwarf_getlocation_attr (attr, expr, &addr_attr) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for addr: %s",
+ dwarf_errmsg (-1));
+
+ Dwarf_Word constant;
+ if (dwarf_formudata (&addr_attr, &constant) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_formudata constant failed: %s",
+ dwarf_errmsg (-1));
+
+ printf ("const: 0x%" PRIx64, constant);
+ }
+ break;
+
default:
error (EXIT_FAILURE, 0, "unhandled opcode: DW_OP_%s (0x%x)",
opname, atom);
/* Only walk actual compile units (not partial units) that
contain code if we are only interested in the function variable
locations. */
+ Dwarf_Die cudie;
+ Dwarf_Die subdie;
+ uint8_t unit_type;
+ if (dwarf_cu_info (cu->cu, NULL, &unit_type, &cudie, &subdie,
+ NULL, NULL, NULL) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_cu_info: %s", dwarf_errmsg (-1));
+ if (unit_type == DW_UT_skeleton)
+ cudie = subdie;
+
Dwarf_Addr cubase;
- if (dwarf_tag (cu) == DW_TAG_compile_unit
- && (exprlocs || dwarf_lowpc (cu, &cubase) == 0))
+ if (dwarf_tag (&cudie) == DW_TAG_compile_unit
+ && (exprlocs || dwarf_lowpc (&cudie, &cubase) == 0))
{
found_cu = true;
? modname
: basename (mainfile));
printf ("module '%s'\n", name);
- print_die (cu, "CU", 0);
+ print_die (&cudie, "CU", 0);
Dwarf_Addr elfbias;
Elf *elf = dwfl_module_getelf (mod, &elfbias);
GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
is_ET_REL = ehdr->e_type == ET_REL;
- // Get the actual CU DIE and walk all all DIEs (or just the
- // functions) inside it.
- Dwarf_Die cudie;
- uint8_t offsize;
- uint8_t addrsize;
- if (dwarf_diecu (cu, &cudie, &addrsize, &offsize) == NULL)
- error (EXIT_FAILURE, 0, "dwarf_diecu %s", dwarf_errmsg (-1));
-
if (exprlocs)
{
Dwarf_Addr entrypc;
- if (dwarf_entrypc (cu, &entrypc) != 0)
+ if (dwarf_entrypc (&cudie, &entrypc) != 0)
entrypc = 0;
/* XXX - Passing true for has_frame_base is not really true.
attributes. Technically we should check that the DIE
(types) are referenced from variables that are defined in
a context (function) that has a frame base. */
- handle_die (cu, 0, true /* Should be false */, entrypc);
+ handle_die (&cudie, 0, true /* Should be false */, entrypc);
}
- else if (dwarf_getfuncs (cu, handle_function, NULL, 0) != 0)
+ else if (dwarf_getfuncs (&cudie, handle_function, NULL, 0) != 0)
error (EXIT_FAILURE, 0, "dwarf_getfuncs %s",
dwarf_errmsg (-1));
}