diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-11-24 15:47:10 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-11-27 05:29:17 -0800 |
commit | 8a1d35e7c28afe518370c82172f257b7809326c2 (patch) | |
tree | 2e413324d8211a5ebebbd4976c8e783d5313338d | |
parent | 6dda7875a8021787f11bd95a69d81a079e408a57 (diff) | |
download | binutils-gdb-users/hjl/pr22490.tar.gz |
Properly handle note sections and segmentsusers/hjl/pr22490
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/readelf.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c index 53896ae647b..a1f43e612a3 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; |