summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlrich Drepper <[email protected]>2009-04-29 15:19:21 -0700
committerUlrich Drepper <[email protected]>2009-04-29 15:19:21 -0700
commit61ad08998d3d91da3660f2cee65c84c0aab2d276 (patch)
tree17495720460f67552db6329d432d3a1e958c4f2e /src
parentc803fbe6c3fa15d08dee1c99948ec66326db1e9e (diff)
parenta7cb532d98e02aae86940ec7c121ce16ced806ee (diff)
Merge branch 'master' of ssh://git.fedorahosted.org/git/elfutils
Conflicts: ChangeLog
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog29
-rw-r--r--src/Makefile.am2
-rw-r--r--src/addr2line.c128
-rw-r--r--src/readelf.c21
-rw-r--r--src/strip.c3
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);