diff --git a/llvm/include/llvm/MC/MCELFObjectWriter.h b/llvm/include/llvm/MC/MCELFObjectWriter.h index 59581a62be52..979fcb5d7504 100644 --- a/llvm/include/llvm/MC/MCELFObjectWriter.h +++ b/llvm/include/llvm/MC/MCELFObjectWriter.h @@ -49,6 +49,9 @@ public: const MCFragment &F, const MCFixup &Fixup, bool IsPCRel) const; + virtual void adjustFixupOffset(const MCFixup &Fixup, + uint64_t &RelocOffset); + /// @name Accessors /// @{ diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index d0b3372b5de6..969e2796e51b 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -28,7 +28,6 @@ #include "llvm/ADT/StringSwitch.h" #include "../Target/Mips/MCTargetDesc/MipsFixupKinds.h" -#include "../Target/PowerPC/MCTargetDesc/PPCFixupKinds.h" #include using namespace llvm; @@ -448,7 +447,8 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); - adjustFixupOffset(Fixup, RelocOffset); + // FIXME: no tests cover this. Is adjustFixupOffset dead code? + TargetObjectWriter->adjustFixupOffset(Fixup, RelocOffset); if (!hasRelocationAddend()) Addend = 0; @@ -1259,12 +1259,11 @@ MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, case ELF::EM_386: case ELF::EM_X86_64: case ELF::EM_ARM: + case ELF::EM_PPC: + case ELF::EM_PPC64: return new ELFObjectWriter(MOTW, OS, IsLittleEndian); break; case ELF::EM_MBLAZE: return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break; - case ELF::EM_PPC: - case ELF::EM_PPC64: - return new PPCELFObjectWriter(MOTW, OS, IsLittleEndian); break; case ELF::EM_MIPS: return new MipsELFObjectWriter(MOTW, OS, IsLittleEndian); break; default: llvm_unreachable("Unsupported architecture"); break; @@ -1281,76 +1280,6 @@ unsigned ELFObjectWriter::GetRelocType(const MCValue &Target, } /// START OF SUBCLASSES for ELFObjectWriter -//===- PPCELFObjectWriter -------------------------------------------===// - -PPCELFObjectWriter::PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW, - raw_ostream &_OS, - bool IsLittleEndian) - : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { -} - -PPCELFObjectWriter::~PPCELFObjectWriter() { -} - -unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel, - bool IsRelocWithSymbol, - int64_t Addend) const { - // determine the type of the relocation - unsigned Type; - if (IsPCRel) { - switch ((unsigned)Fixup.getKind()) { - default: - llvm_unreachable("Unimplemented"); - case PPC::fixup_ppc_br24: - Type = ELF::R_PPC_REL24; - break; - case FK_PCRel_4: - Type = ELF::R_PPC_REL32; - break; - } - } else { - switch ((unsigned)Fixup.getKind()) { - default: llvm_unreachable("invalid fixup kind!"); - case PPC::fixup_ppc_br24: - Type = ELF::R_PPC_ADDR24; - break; - case PPC::fixup_ppc_brcond14: - Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_ - break; - case PPC::fixup_ppc_ha16: - Type = ELF::R_PPC_ADDR16_HA; - break; - case PPC::fixup_ppc_lo16: - Type = ELF::R_PPC_ADDR16_LO; - break; - case PPC::fixup_ppc_lo14: - Type = ELF::R_PPC_ADDR14; - break; - case FK_Data_4: - Type = ELF::R_PPC_ADDR32; - break; - case FK_Data_2: - Type = ELF::R_PPC_ADDR16; - break; - } - } - return Type; -} - -void PPCELFObjectWriter:: -adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) { - switch ((unsigned)Fixup.getKind()) { - case PPC::fixup_ppc_ha16: - case PPC::fixup_ppc_lo16: - RelocOffset += 2; - break; - default: - break; - } -} - //===- MBlazeELFObjectWriter -------------------------------------------===// MBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW, diff --git a/llvm/lib/MC/ELFObjectWriter.h b/llvm/lib/MC/ELFObjectWriter.h index 71140f10e808..6516fb587c89 100644 --- a/llvm/lib/MC/ELFObjectWriter.h +++ b/llvm/lib/MC/ELFObjectWriter.h @@ -353,24 +353,6 @@ class ELFObjectWriter : public MCObjectWriter { virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel, bool IsRelocWithSymbol, int64_t Addend) const; - virtual void adjustFixupOffset(const MCFixup &Fixup, - uint64_t &RelocOffset) {} - }; - - //===- PPCELFObjectWriter -------------------------------------------===// - - class PPCELFObjectWriter : public ELFObjectWriter { - public: - PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW, - raw_ostream &_OS, - bool IsLittleEndian); - - virtual ~PPCELFObjectWriter(); - protected: - virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, - bool IsPCRel, bool IsRelocWithSymbol, - int64_t Addend) const; - virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset); }; //===- MBlazeELFObjectWriter -------------------------------------------===// diff --git a/llvm/lib/MC/MCELFObjectTargetWriter.cpp b/llvm/lib/MC/MCELFObjectTargetWriter.cpp index 055f2c21d124..37246d089668 100644 --- a/llvm/lib/MC/MCELFObjectTargetWriter.cpp +++ b/llvm/lib/MC/MCELFObjectTargetWriter.cpp @@ -33,6 +33,10 @@ const MCSymbol *MCELFObjectTargetWriter::ExplicitRelSym(const MCAssembler &Asm, } +void MCELFObjectTargetWriter::adjustFixupOffset(const MCFixup &Fixup, + uint64_t &RelocOffset) { +} + unsigned MCELFObjectTargetWriter::GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel, diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp new file mode 100644 index 000000000000..90f674d0b907 --- /dev/null +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -0,0 +1,103 @@ +//===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/PPCFixupKinds.h" +#include "MCTargetDesc/PPCMCTargetDesc.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +namespace { + class PPCELFObjectWriter : public MCELFObjectTargetWriter { + public: + PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI); + + virtual ~PPCELFObjectWriter(); + protected: + virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, + bool IsPCRel, bool IsRelocWithSymbol, + int64_t Addend) const; + virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset); + }; +} + +PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) + : MCELFObjectTargetWriter(Is64Bit, OSABI, + Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, + /*HasRelocationAddend*/ false) {} + +PPCELFObjectWriter::~PPCELFObjectWriter() { +} + +unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel, + bool IsRelocWithSymbol, + int64_t Addend) const { + // determine the type of the relocation + unsigned Type; + if (IsPCRel) { + switch ((unsigned)Fixup.getKind()) { + default: + llvm_unreachable("Unimplemented"); + case PPC::fixup_ppc_br24: + Type = ELF::R_PPC_REL24; + break; + case FK_PCRel_4: + Type = ELF::R_PPC_REL32; + break; + } + } else { + switch ((unsigned)Fixup.getKind()) { + default: llvm_unreachable("invalid fixup kind!"); + case PPC::fixup_ppc_br24: + Type = ELF::R_PPC_ADDR24; + break; + case PPC::fixup_ppc_brcond14: + Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_ + break; + case PPC::fixup_ppc_ha16: + Type = ELF::R_PPC_ADDR16_HA; + break; + case PPC::fixup_ppc_lo16: + Type = ELF::R_PPC_ADDR16_LO; + break; + case PPC::fixup_ppc_lo14: + Type = ELF::R_PPC_ADDR14; + break; + case FK_Data_4: + Type = ELF::R_PPC_ADDR32; + break; + case FK_Data_2: + Type = ELF::R_PPC_ADDR16; + break; + } + } + return Type; +} + +void PPCELFObjectWriter:: +adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) { + switch ((unsigned)Fixup.getKind()) { + case PPC::fixup_ppc_ha16: + case PPC::fixup_ppc_lo16: + RelocOffset += 2; + break; + default: + break; + } +} + +MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS, + bool Is64Bit, + uint8_t OSABI) { + MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI); + return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true); +} diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h index e5bf2a9dd92f..b7fa0646288d 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h @@ -14,14 +14,18 @@ #ifndef PPCMCTARGETDESC_H #define PPCMCTARGETDESC_H +#include "llvm/Support/DataTypes.h" + namespace llvm { class MCAsmBackend; class MCCodeEmitter; class MCContext; class MCInstrInfo; +class MCObjectWriter; class MCSubtargetInfo; class Target; class StringRef; +class raw_ostream; extern Target ThePPC32Target; extern Target ThePPC64Target; @@ -31,7 +35,11 @@ MCCodeEmitter *createPPCMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx); MCAsmBackend *createPPCAsmBackend(const Target &T, StringRef TT); - + +/// createPPCELFObjectWriter - Construct an PPC ELF object writer. +MCObjectWriter *createPPCELFObjectWriter(raw_ostream &OS, + bool Is64Bit, + uint8_t OSABI); } // End llvm namespace // Defines symbolic names for PowerPC registers. This defines a mapping from