Bug 1423822 - Set the address for the elfhack code section based on that of the section it is attached to. r=froydnj draft
authorMike Hommey <mh+mozilla@glandium.org>
Wed, 01 Aug 2018 07:21:36 +0900
changeset 825730 9f6bdfb258445e0301ff5f50aa1ed0a86abfb4c4
parent 825729 9ca3ce5300f0923a6e14bb1661cd834079ba4c85
child 825731 2375bfeb5e4d35e63c6075cbb8981462e8ed6358
child 825738 bbb152a831e99daf35052d468a3ad20c4e944417
child 826057 4faa693fb0dc43fc73bf48c50f7c2fefd8ec35dd
push id118154
push userbmo:mh+mozilla@glandium.org
push dateThu, 02 Aug 2018 05:40:11 +0000
reviewersfroydnj
bugs1423822
milestone63.0a1
Bug 1423822 - Set the address for the elfhack code section based on that of the section it is attached to. r=froydnj When linking with ld.bfd or gold, this changes the PT_LOAD in which the elfhack code section ends up, making it go in the same one as .init, .text, etc. rather than .rel.*. When linking with lld, this completely avoids doing a PT_LOAD split, because lld already splits .rel.* and .text.
build/unix/elfhack/elfhack.cpp
build/unix/elfhack/elfxx.h
--- a/build/unix/elfhack/elfhack.cpp
+++ b/build/unix/elfhack/elfhack.cpp
@@ -191,22 +191,32 @@ public:
                         apply_relocations((ElfRel_Section<Elf_Rela> *)rel, *c);
                 }
             }
 
         ElfSection::serialize(file, ei_class, ei_data);
     }
 
     bool isRelocatable() {
-        return true;
+        return false;
     }
 
     unsigned int getEntryPoint() {
         return entry_point;
     }
+
+    void insertBefore(ElfSection *section, bool dirty = true) override {
+        // Adjust the address so that this section is adjacent to the one it's
+        // being inserted before. This avoids creating holes which subsequently
+        // might lead the PHDR-adjusting code to create unnecessary additional
+        // PT_LOADs.
+        shdr.sh_addr = (section->getAddr() - shdr.sh_size) & ~(shdr.sh_addralign - 1);
+        ElfSection::insertBefore(section, dirty);
+    }
+
 private:
     void add_code_section(ElfSection *section)
     {
         if (section) {
             /* Don't add section if it's already been added in the past */
             for (auto s = code.begin(); s != code.end(); ++s) {
                 if (section == *s)
                     return;
--- a/build/unix/elfhack/elfxx.h
+++ b/build/unix/elfhack/elfxx.h
@@ -378,17 +378,17 @@ public:
             next = nullptr;
         if (next != nullptr)
             next->previous = this;
         if (dirty)
             markDirty();
         insertInSegments(section->segments);
     }
 
-    void insertBefore(ElfSection *section, bool dirty = true) {
+    virtual void insertBefore(ElfSection *section, bool dirty = true) {
         if (previous != nullptr)
             previous->next = next;
         if (next != nullptr)
             next->previous = previous;
         next = section;
         if (section != nullptr) {
             previous = section->previous;
             section->previous = this;