]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/readelf.c
Fix sol-thread.c compilation on Solaris
[thirdparty/binutils-gdb.git] / binutils / readelf.c
index ea7cc3e18eefe110b1fc0b03592346731f8399c8..a1f43e612a3b74e19f51946652c8016af920ca13 100644 (file)
@@ -13581,7 +13581,7 @@ load_debug_section (enum dwarf_section_display_enum debug, void * data)
       /* Read in the string table, so that we have section names to scan.  */
       strs = filedata->section_headers + filedata->file_header.e_shstrndx;
 
-      if (strs->sh_size != 0)
+      if (strs != NULL && strs->sh_size != 0)
        {
          filedata->string_table = (char *) get_data (NULL, filedata, strs->sh_offset,
                                                      1, strs->sh_size,
@@ -17904,12 +17904,13 @@ static bfd_boolean
 process_notes_at (Filedata *           filedata,
                  Elf_Internal_Shdr *  section,
                  bfd_vma              offset,
-                 bfd_vma              length)
+                 bfd_vma              length,
+                 bfd_vma              align)
 {
   Elf_External_Note * pnotes;
   Elf_External_Note * external;
-  char * end;
-  bfd_boolean res = TRUE;
+  char *              end;
+  bfd_boolean         res = TRUE;
 
   if (length <= 0)
     return FALSE;
@@ -17926,6 +17927,7 @@ process_notes_at (Filedata *           filedata,
   else
     pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
                                             _("notes"));
+
   if (pnotes == NULL)
     return FALSE;
 
@@ -17937,6 +17939,20 @@ process_notes_at (Filedata *           filedata,
     printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
            (unsigned long) offset, (unsigned long) length);
 
+  /* NB: Some note sections may have alignment value of 0 or 1.  gABI
+     specifies that notes should be aligned to 4 bytes in 32-bit
+     objects and to 8 bytes in 64-bit objects.  As a Linux extension,
+     we also support 4 byte alignment in 64-bit objects.  If section
+     alignment is less than 4, we treate alignment as 4 bytes.   */
+  if (align < 4)
+    align = 4;
+  else if (align != 4 && align != 8)
+    {
+      warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
+           (long) align);
+      return FALSE;
+    }
+
   printf (_("  %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
 
   end = (char *) pnotes + length;
@@ -17944,7 +17960,7 @@ process_notes_at (Filedata *           filedata,
     {
       Elf_Internal_Note inote;
       size_t min_notesz;
-      char *next;
+      char * next;
       char * temp = NULL;
       size_t data_remaining = end - (char *) external;
 
@@ -17969,9 +17985,11 @@ process_notes_at (Filedata *           filedata,
          inote.namesz   = BYTE_GET (external->namesz);
          inote.namedata = external->name;
          inote.descsz   = BYTE_GET (external->descsz);
-         inote.descdata = inote.namedata + align_power (inote.namesz, 2);
+         inote.descdata = ((char *) external
+                           + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
          inote.descpos  = offset + (inote.descdata - (char *) pnotes);
-         next = inote.descdata + align_power (inote.descsz, 2);
+         next = ((char *) external
+                 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
        }
       else
        {
@@ -18012,8 +18030,8 @@ process_notes_at (Filedata *           filedata,
        {
          warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
                (unsigned long) ((char *) external - (char *) pnotes));
-         warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
-               inote.type, inote.namesz, inote.descsz);
+         warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
+               inote.type, inote.namesz, inote.descsz, (int) align);
          break;
        }
 
@@ -18073,7 +18091,8 @@ process_corefile_note_segments (Filedata * filedata)
       if (segment->p_type == PT_NOTE)
        if (! process_notes_at (filedata, NULL,
                                (bfd_vma) segment->p_offset,
-                               (bfd_vma) segment->p_filesz))
+                               (bfd_vma) segment->p_filesz,
+                               (bfd_vma) segment->p_align))
          res = FALSE;
     }
 
@@ -18177,7 +18196,8 @@ process_note_sections (Filedata * filedata)
        {
          if (! process_notes_at (filedata, section,
                                  (bfd_vma) section->sh_offset,
-                                 (bfd_vma) section->sh_size))
+                                 (bfd_vma) section->sh_size,
+                                 (bfd_vma) section->sh_addralign))
            res = FALSE;
          n++;
        }
@@ -18552,7 +18572,10 @@ process_object (Filedata * filedata)
   if (! process_version_sections (filedata))
     res = FALSE;
 
-  separates = load_separate_debug_file (filedata, filedata->file_name);
+  if (filedata->file_header.e_shstrndx != SHN_UNDEF)
+    separates = load_separate_debug_file (filedata, filedata->file_name);
+  else
+    separates = NULL;
 
   if (! process_section_contents (filedata))
     res = FALSE;
@@ -18845,7 +18868,9 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
         }
       else if (is_thin_archive)
         {
-          Filedata thin_filedata = { 0 };
+          Filedata thin_filedata;
+
+          memset (&thin_filedata, 0, sizeof (thin_filedata));
 
          /* PR 15140: Allow for corrupt thin archives.  */
          if (nested_arch.file == NULL)