X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FPowerPC%2FMCTargetDesc%2FPPCELFObjectWriter.cpp;h=b817394e52c63d4e35d30709df57581741e10663;hb=180f89537ac8a53025b528540746debde034bf62;hp=b5c5e194fec514eddbd3d36425f08b1270e7711f;hpb=74dcb03fa912a4b3b32eda19eea57b4fa56f5cc7;p=oota-llvm.git diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp index b5c5e194fec..b817394e52c 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" @@ -23,21 +24,12 @@ namespace { public: PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI); - virtual ~PPCELFObjectWriter(); protected: - virtual unsigned getRelocTypeInner(const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const; unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override; - virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, - const MCValue &Target, - const MCFragment &F, - const MCFixup &Fixup, - bool IsPCRel) const; - virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const; + + bool needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const override; }; } @@ -46,14 +38,12 @@ PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, /*HasRelocationAddend*/ true) {} -PPCELFObjectWriter::~PPCELFObjectWriter() { -} - -static MCSymbolRefExpr::VariantKind getAccessVariant(const MCFixup &Fixup) { +static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target, + const MCFixup &Fixup) { const MCExpr *Expr = Fixup.getValue(); if (Expr->getKind() != MCExpr::Target) - return Fixup.getAccessVariant(); + return Target.getAccessVariant(); switch (cast(Expr)->getKind()) { case PPCMCExpr::VK_PPC_None: @@ -76,11 +66,10 @@ static MCSymbolRefExpr::VariantKind getAccessVariant(const MCFixup &Fixup) { llvm_unreachable("unknown PPCMCExpr kind"); } -unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const -{ - MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Fixup); +unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel) const { + MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup); // determine the type of the relocation unsigned Type; @@ -90,7 +79,18 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, llvm_unreachable("Unimplemented"); case PPC::fixup_ppc_br24: case PPC::fixup_ppc_br24abs: - Type = ELF::R_PPC_REL24; + switch (Modifier) { + default: llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_None: + Type = ELF::R_PPC_REL24; + break; + case MCSymbolRefExpr::VK_PLT: + Type = ELF::R_PPC_PLTREL24; + break; + case MCSymbolRefExpr::VK_PPC_LOCAL: + Type = ELF::R_PPC_LOCAL24PC; + break; + } break; case PPC::fixup_ppc_brcond14: case PPC::fixup_ppc_brcond14abs: @@ -231,7 +231,10 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, Type = ELF::R_PPC64_DTPREL16_HIGHESTA; break; case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: - Type = ELF::R_PPC64_GOT_TLSGD16; + if (is64Bit()) + Type = ELF::R_PPC64_GOT_TLSGD16; + else + Type = ELF::R_PPC_GOT_TLSGD16; break; case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: Type = ELF::R_PPC64_GOT_TLSGD16_LO; @@ -243,7 +246,10 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, Type = ELF::R_PPC64_GOT_TLSGD16_HA; break; case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: - Type = ELF::R_PPC64_GOT_TLSLD16; + if (is64Bit()) + Type = ELF::R_PPC64_GOT_TLSLD16; + else + Type = ELF::R_PPC_GOT_TLSLD16; break; case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: Type = ELF::R_PPC64_GOT_TLSLD16_LO; @@ -339,13 +345,22 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); case MCSymbolRefExpr::VK_PPC_TLSGD: - Type = ELF::R_PPC64_TLSGD; + if (is64Bit()) + Type = ELF::R_PPC64_TLSGD; + else + Type = ELF::R_PPC_TLSGD; break; case MCSymbolRefExpr::VK_PPC_TLSLD: - Type = ELF::R_PPC64_TLSLD; + if (is64Bit()) + Type = ELF::R_PPC64_TLSLD; + else + Type = ELF::R_PPC_TLSLD; break; case MCSymbolRefExpr::VK_PPC_TLS: - Type = ELF::R_PPC64_TLS; + if (is64Bit()) + Type = ELF::R_PPC64_TLS; + else + Type = ELF::R_PPC_TLS; break; } break; @@ -380,58 +395,21 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, return Type; } -unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { - return getRelocTypeInner(Target, Fixup, IsPCRel); -} - -const MCSymbol *PPCELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, - const MCValue &Target, - const MCFragment &F, - const MCFixup &Fixup, - bool IsPCRel) const { - assert(Target.getSymA() && "SymA cannot be 0"); - MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant(); - - bool EmitThisSym; - switch (Modifier) { - // GOT references always need a relocation, even if the - // target symbol is local. - case MCSymbolRefExpr::VK_GOT: - case MCSymbolRefExpr::VK_PPC_GOT_LO: - case MCSymbolRefExpr::VK_PPC_GOT_HI: - case MCSymbolRefExpr::VK_PPC_GOT_HA: - EmitThisSym = true; - break; - default: - EmitThisSym = false; - break; - } - - if (EmitThisSym) - return &Target.getSymA()->getSymbol().AliasedSymbol(); - return NULL; -} - -const MCSymbol *PPCELFObjectWriter::undefinedExplicitRelSym(const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { - assert(Target.getSymA() && "SymA cannot be 0"); - const MCSymbol &Symbol = Target.getSymA()->getSymbol().AliasedSymbol(); - - unsigned RelocType = getRelocTypeInner(Target, Fixup, IsPCRel); - - // The .odp creation emits a relocation against the symbol ".TOC." which - // create a R_PPC64_TOC relocation. However the relocation symbol name - // in final object creation should be NULL, since the symbol does not - // really exist, it is just the reference to TOC base for the current - // object file. - bool EmitThisSym = RelocType != ELF::R_PPC64_TOC; +bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD, + unsigned Type) const { + switch (Type) { + default: + return false; - if (EmitThisSym && !Symbol.isTemporary()) - return &Symbol; - return NULL; + case ELF::R_PPC_REL24: + // 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; + } } MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,