summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2010-01-07 20:31:59 -0800
committerRoland McGrath <roland@redhat.com>2010-01-07 20:31:59 -0800
commit8111da06cc8f0745bb521f8b28d06f96f0a5a887 (patch)
tree9d4e99fad79f7224101a9cd7f1ae261d8b3bb955
parentf95760aff004850544f83626404c134d6a07c630 (diff)
downloadelfutils-8111da06cc8f0745bb521f8b28d06f96f0a5a887.tar.gz
Handle extended phnum in readelf.
-rw-r--r--src/ChangeLog7
-rw-r--r--src/readelf.c44
2 files changed, 38 insertions, 13 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 2a925388..c4b5b053 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,12 @@
2010-01-07 Roland McGrath <roland@redhat.com>
+ * readelf.c (print_ehdr): Handle PN_XNUM.
+ (phnum): New static variable.
+ (process_elf_file): Set it with elf_getphdrnum.
+ (print_phdr): Use phnum instead of EHDR->e_phnum.
+ (print_dynamic, handle_notes): Likewise.
+ (handle_relocs_rel, handle_relocs_rela): Likewise.
+
* elfcmp.c (main): Use elf_getshdrnum and elf_getphdrnum.
* elflint.c (phnum): New static variable.
diff --git a/src/readelf.c b/src/readelf.c
index 19792acb..44648669 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -208,8 +208,9 @@ struct section_argument
bool implicit;
};
-/* Number of sections in the file. */
+/* Numbers of sections and program headers in the file. */
static size_t shnum;
+static size_t phnum;
/* Declarations of local functions. */
@@ -219,7 +220,7 @@ static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
static void print_scngrp (Ebl *ebl);
-static void print_dynamic (Ebl *ebl, GElf_Ehdr *ehdr);
+static void print_dynamic (Ebl *ebl);
static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
GElf_Shdr *shdr);
@@ -626,6 +627,12 @@ process_elf_file (Dwfl_Module *dwflmod, int fd)
gettext ("cannot determine number of sections: %s"),
elf_errmsg (-1));
+ /* Determine the number of phdrs. */
+ if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
+ error (EXIT_FAILURE, 0,
+ gettext ("cannot determine number of program headers: %s"),
+ elf_errmsg (-1));
+
/* For an ET_REL file, libdwfl has adjusted the in-core shdrs
and may have applied relocation to some sections.
So we need to get a fresh Elf handle on the file to display those. */
@@ -665,7 +672,7 @@ process_elf_file (Dwfl_Module *dwflmod, int fd)
if (print_section_groups)
print_scngrp (ebl);
if (print_dynamic_table)
- print_dynamic (ebl, ehdr);
+ print_dynamic (ebl);
if (print_relocations)
print_relocs (pure_ebl, ehdr);
if (print_histogram)
@@ -784,8 +791,19 @@ print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
ehdr->e_phentsize, gettext ("(bytes)"));
- printf (gettext (" Number of program headers entries: %" PRId16 "\n"),
+ printf (gettext (" Number of program headers entries: %" PRId16),
ehdr->e_phnum);
+ if (ehdr->e_phnum == PN_XNUM)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+ if (shdr != NULL)
+ printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
+ (uint32_t) shdr->sh_info);
+ else
+ fputs_unlocked (gettext (" ([0] not available)"), stdout);
+ }
+ fputc_unlocked ('\n', stdout);
printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
ehdr->e_shentsize, gettext ("(bytes)"));
@@ -953,7 +971,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
bool has_relro = false;
GElf_Addr relro_from = 0;
GElf_Addr relro_to = 0;
- for (size_t cnt = 0; cnt < ehdr->e_phnum; ++cnt)
+ for (size_t cnt = 0; cnt < phnum; ++cnt)
{
char buf[128];
GElf_Phdr mem;
@@ -1009,7 +1027,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
- for (size_t cnt = 0; cnt < ehdr->e_phnum; ++cnt)
+ for (size_t cnt = 0; cnt < phnum; ++cnt)
{
/* Print the segment number. */
printf (" %2.2zu ", cnt);
@@ -1079,7 +1097,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
/* Determine the segment this section is part of. */
size_t cnt2;
GElf_Phdr *phdr2 = NULL;
- for (cnt2 = 0; cnt2 < ehdr->e_phnum; ++cnt2)
+ for (cnt2 = 0; cnt2 < phnum; ++cnt2)
{
GElf_Phdr phdr2_mem;
phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
@@ -1091,7 +1109,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
break;
}
- if (cnt2 < ehdr->e_phnum)
+ if (cnt2 < phnum)
{
if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
{
@@ -1442,9 +1460,9 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
/* Print the dynamic segment. */
static void
-print_dynamic (Ebl *ebl, GElf_Ehdr *ehdr)
+print_dynamic (Ebl *ebl)
{
- for (int i = 0; i < ehdr->e_phnum; ++i)
+ for (size_t i = 0; i < phnum; ++i)
{
GElf_Phdr phdr_mem;
GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
@@ -1586,7 +1604,7 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
{
is_statically_linked = 1;
- for (size_t inner = 0; inner < ehdr->e_phnum; ++inner)
+ for (size_t inner = 0; inner < phnum; ++inner)
{
GElf_Phdr phdr_mem;
GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
@@ -1759,7 +1777,7 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
{
is_statically_linked = 1;
- for (size_t inner = 0; inner < ehdr->e_phnum; ++inner)
+ for (size_t inner = 0; inner < phnum; ++inner)
{
GElf_Phdr phdr_mem;
GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
@@ -7398,7 +7416,7 @@ handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
/* We have to look through the program header to find the note
sections. There can be more than one. */
- for (size_t cnt = 0; cnt < ehdr->e_phnum; ++cnt)
+ for (size_t cnt = 0; cnt < phnum; ++cnt)
{
GElf_Phdr mem;
GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);