diff options
| author | Ulrich Drepper <[email protected]> | 2009-04-29 15:19:21 -0700 |
|---|---|---|
| committer | Ulrich Drepper <[email protected]> | 2009-04-29 15:19:21 -0700 |
| commit | 61ad08998d3d91da3660f2cee65c84c0aab2d276 (patch) | |
| tree | 17495720460f67552db6329d432d3a1e958c4f2e /src | |
| parent | c803fbe6c3fa15d08dee1c99948ec66326db1e9e (diff) | |
| parent | a7cb532d98e02aae86940ec7c121ce16ced806ee (diff) | |
Merge branch 'master' of ssh://git.fedorahosted.org/git/elfutils
Conflicts:
ChangeLog
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 29 | ||||
| -rw-r--r-- | src/Makefile.am | 2 | ||||
| -rw-r--r-- | src/addr2line.c | 128 | ||||
| -rw-r--r-- | src/readelf.c | 21 | ||||
| -rw-r--r-- | src/strip.c | 3 |
5 files changed, 128 insertions, 55 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 88dd78a9..49b72037 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,32 @@ +2009-04-23 Ulrich Drepper <[email protected]> + + * Makefile [BUILD_STATIC] (libdw): Add $(zip_LIBS). + +2009-04-20 Roland McGrath <[email protected]> + + * addr2line.c (print_dwarf_function): Honor -s and -A for file names + of inline call sites. + + * addr2line.c (just_section): New variable. + (adjust_to_section): New function, broken out of ... + (handle_address): ... here. + (options, parse_opt): Add -j/--section=NAME to set it. + +2009-04-15 Roland McGrath <[email protected]> + + * readelf.c (print_debug_frame_section): Check for DW_CIE_ID_64 in + 64-bit format header, DW_CIE_ID_32 in 32-bit format header. + +2009-04-14 Roland McGrath <[email protected]> + + * readelf.c (print_attributes): Treat SHT_ARM_ATTRIBUTES on EM_ARM + like SHT_GNU_ATTRIBUTES. + + * readelf.c (handle_core_registers): Fix error message. + + * strip.c (handle_elf: check_preserved): Don't note any change when + .debug_data is already filled from a previous pass. + 2009-02-05 Ulrich Drepper <[email protected]> * objdump.c (show_relocs_x): Minor cleanups. diff --git a/src/Makefile.am b/src/Makefile.am index 64e4478b..c644a062 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -95,7 +95,7 @@ endif if BUILD_STATIC libasm = ../libasm/libasm.a -libdw = ../libdw/libdw.a $(libelf) $(libebl) -ldl +libdw = ../libdw/libdw.a $(zip_LIBS) $(libelf) $(libebl) -ldl libelf = ../libelf/libelf.a else libasm = ../libasm/libasm.so diff --git a/src/addr2line.c b/src/addr2line.c index 5a7b0456..99264b01 100644 --- a/src/addr2line.c +++ b/src/addr2line.c @@ -69,6 +69,8 @@ static const struct argp_option options[] = N_("Show absolute file names using compilation directory"), 0 }, { "functions", 'f', NULL, 0, N_("Also show function names"), 0 }, { "symbols", 'S', NULL, 0, N_("Also show symbol or section names"), 0 }, + { "section", 'j', "NAME", 0, + N_("Treat addresses as offsets relative to NAME section."), 0 }, { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, /* Unsupported options. */ @@ -113,6 +115,9 @@ static bool show_functions; /* True if ELF symbol or section info should be shown. */ static bool show_symbols; +/* If non-null, take address parameters as relative to named section. */ +static const char *just_section; + int main (int argc, char *argv[]) @@ -188,8 +193,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ /* Handle program arguments. */ static error_t -parse_opt (int key, char *arg __attribute__ ((unused)), - struct argp_state *state) +parse_opt (int key, char *arg, struct argp_state *state) { switch (key) { @@ -219,6 +223,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)), show_symbols = true; break; + case 'j': + just_section = arg; + break; + default: return ARGP_ERR_UNKNOWN; } @@ -276,15 +284,35 @@ print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr) DW_AT_call_column, &attr_mem), &val) == 0) colno = val; - if (lineno == 0) + + const char *comp_dir = ""; + const char *comp_dir_sep = ""; + + if (file == NULL) + file = "???"; + else if (only_basenames) + file = basename (file); + else if (use_comp_dir && file[0] != '/') { - if (file != NULL) - printf (" from %s", file); + const char *const *dirs; + size_t ndirs; + if (dwarf_getsrcdirs (files, &dirs, &ndirs) == 0 + && dirs[0] != NULL) + { + comp_dir = dirs[0]; + comp_dir_sep = "/"; + } } + + if (lineno == 0) + printf (" from %s%s%s", + comp_dir, comp_dir_sep, file); else if (colno == 0) - printf (" at %s:%u", file, lineno); + printf (" at %s%s%s:%u", + comp_dir, comp_dir_sep, file, lineno); else - printf (" at %s:%u:%u", file, lineno, colno); + printf (" at %s%s%s:%u:%u", + comp_dir, comp_dir_sep, file, lineno, colno); } } printf (" in "); @@ -366,6 +394,49 @@ find_symbol (Dwfl_Module *mod, return DWARF_CB_OK; } +static bool +adjust_to_section (const char *name, uintmax_t *addr, Dwfl *dwfl) +{ + /* It was (section)+offset. This makes sense if there is + only one module to look in for a section. */ + Dwfl_Module *mod = NULL; + if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0 + || mod == NULL) + error (EXIT_FAILURE, 0, gettext ("Section syntax requires" + " exactly one module")); + + int nscn = dwfl_module_relocations (mod); + for (int i = 0; i < nscn; ++i) + { + GElf_Word shndx; + const char *scn = dwfl_module_relocation_info (mod, i, &shndx); + if (unlikely (scn == NULL)) + break; + if (!strcmp (scn, name)) + { + /* Found the section. */ + GElf_Shdr shdr_mem; + GElf_Addr shdr_bias; + GElf_Shdr *shdr = gelf_getshdr + (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx), + &shdr_mem); + if (unlikely (shdr == NULL)) + break; + + if (*addr >= shdr->sh_size) + error (0, 0, + gettext ("offset %#" PRIxMAX " lies outside" + " section '%s'"), + *addr, scn); + + *addr += shdr->sh_addr + shdr_bias; + return true; + } + } + + return false; +} + static int handle_address (const char *string, Dwfl *dwfl) { @@ -378,45 +449,7 @@ handle_address (const char *string, Dwfl *dwfl) char *name = NULL; if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &n) == 2 && string[n] == '\0') - { - /* It was (section)+offset. This makes sense if there is - only one module to look in for a section. */ - Dwfl_Module *mod = NULL; - if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0 - || mod == NULL) - error (EXIT_FAILURE, 0, gettext ("Section syntax requires" - " exactly one module")); - - int nscn = dwfl_module_relocations (mod); - for (int i = 0; i < nscn; ++i) - { - GElf_Word shndx; - const char *scn = dwfl_module_relocation_info (mod, i, &shndx); - if (unlikely (scn == NULL)) - break; - if (!strcmp (scn, name)) - { - /* Found the section. */ - GElf_Shdr shdr_mem; - GElf_Addr shdr_bias; - GElf_Shdr *shdr = gelf_getshdr - (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx), - &shdr_mem); - if (unlikely (shdr == NULL)) - break; - - if (addr >= shdr->sh_size) - error (0, 0, - gettext ("offset %#" PRIxMAX " lies outside" - " section '%s'"), - addr, scn); - - addr += shdr->sh_addr + shdr_bias; - parsed = true; - break; - } - } - } + parsed = adjust_to_section (name, &addr, dwfl); else if (sscanf (string, "%m[^-+]%" PRIiMAX "%n", &name, &addr, &n) == 2 && string[n] == '\0') { @@ -442,6 +475,9 @@ handle_address (const char *string, Dwfl *dwfl) if (!parsed) return 1; } + else if (just_section != NULL + && !adjust_to_section (just_section, &addr, dwfl)) + return 1; Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr); diff --git a/src/readelf.c b/src/readelf.c index f4ed033e..1c790650 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -2824,7 +2824,9 @@ print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr) GElf_Shdr shdr_mem; GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); - if (shdr == NULL || shdr->sh_type != SHT_GNU_ATTRIBUTES) + if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES + && (shdr->sh_type != SHT_ARM_ATTRIBUTES + || ehdr->e_machine != EM_ARM))) continue; printf (gettext ("\ @@ -2871,8 +2873,9 @@ print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr) printf (gettext (" %-13s %4" PRIu32 "\n"), name, len); - if (q - name == sizeof "gnu" - && !memcmp (name, "gnu", sizeof "gnu")) + if (shdr->sh_type != SHT_GNU_ATTRIBUTES + || (q - name == sizeof "gnu" + && !memcmp (name, "gnu", sizeof "gnu"))) while (q < p) { const unsigned char *const sub = q; @@ -4673,9 +4676,13 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, if (unlikely (cieend > dataend || readp + 8 > dataend)) goto invalid_data; - Dwarf_Word cie_id; + Dwarf_Off cie_id; if (length == 4) - cie_id = read_4ubyte_unaligned_inc (dbg, readp); + { + cie_id = read_4ubyte_unaligned_inc (dbg, readp); + if (!is_eh_frame && cie_id == DW_CIE_ID_32) + cie_id = DW_CIE_ID_64; + } else cie_id = read_8ubyte_unaligned_inc (dbg, readp); @@ -4686,7 +4693,7 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, Dwarf_Word initial_location = 0; Dwarf_Word vma_base = 0; - if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID)) + if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64)) { uint_fast8_t version = *readp++; const char *const augmentation = (const char *) readp; @@ -6922,7 +6929,7 @@ handle_core_registers (Ebl *ebl, Elf *core, const void *desc, ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL); if (maxnreg <= 0) error (EXIT_FAILURE, 0, - gettext ("cannot register info: %s"), elf_errmsg (-1)); + gettext ("cannot get register info: %s"), elf_errmsg (-1)); struct register_info regs[maxnreg]; memset (regs, 0, sizeof regs); diff --git a/src/strip.c b/src/strip.c index 27eb2106..d788ebf2 100644 --- a/src/strip.c +++ b/src/strip.c @@ -835,7 +835,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, inline void check_preserved (size_t i) { - if (i != 0 && shdr_info[i].idx != 0) + if (i != 0 && shdr_info[i].idx != 0 + && shdr_info[i].debug_data == NULL) { if (shdr_info[i].data == NULL) shdr_info[i].data = elf_getdata (shdr_info[i].scn, NULL); |
