[llvm-commits] [llvm] r153147 - in /llvm/trunk/lib/ExecutionEngine/RuntimeDyld: RuntimeDyldMachO.cpp RuntimeDyldMachO.h

Sean Callanan scallanan at apple.com
Tue Mar 20 15:25:40 PDT 2012


Author: spyffe
Date: Tue Mar 20 17:25:39 2012
New Revision: 153147

URL: http://llvm.org/viewvc/llvm-project?rev=153147&view=rev
Log:
RuntimeDyldMachO has the ability to keep track of
relocations (i.e., pieces of data whose addresses
are referred to elsewhere in the binary image) and
update the references when the section containing
the relocations moves.  The way this works is that
there is a map from section IDs to lists of
relocations.

Because the relocations are associated with the
section containing the data being referred to, they
are updated only when the target moves.  However,
many data references are relative and also depend
on the location of the referrer.

To solve this problem, I introduced a new data
structure, Referrer, which simply contains the
section being referred to and the index of the
relocation in that section.  These referrers are
associated with the source containing the
reference that needs to be updated, so now
regardless of which end of the relocation moves,
the relocation will now be updated correctly.

Modified:
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp?rev=153147&r1=153146&r2=153147&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp Tue Mar 20 17:25:39 2012
@@ -210,6 +210,7 @@
 
   // Process the relocations for each section we're loading.
   Relocations.grow(Relocations.size() + SegmentLC->NumSections);
+  Referrers.grow(Referrers.size() + SegmentLC->NumSections);
   for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
     InMemoryStruct<macho::Section> Sect;
     Obj->ReadSection(*SegmentLCI, SectNum, Sect);
@@ -246,10 +247,12 @@
 
         // Store the relocation information. It will get resolved when
         // the section addresses are assigned.
+        uint32_t RelocationIndex = Relocations[SectionID].size();
         Relocations[SectionID].push_back(RelocationEntry(TargetID,
                                                          Offset,
                                                          RE->Word1,
                                                          0 /*Addend*/));
+        Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex));
       } else {
         StringRef SourceName = SymbolNames[SourceNum];
 
@@ -332,6 +335,7 @@
 
   // Process the relocations for each section we're loading.
   Relocations.grow(Relocations.size() + Segment64LC->NumSections);
+  Referrers.grow(Referrers.size() + Segment64LC->NumSections);
   for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
     InMemoryStruct<macho::Section64> Sect;
     Obj->ReadSection64(*SegmentLCI, SectNum, Sect);
@@ -368,10 +372,12 @@
 
         // Store the relocation information. It will get resolved when
         // the section addresses are assigned.
+        uint32_t RelocationIndex = Relocations[SectionID].size();
         Relocations[SectionID].push_back(RelocationEntry(TargetID,
                                                          Offset,
                                                          RE->Word1,
                                                          0 /*Addend*/));
+        Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex));
       } else {
         StringRef SourceName = SymbolNames[SourceNum];
 
@@ -475,7 +481,9 @@
     // relative and move it to the resolved relocation list.
     RelocationEntry Entry = Relocs[i];
     Entry.Addend += Loc->second.second;
+    uint32_t RelocationIndex = Relocations[Loc->second.first].size();
     Relocations[Loc->second.first].push_back(Entry);
+    Referrers[Entry.SectionID].push_back(Referrer(Loc->second.first, RelocationIndex));
   }
   // FIXME: Keep a worklist of the relocations we've added so that we can
   // resolve more selectively later.
@@ -614,6 +622,31 @@
                       Size,
                       RE.Addend);
   }
+  ReferrerList &Refers = Referrers[SectionID];
+  for (unsigned i = 0, e = Refers.size(); i != e; ++i) {
+    Referrer &R = Refers[i];
+    RelocationEntry &RE = Relocations[R.SectionID][R.Index];
+    uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset;
+    uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset;
+    bool isPCRel = (RE.Data >> 24) & 1;
+    unsigned Type = (RE.Data >> 28) & 0xf;
+    unsigned Size = 1 << ((RE.Data >> 25) & 3);
+
+    DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID
+          << " + " << RE.Offset << " (" << format("%p", Target) << ")"
+          << " from Section #" << SectionID << " (" << format("%p", Addr) << ")"
+          << "(" << (isPCRel ? "pcrel" : "absolute")
+          << ", type: " << Type << ", Size: " << Size << ", Addend: "
+          << RE.Addend << ").\n");
+
+    resolveRelocation(Target,
+                      FinalTarget,
+                      Addr,
+                      isPCRel,
+                      Type,
+                      Size,
+                      RE.Addend);
+  }
 }
 
 bool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) {

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h?rev=153147&r1=153146&r2=153147&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h Tue Mar 20 17:25:39 2012
@@ -43,10 +43,26 @@
       : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
   };
   typedef SmallVector<RelocationEntry, 4> RelocationList;
+
+  // For each section, keep a list of referrers in that section that are clients
+  // of relocations in other sections.  Whenever a relocation gets created,
+  // create a corresponding referrer.  Whenever relocations are re-resolved,
+  // re-resolve the referrers' relocations as well.
+  struct Referrer {
+    unsigned    SectionID;  // Section whose RelocationList contains the relocation.
+    uint32_t    Index;      // Index of the RelocatonEntry in that RelocationList.
+
+    Referrer(unsigned id, uint32_t index)
+      : SectionID(id), Index(index) {}
+  };
+  typedef SmallVector<Referrer, 4> ReferrerList;
+
   // Relocations to sections already loaded. Indexed by SectionID which is the
   // source of the address. The target where the address will be writen is
   // SectionID/Offset in the relocation itself.
   IndexedMap<RelocationList> Relocations;
+  // Referrers corresponding to Relocations.
+  IndexedMap<ReferrerList> Referrers;
   // Relocations to symbols that are not yet resolved. Must be external
   // relocations by definition. Indexed by symbol name.
   StringMap<RelocationList> UnresolvedRelocations;





More information about the llvm-commits mailing list