[PATCH] D153839: [XCOFF] Force recording a relocation for weak symbol label.
Esme Yi via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 27 00:33:56 PDT 2023
Esme created this revision.
Esme added reviewers: shchenz, hubert.reinterpretcast, anhtuyen, DiggerLin, w2yehia, stephenpeckham, PowerPC.
Herald added subscribers: kbarton, hiraditya, nemanjai.
Herald added a project: All.
Esme requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Currently, if there are multiple definitions of the same symbol declared has weak linkage, the linker may choose the wrong one when they are compiled with integrated-as.
For example
> cat t1.c
__attribute__((weak))
__attribute__((noinline))
int foo() { return 3; }
int main() { return foo(); }
> cat t2.c
__attribute__((weak))
int foo() { return 1; }
> ~/Source/install.opt/bin/ibm-clang t2.c t1.c -fintegrated-as && ./a.out; echo $?
3
> ~/Source/install.opt/bin/ibm-clang t2.c t1.c -fno-integrated-as && ./a.out; echo $?
1
This patch fixes the issue.
If the target symbol is a weak label we must not attempt to resolve the fixup directly. Emit a relocation and leave resolution of the final target address to the linker.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D153839
Files:
llvm/lib/MC/XCOFFObjectWriter.cpp
llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
llvm/test/CodeGen/PowerPC/aix-weak-reloc.ll
Index: llvm/test/CodeGen/PowerPC/aix-weak-reloc.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-weak-reloc.ll
@@ -0,0 +1,47 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj -o %t.o < %s
+; RUN: llvm-objdump -dr %t.o | FileCheck --check-prefix=OBJ32 %s
+
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj -o %t.o < %s
+; RUN: llvm-objdump -dr %t.o | FileCheck --check-prefix=OBJ64 %s
+
+; Function Attrs: noinline nounwind optnone
+define i32 @main() {
+entry:
+ %retval = alloca i32, align 4
+ store i32 0, ptr %retval, align 4
+ %call = call i32 @foo()
+ ret i32 %call
+}
+
+; Function Attrs: noinline nounwind optnone
+define weak i32 @foo() {
+entry:
+ ret i32 3
+}
+
+; OBJ32: 00000000 <.main>:
+; OBJ32-NEXT: 0: 7c 08 02 a6 mflr 0
+; OBJ32-NEXT: 4: 94 21 ff c0 stwu 1, -64(1)
+; OBJ32-NEXT: 8: 38 60 00 00 li 3, 0
+; OBJ32-NEXT: c: 90 01 00 48 stw 0, 72(1)
+; OBJ32-NEXT: 10: 90 61 00 3c stw 3, 60(1)
+; OBJ32-NEXT: 14: 48 00 00 31 bl 0x44 <.foo>
+; OBJ32-NEXT: 00000014: R_RBR .foo
+; OBJ32-NEXT: 18: 60 00 00 00 nop
+; OBJ32: 00000044 <.foo>:
+; OBJ32-NEXT: 44: 38 60 00 03 li 3, 3
+; OBJ32-NEXT: 48: 4e 80 00 20 blr
+
+; OBJ64: 0000000000000000 <.main>:
+; OBJ64-NEXT: 0: 7c 08 02 a6 mflr 0
+; OBJ64-NEXT: 4: f8 21 ff 81 stdu 1, -128(1)
+; OBJ64-NEXT: 8: 38 60 00 00 li 3, 0
+; OBJ64-NEXT: c: f8 01 00 90 std 0, 144(1)
+; OBJ64-NEXT: 10: 90 61 00 7c stw 3, 124(1)
+; OBJ64-NEXT: 14: 48 00 00 31 bl 0x44 <.foo>
+; OBJ64-NEXT: 0000000000000014: R_RBR .foo
+; OBJ64-NEXT: 18: 60 00 00 00 nop
+; OBJ64: 0000000000000044 <.foo>:
+; OBJ64-NEXT: 44: 38 60 00 03 li 3, 3
+; OBJ64-NEXT: 48: 4e 80 00 20 blr
+
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
@@ -19,6 +19,7 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbolELF.h"
+#include "llvm/MC/MCSymbolXCOFF.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
@@ -178,7 +179,10 @@
unsigned Other = S->getOther() << 2;
if ((Other & ELF::STO_PPC64_LOCAL_MASK) != 0)
return true;
- }
+ } else if (const auto *S = dyn_cast<MCSymbolXCOFF>(&A->getSymbol())) {
+ return !Target.isAbsolute() && S->isExternal() &&
+ S->getStorageClass() == XCOFF::C_WEAKEXT;
+ }
}
return false;
}
Index: llvm/lib/MC/XCOFFObjectWriter.cpp
===================================================================
--- llvm/lib/MC/XCOFFObjectWriter.cpp
+++ llvm/lib/MC/XCOFFObjectWriter.cpp
@@ -730,10 +730,10 @@
// address, fragment offset and Fixup offset.
uint64_t BRInstrAddress =
SectionMap[ParentSec]->Address + FixupOffsetInCsect;
- // The FixedValue should be the difference between SymA csect address and BR
- // instr address plus any constant value.
- FixedValue =
- SectionMap[SymASec]->Address - BRInstrAddress + Target.getConstant();
+ // The FixedValue should be the difference between symbol's virtual address
+ // and BR instr address plus any constant value.
+ FixedValue = getVirtualAddress(SymA, SymASec) - BRInstrAddress +
+ Target.getConstant();
} else if (Type == XCOFF::RelocationType::R_REF) {
// The FixedValue and FixupOffsetInCsect should always be 0 since it
// specifies a nonrelocating reference.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D153839.534853.patch
Type: text/x-patch
Size: 3820 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230627/8a86349b/attachment.bin>
More information about the llvm-commits
mailing list