summaryrefslogtreecommitdiffstats
path: root/src/readelf.c
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2010-01-06 16:31:58 -0800
committerRoland McGrath <[email protected]>2010-01-06 16:31:58 -0800
commite9f969c1b222dceb89103db63b9b115c5a59a6e4 (patch)
tree2e8aaf908dfce99c937f08c09cbe7df2e0c1f2fa /src/readelf.c
parentd8bb58597ce0003ee75d5c98a634abb42f32f462 (diff)
parent7452e1953a4a4e70af3fb472e609e89776031e53 (diff)
Merge commit 'origin/master' into dwarf
Conflicts: src/ChangeLog src/readelf.c
Diffstat (limited to 'src/readelf.c')
-rw-r--r--src/readelf.c94
1 files changed, 66 insertions, 28 deletions
diff --git a/src/readelf.c b/src/readelf.c
index b7fab2ab..035042a7 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -1,5 +1,5 @@
/* Print information from ELF file in human-readable form.
- Copyright (C) 1999-2008, 2009 Red Hat, Inc.
+ Copyright (C) 1999-2010 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 1999.
@@ -70,8 +70,9 @@ ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
/* Definitions of arguments for argp functions. */
static const struct argp_option options[] =
{
- { NULL, 0, NULL, 0, N_("Output selection:"), 0 },
- { "all", 'a', NULL, 0, N_("Equivalent to: -e -h -l"), 0 },
+ { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
+ { "all", 'a', NULL, 0,
+ N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
{ "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
{ "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
{ "histogram", 'I', NULL, 0,
@@ -79,17 +80,21 @@ static const struct argp_option options[] =
{ "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
{ "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
{ "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
- { "section-headers", 'S', NULL, 0, N_("Display the sections' header"), 0 },
+ { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
{ "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
{ "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 },
{ "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
+ { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
+ { "arch-specific", 'A', NULL, 0,
+ N_("Display architecture specific information, if any"), 0 },
+ { "exception", 'e', NULL, 0,
+ N_("Display sections for exception handling"), 0 },
+
+ { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
{ "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
N_("Display DWARF section content. SECTION can be one of abbrev, "
"aranges, frame, info, loc, line, ranges, pubnames, str, macinfo, "
"or exception"), 0 },
- { "notes", 'n', NULL, 0, N_("Display the core notes"), 0 },
- { "arch-specific", 'A', NULL, 0,
- N_("Display architecture specific information (if any)"), 0 },
{ "hex-dump", 'x', "SECTION", 0,
N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
{ "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
@@ -97,8 +102,6 @@ static const struct argp_option options[] =
{ "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
{ "archive-index", 'c', NULL, 0,
N_("Display the symbol index of an archive"), 0 },
- { "exception", 'e', NULL, 0, N_("Display sections for exception handling"),
- 0 },
{ NULL, 0, NULL, 0, N_("Output control:"), 0 },
{ "numeric-addresses", 'N', NULL, 0,
@@ -189,7 +192,7 @@ static enum section_e
| section_info | section_line | section_loc
| section_pubnames | section_str | section_macinfo
| section_ranges | section_exception)
-} print_debug_sections;
+} print_debug_sections, implicit_debug_sections;
/* Select hex dumping of sections. */
static struct section_argument *dump_data_sections;
@@ -203,6 +206,7 @@ struct section_argument
{
struct section_argument *next;
const char *arg;
+ bool implicit;
};
/* Number of sections in the file. */
@@ -283,11 +287,12 @@ static error_t
parse_opt (int key, char *arg,
struct argp_state *state __attribute__ ((unused)))
{
- void add_dump_section (const char *name)
+ void add_dump_section (const char *name, bool implicit)
{
struct section_argument *a = xmalloc (sizeof *a);
a->arg = name;
a->next = NULL;
+ a->implicit = implicit;
struct section_argument ***tailp
= key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
**tailp = a;
@@ -308,10 +313,10 @@ parse_opt (int key, char *arg,
print_histogram = true;
print_arch = true;
print_notes = true;
- print_debug_sections |= section_exception;
- add_dump_section (".strtab");
- add_dump_section (".dynstr");
- add_dump_section (".comment");
+ implicit_debug_sections |= section_exception;
+ add_dump_section (".strtab", true);
+ add_dump_section (".dynstr", true);
+ add_dump_section (".comment", true);
any_control_option = true;
break;
case 'A':
@@ -409,7 +414,7 @@ parse_opt (int key, char *arg,
}
/* Fall through. */
case 'x':
- add_dump_section (arg);
+ add_dump_section (arg, false);
any_control_option = true;
break;
case 'N':
@@ -680,7 +685,7 @@ process_elf_file (Dwfl_Module *dwflmod, int fd)
dump_data (pure_ebl);
if (string_sections != NULL)
dump_strings (ebl);
- if (print_debug_sections != 0)
+ if ((print_debug_sections | implicit_debug_sections) != 0)
print_debug (dwflmod, ebl, ehdr);
if (print_notes)
handle_notes (pure_ebl, ehdr);
@@ -3138,7 +3143,6 @@ format_dwarf_addr (Dwfl_Module *dwflmod,
return result;
}
-
static void
print_block (size_t n, const void *block)
{
@@ -5881,8 +5885,9 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
if (dbg == NULL)
{
- error (0, 0, gettext ("cannot get debug context descriptor: %s"),
- dwfl_errmsg (-1));
+ if (print_debug_sections != 0)
+ error (0, 0, gettext ("cannot get debug context descriptor: %s"),
+ dwfl_errmsg (-1));
return;
}
@@ -5937,7 +5942,8 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
for (n = 0; n < ndebug_sections; ++n)
if (strcmp (name, debug_sections[n].name) == 0)
{
- if (print_debug_sections & debug_sections[n].bitmask)
+ if ((print_debug_sections | implicit_debug_sections)
+ & debug_sections[n].bitmask)
debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
break;
}
@@ -6053,11 +6059,11 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
convsize = count * size;
*repeated_size -= convsize;
}
- else
+ else if (item->count != 0 || item->format != '\n')
*repeated_size -= size;
}
- desc = convert (core, item->type, count, data, desc + item->offset, convsize);
+ convert (core, item->type, count, data, desc + item->offset, convsize);
Elf_Type type = item->type;
if (type == ELF_T_ADDR)
@@ -6203,6 +6209,33 @@ handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
count, "%.*s", (int) count, value.Byte);
break;
+ case '\n':
+ /* This is a list of strings separated by '\n'. */
+ assert (item->count == 0);
+ assert (repeated_size != NULL);
+ assert (item->name == NULL);
+ if (unlikely (item->offset >= *repeated_size))
+ break;
+
+ const char *s = desc + item->offset;
+ size = *repeated_size - item->offset;
+ *repeated_size = 0;
+ while (size > 0)
+ {
+ const char *eol = memchr (s, '\n', size);
+ int len = size;
+ if (eol != NULL)
+ len = eol - s;
+ printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
+ if (eol == NULL)
+ break;
+ size -= eol + 1 - s;
+ s = eol + 1;
+ }
+
+ colno = ITEM_WRAP_COLUMN;
+ break;
+
default:
error (0, 0, "XXX not handling format '%c' for %s",
item->format, item->name);
@@ -6647,7 +6680,8 @@ handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
}
static void
-handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const void *desc)
+handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
+ const char *name, const void *desc)
{
GElf_Word regs_offset;
size_t nregloc;
@@ -6655,7 +6689,7 @@ handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const void *desc)
size_t nitems;
const Ebl_Core_Item *items;
- if (! ebl_core_note (ebl, nhdr->n_type, nhdr->n_descsz,
+ if (! ebl_core_note (ebl, nhdr, name,
&regs_offset, &nregloc, &reglocs, &nitems, &items))
return;
@@ -6712,11 +6746,14 @@ handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
{
if (ehdr->e_type == ET_CORE)
{
- if (nhdr.n_type == NT_AUXV)
+ if (nhdr.n_type == NT_AUXV
+ && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
+ || (nhdr.n_namesz == 5 && name[4] == '\0'))
+ && !memcmp (name, "CORE", 4))
handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
start + desc_offset);
else
- handle_core_note (ebl, &nhdr, desc);
+ handle_core_note (ebl, &nhdr, name, desc);
}
else
ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
@@ -6931,7 +6968,8 @@ for_each_section_argument (Elf *elf, const struct section_argument *list,
if (unlikely (scn == NULL))
{
- error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
+ if (!a->implicit)
+ error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
continue;
}
}