mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-15 06:29:05 +00:00
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> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115753 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -19,18 +19,16 @@
|
|||||||
#include "llvm/Linker.h"
|
#include "llvm/Linker.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/LLVMContext.h"
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/TypeSymbolTable.h"
|
#include "llvm/TypeSymbolTable.h"
|
||||||
#include "llvm/ValueSymbolTable.h"
|
#include "llvm/ValueSymbolTable.h"
|
||||||
#include "llvm/Instructions.h"
|
|
||||||
#include "llvm/Assembly/Writer.h"
|
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/System/Path.h"
|
#include "llvm/System/Path.h"
|
||||||
#include "llvm/Transforms/Utils/ValueMapper.h"
|
#include "llvm/Transforms/Utils/ValueMapper.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
// Error - Simple wrapper function to conditionally assign to E and return true.
|
// Error - Simple wrapper function to conditionally assign to E and return true.
|
||||||
@@ -456,6 +454,23 @@ static void LinkNamedMDNodes(Module *Dest, Module *Src,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
// LinkGlobals - Loop through the global variables in the src module and merge
|
||||||
// them into the dest module.
|
// them into the dest module.
|
||||||
static bool LinkGlobals(Module *Dest, const Module *Src,
|
static bool LinkGlobals(Module *Dest, const Module *Src,
|
||||||
@@ -470,10 +485,24 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
|
|||||||
const GlobalVariable *SGV = I;
|
const GlobalVariable *SGV = I;
|
||||||
GlobalValue *DGV = 0;
|
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.
|
// function.
|
||||||
if (SGV->hasName() && !SGV->hasLocalLinkage())
|
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
|
// 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.
|
// internal linkage, we are really not doing any linkage here.
|
||||||
@@ -819,10 +848,10 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
|
|||||||
// Grab destination global variable or alias.
|
// Grab destination global variable or alias.
|
||||||
GlobalValue *DGV = cast<GlobalValue>(ValueMap[SGV]->stripPointerCasts());
|
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 (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV)) {
|
||||||
if (DGVar->hasInitializer()) {
|
if (DGVar->hasInitializer()) {
|
||||||
if (SGV->hasExternalLinkage()) {
|
if (SGV->hasExternalLinkage() || RequiresMerge(SGV, DGVar)) {
|
||||||
if (DGVar->getInitializer() != SInit)
|
if (DGVar->getInitializer() != SInit)
|
||||||
return Error(Err, "Global Variable Collision on '" +
|
return Error(Err, "Global Variable Collision on '" +
|
||||||
SGV->getName() +
|
SGV->getName() +
|
||||||
|
Reference in New Issue
Block a user