diff options
| author | Mark Wielaard <[email protected]> | 2019-01-11 13:39:27 +0100 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2019-01-11 13:39:27 +0100 |
| commit | b244a241a82c28f7fef33f37d82bc47631ceca4e (patch) | |
| tree | 8b83c72f0a99dca6624f0903e8c3ee1eb26ad900 /libelf/elf_getdata.c | |
| parent | 029c76f0d4b06584e370b5fc0112712ba99a6219 (diff) | |
| parent | 4ea9a2db164caadf836a65d5cdffb09a2d5a37ce (diff) | |
Merge tag 'elfutils-0.175' into mjw/RH-DTSdts-0.175
elfutils 0.175 release
Diffstat (limited to 'libelf/elf_getdata.c')
| -rw-r--r-- | libelf/elf_getdata.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c index 278dfa8f..639a798e 100644 --- a/libelf/elf_getdata.c +++ b/libelf/elf_getdata.c @@ -65,7 +65,7 @@ static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] = [SHT_PREINIT_ARRAY] = ELF_T_ADDR, [SHT_GROUP] = ELF_T_WORD, [SHT_SYMTAB_SHNDX] = ELF_T_WORD, - [SHT_NOTE] = ELF_T_NHDR, + [SHT_NOTE] = ELF_T_NHDR, /* Need alignment to guess ELF_T_NHDR8. */ [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF, [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED, [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF, @@ -106,6 +106,7 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] [ELF_T_GNUHASH] = __alignof__ (Elf32_Word), \ [ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)), \ [ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)), \ + [ELF_T_NHDR8] = 8 /* Special case for GNU Property note. */ \ } [EV_CURRENT - 1] = { @@ -118,7 +119,7 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] Elf_Type internal_function -__libelf_data_type (Elf *elf, int sh_type) +__libelf_data_type (Elf *elf, int sh_type, GElf_Xword align) { /* Some broken ELF ABI for 64-bit machines use the wrong hash table entry size. See elf-knowledge.h for more information. */ @@ -129,7 +130,13 @@ __libelf_data_type (Elf *elf, int sh_type) return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD); } else - return shtype_map[LIBELF_EV_IDX][TYPEIDX (sh_type)]; + { + Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (sh_type)]; + /* Special case for GNU Property notes. */ + if (t == ELF_T_NHDR && align == 8) + t = ELF_T_NHDR8; + return t; + } } /* Convert the data in the current section. */ @@ -139,7 +146,8 @@ convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass, { const size_t align = __libelf_type_align (eclass, type); - if (data == MY_ELFDATA) + /* Do we need to convert the data and/or adjust for alignment? */ + if (data == MY_ELFDATA || type == ELF_T_BYTE) { if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0) /* No need to copy, we can use the raw data. */ @@ -260,9 +268,15 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn) /* First a test whether the section is valid at all. */ size_t entsize; - /* Compressed data has a header, but then compressed data. */ + /* Compressed data has a header, but then compressed data. + Make sure to set the alignment of the header explicitly, + don't trust the file alignment for the section, it is + often wrong. */ if ((flags & SHF_COMPRESSED) != 0) - entsize = 1; + { + entsize = 1; + align = __libelf_type_align (elf->class, ELF_T_CHDR); + } else if (type == SHT_HASH) { GElf_Ehdr ehdr_mem; @@ -272,7 +286,9 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn) else { Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)]; - if (t == ELF_T_VDEF || t == ELF_T_NHDR + if (t == ELF_T_NHDR && align == 8) + t = ELF_T_NHDR8; + if (t == ELF_T_VDEF || t == ELF_T_NHDR || t == ELF_T_NHDR8 || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64)) entsize = 1; else @@ -357,7 +373,7 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn) if ((flags & SHF_COMPRESSED) != 0) scn->rawdata.d.d_type = ELF_T_CHDR; else - scn->rawdata.d.d_type = __libelf_data_type (elf, type); + scn->rawdata.d.d_type = __libelf_data_type (elf, type, align); scn->rawdata.d.d_off = 0; /* Make sure the alignment makes sense. d_align should be aligned both |
