[llvm] r361237 - [PPC64] Update LocalEntry from assigned symbols
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue May 21 03:41:25 PDT 2019
Author: maskray
Date: Tue May 21 03:41:25 2019
New Revision: 361237
URL: http://llvm.org/viewvc/llvm-project?rev=361237&view=rev
Log:
[PPC64] Update LocalEntry from assigned symbols
On PowerPC64 ELFv2 ABI, functions may have 2 entry points: global and local.
The local entry point location of a function is stored in the st_other field of the symbol, as an offset relative to the global entry point.
In order to make symbol assignments (e.g. .equ/.set) work properly with this, PPCTargetELFStreamer already copies the local entry bits from the source symbol to the destination one, on emitAssignment(). The problem is that this copy is performed only at the assignment location, where the source symbol may not yet have processed the .localentry directive, that sets the local entry. This may cause the destination symbol to end up with wrong local entry information. Other symbol info is not affected by this because, in this case, the destination symbol value is actually a symbol reference.
This change keeps track of these assignments, and update all needed st_other fields when finish() is called.
Patch by Leandro Lupori!
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D56586
Added:
llvm/trunk/test/MC/PowerPC/ppc64-localentry-symbols.s
Removed:
llvm/trunk/test/MC/PowerPC/ppc64-localentry-symver.s
Modified:
llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp?rev=361237&r1=361236&r2=361237&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp Tue May 21 03:41:25 2019
@@ -15,6 +15,7 @@
#include "MCTargetDesc/PPCMCAsmInfo.h"
#include "PPCTargetStreamer.h"
#include "TargetInfo/PowerPCTargetInfo.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/BinaryFormat/ELF.h"
@@ -182,16 +183,33 @@ public:
void emitAssignment(MCSymbol *S, const MCExpr *Value) override {
auto *Symbol = cast<MCSymbolELF>(S);
+
// When encoding an assignment to set symbol A to symbol B, also copy
// the st_other bits encoding the local entry point offset.
- if (Value->getKind() != MCExpr::SymbolRef)
- return;
- const auto &RhsSym = cast<MCSymbolELF>(
- static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
- unsigned Other = Symbol->getOther();
+ if (copyLocalEntry(Symbol, Value))
+ UpdateOther.insert(Symbol);
+ else
+ UpdateOther.erase(Symbol);
+ }
+
+ void finish() override {
+ for (auto *Sym : UpdateOther)
+ copyLocalEntry(Sym, Sym->getVariableValue());
+ }
+
+private:
+ SmallPtrSet<MCSymbolELF *, 32> UpdateOther;
+
+ bool copyLocalEntry(MCSymbolELF *D, const MCExpr *S) {
+ auto *Ref = dyn_cast<const MCSymbolRefExpr>(S);
+ if (!Ref)
+ return false;
+ const auto &RhsSym = cast<MCSymbolELF>(Ref->getSymbol());
+ unsigned Other = D->getOther();
Other &= ~ELF::STO_PPC64_LOCAL_MASK;
Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK;
- Symbol->setOther(Other);
+ D->setOther(Other);
+ return true;
}
};
Added: llvm/trunk/test/MC/PowerPC/ppc64-localentry-symbols.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/ppc64-localentry-symbols.s?rev=361237&view=auto
==============================================================================
--- llvm/trunk/test/MC/PowerPC/ppc64-localentry-symbols.s (added)
+++ llvm/trunk/test/MC/PowerPC/ppc64-localentry-symbols.s Tue May 21 03:41:25 2019
@@ -0,0 +1,34 @@
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd13.0 %s -o %t
+# RUN: llvm-objdump -t %t | FileCheck %s
+
+# CHECK: 0000000000000000 gw F .text 00000000 0x60 __impl_foo
+# CHECK: 0000000000000000 g F .text 00000000 0x60 foo
+# CHECK: 0000000000000000 gw F .text 00000000 0x60 foo at FBSD_1.1
+# CHECK: 0000000000000008 g F .text 00000000 0x60 func
+# CHECK: 0000000000000008 gw F .text 00000000 0x60 weak_func
+
+.text
+.abiversion 2
+
+.globl foo
+.type foo, at function
+foo:
+ nop
+ nop
+ .localentry foo, 8
+
+.symver __impl_foo, foo at FBSD_1.1
+.weak __impl_foo
+.set __impl_foo, foo
+
+.globl func
+# Mimick FreeBSD weak function/reference
+.weak weak_func
+.equ weak_func, func
+
+.p2align 2
+.type func, at function
+func:
+ nop
+ nop
+ .localentry func, 8
Removed: llvm/trunk/test/MC/PowerPC/ppc64-localentry-symver.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/ppc64-localentry-symver.s?rev=361236&view=auto
==============================================================================
--- llvm/trunk/test/MC/PowerPC/ppc64-localentry-symver.s (original)
+++ llvm/trunk/test/MC/PowerPC/ppc64-localentry-symver.s (removed)
@@ -1,17 +0,0 @@
-# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd13.0 %s -o %t
-# RUN: llvm-objdump -t %t | FileCheck %s
-
-# CHECK: 0000000000000000 gw F .text 00000000 0x60 __impl_foo
-# CHECK: 0000000000000000 g F .text 00000000 0x60 foo
-# CHECK: 0000000000000000 gw F .text 00000000 0x60 foo at FBSD_1.1
-
-.globl foo
-.type foo, at function
-foo:
- nop
- nop
- .localentry foo, 8
-
-.symver __impl_foo, foo at FBSD_1.1
-.weak __impl_foo
-.set __impl_foo, foo
More information about the llvm-commits
mailing list