]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/readelf.c
* readelf.c (get_ppc_dynamic_type): New function for DT_PPC_GLINK.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
index 31fd3fa0e9278cb6ed0ebc020ce4c83440932c4c..9b83f08229cbed15a73b5abe2c2782ddee5c91a1 100644 (file)
@@ -19,8 +19,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 \f
 /* The difference between readelf and objdump:
 
 #include "libiberty.h"
 
 char *program_name = "readelf";
-long archive_file_offset;
-unsigned long archive_file_size;
-unsigned long dynamic_addr;
-bfd_size_type dynamic_size;
-unsigned int dynamic_nent;
-char *dynamic_strings;
-unsigned long dynamic_strings_length;
-char *string_table;
-unsigned long string_table_length;
-unsigned long num_dynamic_syms;
-Elf_Internal_Sym *dynamic_symbols;
-Elf_Internal_Syminfo *dynamic_syminfo;
-unsigned long dynamic_syminfo_offset;
-unsigned int dynamic_syminfo_nent;
-char program_interpreter[64];
-bfd_vma dynamic_info[DT_JMPREL + 1];
-bfd_vma version_info[16];
-Elf_Internal_Ehdr elf_header;
-Elf_Internal_Shdr *section_headers;
-Elf_Internal_Phdr *program_headers;
-Elf_Internal_Dyn *dynamic_section;
-Elf_Internal_Shdr *symtab_shndx_hdr;
-int show_name;
-int do_dynamic;
-int do_syms;
-int do_reloc;
-int do_sections;
-int do_section_groups;
-int do_segments;
-int do_unwind;
-int do_using_dynamic;
-int do_header;
-int do_dump;
-int do_version;
-int do_wide;
-int do_histogram;
-int do_debugging;
-int do_debug_info;
-int do_debug_abbrevs;
-int do_debug_lines;
-int do_debug_pubnames;
-int do_debug_aranges;
-int do_debug_ranges;
-int do_debug_frames;
-int do_debug_frames_interp;
-int do_debug_macinfo;
-int do_debug_str;
-int do_debug_loc;
-int do_arch;
-int do_notes;
-int is_32bit_elf;
-int have_frame_base;
-int need_base_address;
-bfd_vma eh_addr_size;
+static long archive_file_offset;
+static unsigned long archive_file_size;
+static unsigned long dynamic_addr;
+static bfd_size_type dynamic_size;
+static unsigned int dynamic_nent;
+static char *dynamic_strings;
+static unsigned long dynamic_strings_length;
+static char *string_table;
+static unsigned long string_table_length;
+static unsigned long num_dynamic_syms;
+static Elf_Internal_Sym *dynamic_symbols;
+static Elf_Internal_Syminfo *dynamic_syminfo;
+static unsigned long dynamic_syminfo_offset;
+static unsigned int dynamic_syminfo_nent;
+static char program_interpreter[64];
+static bfd_vma dynamic_info[DT_JMPREL + 1];
+static bfd_vma version_info[16];
+static Elf_Internal_Ehdr elf_header;
+static Elf_Internal_Shdr *section_headers;
+static Elf_Internal_Phdr *program_headers;
+static Elf_Internal_Dyn *dynamic_section;
+static Elf_Internal_Shdr *symtab_shndx_hdr;
+static int show_name;
+static int do_dynamic;
+static int do_syms;
+static int do_reloc;
+static int do_sections;
+static int do_section_groups;
+static int do_full_section_name;
+static int do_segments;
+static int do_unwind;
+static int do_using_dynamic;
+static int do_header;
+static int do_dump;
+static int do_version;
+static int do_wide;
+static int do_histogram;
+static int do_debugging;
+static int do_debug_info;
+static int do_debug_abbrevs;
+static int do_debug_lines;
+static int do_debug_pubnames;
+static int do_debug_aranges;
+static int do_debug_ranges;
+static int do_debug_frames;
+static int do_debug_frames_interp;
+static int do_debug_macinfo;
+static int do_debug_str;
+static int do_debug_loc;
+static int do_arch;
+static int do_notes;
+static int is_32bit_elf;
+static int have_frame_base;
+static int need_base_address;
+static bfd_vma eh_addr_size;
 
 struct group_list
 {
@@ -184,10 +185,9 @@ struct group
   unsigned int group_index;
 };
 
-struct group *section_groups;
-size_t group_count;
-
-struct group **section_headers_groups;
+static size_t group_count;
+static struct group *section_groups;
+static struct group **section_headers_groups;
 
 /* A dynamic array of flags indicating for which sections a hex dump
    has been requested (via the -x switch) and/or a disassembly dump
@@ -1412,6 +1412,17 @@ get_sparc64_dynamic_type (unsigned long type)
     }
 }
 
+static const char *
+get_ppc_dynamic_type (unsigned long type)
+{
+  switch (type)
+    {
+    case DT_PPC_GLINK: return "PPC_GLINK";
+    default:
+      return NULL;
+    }
+}
+
 static const char *
 get_ppc64_dynamic_type (unsigned long type)
 {
@@ -1552,6 +1563,9 @@ get_dynamic_type (unsigned long type)
            case EM_SPARCV9:
              result = get_sparc64_dynamic_type (type);
              break;
+           case EM_PPC:
+             result = get_ppc_dynamic_type (type);
+             break;
            case EM_PPC64:
              result = get_ppc64_dynamic_type (type);
              break;
@@ -2576,7 +2590,7 @@ get_section_type_name (unsigned int sh_type)
 
 #define OPTION_DEBUG_DUMP      512
 
-struct option options[] =
+static struct option options[] =
 {
   {"all",             no_argument, 0, 'a'},
   {"file-header",      no_argument, 0, 'h'},
@@ -2587,6 +2601,7 @@ struct option options[] =
   {"sections",        no_argument, 0, 'S'},
   {"section-headers",  no_argument, 0, 'S'},
   {"section-groups",   no_argument, 0, 'g'},
+  {"full-section-name",no_argument, 0, 'N'},
   {"symbols",         no_argument, 0, 's'},
   {"syms",            no_argument, 0, 's'},
   {"relocs",          no_argument, 0, 'r'},
@@ -2621,6 +2636,8 @@ usage (void)
   -S --section-headers   Display the sections' header\n\
      --sections          An alias for --section-headers\n\
   -g --section-groups    Display the section groups\n\
+  -N --full-section-name\n\
+                         Display the full section name\n\
   -e --headers           Equivalent to: -h -l -S\n\
   -s --syms              Display the symbol table\n\
       --symbols          An alias for --syms\n\
@@ -2693,7 +2710,7 @@ parse_args (int argc, char **argv)
     usage ();
 
   while ((c = getopt_long
-         (argc, argv, "ersuahnldSDAIgw::x:i:vVWH", options, NULL)) != EOF)
+         (argc, argv, "ersuahnldSDAINgw::x:i:vVWH", options, NULL)) != EOF)
     {
       char *cp;
       int section;
@@ -2724,6 +2741,9 @@ parse_args (int argc, char **argv)
        case 'g':
          do_section_groups++;
          break;
+       case 'N':
+         do_full_section_name++;
+         break;
        case 'e':
          do_header++;
          do_sections++;
@@ -3847,25 +3867,60 @@ process_section_headers (FILE *file)
     printf (_("\nSection Header:\n"));
 
   if (is_32bit_elf)
-    printf
-      (_("  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al\n"));
+    {
+      if (do_full_section_name)
+       {
+         printf (_("  [Nr] Name\n"));
+         printf (_("       Type            Addr     Off    Size   ES Flg Lk Inf Al\n"));
+       }
+      else
+       printf
+         (_("  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al\n"));
+    }
   else if (do_wide)
-    printf
-      (_("  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al\n"));
+    {
+      if (do_full_section_name)
+       {
+         printf (_("  [Nr] Name\n"));
+         printf (_("       Type            Address          Off    Size   ES Flg Lk Inf Al\n"));
+       }
+      else
+       printf
+         (_("  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al\n"));
+    }
   else
     {
-      printf (_("  [Nr] Name              Type             Address           Offset\n"));
-      printf (_("       Size              EntSize          Flags  Link  Info  Align\n"));
+      if (do_full_section_name)
+       {
+         printf (_("  [Nr] Name\n"));
+         printf (_("       Flags             Type             Address           Offset\n"));
+         printf (_("       Size              EntSize          Link     Info     Align\n"));
+       }
+      else
+       {
+         printf (_("  [Nr] Name              Type             Address           Offset\n"));
+         printf (_("       Size              EntSize          Flags  Link  Info  Align\n"));
+       }
     }
 
   for (i = 0, section = section_headers;
        i < elf_header.e_shnum;
        i++, section++)
     {
-      printf ("  [%2u] %-17.17s %-15.15s ",
-             SECTION_HEADER_NUM (i),
-             SECTION_NAME (section),
-             get_section_type_name (section->sh_type));
+      if (do_full_section_name)
+       {
+         printf ("  [%2u] %s\n",
+                 SECTION_HEADER_NUM (i),
+                 SECTION_NAME (section));
+         if (is_32bit_elf || do_wide)
+           printf ("       %-15.15s ",
+                   get_section_type_name (section->sh_type));
+       }
+      else
+       printf ("  [%2u] %-17.17s %-15.15s ",
+               SECTION_HEADER_NUM (i),
+               SECTION_NAME (section),
+               get_section_type_name (section->sh_type));
 
       if (is_32bit_elf)
        {
@@ -3925,6 +3980,30 @@ process_section_headers (FILE *file)
              putchar ('\n');
            }
        }
+      else if (do_full_section_name)
+       {
+         printf ("       %-15.15s   %-15.15s ",
+                 get_elf_section_flags (section->sh_flags),
+                 get_section_type_name (section->sh_type));
+         putchar (' ');
+         print_vma (section->sh_addr, LONG_HEX);
+         if ((long) section->sh_offset == section->sh_offset)
+           printf ("  %8.8lx", (unsigned long) section->sh_offset);
+         else
+           {
+             printf ("  ");
+             print_vma (section->sh_offset, LONG_HEX);
+           }
+         printf ("\n       ");
+         print_vma (section->sh_size, LONG_HEX);
+         printf ("  ");
+         print_vma (section->sh_entsize, LONG_HEX);
+
+         printf ("   %2ld      %3lu        %ld\n",
+                 (unsigned long) section->sh_link,
+                 (unsigned long) section->sh_info,
+                 (unsigned long) section->sh_addralign);
+       }
       else
        {
          putchar (' ');
@@ -4178,7 +4257,7 @@ process_section_groups (FILE *file)
   return 1;
 }
 
-struct
+static struct
 {
   const char *name;
   int reloc;
@@ -7321,7 +7400,7 @@ debug_apply_rela_addends (FILE *file,
                     example of this see the _clz.o binary in libgcc.a.  */
                  && ELF32_ST_TYPE (sym->st_info) != STT_OBJECT)
                {
-                 warn (_("%s: skipping unexpected symbol type %s in relocation in section .rela%s\n"),
+                 warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"),
                        get_symbol_type (ELF32_ST_TYPE (sym->st_info)),
                        SECTION_NAME (section));
                  continue;
@@ -7329,6 +7408,18 @@ debug_apply_rela_addends (FILE *file,
            }
          else
            {
+             /* In MIPS little-endian objects, r_info isn't really a
+                64-bit little-endian value: it has a 32-bit little-endian
+                symbol index followed by four individual byte fields.
+                Reorder INFO accordingly.  */
+             if (elf_header.e_machine == EM_MIPS
+                 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
+               rp->r_info = (((rp->r_info & 0xffffffff) << 32)
+                             | ((rp->r_info >> 56) & 0xff)
+                             | ((rp->r_info >> 40) & 0xff00)
+                             | ((rp->r_info >> 24) & 0xff0000)
+                             | ((rp->r_info >> 8) & 0xff000000));
+
              sym = symtab + ELF64_R_SYM (rp->r_info);
 
              if (ELF64_R_SYM (rp->r_info) != 0
@@ -10631,6 +10722,7 @@ display_debug_frames (Elf_Internal_Shdr *section,
            case DW_CFA_def_cfa_sf:
              fc->cfa_reg = LEB ();
              fc->cfa_offset = SLEB ();
+             fc->cfa_offset = fc->cfa_offset * fc->data_factor;
              fc->cfa_exp = 0;
              if (! do_debug_frames_interp)
                printf ("  DW_CFA_def_cfa_sf: r%d ofs %d\n",
@@ -10639,6 +10731,7 @@ display_debug_frames (Elf_Internal_Shdr *section,
 
            case DW_CFA_def_cfa_offset_sf:
              fc->cfa_offset = SLEB ();
+             fc->cfa_offset = fc->cfa_offset * fc->data_factor;
              if (! do_debug_frames_interp)
                printf ("  DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
              break;
@@ -10710,7 +10803,7 @@ display_debug_not_supported (Elf_Internal_Shdr *section,
 
 /* A structure containing the name of a debug section
    and a pointer to a function that can decode it.  */
-struct
+static struct
 {
   const char *const name;
   int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);