forked from OSchip/llvm-project
[ELF] - Do not produce broken output when amount of sections is > ~65k
This is a part of ttps://bugs.llvm.org//show_bug.cgi?id=38119 We produce broken ELF header now when the number of output sections is >= SHN_LORESERVE (0xff00). ELF spec says (http://www.sco.com/developers/gabi/2003-12-17/ch4.eheader.html): e_shnum: If the number of sections is greater than or equal to SHN_LORESERVE (0xff00), this member has the value zero and the actual number of section header table entries is contained in the sh_size field of the section header at index 0. (Otherwise, the sh_size member of the initial entry contains 0.) e_shstrndx If the section name string table section index is greater than or equal to SHN_LORESERVE (0xff00), this member has the value SHN_XINDEX (0xffff) and the actual index of the section name string table section is contained in the sh_link field of the section header at index 0. (Otherwise, the sh_link member of the initial entry contains 0.) We did not set these fields correctly earlier. The patch fixes the issue. Differential revision: https://reviews.llvm.org/D49371 llvm-svn: 337363
This commit is contained in:
parent
9958f620f9
commit
b9f3ea3e1c
|
@ -2242,8 +2242,6 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
|
|||
EHdr->e_ehsize = sizeof(Elf_Ehdr);
|
||||
EHdr->e_phnum = Phdrs.size();
|
||||
EHdr->e_shentsize = sizeof(Elf_Shdr);
|
||||
EHdr->e_shnum = OutputSections.size() + 1;
|
||||
EHdr->e_shstrndx = InX::ShStrTab->getParent()->SectionIndex;
|
||||
|
||||
if (!Config->Relocatable) {
|
||||
EHdr->e_phoff = sizeof(Elf_Ehdr);
|
||||
|
@ -2264,8 +2262,30 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
|
|||
++HBuf;
|
||||
}
|
||||
|
||||
// Write the section header table. Note that the first table entry is null.
|
||||
// Write the section header table.
|
||||
//
|
||||
// The ELF header can only store numbers up to SHN_LORESERVE in the e_shnum
|
||||
// and e_shstrndx fields. When the value of one of these fields exceeds
|
||||
// SHN_LORESERVE ELF requires us to put sentinel values in the ELF header and
|
||||
// use fields in the section header at index 0 to store
|
||||
// the value. The sentinel values and fields are:
|
||||
// e_shnum = 0, SHdrs[0].sh_size = number of sections.
|
||||
// e_shstrndx = SHN_XINDEX, SHdrs[0].sh_link = .shstrtab section index.
|
||||
auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
|
||||
size_t Num = OutputSections.size() + 1;
|
||||
if (Num >= SHN_LORESERVE)
|
||||
SHdrs->sh_size = Num;
|
||||
else
|
||||
EHdr->e_shnum = Num;
|
||||
|
||||
uint32_t StrTabIndex = InX::ShStrTab->getParent()->SectionIndex;
|
||||
if (StrTabIndex >= SHN_LORESERVE) {
|
||||
SHdrs->sh_link = StrTabIndex;
|
||||
EHdr->e_shstrndx = SHN_XINDEX;
|
||||
} else {
|
||||
EHdr->e_shstrndx = StrTabIndex;
|
||||
}
|
||||
|
||||
for (OutputSection *Sec : OutputSections)
|
||||
Sec->writeHeaderTo<ELFT>(++SHdrs);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o
|
||||
# RUN: ld.lld -r %t.o -o %t
|
||||
# RUN: llvm-readobj -file-headers %t | FileCheck %s
|
||||
|
||||
## Check we are able to emit a valid ELF header when
|
||||
## sections amount is greater than SHN_LORESERVE.
|
||||
# CHECK: ElfHeader {
|
||||
# CHECK: SectionHeaderCount: 0 (65541)
|
||||
# CHECK-NEXT: StringTableSectionIndex: 65535 (65539)
|
||||
|
||||
.macro gen_sections4 x
|
||||
.section a\x
|
||||
.section b\x
|
||||
.section c\x
|
||||
.section d\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections8 x
|
||||
gen_sections4 a\x
|
||||
gen_sections4 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections16 x
|
||||
gen_sections8 a\x
|
||||
gen_sections8 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections32 x
|
||||
gen_sections16 a\x
|
||||
gen_sections16 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections64 x
|
||||
gen_sections32 a\x
|
||||
gen_sections32 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections128 x
|
||||
gen_sections64 a\x
|
||||
gen_sections64 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections256 x
|
||||
gen_sections128 a\x
|
||||
gen_sections128 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections512 x
|
||||
gen_sections256 a\x
|
||||
gen_sections256 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections1024 x
|
||||
gen_sections512 a\x
|
||||
gen_sections512 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections2048 x
|
||||
gen_sections1024 a\x
|
||||
gen_sections1024 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections4096 x
|
||||
gen_sections2048 a\x
|
||||
gen_sections2048 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections8192 x
|
||||
gen_sections4096 a\x
|
||||
gen_sections4096 b\x
|
||||
.endm
|
||||
|
||||
.macro gen_sections16384 x
|
||||
gen_sections8192 a\x
|
||||
gen_sections8192 b\x
|
||||
.endm
|
||||
|
||||
gen_sections16384 a
|
||||
gen_sections16384 b
|
||||
gen_sections16384 c
|
||||
gen_sections16384 d
|
||||
|
||||
.global _start
|
||||
_start:
|
Loading…
Reference in New Issue