LinkFromSrc);
}
-/// getLinkageResult - This analyzes the two global values and determines what
-/// the result will look like in the destination module. In particular, it
-/// computes the resultant linkage type and visibility, computes whether the
-/// global in the source should be copied over to the destination (replacing
-/// the existing one), and computes whether this linkage is an error or not.
+// FIXME: Duplicated from the gold plugin. This should be refactored somewhere.
+static bool isDeclaration(const GlobalValue &V) {
+ if (V.hasAvailableExternallyLinkage())
+ return true;
+
+ if (V.isMaterializable())
+ return false;
+
+ return V.isDeclaration();
+}
+
+/// This analyzes the two global values and determines what the result will look
+/// like in the destination module. In particular, it computes the resultant
+/// linkage type and visibility, computes whether the global in the source
+/// should be copied over to the destination (replacing the existing one), and
+/// computes whether this linkage is an error or not.
bool ModuleLinker::getLinkageResult(GlobalValue *Dest, const GlobalValue *Src,
GlobalValue::LinkageTypes <,
GlobalValue::VisibilityTypes &Vis,
assert(!Src->hasLocalLinkage() &&
"If Src has internal linkage, Dest shouldn't be set!");
- bool SrcIsDeclaration = Src->isDeclaration() && !Src->isMaterializable();
- bool DestIsDeclaration = Dest->isDeclaration();
+ bool SrcIsDeclaration = isDeclaration(*Src);
+ bool DestIsDeclaration = isDeclaration(*Dest);
if (SrcIsDeclaration) {
// If Src is external or if both Src & Dest are external.. Just link the
LinkFromSrc = false;
LT = Dest->getLinkage();
}
- } else if (DestIsDeclaration && !Dest->hasDLLImportStorageClass()) {
+ } else if (DestIsDeclaration) {
// If Dest is external but Src is not:
LinkFromSrc = true;
LT = Src->getLinkage();
} else if (Src->isWeakForLinker()) {
- // At this point we know that Dest has LinkOnce, External*, Weak, Common,
- // or DLL* linkage.
- if (Dest->hasExternalWeakLinkage() ||
- Dest->hasAvailableExternallyLinkage() ||
- (Dest->hasLinkOnceLinkage() &&
- (Src->hasWeakLinkage() || Src->hasCommonLinkage()))) {
+ assert(!Dest->hasExternalWeakLinkage());
+ assert(!Dest->hasAvailableExternallyLinkage());
+ if (Dest->hasLinkOnceLinkage() &&
+ (Src->hasWeakLinkage() || Src->hasCommonLinkage())) {
LinkFromSrc = true;
LT = Src->getLinkage();
} else {
LT = Dest->getLinkage();
}
} else if (Dest->isWeakForLinker()) {
- // At this point we know that Src has External* or DLL* linkage.
- if (Src->hasExternalWeakLinkage()) {
- LinkFromSrc = false;
- LT = Dest->getLinkage();
- } else {
- LinkFromSrc = true;
- LT = GlobalValue::ExternalLinkage;
- }
+ assert(!Src->hasExternalWeakLinkage());
+ LinkFromSrc = true;
+ LT = GlobalValue::ExternalLinkage;
} else {
- assert((Dest->hasExternalLinkage() || Dest->hasExternalWeakLinkage()) &&
- (Src->hasExternalLinkage() || Src->hasExternalWeakLinkage()) &&
+ assert(!Src->hasExternalWeakLinkage());
+ assert(!Dest->hasExternalWeakLinkage());
+ assert(Dest->hasExternalLinkage() && Src->hasExternalLinkage() &&
"Unexpected linkage type!");
return emitError("Linking globals named '" + Src->getName() +
- "': symbol multiply defined!");
+ "': symbol multiply defined!");
}
// Compute the visibility. We follow the rules in the System V Application
void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) {
// Merge the initializer.
- SmallVector<Constant*, 16> Elements;
- getArrayElements(AVI.DstInit, Elements);
+ SmallVector<Constant *, 16> DstElements;
+ getArrayElements(AVI.DstInit, DstElements);
- Constant *SrcInit = MapValue(AVI.SrcInit, ValueMap, RF_None, &TypeMap, &ValMaterializer);
- getArrayElements(SrcInit, Elements);
+ SmallVector<Constant *, 16> SrcElements;
+ getArrayElements(AVI.SrcInit, SrcElements);
ArrayType *NewType = cast<ArrayType>(AVI.NewGV->getType()->getElementType());
- AVI.NewGV->setInitializer(ConstantArray::get(NewType, Elements));
+
+ StringRef Name = AVI.NewGV->getName();
+ bool IsNewStructor =
+ (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") &&
+ cast<StructType>(NewType->getElementType())->getNumElements() == 3;
+
+ for (auto *V : SrcElements) {
+ if (IsNewStructor) {
+ Constant *Key = V->getAggregateElement(2);
+ if (DoNotLinkFromSource.count(Key))
+ continue;
+ }
+ DstElements.push_back(
+ MapValue(V, ValueMap, RF_None, &TypeMap, &ValMaterializer));
+ }
+ if (IsNewStructor) {
+ NewType = ArrayType::get(NewType->getElementType(), DstElements.size());
+ AVI.NewGV->mutateType(PointerType::get(NewType, 0));
+ }
+
+ AVI.NewGV->setInitializer(ConstantArray::get(NewType, DstElements));
}
/// linkGlobalInits - Update the initializers in the Dest module now that all