llvm.org GIT mirror llvm / 758e1f3
Merging r361237: ------------------------------------------------------------------------ r361237 | maskray | 2019-05-21 03:41:25 -0700 (Tue, 21 May 2019) | 14 lines [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 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_80@362671 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 2 months ago
3 changed file(s) with 58 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
1414 #include "InstPrinter/PPCInstPrinter.h"
1515 #include "MCTargetDesc/PPCMCAsmInfo.h"
1616 #include "PPCTargetStreamer.h"
17 #include "llvm/ADT/SmallPtrSet.h"
1718 #include "llvm/ADT/StringRef.h"
1819 #include "llvm/ADT/Triple.h"
1920 #include "llvm/BinaryFormat/ELF.h"
181182
182183 void emitAssignment(MCSymbol *S, const MCExpr *Value) override {
183184 auto *Symbol = cast(S);
185
184186 // When encoding an assignment to set symbol A to symbol B, also copy
185187 // the st_other bits encoding the local entry point offset.
186 if (Value->getKind() != MCExpr::SymbolRef)
187 return;
188 const auto &RhsSym = cast(
189 static_cast(Value)->getSymbol());
190 unsigned Other = Symbol->getOther();
188 if (copyLocalEntry(Symbol, Value))
189 UpdateOther.insert(Symbol);
190 else
191 UpdateOther.erase(Symbol);
192 }
193
194 void finish() override {
195 for (auto *Sym : UpdateOther)
196 copyLocalEntry(Sym, Sym->getVariableValue());
197 }
198
199 private:
200 SmallPtrSet UpdateOther;
201
202 bool copyLocalEntry(MCSymbolELF *D, const MCExpr *S) {
203 auto *Ref = dyn_cast(S);
204 if (!Ref)
205 return false;
206 const auto &RhsSym = cast(Ref->getSymbol());
207 unsigned Other = D->getOther();
191208 Other &= ~ELF::STO_PPC64_LOCAL_MASK;
192209 Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK;
193 Symbol->setOther(Other);
210 D->setOther(Other);
211 return true;
194212 }
195213 };
196214
0 # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd13.0 %s -o %t
1 # RUN: llvm-objdump -t %t | FileCheck %s
2
3 # CHECK: 0000000000000000 gw F .text 00000000 0x60 __impl_foo
4 # CHECK: 0000000000000000 g F .text 00000000 0x60 foo
5 # CHECK: 0000000000000000 gw F .text 00000000 0x60 foo@FBSD_1.1
6 # CHECK: 0000000000000008 g F .text 00000000 0x60 func
7 # CHECK: 0000000000000008 gw F .text 00000000 0x60 weak_func
8
9 .text
10 .abiversion 2
11
12 .globl foo
13 .type foo,@function
14 foo:
15 nop
16 nop
17 .localentry foo, 8
18
19 .symver __impl_foo, foo@FBSD_1.1
20 .weak __impl_foo
21 .set __impl_foo, foo
22
23 .globl func
24 # Mimick FreeBSD weak function/reference
25 .weak weak_func
26 .equ weak_func, func
27
28 .p2align 2
29 .type func,@function
30 func:
31 nop
32 nop
33 .localentry func, 8
+0
-17
test/MC/PowerPC/ppc64-localentry-symver.s less more
None # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd13.0 %s -o %t
1 # RUN: llvm-objdump -t %t | FileCheck %s
2
3 # CHECK: 0000000000000000 gw F .text 00000000 0x60 __impl_foo
4 # CHECK: 0000000000000000 g F .text 00000000 0x60 foo
5 # CHECK: 0000000000000000 gw F .text 00000000 0x60 foo@FBSD_1.1
6
7 .globl foo
8 .type foo,@function
9 foo:
10 nop
11 nop
12 .localentry foo, 8
13
14 .symver __impl_foo, foo@FBSD_1.1
15 .weak __impl_foo
16 .set __impl_foo, foo