[llvm-commits] [llvm] r115753 - /llvm/trunk/lib/Linker/LinkModules.cpp

Bill Wendling isanbard at gmail.com
Tue Oct 5 23:16:30 PDT 2010


Author: void
Date: Wed Oct  6 01:16:30 2010
New Revision: 115753

URL: http://llvm.org/viewvc/llvm-project?rev=115753&view=rev
Log:
If the destination module all ready has a copy of the global coming from the
source module *and* it must be merged (instead of simply replaced or appended
to), then merge instead of replacing or adding another global.

The ObjC __image_info section was being appended to because of this
failure. This caused a crash because the linker expects the image info section
to be a specific size.

<rdar://problem/8198537>

Modified:
    llvm/trunk/lib/Linker/LinkModules.cpp

Modified: llvm/trunk/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=115753&r1=115752&r2=115753&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)
+++ llvm/trunk/lib/Linker/LinkModules.cpp Wed Oct  6 01:16:30 2010
@@ -19,18 +19,16 @@
 #include "llvm/Linker.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
 #include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/TypeSymbolTable.h"
 #include "llvm/ValueSymbolTable.h"
-#include "llvm/Instructions.h"
-#include "llvm/Assembly/Writer.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Path.h"
 #include "llvm/Transforms/Utils/ValueMapper.h"
-#include "llvm/ADT/DenseMap.h"
 using namespace llvm;
 
 // Error - Simple wrapper function to conditionally assign to E and return true.
@@ -456,6 +454,23 @@
   }
 }
 
+// RequiresMerge - Return true if the source global variable needs to be merged
+// with the destination global variable. I.e., there shouldn't be a new global
+// variable created in the destination Module, rather the initializers should be
+// merged in an intelligent fashion.
+static bool RequiresMerge(const GlobalVariable *SGV, const GlobalVariable *DGV){
+  const StringRef SrcSec(SGV->getSection());
+  const StringRef DstSec(DGV->getSection());
+
+  // The Objective-C __image_info section should be unique.
+  if (SrcSec == DstSec &&
+      (SrcSec.find("__objc_imageinfo") != StringRef::npos ||
+       SrcSec.find("__image_info") != StringRef::npos))
+    return true;
+
+  return false;
+}
+
 // LinkGlobals - Loop through the global variables in the src module and merge
 // them into the dest module.
 static bool LinkGlobals(Module *Dest, const Module *Src,
@@ -470,10 +485,24 @@
     const GlobalVariable *SGV = I;
     GlobalValue *DGV = 0;
 
-    // Check to see if may have to link the global with the global, alias or
+    GlobalValue *SymTabGV =
+      cast_or_null<GlobalValue>(DestSymTab.lookup(SGV->getName()));
+
+    // Check to see if the symbol exists in the destination module and needs to
+    // be merged instead of replaced.
+    if (SymTabGV) {
+      const GlobalVariable *GV = dyn_cast<GlobalVariable>(SymTabGV);
+      if (GV && RequiresMerge(SGV, GV)) {
+        // Make sure to remember this mapping.
+        ValueMap[SGV] = SymTabGV;
+        continue;
+      }
+    }
+
+    // Check to see if we may have to link the global with a global, alias, or
     // function.
     if (SGV->hasName() && !SGV->hasLocalLinkage())
-      DGV = cast_or_null<GlobalValue>(DestSymTab.lookup(SGV->getName()));
+      DGV = SymTabGV;
 
     // If we found a global with the same name in the dest module, but it has
     // internal linkage, we are really not doing any linkage here.
@@ -819,10 +848,10 @@
       // Grab destination global variable or alias.
       GlobalValue *DGV = cast<GlobalValue>(ValueMap[SGV]->stripPointerCasts());
 
-      // If dest if global variable, check that initializers match.
+      // If dest is a global variable, check that initializers match.
       if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV)) {
         if (DGVar->hasInitializer()) {
-          if (SGV->hasExternalLinkage()) {
+          if (SGV->hasExternalLinkage() || RequiresMerge(SGV, DGVar)) {
             if (DGVar->getInitializer() != SInit)
               return Error(Err, "Global Variable Collision on '" +
                            SGV->getName() +





More information about the llvm-commits mailing list