summaryrefslogtreecommitdiff
path: root/src/addr2line.c
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2015-05-19 16:21:27 +0200
committerMark Wielaard <mjw@redhat.com>2015-05-27 17:17:51 +0200
commit70a504d1e19fe14cf34ab3e7a0179aa421f548e0 (patch)
tree30cc6e119029e58ac3f3632b524ad2dd457119d6 /src/addr2line.c
parentd76d73f490b1e097e650bb77277ae9ed1efd5b1a (diff)
downloadelfutils-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.c38
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