From 76fcace66e918791d00c898d38fea0b44d972aa0 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Sun, 20 Jul 2014 23:15:06 +0000 Subject: [PATCH] [MC] Pass MCSymbolData to needsRelocateWithSymbol As discussed in a previous checking to support the .localentry directive on PowerPC, we need to inspect the actual target symbol in needsRelocateWithSymbol to make the appropriate decision based on that symbol's st_other bits. Currently, needsRelocateWithSymbol does not get the target symbol. However, it is directly available to its sole caller. This patch therefore simply extends the needsRelocateWithSymbol by a new parameter "const MCSymbolData &SD", passes in the target symbol, and updates all derived implementations. In particular, in the PowerPC implementation, this patch removes the FIXME added by the previous checkin. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213487 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCELFObjectWriter.h | 4 +++- lib/MC/ELFObjectWriter.cpp | 2 +- lib/MC/MCELFObjectTargetWriter.cpp | 3 ++- .../ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 6 ++++-- .../Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 6 ++++-- .../MCTargetDesc/PPCELFObjectWriter.cpp | 18 ++++++++++++------ test/MC/PowerPC/ppc64-localentry.s | 12 ++++++++++++ 7 files changed, 38 insertions(+), 13 deletions(-) diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 127f1624878..421e7a0b2c1 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -22,6 +22,7 @@ class MCFragment; class MCObjectWriter; class MCSectionData; class MCSymbol; +class MCSymbolData; class MCValue; class MCELFObjectTargetWriter { @@ -54,7 +55,8 @@ public: virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const = 0; - virtual bool needsRelocateWithSymbol(unsigned Type) const; + virtual bool needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const; /// @name Accessors /// @{ diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 7fb9fae54a7..5779b27a2c4 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -782,7 +782,7 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, if (Asm.isThumbFunc(&Sym)) return true; - if (TargetObjectWriter->needsRelocateWithSymbol(Type)) + if (TargetObjectWriter->needsRelocateWithSymbol(*SD, Type)) return true; return false; } diff --git a/lib/MC/MCELFObjectTargetWriter.cpp b/lib/MC/MCELFObjectTargetWriter.cpp index 4012c442e4f..84176dc1e90 100644 --- a/lib/MC/MCELFObjectTargetWriter.cpp +++ b/lib/MC/MCELFObjectTargetWriter.cpp @@ -24,6 +24,7 @@ MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_, IsN64(IsN64_){ } -bool MCELFObjectTargetWriter::needsRelocateWithSymbol(unsigned Type) const { +bool MCELFObjectTargetWriter::needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const { return false; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index 1c842633f43..a86601b6bb5 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -37,7 +37,8 @@ namespace { unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(unsigned Type) const override; + bool needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const override; }; } @@ -48,7 +49,8 @@ ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI) ARMELFObjectWriter::~ARMELFObjectWriter() {} -bool ARMELFObjectWriter::needsRelocateWithSymbol(unsigned Type) const { +bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const { // FIXME: This is extremelly conservative. This really needs to use a // whitelist with a clear explanation for why each realocation needs to // point to the symbol, not to the section. diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 49ac25690b9..4ea7846f83f 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -30,7 +30,8 @@ namespace { unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(unsigned Type) const override; + bool needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const override; }; } @@ -216,7 +217,8 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, } bool -MipsELFObjectWriter::needsRelocateWithSymbol(unsigned Type) const { +MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const { // FIXME: This is extremelly conservative. This really needs to use a // whitelist with a clear explanation for why each realocation needs to // point to the symbol, not to the section. diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp index a6fd3dd45fa..e93e95fc075 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -11,6 +11,7 @@ #include "MCTargetDesc/PPCFixupKinds.h" #include "MCTargetDesc/PPCMCExpr.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/MC/MCELF.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCValue.h" @@ -31,7 +32,8 @@ namespace { unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - bool needsRelocateWithSymbol(unsigned Type) const override; + bool needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const override; }; } @@ -389,16 +391,20 @@ unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, return getRelocTypeInner(Target, Fixup, IsPCRel); } -bool PPCELFObjectWriter::needsRelocateWithSymbol(unsigned Type) const { +bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const { switch (Type) { default: return false; case ELF::R_PPC_REL24: - // FIXME: We only need to keep the target symbol of the relocation - // if the symbol uses a local entry point. Unfortunately, we do not - // have access to the symbol here ... - return true; + // If the target symbol has a local entry point, we must keep the + // target symbol to preserve that information for the linker. + // 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(SD) << 2; + return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0; } } diff --git a/test/MC/PowerPC/ppc64-localentry.s b/test/MC/PowerPC/ppc64-localentry.s index f30b192d5e2..6d2c1207228 100644 --- a/test/MC/PowerPC/ppc64-localentry.s +++ b/test/MC/PowerPC/ppc64-localentry.s @@ -27,6 +27,14 @@ caller: nop .size caller, .-caller + .section .text.other +caller_other: + bl callee1 + nop + bl callee2 + nop + .size caller_other, .-caller_other + # Verify that use of .localentry implies ABI version 2 # CHECK: ElfHeader { # CHECK: Flags [ (0x2) @@ -38,6 +46,10 @@ caller: # CHECK-NEXT: R_PPC64_REL24 callee1 # CHECK-NEXT: } # CHECK-NOT: R_PPC64_REL24 callee2 +# CHECK: Section ({{[0-9]*}}) .rela.text.other { +# CHECK-NEXT: R_PPC64_REL24 callee1 +# CHECK-NEXT: R_PPC64_REL24 .text +# CHECK-NEXT: } # Verify that .localentry is encoded in the Other field. # CHECK: Symbols [