[PATCH] Getter and setter for Dwfl's offline_next_address

Martin Rodriguez Reboredo yakoyoku@gmail.com
Sun Mar 24 19:17:59 GMT 2024


On 3/24/24 14:08, Mark Wielaard wrote:
> Hi Martin,
> 
> On Sun, Mar 24, 2024 at 11:11:21AM -0300, Martin Rodriguez Reboredo wrote:
>> [...]
>> So this patch is kinda pointless, but at least I've managed to learn
>> what I was missing. Anyways, thanks for the heads-up. :)
> 
> I don't think it was pointless. Clearly our documentation is not very
> good (and given eu-readelf and eu-nm do cheat, maybe our interface/api
> isn't really good either).

At least to get the gist of it the header comments were good enough, it
was this particular case that I misunderstood. I could do what I wanted
with the API, so no problem with that.

> Maybe you could post your code for that ./report program and what you
> had to do to get it to print the correct address/symbols. Then we at
> least have some documentation for others which hit the same issue.

     #ifdef USE_DEMANGLE
     #include <cxxabi.h>
     #endif
     #include <elfutils/libdwfl.h>
     #include <dwarf.h>
     #include <inttypes.h>
     #include <stdio.h>
     #include <stdlib.h>

     static const char *symname(const char *name)
     {
     #ifdef USE_DEMANGLE
       // Require GNU v3 ABI by the "_Z" prefix.
       if (name[0] == '_' && name[1] == 'Z') {
         int status = -1;
         char *dsymname = __cxa_demangle(name, demangle_buffer,
                 &demangle_buffer_len, &status);
         if (status == 0)
           name = demangle_buffer = dsymname;
       }
     #endif
       return name;
     }

     static int get_addr_width(Dwfl_Module *mod)
     {
       // Try to find the address width if possible.
       static int width = 0;
       if (width == 0 && mod != NULL) {
         Dwarf_Addr bias;
         Elf *elf = dwfl_module_getelf(mod, &bias);
         if (elf != NULL) {
           GElf_Ehdr ehdr_mem;
           GElf_Ehdr *ehdr = gelf_getehdr(elf, &ehdr_mem);
           if (ehdr != NULL)
             width = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ?
                 8 :
                 16;
         }
       }
       if (width == 0)
         width = 16;

       return width;
     }

     int main(int argc, const char **argv)
     {
       if (argc != 3)
         return 1;

       Dwfl *dwfl = dwfl_begin(&offline_callbacks);
       if (!dwfl)
         return 1;
       //dwfl->offline_next_address = 0; // What I thought it was needed

       if (!dwfl_report_offline(dwfl, "", argv[1], -1)) {
         dwfl_end(dwfl);
         return 1;
       }
       if (dwfl_report_end(dwfl, NULL, NULL)) {
         dwfl_end(dwfl);
         return 1;
       }

       char *endp = NULL;
       GElf_Addr addr = strtoumax(argv[2], &endp, 16), bias;

       Dwfl_Module *mod = dwfl_addrmodule(dwfl, addr);

       int width = get_addr_width(mod);
       printf("0x%.*" PRIx64 "%s", width, addr, "\n");

       dwfl_module_getdwarf(mod, &bias); // This line did the trick!

       const char *name = dwfl_module_addrname(mod, addr + bias);
       name = name != NULL ? symname(name) : "??";
       printf("%s%c", name, '\n');

       GElf_Sym s;
       GElf_Off off = 0;
       name = dwfl_module_addrinfo(mod, addr + bias, &off, &s, NULL, NULL, NULL);

       Dwfl_Line *line = dwfl_module_getsrc(mod, addr + bias);
       if (!line)
         line = dwfl_getsrc(dwfl, addr + bias);
       if (line) {
         int nline, column;
         const char *filename =
           dwfl_lineinfo(line, &addr, &nline, &column, NULL, NULL);
         printf("%s:%i,%i\n", filename, nline, column);
       } else {
         printf("??:0\n");
       }

       dwfl_end(dwfl);

       return 0;
     }

> Thanks,
> 
> Mark


More information about the Elfutils-devel mailing list