diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-11-24 06:41:40 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-11-24 06:41:52 -0800 |
commit | 650444eb540f9fd85e821567a3f943b4bc41b8be (patch) | |
tree | 2c5e0bf7934a74df34cfd3a0c9377d62903717bb /include/elf/external.h | |
parent | a63f2d2feedcfce401ae1d7d03d119bfa5e4d8bc (diff) | |
download | gdb-650444eb540f9fd85e821567a3f943b4bc41b8be.zip gdb-650444eb540f9fd85e821567a3f943b4bc41b8be.tar.gz gdb-650444eb540f9fd85e821567a3f943b4bc41b8be.tar.bz2 |
elf: Properly compute offsets of note descriptor and next note
According to gABI, in a note entry, the note name field, not note name
size, is padded for the note descriptor. And the note descriptor field,
not note descriptor size, is padded for the next note entry. Also notes
are aligned to 4 bytes in 32-bit objects and 8 bytes in 64-bit objects.
Since on Linux, .note.ABI-tag and .note.gnu.build-id notes are always
aligned to 4 bytes, we need to use alignment of note section or note
segment, instead of assuming alignment based on ELF file class.
Tested on i686 and x86-64.
bfd/
PR binutils/22444
* elf.c (elf_read_notes): Add an argument for note aligment.
(elf_parse_notes): Likewise.
(_bfd_elf_make_section_from_shdr): Pass section aligment to
elf_parse_notes.
(bfd_section_from_phdr): Pass segment aligment to elf_read_notes.
(elf_parse_notes): Add an argument for note aligment. Use
ELF_NOTE_DESC_OFFSET to get the offset of the note descriptor.
Use ELF_NOTE_NEXT_OFFSET to get the offset of the next note
entry.
(elf_read_notes): Add an argument for note aligment and pass it
to elf_parse_notes.
binutils/
PR binutils/22444
* readelf.c (process_notes_at): Use ELF_NOTE_DESC_OFFSET to get
the offset of the note descriptor. Use ELF_NOTE_NEXT_OFFSET to
get the offset of the next note entry.
include/
PR binutils/22444
* elf/external.h (ELF_ALIGN_UP): New.
(ELF_NOTE_DESC_OFFSET): Likewise.
(ELF_NOTE_NEXT_OFFSET): Likewise.
Diffstat (limited to 'include/elf/external.h')
-rw-r--r-- | include/elf/external.h | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/include/elf/external.h b/include/elf/external.h index d65bae0..eb0a53a 100644 --- a/include/elf/external.h +++ b/include/elf/external.h @@ -183,6 +183,22 @@ typedef struct { char name[1]; /* Start of the name+desc data */ } Elf_External_Note; +/* Align an address upward to a boundary, expressed as a number of bytes. + E.g. align to an 8-byte boundary with argument of 8. */ +#define ELF_ALIGN_UP(addr, boundary) \ + (((bfd_vma) (addr) + ((boundary) - 1)) & ~ (bfd_vma) ((boundary) -1)) + +/* Compute the offset of the note descriptor from size of note entry's + owner string and note alignment. */ +#define ELF_NOTE_DESC_OFFSET(namesz, align) \ + ELF_ALIGN_UP (offsetof (Elf_External_Note, name) + (namesz), (align)) + +/* Compute the offset of the next note entry from size of note entry's + owner string, size of the note descriptor and note alignment. */ +#define ELF_NOTE_NEXT_OFFSET(namesz, descsz, align) \ + ELF_ALIGN_UP (ELF_NOTE_DESC_OFFSET ((namesz), (align)) + (descsz), \ + (align)) + /* Relocation Entries */ typedef struct { unsigned char r_offset[4]; /* Location at which to apply the action */ |