Bug 771569 - Move elfhack sections before .rel{,a}.dyn to work around glibc 2.16 bug. r=froydnj a=akeybl
authorMike Hommey <mh+mozilla@glandium.org>
Mon, 09 Jul 2012 17:10:40 +0200 (2012-07-09)
changeset 81897 2ffb11d8b2f89ad033f5a4f4196f96dc502a0d32
parent 81896 b53cce148fbdf82e8ee00b7ca1067f4e8bd35bdc
child 81898 fc0d888d693d0bb9e94324a3b469954e95833cb1
push id200
push userkhuey@mozilla.com
push dateMon, 09 Jul 2012 22:48:23 +0000 (2012-07-09)
reviewersfroydnj, akeybl
bugs771569
milestone10.0.6esrpre
Bug 771569 - Move elfhack sections before .rel{,a}.dyn to work around glibc 2.16 bug. r=froydnj a=akeybl
build/unix/elfhack/elfhack.cpp
build/unix/elfhack/elfxx.h
--- a/build/unix/elfhack/elfhack.cpp
+++ b/build/unix/elfhack/elfhack.cpp
@@ -470,29 +470,30 @@ int do_relocation_section(Elf *elf, unsi
         }
     }
     if (relhack_entry.r_offset)
         relhack->push_back(relhack_entry);
     // Last entry must be NULL
     relhack_entry.r_offset = relhack_entry.r_info = 0;
     relhack->push_back(relhack_entry);
 
-    relhackcode->insertAfter(section);
+    unsigned int old_end = section->getOffset() + section->getSize();
+
+    relhackcode->insertBefore(section);
     relhack->insertAfter(relhackcode);
 
-    unsigned int old_end = section->getOffset() + section->getSize();
     section->rels.assign(new_rels.begin(), new_rels.end());
     section->shrink(new_rels.size() * section->getEntSize());
     ElfLocation *init = new ElfLocation(relhackcode, relhackcode->getEntryPoint());
     dyn->setValueForType(DT_INIT, init);
     // TODO: adjust the value according to the remaining number of relative relocations
     if (dyn->getValueForType(Rel_Type::d_tag_count))
         dyn->setValueForType(Rel_Type::d_tag_count, new ElfPlainValue(0));
 
-    if (relhack->getOffset() + relhack->getSize() >= old_end) {
+    if (section->getOffset() + section->getSize() >= old_end) {
         fprintf(stderr, "No gain. Skipping\n");
         return -1;
     }
     return 0;
 }
 
 static inline int backup_file(const char *name)
 {
--- a/build/unix/elfhack/elfxx.h
+++ b/build/unix/elfhack/elfxx.h
@@ -388,16 +388,33 @@ public:
         } else
             next = NULL;
         if (next != NULL)
             next->previous = this;
         if (dirty)
             markDirty();
     }
 
+    void insertBefore(ElfSection *section, bool dirty = true) {
+        if (previous != NULL)
+            previous->next = next;
+        if (next != NULL)
+            next->previous = previous;
+        next = section;
+        if (section != NULL) {
+            previous = section->previous;
+            section->previous = this;
+        } else
+            previous = NULL;
+        if (previous != NULL)
+            previous->next = this;
+        if (dirty)
+            markDirty();
+    }
+
     void markDirty() {
         if (link != NULL)
             shdr.sh_link = -1;
         if (info.index)
             shdr.sh_info = -1;
         shdr.sh_offset = -1;
         if (isRelocatable())
             shdr.sh_addr = -1;