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.
This commit is contained in:
parent
a63f2d2fee
commit
650444eb54
@ -1,3 +1,18 @@
|
|||||||
|
2017-11-24 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2017-11-23 Alan Modra <amodra@gmail.com>
|
2017-11-23 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elf32-hppa.c (pc_dynrelocs): Define.
|
* elf32-hppa.c (pc_dynrelocs): Define.
|
||||||
|
24
bfd/elf.c
24
bfd/elf.c
@ -52,9 +52,10 @@ static int elf_sort_sections (const void *, const void *);
|
|||||||
static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
|
static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
|
||||||
static bfd_boolean prep_headers (bfd *);
|
static bfd_boolean prep_headers (bfd *);
|
||||||
static bfd_boolean swap_out_syms (bfd *, struct elf_strtab_hash **, int) ;
|
static bfd_boolean swap_out_syms (bfd *, struct elf_strtab_hash **, int) ;
|
||||||
static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ;
|
static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type,
|
||||||
|
size_t align) ;
|
||||||
static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
|
static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
|
||||||
file_ptr offset);
|
file_ptr offset, size_t align);
|
||||||
|
|
||||||
/* Swap version information in and out. The version information is
|
/* Swap version information in and out. The version information is
|
||||||
currently size independent. If that ever changes, this code will
|
currently size independent. If that ever changes, this code will
|
||||||
@ -1089,7 +1090,8 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
|||||||
if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
|
if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
elf_parse_notes (abfd, (char *) contents, hdr->sh_size, hdr->sh_offset);
|
elf_parse_notes (abfd, (char *) contents, hdr->sh_size,
|
||||||
|
hdr->sh_offset, hdr->sh_addralign);
|
||||||
free (contents);
|
free (contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2990,7 +2992,8 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index)
|
|||||||
case PT_NOTE:
|
case PT_NOTE:
|
||||||
if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "note"))
|
if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "note"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
|
if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz,
|
||||||
|
hdr->p_align))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@ -10970,14 +10973,14 @@ elfcore_write_register_note (bfd *abfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
|
elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset,
|
||||||
|
size_t align)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
p = buf;
|
p = buf;
|
||||||
while (p < buf + size)
|
while (p < buf + size)
|
||||||
{
|
{
|
||||||
/* FIXME: bad alignment assumption. */
|
|
||||||
Elf_External_Note *xnp = (Elf_External_Note *) p;
|
Elf_External_Note *xnp = (Elf_External_Note *) p;
|
||||||
Elf_Internal_Note in;
|
Elf_Internal_Note in;
|
||||||
|
|
||||||
@ -10992,7 +10995,7 @@ elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
in.descsz = H_GET_32 (abfd, xnp->descsz);
|
in.descsz = H_GET_32 (abfd, xnp->descsz);
|
||||||
in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
|
in.descdata = p + ELF_NOTE_DESC_OFFSET (in.namesz, align);
|
||||||
in.descpos = offset + (in.descdata - buf);
|
in.descpos = offset + (in.descdata - buf);
|
||||||
if (in.descsz != 0
|
if (in.descsz != 0
|
||||||
&& (in.descdata >= buf + size
|
&& (in.descdata >= buf + size
|
||||||
@ -11054,14 +11057,15 @@ elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = in.descdata + BFD_ALIGN (in.descsz, 4);
|
p += ELF_NOTE_NEXT_OFFSET (in.namesz, in.descsz, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
|
elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size,
|
||||||
|
size_t align)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
@ -11080,7 +11084,7 @@ elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
|
|||||||
buf[size] = 0;
|
buf[size] = 0;
|
||||||
|
|
||||||
if (bfd_bread (buf, size, abfd) != size
|
if (bfd_bread (buf, size, abfd) != size
|
||||||
|| !elf_parse_notes (abfd, buf, size, offset))
|
|| !elf_parse_notes (abfd, buf, size, offset, align))
|
||||||
{
|
{
|
||||||
free (buf);
|
free (buf);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2017-11-24 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2017-11-23 Pavel I. Kryukov <kryukov@frtk.ru>
|
2017-11-23 Pavel I. Kryukov <kryukov@frtk.ru>
|
||||||
|
|
||||||
PR 22485
|
PR 22485
|
||||||
|
@ -17969,9 +17969,13 @@ process_notes_at (Filedata * filedata,
|
|||||||
inote.namesz = BYTE_GET (external->namesz);
|
inote.namesz = BYTE_GET (external->namesz);
|
||||||
inote.namedata = external->name;
|
inote.namedata = external->name;
|
||||||
inote.descsz = BYTE_GET (external->descsz);
|
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,
|
||||||
|
section->sh_addralign));
|
||||||
inote.descpos = offset + (inote.descdata - (char *) pnotes);
|
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,
|
||||||
|
section->sh_addralign));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2017-11-24 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR binutils/22444
|
||||||
|
* elf/external.h (ELF_ALIGN_UP): New.
|
||||||
|
(ELF_NOTE_DESC_OFFSET): Likewise.
|
||||||
|
(ELF_NOTE_NEXT_OFFSET): Likewise.
|
||||||
|
|
||||||
2017-11-16 Tamar Christina <tamar.christina@arm.com>
|
2017-11-16 Tamar Christina <tamar.christina@arm.com>
|
||||||
|
|
||||||
* opcode/aarch64.h: (AARCH64_FEATURE_F16_FML): New.
|
* opcode/aarch64.h: (AARCH64_FEATURE_F16_FML): New.
|
||||||
|
@ -183,6 +183,22 @@ typedef struct {
|
|||||||
char name[1]; /* Start of the name+desc data */
|
char name[1]; /* Start of the name+desc data */
|
||||||
} Elf_External_Note;
|
} 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 */
|
/* Relocation Entries */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char r_offset[4]; /* Location at which to apply the action */
|
unsigned char r_offset[4]; /* Location at which to apply the action */
|
||||||
|
Loading…
Reference in New Issue
Block a user