]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Handle extended phnum in readelf.
authorRoland McGrath <roland@redhat.com>
Fri, 8 Jan 2010 04:31:59 +0000 (20:31 -0800)
committerRoland McGrath <roland@redhat.com>
Fri, 8 Jan 2010 04:31:59 +0000 (20:31 -0800)
src/ChangeLog
src/readelf.c

index 2a925388702fe9a59c6b8952a8fe07987d00deea..c4b5b053764c6ebfe74f837116e06366c02b61a9 100644 (file)
@@ -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.
index 19792acbf6578c38df3b22a01c3c7adde2766044..446486696f30d58a00a656fcf78910dc8c11ad21 100644 (file)
@@ -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);