X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FMC%2FMCELFObjectWriter.h;h=38cdc7293ba01829a4632c0d3827596a00516a60;hb=645016533d1208d2e7a17d917d64b8b63c4f9939;hp=a5555e38e049f9e29897234776c4a75f35b8d051;hpb=6024c97ffa15766bc0f200ffd309d9e017ae0d4b;p=oota-llvm.git diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index a5555e38e04..38cdc7293ba 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -10,16 +10,137 @@ #ifndef LLVM_MC_MCELFOBJECTWRITER_H #define LLVM_MC_MCELFOBJECTWRITER_H -#include "llvm/MC/MCObjectWriter.h" +#include "llvm/ADT/Triple.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ELF.h" +#include namespace llvm { +class MCAssembler; +class MCFixup; +class MCFragment; +class MCObjectWriter; +class MCSymbol; +class MCValue; + +/// @name Relocation Data +/// @{ + +struct ELFRelocationEntry { + // Make these big enough for both 32-bit and 64-bit + uint64_t r_offset; + int Index; + unsigned Type; + const MCSymbol *Symbol; + uint64_t r_addend; + const MCFixup *Fixup; + + ELFRelocationEntry() + : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {} + + ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType, + const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup) + : r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym), + r_addend(Addend), Fixup(&Fixup) {} + + // Support lexicographic sorting. + bool operator<(const ELFRelocationEntry &RE) const { + return RE.r_offset < r_offset; + } +}; + class MCELFObjectTargetWriter { + const uint8_t OSABI; + const uint16_t EMachine; + const unsigned HasRelocationAddend : 1; + const unsigned Is64Bit : 1; + const unsigned IsN64 : 1; + protected: - MCELFObjectTargetWriter(); + + MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, + uint16_t EMachine_, bool HasRelocationAddend, + bool IsN64=false); public: - virtual ~MCELFObjectTargetWriter(); + static uint8_t getOSABI(Triple::OSType OSType) { + switch (OSType) { + case Triple::FreeBSD: + return ELF::ELFOSABI_FREEBSD; + case Triple::Linux: + return ELF::ELFOSABI_LINUX; + default: + return ELF::ELFOSABI_NONE; + } + } + + virtual ~MCELFObjectTargetWriter() {} + + virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, + bool IsPCRel, bool IsRelocWithSymbol, + int64_t Addend) const = 0; + virtual unsigned getEFlags() const; + 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; + virtual void adjustFixupOffset(const MCFixup &Fixup, + uint64_t &RelocOffset); + + virtual void sortRelocs(const MCAssembler &Asm, + std::vector &Relocs); + + /// @name Accessors + /// @{ + uint8_t getOSABI() const { return OSABI; } + uint16_t getEMachine() const { return EMachine; } + bool hasRelocationAddend() const { return HasRelocationAddend; } + bool is64Bit() const { return Is64Bit; } + bool isN64() const { return IsN64; } + /// @} + + // Instead of changing everyone's API we pack the N64 Type fields + // into the existing 32 bit data unsigned. +#define R_TYPE_SHIFT 0 +#define R_TYPE_MASK 0xffffff00 +#define R_TYPE2_SHIFT 8 +#define R_TYPE2_MASK 0xffff00ff +#define R_TYPE3_SHIFT 16 +#define R_TYPE3_MASK 0xff00ffff +#define R_SSYM_SHIFT 24 +#define R_SSYM_MASK 0x00ffffff + + // N64 relocation type accessors + unsigned getRType(uint32_t Type) const { + return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff); + } + unsigned getRType2(uint32_t Type) const { + return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff); + } + unsigned getRType3(uint32_t Type) const { + return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff); + } + unsigned getRSsym(uint32_t Type) const { + return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff); + } + + // N64 relocation type setting + unsigned setRType(unsigned Value, unsigned Type) const { + return ((Type & R_TYPE_MASK) | ((Value & 0xff) << R_TYPE_SHIFT)); + } + unsigned setRType2(unsigned Value, unsigned Type) const { + return (Type & R_TYPE2_MASK) | ((Value & 0xff) << R_TYPE2_SHIFT); + } + unsigned setRType3(unsigned Value, unsigned Type) const { + return (Type & R_TYPE3_MASK) | ((Value & 0xff) << R_TYPE3_SHIFT); + } + unsigned setRSsym(unsigned Value, unsigned Type) const { + return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT); + } }; /// \brief Construct a new ELF writer instance. @@ -28,10 +149,7 @@ public: /// \param OS - The stream to write to. /// \returns The constructed object writer. MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW, - raw_ostream &OS, bool is64Bit, - Triple::OSType OSType, uint16_t EMachine, - bool IsLittleEndian, - bool HasRelocationAddend); + raw_ostream &OS, bool IsLittleEndian); } // End llvm namespace #endif