Hi Sasha, On Sat, 2020-06-06 at 00:30 +0000, Sasha Da Rocha Pinheiro wrote: > As you can see the following variables have distinct locations: > [ 81] variable abbrev: 5 > name (string) "a" > decl_file (data1) sasha.c (1) > decl_line (data1) 12 > type (ref4) [ cd] > location (sec_offset) location list > [ 0] > [ 9f] variable abbrev: 5 > name (string) "g" > decl_file (data1) sasha.c (1) > decl_line (data1) 15 > type (ref4) [ cd] > location (sec_offset) location list > [ 4a] > [ bd] variable abbrev: 5 > name (string) "z" > decl_file (data1) sasha.c (1) > decl_line (data1) 16 > type (ref4) [ cd] > location (sec_offset) location list > [ 6e] > > But when I use the code I sent before to list the three variables, I > always get: > > [main01.cpp:73] - Variable and location found (a), size(1). > [main01.cpp:78] - interval: (0x0,0x5) > [main01.cpp:78] - interval: (0x5,0xa) > [main01.cpp:78] - interval: (0x16,0x24) > [main01.cpp:73] - Variable and location found (g), size(1). > [main01.cpp:78] - interval: (0x0,0x5) > [main01.cpp:78] - interval: (0x5,0xa) > [main01.cpp:78] - interval: (0x16,0x24) > [main01.cpp:73] - Variable and location found (z), size(1). > [main01.cpp:78] - interval: (0x0,0x5) > [main01.cpp:78] - interval: (0x5,0xa) > [main01.cpp:78] - interval: (0x16,0x24) > > > No matter the locationAttribute the code always get the first > location descriptors in .debug_loc: > > DWARF section [ 7] '.debug_loc' at offset 0x1c6: > > CU [ b] base: .text+000000000000000000 <main> > [ 0] range 0, 5 > .text+000000000000000000 <main>.. > .text+0x0000000000000004 <main+0x4> > [ 0] lit0 > [ 1] stack_value > range 5, a > .text+0x0000000000000005 <main+0x5>.. > .text+0x0000000000000009 <main+0x9> > [ 0] reg1 > range 16, 24 > .text+0x0000000000000016 <main+0x16>.. > .text+0x0000000000000023 <main+0x23> > [ 0] reg1 > [ 4a] range 0, 5 > .text+000000000000000000 <main>.. > .text+0x0000000000000004 <main+0x4> > [ 0] lit0 > [ 1] stack_value > [ 6e] range 5, a > .text+0x0000000000000005 <main+0x5>.. > .text+0x0000000000000009 <main+0x9> > [ 0] lit0 > [ 1] stack_value > range a, e > .text+0x000000000000000a <main+0xa>.. > .text+0x000000000000000d <main+0xd> > [ 0] const4u 65537 > [ 5] breg0 0 > [ 7] minus > [ 8] stack_value
I think I see what is happening. The fact that <main> is at .text+000000000000000000 suggests that this is actually an ET_REL file (not linked object file). The libdw dwarf_xxx calls don't do relocations. But eu-readelf does. So while eu-readelf shows some offsets as their relocated values, your program just using dwarf_xxx calls does not. Specifically the DW_AT_location list attributes will all point to zero. Which explains why every location list seems to be the same. We don't have a public function to just apply all relocations to an object file, but opening the file through dwfl_begin () will do it. Something like the attached. Hope that helps, Mark
/* Print all locations in the whole DIE tree of a single file using dwfl to handle ET_REL files (which need the .debug sections to be relocated) and to automatically get separate debuginfo. gcc -Wall -Wextra -g -O2 -o dwfl_dwarf dwfl_dwarf.c -ldw */ /* We want the sane basename function. */ #define _GNU_SOURCE #include <string.h> #include <stdbool.h> #include <stdio.h> #include <inttypes.h> #include <dwarf.h> #include <elfutils/libdw.h> #include <elfutils/libdwfl.h> void handle_die (Dwarf_Die *die) { do { Dwarf_Attribute attr; if ((dwarf_attr (die, DW_AT_location, &attr) != NULL)) { printf ("[%" PRIx64 "]", dwarf_dieoffset (die)); ptrdiff_t off = 0; Dwarf_Addr base, start, end; do { Dwarf_Op *expr; size_t exprlen; off = dwarf_getlocations(&attr, off, &base, &start, &end, &expr, &exprlen); if (off > 0) printf ("(%" PRIx64 ",%" PRIx64 ")[%zd] ", start, end, exprlen); } while (off > 0); printf ("\n"); } Dwarf_Die child; if (dwarf_child (die, &child) == 0) handle_die (&child); } while (dwarf_siblingof (die, die) == 0); } static const Dwfl_Callbacks dwfl_callbacks = { .find_debuginfo = dwfl_standard_find_debuginfo, .section_address = dwfl_offline_section_address, .find_elf = dwfl_build_id_find_elf, }; int main (int argc, char **argv) { if (argc == 2) { const char *file = argv[1]; const char *base = basename (file); /* Create a one elf module file Dwfl. */ Dwfl *dwfl = dwfl_begin (&dwfl_callbacks); dwfl_report_begin (dwfl); Dwfl_Module *mod = dwfl_report_elf (dwfl, base, file, -1, 0, true); dwfl_report_end (dwfl, NULL, NULL); Dwarf_Addr bias; Dwarf *dbg = dwfl_module_getdwarf(mod, &bias); if (dbg != NULL) { /* Should be zero with one module. */ printf ("bias: %" PRIx64 "\n", bias); Dwarf_CU *cu = NULL; Dwarf_Half version; Dwarf_Die cudie, subdie; uint8_t unit_type; while (dwarf_get_units (dbg, cu, &cu, &version, &unit_type, &cudie, &subdie) == 0) handle_die (&cudie); } dwfl_end (dwfl); } }