From edc6a1399285a8d81c7cbe3baad441b7bcff9a13 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Mon, 24 Nov 2014 18:09:47 +0000 Subject: [PATCH] [PowerPC] Fix PR 21652 - copy st_other bits on symbol assignment When processing an assignment in the integrated assembler that sets a symbol to the value of another symbol, we need to copy the st_other bits that encode the local entry point offset. Modeled after MipsTargetELFStreamer::emitAssignment handling of the ELF::STO_MIPS_MICROMIPS flag. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222672 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp | 17 +++++++++++++++++ test/MC/PowerPC/ppc64-localentry.s | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp index 00be8f444d3..f2da3896168 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -184,6 +184,23 @@ public: if ((Flags & ELF::EF_PPC64_ABI) == 0) MCA.setELFHeaderEFlags(Flags | 2); } + void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override { + // 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 MCSymbol &RhsSym = + static_cast(Value)->getSymbol(); + MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym); + MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol); + // The "other" values are stored in the last 6 bits of the second byte. + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + unsigned Other = MCELF::getOther(SymbolData) << 2; + Other &= ~ELF::STO_PPC64_LOCAL_MASK; + Other |= (MCELF::getOther(Data) << 2) & ELF::STO_PPC64_LOCAL_MASK; + MCELF::setOther(SymbolData, Other >> 2); + } }; class PPCTargetMachOStreamer : public PPCTargetStreamer { diff --git a/test/MC/PowerPC/ppc64-localentry.s b/test/MC/PowerPC/ppc64-localentry.s index 6d2c1207228..03f760ef86e 100644 --- a/test/MC/PowerPC/ppc64-localentry.s +++ b/test/MC/PowerPC/ppc64-localentry.s @@ -35,6 +35,9 @@ caller_other: nop .size caller_other, .-caller_other +copy1 = callee1 +copy2 = callee2 + # Verify that use of .localentry implies ABI version 2 # CHECK: ElfHeader { # CHECK: Flags [ (0x2) @@ -68,3 +71,19 @@ caller_other: # CHECK-NEXT: Other: 0 # CHECK-NEXT: Section: .text +# Verify that symbol assignment copies the Other bits. +# CHECK: Name: copy1 +# CHECK-NEXT: Value: +# CHECK-NEXT: Size: 16 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 96 +# CHECK-NEXT: Section: .text +# CHECK: Name: copy2 +# CHECK-NEXT: Value: +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text + -- 2.34.1