-namespace {
-
- class ELFObjectWriterImpl {
- /*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 {
- if (GetType(*SymbolData) == ELF::STT_FILE)
- return true;
- if (GetType(*RHS.SymbolData) == ELF::STT_FILE)
- return false;
- return SymbolData->getSymbol().getName() <
- RHS.SymbolData->getSymbol().getName();
- }
- };
-
- /// @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 {
- return RE.r_offset < r_offset;
- }
- };
-
- SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
- 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;
-
- ELFObjectWriter *Writer;
-
- raw_ostream &OS;
-
- 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;
-
- unsigned ShstrtabIndex;
-
- public:
- ELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _Is64Bit,
- uint16_t _EMachine, bool _HasRelAddend,
- Triple::OSType _OSType)
- : NeedsGOT(false), Writer(_Writer), OS(Writer->getStream()),
- Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelAddend),
- OSType(_OSType), EMachine(_EMachine) {
- }
-
- void Write8(uint8_t Value) { Writer->Write8(Value); }
- void Write16(uint16_t Value) { Writer->Write16(Value); }
- void Write32(uint32_t Value) { Writer->Write32(Value); }
- //void Write64(uint64_t Value) { Writer->Write64(Value); }
- void WriteZeros(unsigned N) { Writer->WriteZeros(N); }
- //void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
- // Writer->WriteBytes(Str, ZeroFillSize);
- //}
-
- void WriteWord(uint64_t W) {
- if (Is64Bit)
- Writer->Write64(W);
- else
- Writer->Write32(W);
- }
-
- void String8(char *buf, uint8_t Value) {
- buf[0] = Value;
- }
-
- 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 String16(char *buf, uint16_t Value) {
- if (Writer->isLittleEndian())
- StringLE16(buf, Value);
- else
- StringBE16(buf, Value);
- }
-
- void String32(char *buf, uint32_t Value) {
- if (Writer->isLittleEndian())
- StringLE32(buf, Value);
- else
- StringBE32(buf, Value);
- }
-
- void String64(char *buf, uint64_t Value) {
- if (Writer->isLittleEndian())
- StringLE64(buf, Value);
- else
- StringBE64(buf, Value);
- }
-
- void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections);
-
- void WriteSymbolEntry(MCDataFragment *F, uint64_t name, uint8_t info,
- uint64_t value, uint64_t size,
- uint8_t other, uint16_t shndx);
-
- void WriteSymbol(MCDataFragment *F, ELFSymbolData &MSD,
- const MCAsmLayout &Layout);
-
- void WriteSymbolTable(MCDataFragment *F, const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- unsigned NumRegularSections);
-
- void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
- const MCFragment *Fragment, const MCFixup &Fixup,
- MCValue Target, uint64_t &FixedValue);
-
- 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.
- void ComputeSymbolTable(MCAssembler &Asm);
-
- void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout,
- const MCSectionData &SD);
-
- void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) {
- for (MCAssembler::const_iterator it = Asm.begin(),
- ie = Asm.end(); it != ie; ++it) {
- WriteRelocation(Asm, Layout, *it);
- }
- }
-
- void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout);
-
- void ExecutePostLayoutBinding(MCAssembler &Asm);
-
- 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);
-
- void WriteRelocationsFragment(const MCAssembler &Asm, MCDataFragment *F,
- const MCSectionData *SD);
-
- bool IsFixupFullyResolved(const MCAssembler &Asm,
- const MCValue Target,
- bool IsPCRel,
- const MCFragment *DF) const;
-
- void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
- };
-
-}