[RuntimeDyld] Make RuntimeDyldImpl::resolveExternalSymbols preserve the
authorLang Hames <lhames@gmail.com>
Wed, 7 May 2014 22:34:08 +0000 (22:34 +0000)
committerLang Hames <lhames@gmail.com>
Wed, 7 May 2014 22:34:08 +0000 (22:34 +0000)
relocation entries it applies.

Prior to this patch, RuntimeDyldImpl::resolveExternalSymbols discarded
relocations for external symbols once they had been applied. This causes issues
if the client calls MCJIT::finalizeLoadedModules more than once, and updates the
location of any symbols in between (e.g. by calling MCJIT::mapSectionAddress).

No test case yet: None of our in-tree memory managers support moving sections
around. I'll have to hack up a dummy memory manager before I can write a unit
test.

Fixes <rdar://problem/16764378>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208257 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp

index 0956761187d6064e1daa9965a004d4dcf67503e1..d415514df0fb66ea5c4bc1c5d121142cfa45280c 100644 (file)
@@ -620,6 +620,8 @@ void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
 }
 
 void RuntimeDyldImpl::resolveExternalSymbols() {
+  StringMap<RelocationList> ProcessedSymbols;
+
   while (!ExternalSymbolRelocations.empty()) {
     StringMap<RelocationList>::iterator i = ExternalSymbolRelocations.begin();
 
@@ -665,8 +667,20 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
       resolveRelocationList(Relocs, Addr);
     }
 
+    ProcessedSymbols[i->first()] = i->second;
     ExternalSymbolRelocations.erase(i);
   }
+
+  // Restore the relocation entries that were consumed in the loop above:
+  //
+  // FIXME: Replace the following loop with:
+  //           std::swap(ProcessedSymbols, ExternalSymbolRelocations)
+  //        once StringMap has copy and move construction.
+  for (StringMap<RelocationList>::iterator I = ProcessedSymbols.begin(),
+                                           E = ProcessedSymbols.end();
+       I != E; ++I) {
+    ExternalSymbolRelocations[I->first()] = I->second;
+  }
 }
 
 //===----------------------------------------------------------------------===//