/// each global symbol based on its internal resolution of that symbol.
struct SymbolResolution {
SymbolResolution()
- : Prevailing(0), FinalDefinitionInLinkageUnit(0), VisibleToRegularObj(0) {
- }
+ : Prevailing(0), FinalDefinitionInLinkageUnit(0), VisibleToRegularObj(0),
+ LinkerRedefined(0) {}
+
/// The linker has chosen this definition of the symbol.
unsigned Prevailing : 1;
/// The definition of this symbol is visible outside of the LTO unit.
unsigned VisibleToRegularObj : 1;
+
+ /// Linker redefined version of the symbol which appeared in -wrap or -defsym
+ /// linker option.
+ unsigned LinkerRedefined : 1;
};
} // namespace lto
if (Res.Prevailing)
GlobalRes.IRName = Sym.getIRName();
- // Set the partition to external if we know it is used elsewhere, e.g.
- // it is visible to a regular object, is referenced from llvm.compiler_used,
- // or was already recorded as being referenced from a different partition.
- if (Res.VisibleToRegularObj || Sym.isUsed() ||
+ // Set the partition to external if we know it is re-defined by the linker
+ // with -defsym or -wrap options, used elsewhere, e.g. it is visible to a
+ // regular object, is referenced from llvm.compiler_used, or was already
+ // recorded as being referenced from a different partition.
+ if (Res.LinkerRedefined || Res.VisibleToRegularObj || Sym.isUsed() ||
(GlobalRes.Partition != GlobalResolution::Unknown &&
GlobalRes.Partition != Partition)) {
GlobalRes.Partition = GlobalResolution::External;
OS << 'l';
if (Res.VisibleToRegularObj)
OS << 'x';
+ if (Res.LinkerRedefined)
+ OS << 'r';
OS << '\n';
}
OS.flush();
if (Sym.isUndefined())
continue;
Keep.push_back(GV);
+ // For symbols re-defined with linker -wrap and -defsym options,
+ // set the linkage to weak to inhibit IPO. The linkage will be
+ // restored by the linker.
+ if (Res.LinkerRedefined)
+ GV->setLinkage(GlobalValue::WeakAnyLinkage);
+
GlobalValue::LinkageTypes OriginalLinkage = GV->getLinkage();
if (GlobalValue::isLinkOnceLinkage(OriginalLinkage))
GV->setLinkage(GlobalValue::getWeakLinkage(
--- /dev/null
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-lto2 run -o %t1.o %t.o -r %t.o,bar,pr
+; RUN: llvm-readobj -t %t1.o.0 | FileCheck %s
+
+; CHECK: Name: bar
+; CHECK-NEXT: Value:
+; CHECK-NEXT: Size:
+; CHECK-NEXT: Binding: Weak
+; CHECK-NEXT: Type: Function
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @bar() {
+ ret void
+}