Bug 1233963 - Work around recent GNU gold behavior with segments starting before the first section they contain. r=froydnj
authorMike Hommey <mh+mozilla@glandium.org>
Tue, 19 Jan 2016 14:31:04 +0900
changeset 280875 1a4c479ec7cd347ad7b939c434633234c8e20b2c
parent 280874 de95a9403057a85e28988c778f95e853c3d46b0a
child 280876 f7a8480e3efaae4fdd07d2908671768b6e0ba15a
push id29922
push usercbook@mozilla.com
push dateThu, 21 Jan 2016 10:51:00 +0000
treeherdermozilla-central@977d78a8dd78 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1233963
milestone46.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1233963 - Work around recent GNU gold behavior with segments starting before the first section they contain. r=froydnj
build/unix/elfhack/elf.cpp
--- a/build/unix/elfhack/elf.cpp
+++ b/build/unix/elfhack/elf.cpp
@@ -253,26 +253,29 @@ Elf::Elf(std::ifstream &file)
         }
         if (phdr.p_type == PT_PHDR)
             segment->addSection(phdr_section);
         for (int j = 1; j < ehdr->e_shnum; j++)
             if (phdr.contains(sections[j]))
                 segment->addSection(sections[j]);
         // Make sure that our view of segments corresponds to the original
         // ELF file.
-        assert(segment->getFileSize() == phdr.p_filesz);
+        // GNU gold likes to start some segments before the first section
+        // they contain. https://sourceware.org/bugzilla/show_bug.cgi?id=19392
+        unsigned int gold_adjustment = segment->getAddr() - phdr.p_vaddr;
+        assert(segment->getFileSize() == phdr.p_filesz - gold_adjustment);
         // gold makes TLS segments end on an aligned virtual address, even
         // when the underlying section ends before that, while bfd ld
         // doesn't. It's fine if we don't keep that alignment.
         unsigned int memsize = segment->getMemSize();
         if (phdr.p_type == PT_TLS && memsize != phdr.p_memsz) {
             unsigned int align = segment->getAlign();
             memsize = (memsize + align - 1) & ~(align - 1);
         }
-        assert(memsize == phdr.p_memsz);
+        assert(memsize == phdr.p_memsz - gold_adjustment);
         segments.push_back(segment);
     }
 
     new (&eh_entry) ElfLocation(ehdr->e_entry, this);
 }
 
 Elf::~Elf()
 {