Bug 1423821 - Add a consistency check for section offsets to elfhack.
lld is being too smart for its own good, and places non-relocatable data
right after the program headers, which prevents the program headers from
growing. But elfhack wasn't checking for that, so happily placed the
non-relocatable data at its non-relocated location, overwriting the last
item of the program headers.
--- a/build/unix/elfhack/elf.cpp
+++ b/build/unix/elfhack/elf.cpp
@@ -415,16 +415,28 @@ void Elf::normalize()
phdr_section->getNext()->markDirty();
}
// fixup shdr before writing
if (ehdr->e_shnum != shdr_section->getSize() / shdr_section->getEntSize())
shdr_section->getShdr().sh_size = ehdr->e_shnum * Elf_Shdr::size(ehdr->e_ident[EI_CLASS]);
ehdr->e_shoff = shdr_section->getOffset();
ehdr->e_entry = eh_entry.getValue();
ehdr->e_shstrndx = eh_shstrndx->getIndex();
+
+ // Check sections consistency
+ unsigned int minOffset = 0;
+ for (ElfSection *section = ehdr; section != nullptr; section = section->getNext()) {
+ unsigned int offset = section->getOffset();
+ if (offset < minOffset) {
+ throw std::runtime_error("Sections overlap");
+ }
+ if (section->getType() != SHT_NOBITS) {
+ minOffset = offset + section->getSize();
+ }
+ }
}
void Elf::write(std::ofstream &file)
{
normalize();
for (ElfSection *section = ehdr;
section != nullptr; section = section->getNext()) {
file.seekp(section->getOffset());