Index: include/llvm/MC/ELFObjectWriter.h |
=================================================================== |
--- include/llvm/MC/ELFObjectWriter.h (revision 118813) |
+++ include/llvm/MC/ELFObjectWriter.h (working copy) |
@@ -11,20 +11,31 @@ |
#define LLVM_MC_ELFOBJECTWRITER_H |
#include "llvm/ADT/Triple.h" |
+#include "llvm/ADT/SmallPtrSet.h" |
+#include "llvm/ADT/StringMap.h" |
+#include "llvm/ADT/DenseMap.h" |
+#include "llvm/ADT/SmallString.h" |
#include "llvm/MC/MCObjectWriter.h" |
-#include "llvm/Support/raw_ostream.h" |
+#include "llvm/MC/MCValue.h" |
+#include "llvm/Support/ELF.h" |
#include <cassert> |
+#include <vector> |
namespace llvm { |
class MCAsmFixup; |
class MCAssembler; |
class MCFragment; |
class MCValue; |
+class MCSectionData; |
+class MCSymbolData; |
+class MCSymbol; |
+class MCDataFragment; |
+class MCSectionELF; |
class raw_ostream; |
class ELFObjectWriter : public MCObjectWriter { |
- void *Impl; |
+ |
public: |
ELFObjectWriter(raw_ostream &OS, bool Is64Bit, Triple::OSType OSType, |
uint16_t EMachine, bool IsLittleEndian = true, |
@@ -38,7 +49,9 @@ |
const MCAsmLayout &Layout, |
const MCFragment *Fragment, |
const MCFixup &Fixup, MCValue Target, |
- uint64_t &FixedValue); |
+ uint64_t &FixedValue) { |
+ assert(0 && "RecordRelocation is not specific enough"); |
+ } |
virtual bool IsFixupFullyResolved(const MCAssembler &Asm, |
const MCValue Target, |
@@ -46,8 +59,233 @@ |
const MCFragment *DF) const; |
virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); |
+ |
+protected: |
+ |
+ /*static bool isFixupKindX86RIPRel(unsigned Kind) { |
+ return Kind == X86::reloc_riprel_4byte || |
+ Kind == X86::reloc_riprel_4byte_movq_load; |
+ }*/ |
+ |
+ |
+ /// ELFSymbolData - Helper struct for containing some precomputed information |
+ /// on symbols. |
+ struct ELFSymbolData { |
+ MCSymbolData *SymbolData; |
+ uint64_t StringIndex; |
+ uint32_t SectionIndex; |
+ |
+ // Support lexicographic sorting. |
+ bool operator<(const ELFSymbolData &RHS) const ; |
+ }; |
+ |
+ /// @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; |
+ |
+ // Support lexicographic sorting. |
+ bool operator<(const ELFRelocationEntry &RE) const; |
+ }; |
+ |
+ SmallPtrSet<const MCSymbol *, 16> UsedInReloc; |
+ SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; |
+ DenseMap<const MCSymbol *, const MCSymbol *> Renames; |
+ |
+ llvm::DenseMap<const MCSectionData*, |
+ std::vector<ELFRelocationEntry> > Relocations; |
+ DenseMap<const MCSection*, uint64_t> SectionStringTableIndex; |
+ |
+ /// @} |
+ /// @name Symbol Table Data |
+ /// @{ |
+ |
+ SmallString<256> StringTable; |
+ std::vector<ELFSymbolData> LocalSymbolData; |
+ std::vector<ELFSymbolData> ExternalSymbolData; |
+ std::vector<ELFSymbolData> UndefinedSymbolData; |
+ |
+ /// @} |
+ |
+ int NumRegularSections; |
+ |
+ bool NeedsGOT; |
+ |
+ bool NeedsSymtabShndx; |
+ |
+ unsigned Is64Bit : 1; |
+ |
+ bool HasRelocationAddend; |
+ |
+ Triple::OSType OSType; |
+ |
+ uint16_t EMachine; |
+ |
+ // This holds the symbol table index of the last local symbol. |
+ unsigned LastLocalSymbolIndex; |
+ // This holds the .strtab section index. |
+ unsigned StringTableIndex; |
+ // This holds the .symtab section index. |
+ unsigned SymbolTableIndex; |
+ |
+ unsigned ShstrtabIndex; |
+ |
+public: |
+ |
+ /// @name new nonvirtual helpers |
+ /// @{ |
+ |
+ void WriteWord(uint64_t W) { |
+ if (Is64Bit) |
+ Write64(W); |
+ else |
+ Write32(W); |
+ } |
+ |
+ void StringLE16(char *buf, uint16_t Value) { |
+ buf[0] = char(Value >> 0); |
+ buf[1] = char(Value >> 8); |
+ } |
+ |
+ void StringLE32(char *buf, uint32_t Value) { |
+ StringLE16(buf, uint16_t(Value >> 0)); |
+ StringLE16(buf + 2, uint16_t(Value >> 16)); |
+ } |
+ |
+ void StringLE64(char *buf, uint64_t Value) { |
+ StringLE32(buf, uint32_t(Value >> 0)); |
+ StringLE32(buf + 4, uint32_t(Value >> 32)); |
+ } |
+ |
+ void StringBE16(char *buf ,uint16_t Value) { |
+ buf[0] = char(Value >> 8); |
+ buf[1] = char(Value >> 0); |
+ } |
+ |
+ void StringBE32(char *buf, uint32_t Value) { |
+ StringBE16(buf, uint16_t(Value >> 16)); |
+ StringBE16(buf + 2, uint16_t(Value >> 0)); |
+ } |
+ |
+ void StringBE64(char *buf, uint64_t Value) { |
+ StringBE32(buf, uint32_t(Value >> 32)); |
+ StringBE32(buf + 4, uint32_t(Value >> 0)); |
+ } |
+ |
+ void String8(MCDataFragment &F, uint8_t Value); |
+ |
+ void String16(MCDataFragment &F, uint16_t Value); |
+ |
+ void String32(MCDataFragment &F, uint32_t Value); |
+ |
+ void String64(MCDataFragment &F, uint64_t Value); |
+ |
+ /// @} |
+ |
+ /// @name new virtuals |
+ /// @{ |
+ virtual void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections); |
+ |
+ virtual void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *ShndxF, |
+ uint64_t name, uint8_t info, |
+ uint64_t value, uint64_t size, |
+ uint8_t other, uint32_t shndx, |
+ bool Reserved); |
+ |
+ virtual void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF, |
+ ELFSymbolData &MSD, |
+ const MCAsmLayout &Layout); |
+ |
+ typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy; |
+ virtual void WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *ShndxF, |
+ const MCAssembler &Asm, |
+ const MCAsmLayout &Layout, |
+ const SectionIndexMapTy &SectionIndexMap); |
+ |
+ virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, |
+ const MCSymbol *S); |
+ |
+ /// ComputeSymbolTable - Compute the symbol table data |
+ /// |
+ /// \param StringTable [out] - The string table data. |
+ /// \param StringIndexMap [out] - Map from symbol names to offsets in the |
+ /// string table. |
+ virtual void ComputeSymbolTable(MCAssembler &Asm, |
+ const SectionIndexMapTy &SectionIndexMap); |
+ |
+ virtual void ComputeIndexMap(MCAssembler &Asm, |
+ SectionIndexMapTy &SectionIndexMap); |
+ |
+ virtual void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, |
+ const MCSectionData &SD); |
+ |
+ virtual void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout); |
+ |
+ virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, |
+ const SectionIndexMapTy &SectionIndexMap); |
+ |
+ // Map from a group section to the signature symbol |
+ typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy; |
+ virtual void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout, |
+ GroupMapTy &GroupMap); |
+ |
+ virtual void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, |
+ uint64_t Address, uint64_t Offset, |
+ uint64_t Size, uint32_t Link, uint32_t Info, |
+ uint64_t Alignment, uint64_t EntrySize); |
+ |
+ virtual void WriteRelocationsFragment(const MCAssembler &Asm, MCDataFragment *F, |
+ const MCSectionData *SD); |
+ |
+ virtual void WriteSection(MCAssembler &Asm, |
+ const SectionIndexMapTy &SectionIndexMap, |
+ uint32_t GroupSymbolIndex, |
+ uint64_t Offset, uint64_t Size, uint64_t Alignment, |
+ const MCSectionELF &Section); |
+ /// @} |
}; |
+ |
+//===- X86ELFObjectWriter -------------------------------------------===// |
+ |
+class X86ELFObjectWriter : public ELFObjectWriter { |
+public: |
+ X86ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, Triple::OSType _OSType, |
+ uint16_t _EMachine, bool _IsLittleEndian = true, |
+ bool _HasRelocationAddend = true); |
+ |
+ virtual ~X86ELFObjectWriter(); |
+ virtual void RecordRelocation(const MCAssembler &Asm, |
+ const MCAsmLayout &Layout, |
+ const MCFragment *Fragment, |
+ const MCFixup &Fixup, MCValue Target, |
+ uint64_t &FixedValue); |
+}; |
+ |
+ |
+//===- ARMELFObjectWriter -------------------------------------------===// |
+ |
+class ARMELFObjectWriter : public ELFObjectWriter { |
+ |
+public: |
+ ARMELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, Triple::OSType _OSType, |
+ uint16_t _EMachine, bool _IsLittleEndian = true, |
+ bool _HasRelocationAddend = true); |
+ |
+ virtual ~ARMELFObjectWriter(); |
+ virtual void RecordRelocation(const MCAssembler &Asm, |
+ const MCAsmLayout &Layout, |
+ const MCFragment *Fragment, |
+ const MCFixup &Fixup, MCValue Target, |
+ uint64_t &FixedValue); |
+}; |
+ |
} // End llvm namespace |
#endif |