OLD | NEW |
1 //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===// | 1 //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===// |
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 // This file implements ELF object file writer information. | 10 // This file implements ELF object file writer information. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 case MCSymbolRefExpr::VK_INDNTPOFF: | 91 case MCSymbolRefExpr::VK_INDNTPOFF: |
92 case MCSymbolRefExpr::VK_NTPOFF: | 92 case MCSymbolRefExpr::VK_NTPOFF: |
93 case MCSymbolRefExpr::VK_GOTNTPOFF: | 93 case MCSymbolRefExpr::VK_GOTNTPOFF: |
94 case MCSymbolRefExpr::VK_TLSLDM: | 94 case MCSymbolRefExpr::VK_TLSLDM: |
95 case MCSymbolRefExpr::VK_DTPOFF: | 95 case MCSymbolRefExpr::VK_DTPOFF: |
96 case MCSymbolRefExpr::VK_TLSLD: | 96 case MCSymbolRefExpr::VK_TLSLD: |
97 return true; | 97 return true; |
98 } | 98 } |
99 } | 99 } |
100 | 100 |
101 namespace { | 101 //===- ELFObjectWriter -------------------===// |
| 102 ELFObjectWriter::~ELFObjectWriter() |
| 103 {} |
102 | 104 |
103 class ELFObjectWriterImpl { | 105 void ELFObjectWriter::String8(MCDataFragment &F, uint8_t Value) { |
104 /*static bool isFixupKindX86RIPRel(unsigned Kind) { | 106 char buf[1]; |
105 return Kind == X86::reloc_riprel_4byte || | 107 buf[0] = Value; |
106 Kind == X86::reloc_riprel_4byte_movq_load; | 108 F.getContents() += StringRef(buf, 1); |
107 }*/ | 109 } |
| 110 |
| 111 void ELFObjectWriter::String16(MCDataFragment &F, uint16_t Value) { |
| 112 char buf[2]; |
| 113 if (isLittleEndian()) |
| 114 StringLE16(buf, Value); |
| 115 else |
| 116 StringBE16(buf, Value); |
| 117 F.getContents() += StringRef(buf, 2); |
| 118 } |
| 119 |
| 120 void ELFObjectWriter::String32(MCDataFragment &F, uint32_t Value) { |
| 121 char buf[4]; |
| 122 if (isLittleEndian()) |
| 123 StringLE32(buf, Value); |
| 124 else |
| 125 StringBE32(buf, Value); |
| 126 F.getContents() += StringRef(buf, 4); |
| 127 } |
| 128 |
| 129 void ELFObjectWriter::String64(MCDataFragment &F, uint64_t Value) { |
| 130 char buf[8]; |
| 131 if (isLittleEndian()) |
| 132 StringLE64(buf, Value); |
| 133 else |
| 134 StringBE64(buf, Value); |
| 135 F.getContents() += StringRef(buf, 8); |
| 136 } |
108 | 137 |
109 | 138 |
110 /// ELFSymbolData - Helper struct for containing some precomputed informatio
n | |
111 /// on symbols. | |
112 struct ELFSymbolData { | |
113 MCSymbolData *SymbolData; | |
114 uint64_t StringIndex; | |
115 uint32_t SectionIndex; | |
116 | |
117 // Support lexicographic sorting. | |
118 bool operator<(const ELFSymbolData &RHS) const { | |
119 if (GetType(*SymbolData) == ELF::STT_FILE) | |
120 return true; | |
121 if (GetType(*RHS.SymbolData) == ELF::STT_FILE) | |
122 return false; | |
123 return SymbolData->getSymbol().getName() < | |
124 RHS.SymbolData->getSymbol().getName(); | |
125 } | |
126 }; | |
127 | |
128 /// @name Relocation Data | |
129 /// @{ | |
130 | |
131 struct ELFRelocationEntry { | |
132 // Make these big enough for both 32-bit and 64-bit | |
133 uint64_t r_offset; | |
134 int Index; | |
135 unsigned Type; | |
136 const MCSymbol *Symbol; | |
137 uint64_t r_addend; | |
138 | |
139 // Support lexicographic sorting. | |
140 bool operator<(const ELFRelocationEntry &RE) const { | |
141 return RE.r_offset < r_offset; | |
142 } | |
143 }; | |
144 | |
145 SmallPtrSet<const MCSymbol *, 16> UsedInReloc; | |
146 SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; | |
147 DenseMap<const MCSymbol *, const MCSymbol *> Renames; | |
148 | |
149 llvm::DenseMap<const MCSectionData*, | |
150 std::vector<ELFRelocationEntry> > Relocations; | |
151 DenseMap<const MCSection*, uint64_t> SectionStringTableIndex; | |
152 | |
153 /// @} | |
154 /// @name Symbol Table Data | |
155 /// @{ | |
156 | |
157 SmallString<256> StringTable; | |
158 std::vector<ELFSymbolData> LocalSymbolData; | |
159 std::vector<ELFSymbolData> ExternalSymbolData; | |
160 std::vector<ELFSymbolData> UndefinedSymbolData; | |
161 | |
162 /// @} | |
163 | |
164 int NumRegularSections; | |
165 | |
166 bool NeedsGOT; | |
167 | |
168 bool NeedsSymtabShndx; | |
169 | |
170 ELFObjectWriter *Writer; | |
171 | |
172 raw_ostream &OS; | |
173 | |
174 unsigned Is64Bit : 1; | |
175 | |
176 bool HasRelocationAddend; | |
177 | |
178 Triple::OSType OSType; | |
179 | |
180 uint16_t EMachine; | |
181 | |
182 // This holds the symbol table index of the last local symbol. | |
183 unsigned LastLocalSymbolIndex; | |
184 // This holds the .strtab section index. | |
185 unsigned StringTableIndex; | |
186 // This holds the .symtab section index. | |
187 unsigned SymbolTableIndex; | |
188 | |
189 unsigned ShstrtabIndex; | |
190 | |
191 public: | |
192 ELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _Is64Bit, | |
193 uint16_t _EMachine, bool _HasRelAddend, | |
194 Triple::OSType _OSType) | |
195 : NeedsGOT(false), NeedsSymtabShndx(false), Writer(_Writer), | |
196 OS(Writer->getStream()), | |
197 Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelAddend), | |
198 OSType(_OSType), EMachine(_EMachine) { | |
199 } | |
200 | |
201 void Write8(uint8_t Value) { Writer->Write8(Value); } | |
202 void Write16(uint16_t Value) { Writer->Write16(Value); } | |
203 void Write32(uint32_t Value) { Writer->Write32(Value); } | |
204 //void Write64(uint64_t Value) { Writer->Write64(Value); } | |
205 void WriteZeros(unsigned N) { Writer->WriteZeros(N); } | |
206 //void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { | |
207 // Writer->WriteBytes(Str, ZeroFillSize); | |
208 //} | |
209 | |
210 void WriteWord(uint64_t W) { | |
211 if (Is64Bit) | |
212 Writer->Write64(W); | |
213 else | |
214 Writer->Write32(W); | |
215 } | |
216 | |
217 void StringLE16(char *buf, uint16_t Value) { | |
218 buf[0] = char(Value >> 0); | |
219 buf[1] = char(Value >> 8); | |
220 } | |
221 | |
222 void StringLE32(char *buf, uint32_t Value) { | |
223 StringLE16(buf, uint16_t(Value >> 0)); | |
224 StringLE16(buf + 2, uint16_t(Value >> 16)); | |
225 } | |
226 | |
227 void StringLE64(char *buf, uint64_t Value) { | |
228 StringLE32(buf, uint32_t(Value >> 0)); | |
229 StringLE32(buf + 4, uint32_t(Value >> 32)); | |
230 } | |
231 | |
232 void StringBE16(char *buf ,uint16_t Value) { | |
233 buf[0] = char(Value >> 8); | |
234 buf[1] = char(Value >> 0); | |
235 } | |
236 | |
237 void StringBE32(char *buf, uint32_t Value) { | |
238 StringBE16(buf, uint16_t(Value >> 16)); | |
239 StringBE16(buf + 2, uint16_t(Value >> 0)); | |
240 } | |
241 | |
242 void StringBE64(char *buf, uint64_t Value) { | |
243 StringBE32(buf, uint32_t(Value >> 32)); | |
244 StringBE32(buf + 4, uint32_t(Value >> 0)); | |
245 } | |
246 | |
247 void String8(MCDataFragment &F, uint8_t Value) { | |
248 char buf[1]; | |
249 buf[0] = Value; | |
250 F.getContents() += StringRef(buf, 1); | |
251 } | |
252 | |
253 void String16(MCDataFragment &F, uint16_t Value) { | |
254 char buf[2]; | |
255 if (Writer->isLittleEndian()) | |
256 StringLE16(buf, Value); | |
257 else | |
258 StringBE16(buf, Value); | |
259 F.getContents() += StringRef(buf, 2); | |
260 } | |
261 | |
262 void String32(MCDataFragment &F, uint32_t Value) { | |
263 char buf[4]; | |
264 if (Writer->isLittleEndian()) | |
265 StringLE32(buf, Value); | |
266 else | |
267 StringBE32(buf, Value); | |
268 F.getContents() += StringRef(buf, 4); | |
269 } | |
270 | |
271 void String64(MCDataFragment &F, uint64_t Value) { | |
272 char buf[8]; | |
273 if (Writer->isLittleEndian()) | |
274 StringLE64(buf, Value); | |
275 else | |
276 StringBE64(buf, Value); | |
277 F.getContents() += StringRef(buf, 8); | |
278 } | |
279 | |
280 void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections); | |
281 | |
282 void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *ShndxF, | |
283 uint64_t name, uint8_t info, | |
284 uint64_t value, uint64_t size, | |
285 uint8_t other, uint32_t shndx, | |
286 bool Reserved); | |
287 | |
288 void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF, | |
289 ELFSymbolData &MSD, | |
290 const MCAsmLayout &Layout); | |
291 | |
292 typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy; | |
293 void WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *ShndxF, | |
294 const MCAssembler &Asm, | |
295 const MCAsmLayout &Layout, | |
296 const SectionIndexMapTy &SectionIndexMap); | |
297 | |
298 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, | |
299 const MCFragment *Fragment, const MCFixup &Fixup, | |
300 MCValue Target, uint64_t &FixedValue); | |
301 | |
302 uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, | |
303 const MCSymbol *S); | |
304 | |
305 /// ComputeSymbolTable - Compute the symbol table data | |
306 /// | |
307 /// \param StringTable [out] - The string table data. | |
308 /// \param StringIndexMap [out] - Map from symbol names to offsets in the | |
309 /// string table. | |
310 void ComputeSymbolTable(MCAssembler &Asm, | |
311 const SectionIndexMapTy &SectionIndexMap); | |
312 | |
313 void ComputeIndexMap(MCAssembler &Asm, | |
314 SectionIndexMapTy &SectionIndexMap); | |
315 | |
316 void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, | |
317 const MCSectionData &SD); | |
318 | |
319 void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) { | |
320 for (MCAssembler::const_iterator it = Asm.begin(), | |
321 ie = Asm.end(); it != ie; ++it) { | |
322 WriteRelocation(Asm, Layout, *it); | |
323 } | |
324 } | |
325 | |
326 void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, | |
327 const SectionIndexMapTy &SectionIndexMap); | |
328 | |
329 // Map from a group section to the signature symbol | |
330 typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy; | |
331 void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout, | |
332 GroupMapTy &GroupMap); | |
333 | |
334 void ExecutePostLayoutBinding(MCAssembler &Asm); | |
335 | |
336 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, | |
337 uint64_t Address, uint64_t Offset, | |
338 uint64_t Size, uint32_t Link, uint32_t Info, | |
339 uint64_t Alignment, uint64_t EntrySize); | |
340 | |
341 void WriteRelocationsFragment(const MCAssembler &Asm, MCDataFragment *F, | |
342 const MCSectionData *SD); | |
343 | |
344 bool IsFixupFullyResolved(const MCAssembler &Asm, | |
345 const MCValue Target, | |
346 bool IsPCRel, | |
347 const MCFragment *DF) const; | |
348 | |
349 void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); | |
350 void WriteSection(MCAssembler &Asm, | |
351 const SectionIndexMapTy &SectionIndexMap, | |
352 uint32_t GroupSymbolIndex, | |
353 uint64_t Offset, uint64_t Size, uint64_t Alignment, | |
354 const MCSectionELF &Section); | |
355 }; | |
356 | |
357 } | |
358 | |
359 // Emit the ELF header. | 139 // Emit the ELF header. |
360 void ELFObjectWriterImpl::WriteHeader(uint64_t SectionDataSize, | 140 void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, |
361 unsigned NumberOfSections) { | 141 unsigned NumberOfSections) { |
362 // ELF Header | 142 // ELF Header |
363 // ---------- | 143 // ---------- |
364 // | 144 // |
365 // Note | 145 // Note |
366 // ---- | 146 // ---- |
367 // emitWord method behaves differently for ELF32 and ELF64, writing | 147 // emitWord method behaves differently for ELF32 and ELF64, writing |
368 // 4 bytes in the former and 8 in the latter. | 148 // 4 bytes in the former and 8 in the latter. |
369 | 149 |
370 Write8(0x7f); // e_ident[EI_MAG0] | 150 Write8(0x7f); // e_ident[EI_MAG0] |
371 Write8('E'); // e_ident[EI_MAG1] | 151 Write8('E'); // e_ident[EI_MAG1] |
372 Write8('L'); // e_ident[EI_MAG2] | 152 Write8('L'); // e_ident[EI_MAG2] |
373 Write8('F'); // e_ident[EI_MAG3] | 153 Write8('F'); // e_ident[EI_MAG3] |
374 | 154 |
375 Write8(Is64Bit ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] | 155 Write8(Is64Bit ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] |
376 | 156 |
377 // e_ident[EI_DATA] | 157 // e_ident[EI_DATA] |
378 Write8(Writer->isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); | 158 Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); |
379 | 159 |
380 Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] | 160 Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] |
381 // e_ident[EI_OSABI] | 161 // e_ident[EI_OSABI] |
382 switch (OSType) { | 162 switch (OSType) { |
383 case Triple::FreeBSD: Write8(ELF::ELFOSABI_FREEBSD); break; | 163 case Triple::FreeBSD: Write8(ELF::ELFOSABI_FREEBSD); break; |
384 case Triple::Linux: Write8(ELF::ELFOSABI_LINUX); break; | 164 case Triple::Linux: Write8(ELF::ELFOSABI_LINUX); break; |
385 default: Write8(ELF::ELFOSABI_NONE); break; | 165 default: Write8(ELF::ELFOSABI_NONE); break; |
386 } | 166 } |
387 Write8(0); // e_ident[EI_ABIVERSION] | 167 Write8(0); // e_ident[EI_ABIVERSION] |
388 | 168 |
(...skipping 27 matching lines...) Expand all Loading... |
416 else | 196 else |
417 Write16(NumberOfSections); | 197 Write16(NumberOfSections); |
418 | 198 |
419 // e_shstrndx = Section # of '.shstrtab' | 199 // e_shstrndx = Section # of '.shstrtab' |
420 if (NumberOfSections >= ELF::SHN_LORESERVE) | 200 if (NumberOfSections >= ELF::SHN_LORESERVE) |
421 Write16(ELF::SHN_XINDEX); | 201 Write16(ELF::SHN_XINDEX); |
422 else | 202 else |
423 Write16(ShstrtabIndex); | 203 Write16(ShstrtabIndex); |
424 } | 204 } |
425 | 205 |
426 void ELFObjectWriterImpl::WriteSymbolEntry(MCDataFragment *SymtabF, | 206 void ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, |
427 MCDataFragment *ShndxF, | 207 MCDataFragment *ShndxF, |
428 uint64_t name, | 208 uint64_t name, |
429 uint8_t info, uint64_t value, | 209 uint8_t info, uint64_t value, |
430 uint64_t size, uint8_t other, | 210 uint64_t size, uint8_t other, |
431 uint32_t shndx, | 211 uint32_t shndx, |
432 bool Reserved) { | 212 bool Reserved) { |
433 if (ShndxF) { | 213 if (ShndxF) { |
434 if (shndx >= ELF::SHN_LORESERVE && !Reserved) | 214 if (shndx >= ELF::SHN_LORESERVE && !Reserved) |
435 String32(*ShndxF, shndx); | 215 String32(*ShndxF, shndx); |
436 else | 216 else |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 S = &Res.getSymA()->getSymbol(); | 270 S = &Res.getSymA()->getSymbol(); |
491 break; | 271 break; |
492 } | 272 } |
493 default: | 273 default: |
494 return *S; | 274 return *S; |
495 } | 275 } |
496 } | 276 } |
497 return *S; | 277 return *S; |
498 } | 278 } |
499 | 279 |
500 void ELFObjectWriterImpl::ExecutePostLayoutBinding(MCAssembler &Asm) { | 280 |
| 281 // Helper routines |
| 282 |
| 283 bool ELFObjectWriter::ELFSymbolData::operator<(const ELFSymbolData &RHS) const { |
| 284 if (GetType(*SymbolData) == ELF::STT_FILE) |
| 285 return true; |
| 286 if (GetType(*RHS.SymbolData) == ELF::STT_FILE) |
| 287 return false; |
| 288 return SymbolData->getSymbol().getName() < |
| 289 RHS.SymbolData->getSymbol().getName(); |
| 290 } |
| 291 |
| 292 |
| 293 bool ELFObjectWriter::ELFRelocationEntry::operator<(const ELFRelocationEntry &RE
) const { |
| 294 return RE.r_offset < r_offset; |
| 295 } |
| 296 |
| 297 |
| 298 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) { |
501 // The presence of symbol versions causes undefined symbols and | 299 // The presence of symbol versions causes undefined symbols and |
502 // versions declared with @@@ to be renamed. | 300 // versions declared with @@@ to be renamed. |
503 | 301 |
504 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), | 302 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), |
505 ie = Asm.symbol_end(); it != ie; ++it) { | 303 ie = Asm.symbol_end(); it != ie; ++it) { |
506 const MCSymbol &Alias = it->getSymbol(); | 304 const MCSymbol &Alias = it->getSymbol(); |
507 const MCSymbol &Symbol = AliasedSymbol(Alias); | 305 const MCSymbol &Symbol = AliasedSymbol(Alias); |
508 MCSymbolData &SD = Asm.getSymbolData(Symbol); | 306 MCSymbolData &SD = Asm.getSymbolData(Symbol); |
509 | 307 |
510 // Undefined symbols are global, but this is the first place we | 308 // Undefined symbols are global, but this is the first place we |
(...skipping 25 matching lines...) Expand all Loading... |
536 | 334 |
537 // FIXME: produce a better error message. | 335 // FIXME: produce a better error message. |
538 if (Symbol.isUndefined() && Rest.startswith("@@") && | 336 if (Symbol.isUndefined() && Rest.startswith("@@") && |
539 !Rest.startswith("@@@")) | 337 !Rest.startswith("@@@")) |
540 report_fatal_error("A @@ version cannot be undefined"); | 338 report_fatal_error("A @@ version cannot be undefined"); |
541 | 339 |
542 Renames.insert(std::make_pair(&Symbol, &Alias)); | 340 Renames.insert(std::make_pair(&Symbol, &Alias)); |
543 } | 341 } |
544 } | 342 } |
545 | 343 |
546 void ELFObjectWriterImpl::WriteSymbol(MCDataFragment *SymtabF, | 344 void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, |
547 MCDataFragment *ShndxF, | 345 MCDataFragment *ShndxF, |
548 ELFSymbolData &MSD, | 346 ELFSymbolData &MSD, |
549 const MCAsmLayout &Layout) { | 347 const MCAsmLayout &Layout) { |
550 MCSymbolData &OrigData = *MSD.SymbolData; | 348 MCSymbolData &OrigData = *MSD.SymbolData; |
551 MCSymbolData &Data = | 349 MCSymbolData &Data = |
552 Layout.getAssembler().getSymbolData(AliasedSymbol(OrigData.getSymbol())); | 350 Layout.getAssembler().getSymbolData(AliasedSymbol(OrigData.getSymbol())); |
553 | 351 |
554 bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || | 352 bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || |
555 Data.getSymbol().isVariable(); | 353 Data.getSymbol().isVariable(); |
556 | 354 |
(...skipping 26 matching lines...) Expand all Loading... |
583 } else { | 381 } else { |
584 assert(0 && "Unsupported size expression"); | 382 assert(0 && "Unsupported size expression"); |
585 } | 383 } |
586 } | 384 } |
587 | 385 |
588 // Write out the symbol table entry | 386 // Write out the symbol table entry |
589 WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, | 387 WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, |
590 Size, Other, MSD.SectionIndex, IsReserved); | 388 Size, Other, MSD.SectionIndex, IsReserved); |
591 } | 389 } |
592 | 390 |
593 void ELFObjectWriterImpl::WriteSymbolTable(MCDataFragment *SymtabF, | 391 void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, |
594 MCDataFragment *ShndxF, | 392 MCDataFragment *ShndxF, |
595 const MCAssembler &Asm, | 393 const MCAssembler &Asm, |
596 const MCAsmLayout &Layout, | 394 const MCAsmLayout &Layout, |
597 const SectionIndexMapTy &SectionIndexMap) { | 395 const SectionIndexMapTy &SectionIndexMap) { |
598 // The string table must be emitted first because we need the index | 396 // The string table must be emitted first because we need the index |
599 // into the string table for all the symbol names. | 397 // into the string table for all the symbol names. |
600 assert(StringTable.size() && "Missing string table"); | 398 assert(StringTable.size() && "Missing string table"); |
601 | 399 |
602 // FIXME: Make sure the start of the symbol table is aligned. | 400 // FIXME: Make sure the start of the symbol table is aligned. |
603 | 401 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 Kind == MCSymbolRefExpr::VK_GOTPCREL || | 469 Kind == MCSymbolRefExpr::VK_GOTPCREL || |
672 Kind == MCSymbolRefExpr::VK_GOTOFF)) | 470 Kind == MCSymbolRefExpr::VK_GOTOFF)) |
673 return true; | 471 return true; |
674 | 472 |
675 if (Section.getFlags() & MCSectionELF::SHF_MERGE) | 473 if (Section.getFlags() & MCSectionELF::SHF_MERGE) |
676 return Target.getConstant() != 0; | 474 return Target.getConstant() != 0; |
677 | 475 |
678 return false; | 476 return false; |
679 } | 477 } |
680 | 478 |
681 // FIXME: this is currently X86/X86_64 only | |
682 void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm, | |
683 const MCAsmLayout &Layout, | |
684 const MCFragment *Fragment, | |
685 const MCFixup &Fixup, | |
686 MCValue Target, | |
687 uint64_t &FixedValue) { | |
688 int64_t Addend = 0; | |
689 int Index = 0; | |
690 int64_t Value = Target.getConstant(); | |
691 const MCSymbol &Symbol = Target.getSymA()->getSymbol(); | |
692 const MCSymbol &ASymbol = AliasedSymbol(Symbol); | |
693 const MCSymbol *RenamedP = Renames.lookup(&Symbol); | |
694 if (!RenamedP) | |
695 RenamedP = &ASymbol; | |
696 const MCSymbol &Renamed = *RenamedP; | |
697 | |
698 bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind()); | |
699 if (!Target.isAbsolute()) { | |
700 MCSymbolData &SD = Asm.getSymbolData(Symbol); | |
701 MCFragment *F = SD.getFragment(); | |
702 | |
703 if (const MCSymbolRefExpr *RefB = Target.getSymB()) { | |
704 const MCSymbol &SymbolB = RefB->getSymbol(); | |
705 MCSymbolData &SDB = Asm.getSymbolData(SymbolB); | |
706 IsPCRel = true; | |
707 MCSectionData *Sec = Fragment->getParent(); | |
708 | |
709 // Offset of the symbol in the section | |
710 int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec); | |
711 | |
712 // Ofeset of the relocation in the section | |
713 int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); | |
714 Value += b - a; | |
715 } | |
716 | |
717 bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target, *Fragment); | |
718 if (!RelocOnSymbol) { | |
719 Index = F->getParent()->getOrdinal(); | |
720 | |
721 MCSectionData *FSD = F->getParent(); | |
722 // Offset of the symbol in the section | |
723 Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD); | |
724 } else { | |
725 if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) | |
726 WeakrefUsedInReloc.insert(&Renamed); | |
727 else | |
728 UsedInReloc.insert(&Renamed); | |
729 Index = -1; | |
730 } | |
731 Addend = Value; | |
732 // Compensate for the addend on i386. | |
733 if (Is64Bit) | |
734 Value = 0; | |
735 } | |
736 | |
737 FixedValue = Value; | |
738 | |
739 // determine the type of the relocation | |
740 | |
741 MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind(); | |
742 unsigned Type; | |
743 if (Is64Bit) { | |
744 if (IsPCRel) { | |
745 switch (Modifier) { | |
746 default: | |
747 llvm_unreachable("Unimplemented"); | |
748 case MCSymbolRefExpr::VK_None: | |
749 Type = ELF::R_X86_64_PC32; | |
750 break; | |
751 case MCSymbolRefExpr::VK_PLT: | |
752 Type = ELF::R_X86_64_PLT32; | |
753 break; | |
754 case MCSymbolRefExpr::VK_GOTPCREL: | |
755 Type = ELF::R_X86_64_GOTPCREL; | |
756 break; | |
757 case MCSymbolRefExpr::VK_GOTTPOFF: | |
758 Type = ELF::R_X86_64_GOTTPOFF; | |
759 break; | |
760 case MCSymbolRefExpr::VK_TLSGD: | |
761 Type = ELF::R_X86_64_TLSGD; | |
762 break; | |
763 case MCSymbolRefExpr::VK_TLSLD: | |
764 Type = ELF::R_X86_64_TLSLD; | |
765 break; | |
766 } | |
767 } else { | |
768 switch ((unsigned)Fixup.getKind()) { | |
769 default: llvm_unreachable("invalid fixup kind!"); | |
770 case FK_Data_8: Type = ELF::R_X86_64_64; break; | |
771 case X86::reloc_signed_4byte: | |
772 case X86::reloc_pcrel_4byte: | |
773 assert(isInt<32>(Target.getConstant())); | |
774 switch (Modifier) { | |
775 default: | |
776 llvm_unreachable("Unimplemented"); | |
777 case MCSymbolRefExpr::VK_None: | |
778 Type = ELF::R_X86_64_32S; | |
779 break; | |
780 case MCSymbolRefExpr::VK_GOT: | |
781 Type = ELF::R_X86_64_GOT32; | |
782 break; | |
783 case MCSymbolRefExpr::VK_GOTPCREL: | |
784 Type = ELF::R_X86_64_GOTPCREL; | |
785 break; | |
786 case MCSymbolRefExpr::VK_TPOFF: | |
787 Type = ELF::R_X86_64_TPOFF32; | |
788 break; | |
789 case MCSymbolRefExpr::VK_DTPOFF: | |
790 Type = ELF::R_X86_64_DTPOFF32; | |
791 break; | |
792 } | |
793 break; | |
794 case FK_Data_4: | |
795 Type = ELF::R_X86_64_32; | |
796 break; | |
797 case FK_Data_2: Type = ELF::R_X86_64_16; break; | |
798 case X86::reloc_pcrel_1byte: | |
799 case FK_Data_1: Type = ELF::R_X86_64_8; break; | |
800 } | |
801 } | |
802 } else { | |
803 if (IsPCRel) { | |
804 switch (Modifier) { | |
805 default: | |
806 llvm_unreachable("Unimplemented"); | |
807 case MCSymbolRefExpr::VK_None: | |
808 Type = ELF::R_386_PC32; | |
809 break; | |
810 case MCSymbolRefExpr::VK_PLT: | |
811 Type = ELF::R_386_PLT32; | |
812 break; | |
813 } | |
814 } else { | |
815 switch ((unsigned)Fixup.getKind()) { | |
816 default: llvm_unreachable("invalid fixup kind!"); | |
817 | |
818 case X86::reloc_global_offset_table: | |
819 Type = ELF::R_386_GOTPC; | |
820 break; | |
821 | |
822 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode | |
823 // instead? | |
824 case X86::reloc_signed_4byte: | |
825 case X86::reloc_pcrel_4byte: | |
826 case FK_Data_4: | |
827 switch (Modifier) { | |
828 default: | |
829 llvm_unreachable("Unimplemented"); | |
830 case MCSymbolRefExpr::VK_None: | |
831 Type = ELF::R_386_32; | |
832 break; | |
833 case MCSymbolRefExpr::VK_GOT: | |
834 Type = ELF::R_386_GOT32; | |
835 break; | |
836 case MCSymbolRefExpr::VK_GOTOFF: | |
837 Type = ELF::R_386_GOTOFF; | |
838 break; | |
839 case MCSymbolRefExpr::VK_TLSGD: | |
840 Type = ELF::R_386_TLS_GD; | |
841 break; | |
842 case MCSymbolRefExpr::VK_TPOFF: | |
843 Type = ELF::R_386_TLS_LE_32; | |
844 break; | |
845 case MCSymbolRefExpr::VK_INDNTPOFF: | |
846 Type = ELF::R_386_TLS_IE; | |
847 break; | |
848 case MCSymbolRefExpr::VK_NTPOFF: | |
849 Type = ELF::R_386_TLS_LE; | |
850 break; | |
851 case MCSymbolRefExpr::VK_GOTNTPOFF: | |
852 Type = ELF::R_386_TLS_GOTIE; | |
853 break; | |
854 case MCSymbolRefExpr::VK_TLSLDM: | |
855 Type = ELF::R_386_TLS_LDM; | |
856 break; | |
857 case MCSymbolRefExpr::VK_DTPOFF: | |
858 Type = ELF::R_386_TLS_LDO_32; | |
859 break; | |
860 } | |
861 break; | |
862 case FK_Data_2: Type = ELF::R_386_16; break; | |
863 case X86::reloc_pcrel_1byte: | |
864 case FK_Data_1: Type = ELF::R_386_8; break; | |
865 } | |
866 } | |
867 } | |
868 | |
869 if (RelocNeedsGOT(Modifier)) | |
870 NeedsGOT = true; | |
871 | |
872 ELFRelocationEntry ERE; | |
873 | |
874 ERE.Index = Index; | |
875 ERE.Type = Type; | |
876 ERE.Symbol = &Renamed; | |
877 | |
878 ERE.r_offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); | |
879 | |
880 if (HasRelocationAddend) | |
881 ERE.r_addend = Addend; | |
882 else | |
883 ERE.r_addend = 0; // Silence compiler warning. | |
884 | |
885 Relocations[Fragment->getParent()].push_back(ERE); | |
886 } | |
887 | 479 |
888 uint64_t | 480 uint64_t |
889 ELFObjectWriterImpl::getSymbolIndexInSymbolTable(const MCAssembler &Asm, | 481 ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, |
890 const MCSymbol *S) { | 482 const MCSymbol *S) { |
891 MCSymbolData &SD = Asm.getSymbolData(*S); | 483 MCSymbolData &SD = Asm.getSymbolData(*S); |
892 | 484 |
893 // Local symbol. | 485 // Local symbol. |
894 if (!SD.isExternal() && !S->isUndefined()) | 486 if (!SD.isExternal() && !S->isUndefined()) |
895 return SD.getIndex() + /* empty symbol */ 1; | 487 return SD.getIndex() + /* empty symbol */ 1; |
896 | 488 |
897 // External or undefined symbol. | 489 // External or undefined symbol. |
898 return SD.getIndex() + NumRegularSections + /* empty symbol */ 1; | 490 return SD.getIndex() + NumRegularSections + /* empty symbol */ 1; |
899 } | 491 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 if (Data.isExternal()) | 523 if (Data.isExternal()) |
932 return false; | 524 return false; |
933 | 525 |
934 const MCSymbol &Symbol = Data.getSymbol(); | 526 const MCSymbol &Symbol = Data.getSymbol(); |
935 if (Symbol.isUndefined() && !Symbol.isVariable()) | 527 if (Symbol.isUndefined() && !Symbol.isVariable()) |
936 return false; | 528 return false; |
937 | 529 |
938 return true; | 530 return true; |
939 } | 531 } |
940 | 532 |
941 void ELFObjectWriterImpl::ComputeIndexMap(MCAssembler &Asm, | 533 void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, |
942 SectionIndexMapTy &SectionIndexMap) { | 534 SectionIndexMapTy &SectionIndexMap) { |
943 unsigned Index = 1; | 535 unsigned Index = 1; |
944 for (MCAssembler::iterator it = Asm.begin(), | 536 for (MCAssembler::iterator it = Asm.begin(), |
945 ie = Asm.end(); it != ie; ++it) { | 537 ie = Asm.end(); it != ie; ++it) { |
946 const MCSectionELF &Section = | 538 const MCSectionELF &Section = |
947 static_cast<const MCSectionELF &>(it->getSection()); | 539 static_cast<const MCSectionELF &>(it->getSection()); |
948 if (Section.getType() != ELF::SHT_GROUP) | 540 if (Section.getType() != ELF::SHT_GROUP) |
949 continue; | 541 continue; |
950 SectionIndexMap[&Section] = Index++; | 542 SectionIndexMap[&Section] = Index++; |
951 } | 543 } |
952 | 544 |
953 for (MCAssembler::iterator it = Asm.begin(), | 545 for (MCAssembler::iterator it = Asm.begin(), |
954 ie = Asm.end(); it != ie; ++it) { | 546 ie = Asm.end(); it != ie; ++it) { |
955 const MCSectionELF &Section = | 547 const MCSectionELF &Section = |
956 static_cast<const MCSectionELF &>(it->getSection()); | 548 static_cast<const MCSectionELF &>(it->getSection()); |
957 if (Section.getType() == ELF::SHT_GROUP) | 549 if (Section.getType() == ELF::SHT_GROUP) |
958 continue; | 550 continue; |
959 SectionIndexMap[&Section] = Index++; | 551 SectionIndexMap[&Section] = Index++; |
960 } | 552 } |
961 } | 553 } |
962 | 554 |
963 void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm, | 555 void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, |
964 const SectionIndexMapTy &SectionIndexMap) { | 556 const SectionIndexMapTy &SectionIndexMap) { |
965 // FIXME: Is this the correct place to do this? | 557 // FIXME: Is this the correct place to do this? |
966 if (NeedsGOT) { | 558 if (NeedsGOT) { |
967 llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; | 559 llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; |
968 MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); | 560 MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); |
969 MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); | 561 MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); |
970 Data.setExternal(true); | 562 Data.setExternal(true); |
971 SetBinding(Data, ELF::STB_GLOBAL); | 563 SetBinding(Data, ELF::STB_GLOBAL); |
972 } | 564 } |
973 | 565 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1051 // symbols with non-local bindings. | 643 // symbols with non-local bindings. |
1052 unsigned Index = 0; | 644 unsigned Index = 0; |
1053 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) | 645 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) |
1054 LocalSymbolData[i].SymbolData->setIndex(Index++); | 646 LocalSymbolData[i].SymbolData->setIndex(Index++); |
1055 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) | 647 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) |
1056 ExternalSymbolData[i].SymbolData->setIndex(Index++); | 648 ExternalSymbolData[i].SymbolData->setIndex(Index++); |
1057 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) | 649 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) |
1058 UndefinedSymbolData[i].SymbolData->setIndex(Index++); | 650 UndefinedSymbolData[i].SymbolData->setIndex(Index++); |
1059 } | 651 } |
1060 | 652 |
1061 void ELFObjectWriterImpl::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, | 653 void ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, |
1062 const MCSectionData &SD) { | 654 const MCSectionData &SD) { |
1063 if (!Relocations[&SD].empty()) { | 655 if (!Relocations[&SD].empty()) { |
1064 MCContext &Ctx = Asm.getContext(); | 656 MCContext &Ctx = Asm.getContext(); |
1065 const MCSectionELF *RelaSection; | 657 const MCSectionELF *RelaSection; |
1066 const MCSectionELF &Section = | 658 const MCSectionELF &Section = |
1067 static_cast<const MCSectionELF&>(SD.getSection()); | 659 static_cast<const MCSectionELF&>(SD.getSection()); |
1068 | 660 |
1069 const StringRef SectionName = Section.getSectionName(); | 661 const StringRef SectionName = Section.getSectionName(); |
1070 std::string RelaSectionName = HasRelocationAddend ? ".rela" : ".rel"; | 662 std::string RelaSectionName = HasRelocationAddend ? ".rela" : ".rel"; |
1071 RelaSectionName += SectionName; | 663 RelaSectionName += SectionName; |
1072 | 664 |
1073 unsigned EntrySize; | 665 unsigned EntrySize; |
1074 if (HasRelocationAddend) | 666 if (HasRelocationAddend) |
1075 EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); | 667 EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); |
1076 else | 668 else |
1077 EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); | 669 EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); |
1078 | 670 |
1079 RelaSection = Ctx.getELFSection(RelaSectionName, HasRelocationAddend ? | 671 RelaSection = Ctx.getELFSection(RelaSectionName, HasRelocationAddend ? |
1080 ELF::SHT_RELA : ELF::SHT_REL, 0, | 672 ELF::SHT_RELA : ELF::SHT_REL, 0, |
1081 SectionKind::getReadOnly(), | 673 SectionKind::getReadOnly(), |
1082 EntrySize, ""); | 674 EntrySize, ""); |
1083 | 675 |
1084 MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); | 676 MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); |
1085 RelaSD.setAlignment(Is64Bit ? 8 : 4); | 677 RelaSD.setAlignment(Is64Bit ? 8 : 4); |
1086 | 678 |
1087 MCDataFragment *F = new MCDataFragment(&RelaSD); | 679 MCDataFragment *F = new MCDataFragment(&RelaSD); |
1088 | 680 |
1089 WriteRelocationsFragment(Asm, F, &SD); | 681 WriteRelocationsFragment(Asm, F, &SD); |
1090 | 682 |
1091 Asm.AddSectionToTheEnd(*Writer, RelaSD, Layout); | 683 Asm.AddSectionToTheEnd(*this, RelaSD, Layout); |
1092 } | 684 } |
1093 } | 685 } |
1094 | 686 |
1095 void ELFObjectWriterImpl::WriteSecHdrEntry(uint32_t Name, uint32_t Type, | 687 |
| 688 void ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) { |
| 689 for (MCAssembler::const_iterator it = Asm.begin(), |
| 690 ie = Asm.end(); it != ie; ++it) { |
| 691 WriteRelocation(Asm, Layout, *it); |
| 692 } |
| 693 } |
| 694 |
| 695 |
| 696 void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, |
1096 uint64_t Flags, uint64_t Address, | 697 uint64_t Flags, uint64_t Address, |
1097 uint64_t Offset, uint64_t Size, | 698 uint64_t Offset, uint64_t Size, |
1098 uint32_t Link, uint32_t Info, | 699 uint32_t Link, uint32_t Info, |
1099 uint64_t Alignment, | 700 uint64_t Alignment, |
1100 uint64_t EntrySize) { | 701 uint64_t EntrySize) { |
1101 Write32(Name); // sh_name: index into string table | 702 Write32(Name); // sh_name: index into string table |
1102 Write32(Type); // sh_type | 703 Write32(Type); // sh_type |
1103 WriteWord(Flags); // sh_flags | 704 WriteWord(Flags); // sh_flags |
1104 WriteWord(Address); // sh_addr | 705 WriteWord(Address); // sh_addr |
1105 WriteWord(Offset); // sh_offset | 706 WriteWord(Offset); // sh_offset |
1106 WriteWord(Size); // sh_size | 707 WriteWord(Size); // sh_size |
1107 Write32(Link); // sh_link | 708 Write32(Link); // sh_link |
1108 Write32(Info); // sh_info | 709 Write32(Info); // sh_info |
1109 WriteWord(Alignment); // sh_addralign | 710 WriteWord(Alignment); // sh_addralign |
1110 WriteWord(EntrySize); // sh_entsize | 711 WriteWord(EntrySize); // sh_entsize |
1111 } | 712 } |
1112 | 713 |
1113 void ELFObjectWriterImpl::WriteRelocationsFragment(const MCAssembler &Asm, | 714 void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, |
1114 MCDataFragment *F, | 715 MCDataFragment *F, |
1115 const MCSectionData *SD) { | 716 const MCSectionData *SD) { |
1116 std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; | 717 std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; |
1117 // sort by the r_offset just like gnu as does | 718 // sort by the r_offset just like gnu as does |
1118 array_pod_sort(Relocs.begin(), Relocs.end()); | 719 array_pod_sort(Relocs.begin(), Relocs.end()); |
1119 | 720 |
1120 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { | 721 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { |
1121 ELFRelocationEntry entry = Relocs[e - i - 1]; | 722 ELFRelocationEntry entry = Relocs[e - i - 1]; |
1122 | 723 |
1123 if (entry.Index < 0) | 724 if (entry.Index < 0) |
(...skipping 15 matching lines...) Expand all Loading... |
1139 struct ELF::Elf32_Rela ERE32; | 740 struct ELF::Elf32_Rela ERE32; |
1140 ERE32.setSymbolAndType(entry.Index, entry.Type); | 741 ERE32.setSymbolAndType(entry.Index, entry.Type); |
1141 String32(*F, ERE32.r_info); | 742 String32(*F, ERE32.r_info); |
1142 | 743 |
1143 if (HasRelocationAddend) | 744 if (HasRelocationAddend) |
1144 String32(*F, entry.r_addend); | 745 String32(*F, entry.r_addend); |
1145 } | 746 } |
1146 } | 747 } |
1147 } | 748 } |
1148 | 749 |
1149 void ELFObjectWriterImpl::CreateMetadataSections(MCAssembler &Asm, | 750 void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, |
1150 MCAsmLayout &Layout, | 751 MCAsmLayout &Layout, |
1151 const SectionIndexMapTy &SectionIndexMap) { | 752 const SectionIndexMapTy &SectionIndexMap) { |
1152 MCContext &Ctx = Asm.getContext(); | 753 MCContext &Ctx = Asm.getContext(); |
1153 MCDataFragment *F; | 754 MCDataFragment *F; |
1154 | 755 |
1155 unsigned EntrySize = Is64Bit ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; | 756 unsigned EntrySize = Is64Bit ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; |
1156 | 757 |
1157 // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. | 758 // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. |
1158 const MCSectionELF *ShstrtabSection = | 759 const MCSectionELF *ShstrtabSection = |
1159 Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, | 760 Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, |
(...skipping 27 matching lines...) Expand all Loading... |
1187 StrtabSD.setAlignment(1); | 788 StrtabSD.setAlignment(1); |
1188 StringTableIndex = Asm.size(); | 789 StringTableIndex = Asm.size(); |
1189 | 790 |
1190 WriteRelocations(Asm, Layout); | 791 WriteRelocations(Asm, Layout); |
1191 | 792 |
1192 // Symbol table | 793 // Symbol table |
1193 F = new MCDataFragment(&SymtabSD); | 794 F = new MCDataFragment(&SymtabSD); |
1194 MCDataFragment *ShndxF = NULL; | 795 MCDataFragment *ShndxF = NULL; |
1195 if (NeedsSymtabShndx) { | 796 if (NeedsSymtabShndx) { |
1196 ShndxF = new MCDataFragment(SymtabShndxSD); | 797 ShndxF = new MCDataFragment(SymtabShndxSD); |
1197 Asm.AddSectionToTheEnd(*Writer, *SymtabShndxSD, Layout); | 798 Asm.AddSectionToTheEnd(*this, *SymtabShndxSD, Layout); |
1198 } | 799 } |
1199 WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); | 800 WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); |
1200 Asm.AddSectionToTheEnd(*Writer, SymtabSD, Layout); | 801 Asm.AddSectionToTheEnd(*this, SymtabSD, Layout); |
1201 | 802 |
1202 F = new MCDataFragment(&StrtabSD); | 803 F = new MCDataFragment(&StrtabSD); |
1203 F->getContents().append(StringTable.begin(), StringTable.end()); | 804 F->getContents().append(StringTable.begin(), StringTable.end()); |
1204 Asm.AddSectionToTheEnd(*Writer, StrtabSD, Layout); | 805 Asm.AddSectionToTheEnd(*this, StrtabSD, Layout); |
1205 | 806 |
1206 F = new MCDataFragment(&ShstrtabSD); | 807 F = new MCDataFragment(&ShstrtabSD); |
1207 | 808 |
1208 // Section header string table. | 809 // Section header string table. |
1209 // | 810 // |
1210 // The first entry of a string table holds a null character so skip | 811 // The first entry of a string table holds a null character so skip |
1211 // section 0. | 812 // section 0. |
1212 uint64_t Index = 1; | 813 uint64_t Index = 1; |
1213 F->getContents() += '\x00'; | 814 F->getContents() += '\x00'; |
1214 | 815 |
(...skipping 12 matching lines...) Expand all Loading... |
1227 // Remember the index into the string table so we can write it | 828 // Remember the index into the string table so we can write it |
1228 // into the sh_name field of the section header table. | 829 // into the sh_name field of the section header table. |
1229 SectionStringTableIndex[&Section] = Index; | 830 SectionStringTableIndex[&Section] = Index; |
1230 SecStringMap[Name] = Index; | 831 SecStringMap[Name] = Index; |
1231 | 832 |
1232 Index += Name.size() + 1; | 833 Index += Name.size() + 1; |
1233 F->getContents() += Name; | 834 F->getContents() += Name; |
1234 F->getContents() += '\x00'; | 835 F->getContents() += '\x00'; |
1235 } | 836 } |
1236 | 837 |
1237 Asm.AddSectionToTheEnd(*Writer, ShstrtabSD, Layout); | 838 Asm.AddSectionToTheEnd(*this, ShstrtabSD, Layout); |
1238 } | 839 } |
1239 | 840 |
1240 bool ELFObjectWriterImpl::IsFixupFullyResolved(const MCAssembler &Asm, | 841 bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, |
1241 const MCValue Target, | 842 const MCValue Target, |
1242 bool IsPCRel, | 843 bool IsPCRel, |
1243 const MCFragment *DF) const { | 844 const MCFragment *DF) const { |
1244 // If this is a PCrel relocation, find the section this fixup value is | 845 // If this is a PCrel relocation, find the section this fixup value is |
1245 // relative to. | 846 // relative to. |
1246 const MCSection *BaseSection = 0; | 847 const MCSection *BaseSection = 0; |
1247 if (IsPCRel) { | 848 if (IsPCRel) { |
1248 BaseSection = &DF->getParent()->getSection(); | 849 BaseSection = &DF->getParent()->getSection(); |
1249 assert(BaseSection); | 850 assert(BaseSection); |
1250 } | 851 } |
(...skipping 13 matching lines...) Expand all Loading... |
1264 if (!BaseSection) | 865 if (!BaseSection) |
1265 return SectionA == SectionB; | 866 return SectionA == SectionB; |
1266 | 867 |
1267 const MCSymbolData &DataA = Asm.getSymbolData(*SymbolA); | 868 const MCSymbolData &DataA = Asm.getSymbolData(*SymbolA); |
1268 if (DataA.isExternal()) | 869 if (DataA.isExternal()) |
1269 return false; | 870 return false; |
1270 | 871 |
1271 return !SectionB && BaseSection == SectionA; | 872 return !SectionB && BaseSection == SectionA; |
1272 } | 873 } |
1273 | 874 |
1274 void ELFObjectWriterImpl::CreateGroupSections(MCAssembler &Asm, | 875 void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm, |
1275 MCAsmLayout &Layout, | 876 MCAsmLayout &Layout, |
1276 GroupMapTy &GroupMap) { | 877 GroupMapTy &GroupMap) { |
1277 typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy; | 878 typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy; |
1278 // Build the groups | 879 // Build the groups |
1279 RevGroupMapTy Groups; | 880 RevGroupMapTy Groups; |
1280 for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); | 881 for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); |
1281 it != ie; ++it) { | 882 it != ie; ++it) { |
1282 const MCSectionELF &Section = | 883 const MCSectionELF &Section = |
1283 static_cast<const MCSectionELF&>(it->getSection()); | 884 static_cast<const MCSectionELF&>(it->getSection()); |
1284 if (!(Section.getFlags() & MCSectionELF::SHF_GROUP)) | 885 if (!(Section.getFlags() & MCSectionELF::SHF_GROUP)) |
(...skipping 25 matching lines...) Expand all Loading... |
1310 MCSectionData &Data = Asm.getOrCreateSectionData(*Group); | 911 MCSectionData &Data = Asm.getOrCreateSectionData(*Group); |
1311 // FIXME: we could use the previous fragment | 912 // FIXME: we could use the previous fragment |
1312 MCDataFragment *F = new MCDataFragment(&Data); | 913 MCDataFragment *F = new MCDataFragment(&Data); |
1313 String32(*F, NumGroups + Index); | 914 String32(*F, NumGroups + Index); |
1314 } | 915 } |
1315 | 916 |
1316 for (RevGroupMapTy::const_iterator i = Groups.begin(), e = Groups.end(); | 917 for (RevGroupMapTy::const_iterator i = Groups.begin(), e = Groups.end(); |
1317 i != e; ++i) { | 918 i != e; ++i) { |
1318 const MCSectionELF *Group = i->second; | 919 const MCSectionELF *Group = i->second; |
1319 MCSectionData &Data = Asm.getOrCreateSectionData(*Group); | 920 MCSectionData &Data = Asm.getOrCreateSectionData(*Group); |
1320 Asm.AddSectionToTheEnd(*Writer, Data, Layout); | 921 Asm.AddSectionToTheEnd(*this, Data, Layout); |
1321 } | 922 } |
1322 } | 923 } |
1323 | 924 |
1324 void ELFObjectWriterImpl::WriteSection(MCAssembler &Asm, | 925 void ELFObjectWriter::WriteSection(MCAssembler &Asm, |
1325 const SectionIndexMapTy &SectionIndexMap, | 926 const SectionIndexMapTy &SectionIndexMap, |
1326 uint32_t GroupSymbolIndex, | 927 uint32_t GroupSymbolIndex, |
1327 uint64_t Offset, uint64_t Size, | 928 uint64_t Offset, uint64_t Size, |
1328 uint64_t Alignment, | 929 uint64_t Alignment, |
1329 const MCSectionELF &Section) { | 930 const MCSectionELF &Section) { |
1330 uint64_t sh_link = 0; | 931 uint64_t sh_link = 0; |
1331 uint64_t sh_info = 0; | 932 uint64_t sh_info = 0; |
1332 | 933 |
1333 switch(Section.getType()) { | 934 switch(Section.getType()) { |
1334 case ELF::SHT_DYNAMIC: | 935 case ELF::SHT_DYNAMIC: |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1384 default: | 985 default: |
1385 assert(0 && "FIXME: sh_type value not supported!"); | 986 assert(0 && "FIXME: sh_type value not supported!"); |
1386 break; | 987 break; |
1387 } | 988 } |
1388 | 989 |
1389 WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), | 990 WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), |
1390 Section.getFlags(), 0, Offset, Size, sh_link, sh_info, | 991 Section.getFlags(), 0, Offset, Size, sh_link, sh_info, |
1391 Alignment, Section.getEntrySize()); | 992 Alignment, Section.getEntrySize()); |
1392 } | 993 } |
1393 | 994 |
1394 void ELFObjectWriterImpl::WriteObject(MCAssembler &Asm, | 995 void ELFObjectWriter::WriteObject(MCAssembler &Asm, |
1395 const MCAsmLayout &Layout) { | 996 const MCAsmLayout &Layout) { |
1396 | 997 |
1397 GroupMapTy GroupMap; | 998 GroupMapTy GroupMap; |
1398 CreateGroupSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap); | 999 CreateGroupSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap); |
1399 | 1000 |
1400 SectionIndexMapTy SectionIndexMap; | 1001 SectionIndexMapTy SectionIndexMap; |
1401 | 1002 |
1402 ComputeIndexMap(Asm, SectionIndexMap); | 1003 ComputeIndexMap(Asm, SectionIndexMap); |
1403 | 1004 |
1404 // Compute symbol table information. | 1005 // Compute symbol table information. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 | 1055 |
1455 uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); | 1056 uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); |
1456 WriteZeros(Padding); | 1057 WriteZeros(Padding); |
1457 FileOff += Padding; | 1058 FileOff += Padding; |
1458 | 1059 |
1459 // Remember the offset into the file for this section. | 1060 // Remember the offset into the file for this section. |
1460 SectionOffsetMap[&Section] = FileOff; | 1061 SectionOffsetMap[&Section] = FileOff; |
1461 | 1062 |
1462 FileOff += Layout.getSectionFileSize(&SD); | 1063 FileOff += Layout.getSectionFileSize(&SD); |
1463 | 1064 |
1464 Asm.WriteSectionData(&SD, Layout, Writer); | 1065 Asm.WriteSectionData(&SD, Layout, this); |
1465 } | 1066 } |
1466 | 1067 |
1467 uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); | 1068 uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); |
1468 WriteZeros(Padding); | 1069 WriteZeros(Padding); |
1469 FileOff += Padding; | 1070 FileOff += Padding; |
1470 | 1071 |
1471 // ... and then the section header table. | 1072 // ... and then the section header table. |
1472 // Should we align the section header table? | 1073 // Should we align the section header table? |
1473 // | 1074 // |
1474 // Null section first. | 1075 // Null section first. |
(...skipping 11 matching lines...) Expand all Loading... |
1486 GroupSymbolIndex = 0; | 1087 GroupSymbolIndex = 0; |
1487 else | 1088 else |
1488 GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]); | 1089 GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]); |
1489 | 1090 |
1490 WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, | 1091 WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, |
1491 SectionOffsetMap[&Section], Layout.getSectionSize(&SD), | 1092 SectionOffsetMap[&Section], Layout.getSectionSize(&SD), |
1492 SD.getAlignment(), Section); | 1093 SD.getAlignment(), Section); |
1493 } | 1094 } |
1494 } | 1095 } |
1495 | 1096 |
1496 ELFObjectWriter::ELFObjectWriter(raw_ostream &OS, | 1097 ELFObjectWriter::ELFObjectWriter(raw_ostream &_OS, |
1497 bool Is64Bit, | 1098 bool _Is64Bit, |
1498 Triple::OSType OSType, | 1099 Triple::OSType _OSType, |
1499 uint16_t EMachine, | 1100 uint16_t _EMachine, |
1500 bool IsLittleEndian, | 1101 bool _IsLittleEndian, |
1501 bool HasRelocationAddend) | 1102 bool _HasRelocationAddend) |
1502 : MCObjectWriter(OS, IsLittleEndian) | 1103 : MCObjectWriter(_OS, _IsLittleEndian), |
| 1104 NeedsGOT(false), NeedsSymtabShndx(false), |
| 1105 Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelocationAddend), |
| 1106 OSType(_OSType), EMachine(_EMachine) |
1503 { | 1107 { |
1504 Impl = new ELFObjectWriterImpl(this, Is64Bit, EMachine, | 1108 // Impl = new ELFObjectWriterImpl(this, Is64Bit, EMachine, |
1505 HasRelocationAddend, OSType); | 1109 // HasRelocationAddend, OSType); |
1506 } | 1110 } |
1507 | 1111 |
1508 ELFObjectWriter::~ELFObjectWriter() { | 1112 //===- ARMELFObjectWriter -------------------------------------------===// |
1509 delete (ELFObjectWriterImpl*) Impl; | 1113 |
1510 } | 1114 ARMELFObjectWriter::ARMELFObjectWriter(raw_ostream &OS, bool Is64Bit, |
1511 | 1115 Triple::OSType OSType, |
1512 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) { | 1116 uint16_t EMachine, bool IsLittleEndian, |
1513 ((ELFObjectWriterImpl*) Impl)->ExecutePostLayoutBinding(Asm); | 1117 bool HasRelocationAddend) |
1514 } | 1118 : ELFObjectWriter(OS, Is64Bit, OSType, EMachine, IsLittleEndian, |
1515 | 1119 HasRelocationAddend) |
1516 void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, | 1120 {} |
1517 const MCAsmLayout &Layout, | 1121 |
1518 const MCFragment *Fragment, | 1122 ARMELFObjectWriter::~ARMELFObjectWriter() |
1519 const MCFixup &Fixup, MCValue Target, | 1123 {} |
1520 uint64_t &FixedValue) { | 1124 |
1521 ((ELFObjectWriterImpl*) Impl)->RecordRelocation(Asm, Layout, Fragment, Fixup, | 1125 void ARMELFObjectWriter::RecordRelocation(const MCAssembler &Asm, |
1522 Target, FixedValue); | 1126 const MCAsmLayout &Layout, |
1523 } | 1127 const MCFragment *Fragment, |
1524 | 1128 const MCFixup &Fixup, |
1525 bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, | 1129 MCValue Target, |
1526 const MCValue Target, | 1130 uint64_t &FixedValue) { |
1527 bool IsPCRel, | 1131 assert(0 && "ARMELFObjectWriter::RecordRelocation() unimplemented"); |
1528 const MCFragment *DF) const { | 1132 } |
1529 return ((ELFObjectWriterImpl*) Impl)->IsFixupFullyResolved(Asm, Target, | 1133 |
1530 IsPCRel, DF); | 1134 |
1531 } | 1135 |
1532 | 1136 //===- X86ELFObjectWriter -------------------------------------------===// |
1533 void ELFObjectWriter::WriteObject(MCAssembler &Asm, | 1137 |
1534 const MCAsmLayout &Layout) { | 1138 |
1535 ((ELFObjectWriterImpl*) Impl)->WriteObject(Asm, Layout); | 1139 X86ELFObjectWriter::X86ELFObjectWriter(raw_ostream &OS, bool Is64Bit, |
1536 } | 1140 Triple::OSType OSType, |
| 1141 uint16_t EMachine, bool IsLittleEndian, |
| 1142 bool HasRelocationAddend) |
| 1143 : ELFObjectWriter(OS, Is64Bit, OSType, EMachine, IsLittleEndian, |
| 1144 HasRelocationAddend) |
| 1145 {} |
| 1146 |
| 1147 X86ELFObjectWriter::~X86ELFObjectWriter() |
| 1148 {} |
| 1149 |
| 1150 void X86ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, |
| 1151 const MCAsmLayout &Layout, |
| 1152 const MCFragment *Fragment, |
| 1153 const MCFixup &Fixup, |
| 1154 MCValue Target, |
| 1155 uint64_t &FixedValue) { |
| 1156 int64_t Addend = 0; |
| 1157 int Index = 0; |
| 1158 int64_t Value = Target.getConstant(); |
| 1159 const MCSymbol &Symbol = Target.getSymA()->getSymbol(); |
| 1160 const MCSymbol &ASymbol = AliasedSymbol(Symbol); |
| 1161 const MCSymbol *RenamedP = Renames.lookup(&Symbol); |
| 1162 if (!RenamedP) |
| 1163 RenamedP = &ASymbol; |
| 1164 const MCSymbol &Renamed = *RenamedP; |
| 1165 |
| 1166 bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind()); |
| 1167 if (!Target.isAbsolute()) { |
| 1168 MCSymbolData &SD = Asm.getSymbolData(Symbol); |
| 1169 MCFragment *F = SD.getFragment(); |
| 1170 |
| 1171 if (const MCSymbolRefExpr *RefB = Target.getSymB()) { |
| 1172 const MCSymbol &SymbolB = RefB->getSymbol(); |
| 1173 MCSymbolData &SDB = Asm.getSymbolData(SymbolB); |
| 1174 IsPCRel = true; |
| 1175 MCSectionData *Sec = Fragment->getParent(); |
| 1176 |
| 1177 // Offset of the symbol in the section |
| 1178 int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec); |
| 1179 |
| 1180 // Ofeset of the relocation in the section |
| 1181 int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); |
| 1182 Value += b - a; |
| 1183 } |
| 1184 |
| 1185 bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target, *Fragment); |
| 1186 if (!RelocOnSymbol) { |
| 1187 Index = F->getParent()->getOrdinal(); |
| 1188 |
| 1189 MCSectionData *FSD = F->getParent(); |
| 1190 // Offset of the symbol in the section |
| 1191 Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD); |
| 1192 } else { |
| 1193 if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) |
| 1194 WeakrefUsedInReloc.insert(&Renamed); |
| 1195 else |
| 1196 UsedInReloc.insert(&Renamed); |
| 1197 Index = -1; |
| 1198 } |
| 1199 Addend = Value; |
| 1200 // Compensate for the addend on i386. |
| 1201 if (Is64Bit) |
| 1202 Value = 0; |
| 1203 } |
| 1204 |
| 1205 FixedValue = Value; |
| 1206 |
| 1207 // determine the type of the relocation |
| 1208 |
| 1209 MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind(); |
| 1210 unsigned Type; |
| 1211 if (Is64Bit) { |
| 1212 if (IsPCRel) { |
| 1213 switch (Modifier) { |
| 1214 default: |
| 1215 llvm_unreachable("Unimplemented"); |
| 1216 case MCSymbolRefExpr::VK_None: |
| 1217 Type = ELF::R_X86_64_PC32; |
| 1218 break; |
| 1219 case MCSymbolRefExpr::VK_PLT: |
| 1220 Type = ELF::R_X86_64_PLT32; |
| 1221 break; |
| 1222 case MCSymbolRefExpr::VK_GOTPCREL: |
| 1223 Type = ELF::R_X86_64_GOTPCREL; |
| 1224 break; |
| 1225 case MCSymbolRefExpr::VK_GOTTPOFF: |
| 1226 Type = ELF::R_X86_64_GOTTPOFF; |
| 1227 break; |
| 1228 case MCSymbolRefExpr::VK_TLSGD: |
| 1229 Type = ELF::R_X86_64_TLSGD; |
| 1230 break; |
| 1231 case MCSymbolRefExpr::VK_TLSLD: |
| 1232 Type = ELF::R_X86_64_TLSLD; |
| 1233 break; |
| 1234 } |
| 1235 } else { |
| 1236 switch ((unsigned)Fixup.getKind()) { |
| 1237 default: llvm_unreachable("invalid fixup kind!"); |
| 1238 case FK_Data_8: Type = ELF::R_X86_64_64; break; |
| 1239 case X86::reloc_signed_4byte: |
| 1240 case X86::reloc_pcrel_4byte: |
| 1241 assert(isInt<32>(Target.getConstant())); |
| 1242 switch (Modifier) { |
| 1243 default: |
| 1244 llvm_unreachable("Unimplemented"); |
| 1245 case MCSymbolRefExpr::VK_None: |
| 1246 Type = ELF::R_X86_64_32S; |
| 1247 break; |
| 1248 case MCSymbolRefExpr::VK_GOT: |
| 1249 Type = ELF::R_X86_64_GOT32; |
| 1250 break; |
| 1251 case MCSymbolRefExpr::VK_GOTPCREL: |
| 1252 Type = ELF::R_X86_64_GOTPCREL; |
| 1253 break; |
| 1254 case MCSymbolRefExpr::VK_TPOFF: |
| 1255 Type = ELF::R_X86_64_TPOFF32; |
| 1256 break; |
| 1257 case MCSymbolRefExpr::VK_DTPOFF: |
| 1258 Type = ELF::R_X86_64_DTPOFF32; |
| 1259 break; |
| 1260 } |
| 1261 break; |
| 1262 case FK_Data_4: |
| 1263 Type = ELF::R_X86_64_32; |
| 1264 break; |
| 1265 case FK_Data_2: Type = ELF::R_X86_64_16; break; |
| 1266 case X86::reloc_pcrel_1byte: |
| 1267 case FK_Data_1: Type = ELF::R_X86_64_8; break; |
| 1268 } |
| 1269 } |
| 1270 } else { |
| 1271 if (IsPCRel) { |
| 1272 switch (Modifier) { |
| 1273 default: |
| 1274 llvm_unreachable("Unimplemented"); |
| 1275 case MCSymbolRefExpr::VK_None: |
| 1276 Type = ELF::R_386_PC32; |
| 1277 break; |
| 1278 case MCSymbolRefExpr::VK_PLT: |
| 1279 Type = ELF::R_386_PLT32; |
| 1280 break; |
| 1281 } |
| 1282 } else { |
| 1283 switch ((unsigned)Fixup.getKind()) { |
| 1284 default: llvm_unreachable("invalid fixup kind!"); |
| 1285 |
| 1286 case X86::reloc_global_offset_table: |
| 1287 Type = ELF::R_386_GOTPC; |
| 1288 break; |
| 1289 |
| 1290 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode |
| 1291 // instead? |
| 1292 case X86::reloc_signed_4byte: |
| 1293 case X86::reloc_pcrel_4byte: |
| 1294 case FK_Data_4: |
| 1295 switch (Modifier) { |
| 1296 default: |
| 1297 llvm_unreachable("Unimplemented"); |
| 1298 case MCSymbolRefExpr::VK_None: |
| 1299 Type = ELF::R_386_32; |
| 1300 break; |
| 1301 case MCSymbolRefExpr::VK_GOT: |
| 1302 Type = ELF::R_386_GOT32; |
| 1303 break; |
| 1304 case MCSymbolRefExpr::VK_GOTOFF: |
| 1305 Type = ELF::R_386_GOTOFF; |
| 1306 break; |
| 1307 case MCSymbolRefExpr::VK_TLSGD: |
| 1308 Type = ELF::R_386_TLS_GD; |
| 1309 break; |
| 1310 case MCSymbolRefExpr::VK_TPOFF: |
| 1311 Type = ELF::R_386_TLS_LE_32; |
| 1312 break; |
| 1313 case MCSymbolRefExpr::VK_INDNTPOFF: |
| 1314 Type = ELF::R_386_TLS_IE; |
| 1315 break; |
| 1316 case MCSymbolRefExpr::VK_NTPOFF: |
| 1317 Type = ELF::R_386_TLS_LE; |
| 1318 break; |
| 1319 case MCSymbolRefExpr::VK_GOTNTPOFF: |
| 1320 Type = ELF::R_386_TLS_GOTIE; |
| 1321 break; |
| 1322 case MCSymbolRefExpr::VK_TLSLDM: |
| 1323 Type = ELF::R_386_TLS_LDM; |
| 1324 break; |
| 1325 case MCSymbolRefExpr::VK_DTPOFF: |
| 1326 Type = ELF::R_386_TLS_LDO_32; |
| 1327 break; |
| 1328 } |
| 1329 break; |
| 1330 case FK_Data_2: Type = ELF::R_386_16; break; |
| 1331 case X86::reloc_pcrel_1byte: |
| 1332 case FK_Data_1: Type = ELF::R_386_8; break; |
| 1333 } |
| 1334 } |
| 1335 } |
| 1336 |
| 1337 if (RelocNeedsGOT(Modifier)) |
| 1338 NeedsGOT = true; |
| 1339 |
| 1340 ELFRelocationEntry ERE; |
| 1341 |
| 1342 ERE.Index = Index; |
| 1343 ERE.Type = Type; |
| 1344 ERE.Symbol = &Renamed; |
| 1345 |
| 1346 ERE.r_offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); |
| 1347 |
| 1348 if (HasRelocationAddend) |
| 1349 ERE.r_addend = Addend; |
| 1350 else |
| 1351 ERE.r_addend = 0; // Silence compiler warning. |
| 1352 |
| 1353 Relocations[Fragment->getParent()].push_back(ERE); |
| 1354 } |
OLD | NEW |