Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(270)

Side by Side Diff: lib/MC/ELFObjectWriter.cpp

Issue 4828001: INFORMATIONAL: new ELFObjectWriter patch (Closed) Base URL: https://llvm.org/svn/llvm-project/llvm/trunk/
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/llvm/MC/ELFObjectWriter.h ('k') | lib/Target/ARM/ARMAsmBackend.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « include/llvm/MC/ELFObjectWriter.h ('k') | lib/Target/ARM/ARMAsmBackend.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698