diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp | 30 | ||||
| -rw-r--r-- | llvm/test/MC/PowerPC/ppc64-localentry-symbols.s (renamed from llvm/test/MC/PowerPC/ppc64-localentry-symver.s) | 17 |
2 files changed, 41 insertions, 6 deletions
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp index 831cf2b1913..395b4236fa8 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -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; } }; diff --git a/llvm/test/MC/PowerPC/ppc64-localentry-symver.s b/llvm/test/MC/PowerPC/ppc64-localentry-symbols.s index 4c7490646db..f1d5c5d0ab1 100644 --- a/llvm/test/MC/PowerPC/ppc64-localentry-symver.s +++ b/llvm/test/MC/PowerPC/ppc64-localentry-symbols.s @@ -4,6 +4,11 @@ # 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@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,@function @@ -15,3 +20,15 @@ foo: .symver __impl_foo, foo@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,@function +func: + nop + nop + .localentry func, 8 |

