Bug 1385783 - Don't assume both elfhack sections are next to each other. r?froydnj draft
authorMike Hommey <mh+mozilla@glandium.org>
Wed, 02 Aug 2017 16:05:07 +0900
changeset 620089 c9ce4b448eed6cae9d10bb2fec3f58574183f3fa
parent 620030 792d0a2e04d7bc337c77f4777848337ac6ba6dd6
child 620090 98599314716c8da7db79684636198aadb1dcdd21
push id71906
push userbmo:mh+mozilla@glandium.org
push dateThu, 03 Aug 2017 01:03:52 +0000
reviewersfroydnj
bugs1385783
milestone57.0a1
Bug 1385783 - Don't assume both elfhack sections are next to each other. r?froydnj
build/unix/elfhack/elfhack.cpp
--- a/build/unix/elfhack/elfhack.cpp
+++ b/build/unix/elfhack/elfhack.cpp
@@ -84,18 +84,20 @@ public:
         shdr.sh_size = rels.size() * shdr.sh_entsize;
     }
 private:
     std::vector<Elf_RelHack> rels;
 };
 
 class ElfRelHackCode_Section: public ElfSection {
 public:
-    ElfRelHackCode_Section(Elf_Shdr &s, Elf &e, unsigned int init, unsigned int mprotect_cb)
-    : ElfSection(s, nullptr, nullptr), parent(e), init(init), mprotect_cb(mprotect_cb) {
+    ElfRelHackCode_Section(Elf_Shdr &s, Elf &e, ElfRelHack_Section &relhack_section,
+                           unsigned int init, unsigned int mprotect_cb)
+    : ElfSection(s, nullptr, nullptr), parent(e), relhack_section(relhack_section),
+      init(init), mprotect_cb(mprotect_cb) {
         std::string file(rundir);
         file += "/inject/";
         switch (parent.getMachine()) {
         case EM_386:
             file += "x86";
             break;
         case EM_X86_64:
             file += "x86_64";
@@ -349,17 +351,17 @@ private:
         // TODO: various checks on the sections
         ElfSymtab_Section *symtab = (ElfSymtab_Section *)rel->getLink();
         for (typename std::vector<Rel_Type>::iterator r = rel->rels.begin(); r != rel->rels.end(); r++) {
             // TODO: various checks on the symbol
             const char *name = symtab->syms[ELF32_R_SYM(r->r_info)].name;
             unsigned int addr;
             if (symtab->syms[ELF32_R_SYM(r->r_info)].value.getSection() == nullptr) {
                 if (strcmp(name, "relhack") == 0) {
-                    addr = getNext()->getAddr();
+                    addr = relhack_section.getAddr();
                 } else if (strcmp(name, "elf_header") == 0) {
                     // TODO: change this ungly hack to something better
                     ElfSection *ehdr = parent.getSection(1)->getPrevious()->getPrevious();
                     addr = ehdr->getAddr();
                 } else if (strcmp(name, "original_init") == 0) {
                     addr = init;
                 } else if (relro && strcmp(name, "mprotect_cb") == 0) {
                     addr = mprotect_cb;
@@ -412,16 +414,17 @@ private:
                 break;
             default:
                 throw std::runtime_error("Unsupported relocation type");
             }
         }
     }
 
     Elf *elf, &parent;
+    ElfRelHack_Section &relhack_section;
     std::vector<ElfSection *> code;
     unsigned int init;
     unsigned int mprotect_cb;
     int entry_point;
     ElfSegment *relro;
     unsigned int align;
 };
 
@@ -745,17 +748,17 @@ int do_relocation_section(Elf *elf, unsi
             fprintf(stderr, "Couldn't find .bss. Skipping\n");
             return -1;
         }
     }
 
     section->rels.assign(new_rels.begin(), new_rels.end());
     section->shrink(new_rels.size() * section->getEntSize());
 
-    ElfRelHackCode_Section *relhackcode = new ElfRelHackCode_Section(relhackcode_section, *elf, original_init, mprotect_cb);
+    ElfRelHackCode_Section *relhackcode = new ElfRelHackCode_Section(relhackcode_section, *elf, *relhack, original_init, mprotect_cb);
     relhackcode->insertBefore(section);
     relhack->insertAfter(relhackcode);
     if (section->getOffset() + section->getSize() >= old_end) {
         fprintf(stderr, "No gain. Skipping\n");
         return -1;
     }
 
     // Adjust PT_LOAD segments