OLD | NEW |
1 //===-- llvm/MC/ELFObjectWriter.h - ELF File Writer ---------*- C++ -*-===// | 1 //===-- llvm/MC/ELFObjectWriter.h - ELF File Writer ---------*- C++ -*-===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 | 9 |
10 #ifndef LLVM_MC_ELFOBJECTWRITER_H | 10 #ifndef LLVM_MC_ELFOBJECTWRITER_H |
11 #define LLVM_MC_ELFOBJECTWRITER_H | 11 #define LLVM_MC_ELFOBJECTWRITER_H |
12 | 12 |
13 #include "llvm/ADT/Triple.h" | 13 #include "llvm/ADT/Triple.h" |
| 14 #include "llvm/ADT/SmallPtrSet.h" |
| 15 #include "llvm/ADT/StringMap.h" |
| 16 #include "llvm/ADT/DenseMap.h" |
| 17 #include "llvm/ADT/SmallString.h" |
14 #include "llvm/MC/MCObjectWriter.h" | 18 #include "llvm/MC/MCObjectWriter.h" |
15 #include "llvm/Support/raw_ostream.h" | 19 #include "llvm/MC/MCValue.h" |
| 20 #include "llvm/Support/ELF.h" |
16 #include <cassert> | 21 #include <cassert> |
| 22 #include <vector> |
17 | 23 |
18 namespace llvm { | 24 namespace llvm { |
19 class MCAsmFixup; | 25 class MCAsmFixup; |
20 class MCAssembler; | 26 class MCAssembler; |
21 class MCFragment; | 27 class MCFragment; |
22 class MCValue; | 28 class MCValue; |
| 29 class MCSectionData; |
| 30 class MCSymbolData; |
| 31 class MCSymbol; |
| 32 class MCDataFragment; |
| 33 class MCSectionELF; |
23 class raw_ostream; | 34 class raw_ostream; |
24 | 35 |
25 class ELFObjectWriter : public MCObjectWriter { | 36 class ELFObjectWriter : public MCObjectWriter { |
26 void *Impl; | 37 |
27 | 38 |
28 public: | 39 public: |
29 ELFObjectWriter(raw_ostream &OS, bool Is64Bit, Triple::OSType OSType, | 40 ELFObjectWriter(raw_ostream &OS, bool Is64Bit, Triple::OSType OSType, |
30 uint16_t EMachine, bool IsLittleEndian = true, | 41 uint16_t EMachine, bool IsLittleEndian = true, |
31 bool HasRelocationAddend = true); | 42 bool HasRelocationAddend = true); |
32 | 43 |
33 virtual ~ELFObjectWriter(); | 44 virtual ~ELFObjectWriter(); |
34 | 45 |
35 virtual void ExecutePostLayoutBinding(MCAssembler &Asm); | 46 virtual void ExecutePostLayoutBinding(MCAssembler &Asm); |
36 | 47 |
37 virtual void RecordRelocation(const MCAssembler &Asm, | 48 virtual void RecordRelocation(const MCAssembler &Asm, |
38 const MCAsmLayout &Layout, | 49 const MCAsmLayout &Layout, |
39 const MCFragment *Fragment, | 50 const MCFragment *Fragment, |
40 const MCFixup &Fixup, MCValue Target, | 51 const MCFixup &Fixup, MCValue Target, |
41 uint64_t &FixedValue); | 52 uint64_t &FixedValue) { |
| 53 assert(0 && "RecordRelocation is not specific enough"); |
| 54 } |
42 | 55 |
43 virtual bool IsFixupFullyResolved(const MCAssembler &Asm, | 56 virtual bool IsFixupFullyResolved(const MCAssembler &Asm, |
44 const MCValue Target, | 57 const MCValue Target, |
45 bool IsPCRel, | 58 bool IsPCRel, |
46 const MCFragment *DF) const; | 59 const MCFragment *DF) const; |
47 | 60 |
48 virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); | 61 virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); |
| 62 |
| 63 protected: |
| 64 |
| 65 /*static bool isFixupKindX86RIPRel(unsigned Kind) { |
| 66 return Kind == X86::reloc_riprel_4byte || |
| 67 Kind == X86::reloc_riprel_4byte_movq_load; |
| 68 }*/ |
| 69 |
| 70 |
| 71 /// ELFSymbolData - Helper struct for containing some precomputed information |
| 72 /// on symbols. |
| 73 struct ELFSymbolData { |
| 74 MCSymbolData *SymbolData; |
| 75 uint64_t StringIndex; |
| 76 uint32_t SectionIndex; |
| 77 |
| 78 // Support lexicographic sorting. |
| 79 bool operator<(const ELFSymbolData &RHS) const ; |
| 80 }; |
| 81 |
| 82 /// @name Relocation Data |
| 83 /// @{ |
| 84 |
| 85 struct ELFRelocationEntry { |
| 86 // Make these big enough for both 32-bit and 64-bit |
| 87 uint64_t r_offset; |
| 88 int Index; |
| 89 unsigned Type; |
| 90 const MCSymbol *Symbol; |
| 91 uint64_t r_addend; |
| 92 |
| 93 // Support lexicographic sorting. |
| 94 bool operator<(const ELFRelocationEntry &RE) const; |
| 95 }; |
| 96 |
| 97 SmallPtrSet<const MCSymbol *, 16> UsedInReloc; |
| 98 SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; |
| 99 DenseMap<const MCSymbol *, const MCSymbol *> Renames; |
| 100 |
| 101 llvm::DenseMap<const MCSectionData*, |
| 102 std::vector<ELFRelocationEntry> > Relocations; |
| 103 DenseMap<const MCSection*, uint64_t> SectionStringTableIndex; |
| 104 |
| 105 /// @} |
| 106 /// @name Symbol Table Data |
| 107 /// @{ |
| 108 |
| 109 SmallString<256> StringTable; |
| 110 std::vector<ELFSymbolData> LocalSymbolData; |
| 111 std::vector<ELFSymbolData> ExternalSymbolData; |
| 112 std::vector<ELFSymbolData> UndefinedSymbolData; |
| 113 |
| 114 /// @} |
| 115 |
| 116 int NumRegularSections; |
| 117 |
| 118 bool NeedsGOT; |
| 119 |
| 120 bool NeedsSymtabShndx; |
| 121 |
| 122 unsigned Is64Bit : 1; |
| 123 |
| 124 bool HasRelocationAddend; |
| 125 |
| 126 Triple::OSType OSType; |
| 127 |
| 128 uint16_t EMachine; |
| 129 |
| 130 // This holds the symbol table index of the last local symbol. |
| 131 unsigned LastLocalSymbolIndex; |
| 132 // This holds the .strtab section index. |
| 133 unsigned StringTableIndex; |
| 134 // This holds the .symtab section index. |
| 135 unsigned SymbolTableIndex; |
| 136 |
| 137 unsigned ShstrtabIndex; |
| 138 |
| 139 public: |
| 140 |
| 141 /// @name new nonvirtual helpers |
| 142 /// @{ |
| 143 |
| 144 void WriteWord(uint64_t W) { |
| 145 if (Is64Bit) |
| 146 Write64(W); |
| 147 else |
| 148 Write32(W); |
| 149 } |
| 150 |
| 151 void StringLE16(char *buf, uint16_t Value) { |
| 152 buf[0] = char(Value >> 0); |
| 153 buf[1] = char(Value >> 8); |
| 154 } |
| 155 |
| 156 void StringLE32(char *buf, uint32_t Value) { |
| 157 StringLE16(buf, uint16_t(Value >> 0)); |
| 158 StringLE16(buf + 2, uint16_t(Value >> 16)); |
| 159 } |
| 160 |
| 161 void StringLE64(char *buf, uint64_t Value) { |
| 162 StringLE32(buf, uint32_t(Value >> 0)); |
| 163 StringLE32(buf + 4, uint32_t(Value >> 32)); |
| 164 } |
| 165 |
| 166 void StringBE16(char *buf ,uint16_t Value) { |
| 167 buf[0] = char(Value >> 8); |
| 168 buf[1] = char(Value >> 0); |
| 169 } |
| 170 |
| 171 void StringBE32(char *buf, uint32_t Value) { |
| 172 StringBE16(buf, uint16_t(Value >> 16)); |
| 173 StringBE16(buf + 2, uint16_t(Value >> 0)); |
| 174 } |
| 175 |
| 176 void StringBE64(char *buf, uint64_t Value) { |
| 177 StringBE32(buf, uint32_t(Value >> 32)); |
| 178 StringBE32(buf + 4, uint32_t(Value >> 0)); |
| 179 } |
| 180 |
| 181 void String8(MCDataFragment &F, uint8_t Value); |
| 182 |
| 183 void String16(MCDataFragment &F, uint16_t Value); |
| 184 |
| 185 void String32(MCDataFragment &F, uint32_t Value); |
| 186 |
| 187 void String64(MCDataFragment &F, uint64_t Value); |
| 188 |
| 189 /// @} |
| 190 |
| 191 /// @name new virtuals |
| 192 /// @{ |
| 193 virtual void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections); |
| 194 |
| 195 virtual void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *ShndxF, |
| 196 uint64_t name, uint8_t info, |
| 197 uint64_t value, uint64_t size, |
| 198 uint8_t other, uint32_t shndx, |
| 199 bool Reserved); |
| 200 |
| 201 virtual void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF, |
| 202 ELFSymbolData &MSD, |
| 203 const MCAsmLayout &Layout); |
| 204 |
| 205 typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy; |
| 206 virtual void WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *ShndxF, |
| 207 const MCAssembler &Asm, |
| 208 const MCAsmLayout &Layout, |
| 209 const SectionIndexMapTy &SectionIndexMap); |
| 210 |
| 211 virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, |
| 212 const MCSymbol *S); |
| 213 |
| 214 /// ComputeSymbolTable - Compute the symbol table data |
| 215 /// |
| 216 /// \param StringTable [out] - The string table data. |
| 217 /// \param StringIndexMap [out] - Map from symbol names to offsets in the |
| 218 /// string table. |
| 219 virtual void ComputeSymbolTable(MCAssembler &Asm, |
| 220 const SectionIndexMapTy &SectionIndexMap); |
| 221 |
| 222 virtual void ComputeIndexMap(MCAssembler &Asm, |
| 223 SectionIndexMapTy &SectionIndexMap); |
| 224 |
| 225 virtual void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, |
| 226 const MCSectionData &SD); |
| 227 |
| 228 virtual void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout); |
| 229 |
| 230 virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, |
| 231 const SectionIndexMapTy &SectionIndexMap); |
| 232 |
| 233 // Map from a group section to the signature symbol |
| 234 typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy; |
| 235 virtual void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout, |
| 236 GroupMapTy &GroupMap); |
| 237 |
| 238 virtual void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, |
| 239 uint64_t Address, uint64_t Offset, |
| 240 uint64_t Size, uint32_t Link, uint32_t Info, |
| 241 uint64_t Alignment, uint64_t EntrySize); |
| 242 |
| 243 virtual void WriteRelocationsFragment(const MCAssembler &Asm, MCDataFragment *
F, |
| 244 const MCSectionData *SD); |
| 245 |
| 246 virtual void WriteSection(MCAssembler &Asm, |
| 247 const SectionIndexMapTy &SectionIndexMap, |
| 248 uint32_t GroupSymbolIndex, |
| 249 uint64_t Offset, uint64_t Size, uint64_t Alignment, |
| 250 const MCSectionELF &Section); |
| 251 /// @} |
49 }; | 252 }; |
50 | 253 |
| 254 |
| 255 //===- X86ELFObjectWriter -------------------------------------------===// |
| 256 |
| 257 class X86ELFObjectWriter : public ELFObjectWriter { |
| 258 public: |
| 259 X86ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, Triple::OSType _OSType, |
| 260 uint16_t _EMachine, bool _IsLittleEndian = true, |
| 261 bool _HasRelocationAddend = true); |
| 262 |
| 263 virtual ~X86ELFObjectWriter(); |
| 264 virtual void RecordRelocation(const MCAssembler &Asm, |
| 265 const MCAsmLayout &Layout, |
| 266 const MCFragment *Fragment, |
| 267 const MCFixup &Fixup, MCValue Target, |
| 268 uint64_t &FixedValue); |
| 269 }; |
| 270 |
| 271 |
| 272 //===- ARMELFObjectWriter -------------------------------------------===// |
| 273 |
| 274 class ARMELFObjectWriter : public ELFObjectWriter { |
| 275 |
| 276 public: |
| 277 ARMELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, Triple::OSType _OSType, |
| 278 uint16_t _EMachine, bool _IsLittleEndian = true, |
| 279 bool _HasRelocationAddend = true); |
| 280 |
| 281 virtual ~ARMELFObjectWriter(); |
| 282 virtual void RecordRelocation(const MCAssembler &Asm, |
| 283 const MCAsmLayout &Layout, |
| 284 const MCFragment *Fragment, |
| 285 const MCFixup &Fixup, MCValue Target, |
| 286 uint64_t &FixedValue); |
| 287 }; |
| 288 |
51 } // End llvm namespace | 289 } // End llvm namespace |
52 | 290 |
53 #endif | 291 #endif |
OLD | NEW |