summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-11-28 08:18:33 -0800
committerH.J. Lu <hjl.tools@gmail.com>2017-11-28 08:18:46 -0800
commit82ed9683ec099d8205dc499ac84febc975235af6 (patch)
tree30fcfb93563f8b9d8234c75567f67d2cb08e6be4
parentb23dc97fe237a1d9e850d7cbeee066183a00630b (diff)
Properly handle note sections and segments
When dumping notes, get note alignment from either note section or note segment. To support notes generated by assemblers with https://sourceware.org/bugzilla/show_bug.cgi?id=22492 we treate alignment as 4 bytes if it is less than 4. Otherwise, we skip notes if alignment isn't 4 nor 8 bytes. We should call load_separate_debug_file only if e_shstrndx != SHN_UNDEF. PR binutils/22490 * readelf.c (process_notes_at): Add an argument for note alignment. If note alignment is less than 4, use 4 byte alignment. Otherwise, skip notes if alignment isn't 4 nor 8 bytes. (process_corefile_note_segments): Pass segment alignment to process_notes_at. (process_note_sections): Pass section alignment to process_notes_at. (process_object): Call load_separate_debug_file only if e_shstrndx != SHN_UNDEF.
-rw-r--r--binutils/ChangeLog14
-rw-r--r--binutils/readelf.c41
2 files changed, 39 insertions, 16 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index f30ef1970f..17b623edb5 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,17 @@
+2017-11-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/22490
+ * readelf.c (process_notes_at): Add an argument for note
+ alignment. If note alignment is less than 4, use 4 byte
+ alignment. Otherwise, skip notes if alignment isn't 4 nor
+ 8 bytes.
+ (process_corefile_note_segments): Pass segment alignment to
+ process_notes_at.
+ (process_note_sections): Pass section alignment to
+ process_notes_at.
+ (process_object): Call load_separate_debug_file only if
+ e_shstrndx != SHN_UNDEF.
+
2017-11-27 Nick Clifton <nickc@redhat.com>
PR 22490
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 53896ae647..a1f43e612a 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -17904,13 +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;
- size_t align;
if (length <= 0)
return FALSE;
@@ -17923,21 +17923,11 @@ process_notes_at (Filedata * filedata,
if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
return FALSE;
}
- align = section->sh_addralign;
}
else
- {
- pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
+ pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
_("notes"));
- /* FIXME: Core notes seem to be produced with
- 4-byte alignment even on 64-bit systems. */
- if (filedata->file_header.e_type == ET_CORE)
- align = 4;
- else
- align = is_32bit_elf ? 4 : 4;
- }
-
if (pnotes == NULL)
return FALSE;
@@ -17949,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;
@@ -18087,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;
}
@@ -18191,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++;
}
@@ -18566,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;