[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