diff options
author | Mark Wielaard <mjw@redhat.com> | 2015-05-19 16:21:27 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2015-05-27 17:17:51 +0200 |
commit | 70a504d1e19fe14cf34ab3e7a0179aa421f548e0 (patch) | |
tree | 30cc6e119029e58ac3f3632b524ad2dd457119d6 /src/addr2line.c | |
parent | d76d73f490b1e097e650bb77277ae9ed1efd5b1a (diff) | |
download | elfutils-70a504d1e19fe14cf34ab3e7a0179aa421f548e0.tar.gz |
addr2line: Add -a, --address. Print address before for each entry.
Adds test cases with sample output.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'src/addr2line.c')
-rw-r--r-- | src/addr2line.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/src/addr2line.c b/src/addr2line.c index b1ff3680..720a087e 100644 --- a/src/addr2line.c +++ b/src/addr2line.c @@ -1,5 +1,5 @@ /* Locate source files and line information for given addresses - Copyright (C) 2005-2010, 2012, 2013 Red Hat, Inc. + Copyright (C) 2005-2010, 2012, 2013, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2005. @@ -59,6 +59,7 @@ static const struct argp_option options[] = N_("Treat addresses as offsets relative to NAME section."), 0 }, { NULL, 0, NULL, 0, N_("Output format options:"), 3 }, + { "addresses", 'a', NULL, 0, N_("Print address before each entry"), 0 }, { "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 }, { "absolute", 'A', NULL, 0, N_("Show absolute file names using compilation directory"), 0 }, @@ -100,6 +101,8 @@ static const struct argp argp = /* Handle ADDR. */ static int handle_address (const char *addr, Dwfl *dwfl); +/* True when we should print the address for each entry. */ +static bool print_addresses; /* True if only base names of files should be shown. */ static bool only_basenames; @@ -210,6 +213,10 @@ parse_opt (int key, char *arg, struct argp_state *state) state->child_inputs[0] = state->input; break; + case 'a': + print_addresses = true; + break; + case 'b': case 'C': case OPT_DEMANGLER: @@ -529,6 +536,29 @@ print_src (const char *src, int lineno, int linecol, Dwarf_Die *cu) } 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; +} + +static int handle_address (const char *string, Dwfl *dwfl) { char *endp; @@ -582,6 +612,12 @@ handle_address (const char *string, Dwfl *dwfl) Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr); + if (print_addresses) + { + int width = get_addr_width (mod); + printf ("0x%.*" PRIx64 "\n", width, addr); + } + if (show_functions) { /* First determine the function name. Use the DWARF information if |