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

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

Issue 4703006: ttryB refactor of elfobjectwriter (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 | « no previous file | no next file » | 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 namespace {
102 102
103 class ELFObjectWriterImpl { 103 class ELFObjectWriterImpl {
104 protected:
104 /*static bool isFixupKindX86RIPRel(unsigned Kind) { 105 /*static bool isFixupKindX86RIPRel(unsigned Kind) {
105 return Kind == X86::reloc_riprel_4byte || 106 return Kind == X86::reloc_riprel_4byte ||
106 Kind == X86::reloc_riprel_4byte_movq_load; 107 Kind == X86::reloc_riprel_4byte_movq_load;
107 }*/ 108 }*/
108 109
109 110
110 /// ELFSymbolData - Helper struct for containing some precomputed informatio n 111 /// ELFSymbolData - Helper struct for containing some precomputed informatio n
111 /// on symbols. 112 /// on symbols.
112 struct ELFSymbolData { 113 struct ELFSymbolData {
113 MCSymbolData *SymbolData; 114 MCSymbolData *SymbolData;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 191
191 public: 192 public:
192 ELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _Is64Bit, 193 ELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _Is64Bit,
193 uint16_t _EMachine, bool _HasRelAddend, 194 uint16_t _EMachine, bool _HasRelAddend,
194 Triple::OSType _OSType) 195 Triple::OSType _OSType)
195 : NeedsGOT(false), NeedsSymtabShndx(false), Writer(_Writer), 196 : NeedsGOT(false), NeedsSymtabShndx(false), Writer(_Writer),
196 OS(Writer->getStream()), 197 OS(Writer->getStream()),
197 Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelAddend), 198 Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelAddend),
198 OSType(_OSType), EMachine(_EMachine) { 199 OSType(_OSType), EMachine(_EMachine) {
199 } 200 }
200 201 virtual ~ELFObjectWriterImpl();
201 void Write8(uint8_t Value) { Writer->Write8(Value); } 202 void Write8(uint8_t Value) { Writer->Write8(Value); }
202 void Write16(uint16_t Value) { Writer->Write16(Value); } 203 void Write16(uint16_t Value) { Writer->Write16(Value); }
203 void Write32(uint32_t Value) { Writer->Write32(Value); } 204 void Write32(uint32_t Value) { Writer->Write32(Value); }
204 //void Write64(uint64_t Value) { Writer->Write64(Value); } 205 //void Write64(uint64_t Value) { Writer->Write64(Value); }
205 void WriteZeros(unsigned N) { Writer->WriteZeros(N); } 206 void WriteZeros(unsigned N) { Writer->WriteZeros(N); }
206 //void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { 207 //void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
207 // Writer->WriteBytes(Str, ZeroFillSize); 208 // Writer->WriteBytes(Str, ZeroFillSize);
208 //} 209 //}
209 210
210 void WriteWord(uint64_t W) { 211 void WriteWord(uint64_t W) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 271
271 void String64(MCDataFragment &F, uint64_t Value) { 272 void String64(MCDataFragment &F, uint64_t Value) {
272 char buf[8]; 273 char buf[8];
273 if (Writer->isLittleEndian()) 274 if (Writer->isLittleEndian())
274 StringLE64(buf, Value); 275 StringLE64(buf, Value);
275 else 276 else
276 StringBE64(buf, Value); 277 StringBE64(buf, Value);
277 F.getContents() += StringRef(buf, 8); 278 F.getContents() += StringRef(buf, 8);
278 } 279 }
279 280
280 void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections); 281 /// @name new virtuals
282 /// @{
283 virtual void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections );
281 284
282 void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *ShndxF, 285 virtual void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *Shndx F,
283 uint64_t name, uint8_t info, 286 uint64_t name, uint8_t info,
284 uint64_t value, uint64_t size, 287 uint64_t value, uint64_t size,
285 uint8_t other, uint32_t shndx, 288 uint8_t other, uint32_t shndx,
286 bool Reserved); 289 bool Reserved);
287 290
288 void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF, 291 virtual void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
289 ELFSymbolData &MSD, 292 ELFSymbolData &MSD,
290 const MCAsmLayout &Layout); 293 const MCAsmLayout &Layout);
291 294
292 void WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *ShndxF, 295 virtual void WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *Shndx F,
293 const MCAssembler &Asm, 296 const MCAssembler &Asm,
294 const MCAsmLayout &Layout, 297 const MCAsmLayout &Layout,
295 unsigned NumRegularSections); 298 unsigned NumRegularSections);
296 299
297 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, 300 virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Lay out,
298 const MCFragment *Fragment, const MCFixup &Fixup, 301 const MCFragment *Fragment, const MCFixup &Fixup,
299 MCValue Target, uint64_t &FixedValue); 302 MCValue Target, uint64_t &FixedValue) {
303 assert(0 && "RecordRelocation is not specific enough");
304 };
300 305
301 uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, 306 virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
302 const MCSymbol *S); 307 const MCSymbol *S);
303 308
304 /// ComputeSymbolTable - Compute the symbol table data 309 /// ComputeSymbolTable - Compute the symbol table data
305 /// 310 ///
306 /// \param StringTable [out] - The string table data. 311 /// \param StringTable [out] - The string table data.
307 /// \param StringIndexMap [out] - Map from symbol names to offsets in the 312 /// \param StringIndexMap [out] - Map from symbol names to offsets in the
308 /// string table. 313 /// string table.
309 void ComputeSymbolTable(MCAssembler &Asm); 314 virtual void ComputeSymbolTable(MCAssembler &Asm);
310 315
311 void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, 316 virtual void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout,
312 const MCSectionData &SD); 317 const MCSectionData &SD);
313 318
314 void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) { 319 virtual void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) {
315 for (MCAssembler::const_iterator it = Asm.begin(), 320 for (MCAssembler::const_iterator it = Asm.begin(),
316 ie = Asm.end(); it != ie; ++it) { 321 ie = Asm.end(); it != ie; ++it) {
317 WriteRelocation(Asm, Layout, *it); 322 WriteRelocation(Asm, Layout, *it);
318 } 323 }
319 } 324 }
320 325
321 void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout); 326 virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout);
322 327
323 void ExecutePostLayoutBinding(MCAssembler &Asm); 328 virtual void ExecutePostLayoutBinding(MCAssembler &Asm);
324 329
325 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, 330 virtual void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
326 uint64_t Address, uint64_t Offset, 331 uint64_t Address, uint64_t Offset,
327 uint64_t Size, uint32_t Link, uint32_t Info, 332 uint64_t Size, uint32_t Link, uint32_t Info,
328 uint64_t Alignment, uint64_t EntrySize); 333 uint64_t Alignment, uint64_t EntrySize);
329 334
330 void WriteRelocationsFragment(const MCAssembler &Asm, MCDataFragment *F, 335 virtual void WriteRelocationsFragment(const MCAssembler &Asm, MCDataFragment *F,
331 const MCSectionData *SD); 336 const MCSectionData *SD);
332 337
333 bool IsFixupFullyResolved(const MCAssembler &Asm, 338 virtual bool IsFixupFullyResolved(const MCAssembler &Asm,
334 const MCValue Target, 339 const MCValue Target,
335 bool IsPCRel, 340 bool IsPCRel,
336 const MCFragment *DF) const; 341 const MCFragment *DF) const;
337 342
338 void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); 343 virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
344 /// @}
339 }; 345 };
340 346
347
348 class X86ELFObjectWriterImpl : public ELFObjectWriterImpl {
349 public:
350 X86ELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _Is64Bit,
351 uint16_t _EMachine, bool _HasRelAddend,
352 Triple::OSType _OSType);
353 virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layou t,
354 const MCFragment *Fragment, const MCFixup &Fixup ,
355 MCValue Target, uint64_t &FixedValue);
356 virtual ~X86ELFObjectWriterImpl();
357 };
358
359 class ARMELFObjectWriterImpl : public ELFObjectWriterImpl {
360 public:
361 ARMELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _Is64Bit,
362 uint16_t _EMachine, bool _HasRelAddend,
363 Triple::OSType _OSType);
364 virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layou t,
365 const MCFragment *Fragment, const MCFixup &Fixup ,
366 MCValue Target, uint64_t &FixedValue);
367 ~ARMELFObjectWriterImpl();
368 };
369
341 } 370 }
342 371
372 // new virtual destructor
373 ELFObjectWriterImpl::~ELFObjectWriterImpl()
374 {}
375
343 // Emit the ELF header. 376 // Emit the ELF header.
344 void ELFObjectWriterImpl::WriteHeader(uint64_t SectionDataSize, 377 void ELFObjectWriterImpl::WriteHeader(uint64_t SectionDataSize,
345 unsigned NumberOfSections) { 378 unsigned NumberOfSections) {
346 // ELF Header 379 // ELF Header
347 // ---------- 380 // ----------
348 // 381 //
349 // Note 382 // Note
350 // ---- 383 // ----
351 // emitWord method behaves differently for ELF32 and ELF64, writing 384 // emitWord method behaves differently for ELF32 and ELF64, writing
352 // 4 bytes in the former and 8 in the latter. 385 // 4 bytes in the former and 8 in the latter.
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 Kind == MCSymbolRefExpr::VK_GOTPCREL || 675 Kind == MCSymbolRefExpr::VK_GOTPCREL ||
643 Kind == MCSymbolRefExpr::VK_GOTOFF)) 676 Kind == MCSymbolRefExpr::VK_GOTOFF))
644 return true; 677 return true;
645 678
646 if (Section.getFlags() & MCSectionELF::SHF_MERGE) 679 if (Section.getFlags() & MCSectionELF::SHF_MERGE)
647 return Target.getConstant() != 0; 680 return Target.getConstant() != 0;
648 681
649 return false; 682 return false;
650 } 683 }
651 684
652 // FIXME: this is currently X86/X86_64 only
653 void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
654 const MCAsmLayout &Layout,
655 const MCFragment *Fragment,
656 const MCFixup &Fixup,
657 MCValue Target,
658 uint64_t &FixedValue) {
659 int64_t Addend = 0;
660 int Index = 0;
661 int64_t Value = Target.getConstant();
662 const MCSymbol *Symbol = 0;
663 const MCSymbol *Renamed = 0;
664
665 bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
666 if (!Target.isAbsolute()) {
667 Symbol = &AliasedSymbol(Target.getSymA()->getSymbol());
668 Renamed = Renames.lookup(Symbol);
669 if (!Renamed)
670 Renamed = &Target.getSymA()->getSymbol();
671 MCSymbolData &SD = Asm.getSymbolData(*Symbol);
672 MCFragment *F = SD.getFragment();
673
674 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
675 const MCSymbol &SymbolB = RefB->getSymbol();
676 MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
677 IsPCRel = true;
678 MCSectionData *Sec = Fragment->getParent();
679
680 // Offset of the symbol in the section
681 int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec);
682
683 // Ofeset of the relocation in the section
684 int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
685 Value += b - a;
686 }
687
688 // Check that this case has already been fully resolved before we get
689 // here.
690 if (Symbol->isDefined() && !SD.isExternal() &&
691 IsPCRel &&
692 &Fragment->getParent()->getSection() == &Symbol->getSection()) {
693 llvm_unreachable("We don't need a relocation in this case.");
694 return;
695 }
696
697 bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target, *Fragment);
698 if (!RelocOnSymbol) {
699 Index = F->getParent()->getOrdinal();
700
701 MCSectionData *FSD = F->getParent();
702 // Offset of the symbol in the section
703 Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
704 } else {
705 UsedInReloc.insert(Renamed);
706 MCSymbolData &RenamedSD = Asm.getSymbolData(*Renamed);
707 if (RenamedSD.getFlags() & ELF_Other_Weakref) {
708 WeakrefUsedInReloc.insert(Symbol);
709 }
710 Index = -1;
711 }
712 Addend = Value;
713 // Compensate for the addend on i386.
714 if (Is64Bit)
715 Value = 0;
716 }
717
718 FixedValue = Value;
719
720 // determine the type of the relocation
721
722 MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind();
723 unsigned Type;
724 if (Is64Bit) {
725 if (IsPCRel) {
726 switch (Modifier) {
727 default:
728 llvm_unreachable("Unimplemented");
729 case MCSymbolRefExpr::VK_None:
730 Type = ELF::R_X86_64_PC32;
731 break;
732 case MCSymbolRefExpr::VK_PLT:
733 Type = ELF::R_X86_64_PLT32;
734 break;
735 case MCSymbolRefExpr::VK_GOTPCREL:
736 Type = ELF::R_X86_64_GOTPCREL;
737 break;
738 case MCSymbolRefExpr::VK_GOTTPOFF:
739 Type = ELF::R_X86_64_GOTTPOFF;
740 break;
741 case MCSymbolRefExpr::VK_TLSGD:
742 Type = ELF::R_X86_64_TLSGD;
743 break;
744 case MCSymbolRefExpr::VK_TLSLD:
745 Type = ELF::R_X86_64_TLSLD;
746 break;
747 }
748 } else {
749 switch ((unsigned)Fixup.getKind()) {
750 default: llvm_unreachable("invalid fixup kind!");
751 case FK_Data_8: Type = ELF::R_X86_64_64; break;
752 case X86::reloc_signed_4byte:
753 case X86::reloc_pcrel_4byte:
754 assert(isInt<32>(Target.getConstant()));
755 switch (Modifier) {
756 default:
757 llvm_unreachable("Unimplemented");
758 case MCSymbolRefExpr::VK_None:
759 Type = ELF::R_X86_64_32S;
760 break;
761 case MCSymbolRefExpr::VK_GOT:
762 Type = ELF::R_X86_64_GOT32;
763 break;
764 case MCSymbolRefExpr::VK_GOTPCREL:
765 Type = ELF::R_X86_64_GOTPCREL;
766 break;
767 case MCSymbolRefExpr::VK_TPOFF:
768 Type = ELF::R_X86_64_TPOFF32;
769 break;
770 case MCSymbolRefExpr::VK_DTPOFF:
771 Type = ELF::R_X86_64_DTPOFF32;
772 break;
773 }
774 break;
775 case FK_Data_4:
776 Type = ELF::R_X86_64_32;
777 break;
778 case FK_Data_2: Type = ELF::R_X86_64_16; break;
779 case X86::reloc_pcrel_1byte:
780 case FK_Data_1: Type = ELF::R_X86_64_8; break;
781 }
782 }
783 } else {
784 if (IsPCRel) {
785 switch (Modifier) {
786 default:
787 llvm_unreachable("Unimplemented");
788 case MCSymbolRefExpr::VK_None:
789 Type = ELF::R_386_PC32;
790 break;
791 case MCSymbolRefExpr::VK_PLT:
792 Type = ELF::R_386_PLT32;
793 break;
794 }
795 } else {
796 switch ((unsigned)Fixup.getKind()) {
797 default: llvm_unreachable("invalid fixup kind!");
798
799 case X86::reloc_global_offset_table:
800 Type = ELF::R_386_GOTPC;
801 break;
802
803 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
804 // instead?
805 case X86::reloc_signed_4byte:
806 case X86::reloc_pcrel_4byte:
807 case FK_Data_4:
808 switch (Modifier) {
809 default:
810 llvm_unreachable("Unimplemented");
811 case MCSymbolRefExpr::VK_None:
812 Type = ELF::R_386_32;
813 break;
814 case MCSymbolRefExpr::VK_GOT:
815 Type = ELF::R_386_GOT32;
816 break;
817 case MCSymbolRefExpr::VK_GOTOFF:
818 Type = ELF::R_386_GOTOFF;
819 break;
820 case MCSymbolRefExpr::VK_TLSGD:
821 Type = ELF::R_386_TLS_GD;
822 break;
823 case MCSymbolRefExpr::VK_TPOFF:
824 Type = ELF::R_386_TLS_LE_32;
825 break;
826 case MCSymbolRefExpr::VK_INDNTPOFF:
827 Type = ELF::R_386_TLS_IE;
828 break;
829 case MCSymbolRefExpr::VK_NTPOFF:
830 Type = ELF::R_386_TLS_LE;
831 break;
832 case MCSymbolRefExpr::VK_GOTNTPOFF:
833 Type = ELF::R_386_TLS_GOTIE;
834 break;
835 case MCSymbolRefExpr::VK_TLSLDM:
836 Type = ELF::R_386_TLS_LDM;
837 break;
838 case MCSymbolRefExpr::VK_DTPOFF:
839 Type = ELF::R_386_TLS_LDO_32;
840 break;
841 }
842 break;
843 case FK_Data_2: Type = ELF::R_386_16; break;
844 case X86::reloc_pcrel_1byte:
845 case FK_Data_1: Type = ELF::R_386_8; break;
846 }
847 }
848 }
849
850 if (RelocNeedsGOT(Modifier))
851 NeedsGOT = true;
852
853 ELFRelocationEntry ERE;
854
855 ERE.Index = Index;
856 ERE.Type = Type;
857 ERE.Symbol = Renamed;
858
859 ERE.r_offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
860
861 if (HasRelocationAddend)
862 ERE.r_addend = Addend;
863 else
864 ERE.r_addend = 0; // Silence compiler warning.
865
866 Relocations[Fragment->getParent()].push_back(ERE);
867 }
868 685
869 uint64_t 686 uint64_t
870 ELFObjectWriterImpl::getSymbolIndexInSymbolTable(const MCAssembler &Asm, 687 ELFObjectWriterImpl::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
871 const MCSymbol *S) { 688 const MCSymbol *S) {
872 MCSymbolData &SD = Asm.getSymbolData(*S); 689 MCSymbolData &SD = Asm.getSymbolData(*S);
873 690
874 // Local symbol. 691 // Local symbol.
875 if (!SD.isExternal() && !S->isUndefined()) 692 if (!SD.isExternal() && !S->isUndefined())
876 return SD.getIndex() + /* empty symbol */ 1; 693 return SD.getIndex() + /* empty symbol */ 1;
877 694
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 } 1184 }
1368 1185
1369 ELFObjectWriter::ELFObjectWriter(raw_ostream &OS, 1186 ELFObjectWriter::ELFObjectWriter(raw_ostream &OS,
1370 bool Is64Bit, 1187 bool Is64Bit,
1371 Triple::OSType OSType, 1188 Triple::OSType OSType,
1372 uint16_t EMachine, 1189 uint16_t EMachine,
1373 bool IsLittleEndian, 1190 bool IsLittleEndian,
1374 bool HasRelocationAddend) 1191 bool HasRelocationAddend)
1375 : MCObjectWriter(OS, IsLittleEndian) 1192 : MCObjectWriter(OS, IsLittleEndian)
1376 { 1193 {
1377 Impl = new ELFObjectWriterImpl(this, Is64Bit, EMachine, 1194 switch (EMachine) {
1195 case ELF::EM_MBLAZE:
1196 case ELF::EM_386:
1197 case ELF::EM_X86_64:
1198 Impl = new X86ELFObjectWriterImpl(this, Is64Bit, EMachine,
1378 HasRelocationAddend, OSType); 1199 HasRelocationAddend, OSType);
1200 break;
1201 case ELF::EM_ARM:
1202 Impl = new ARMELFObjectWriterImpl(this, Is64Bit, EMachine,
1203 HasRelocationAddend, OSType);
1204 break;
1205 default:
1206 assert(0 && "Unsupported EMachine"); break;
1207 }
1379 } 1208 }
1380 1209
1381 ELFObjectWriter::~ELFObjectWriter() { 1210 ELFObjectWriter::~ELFObjectWriter() {
1382 delete (ELFObjectWriterImpl*) Impl; 1211 delete (ELFObjectWriterImpl*) Impl;
1383 } 1212 }
1384 1213
1385 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) { 1214 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) {
1386 ((ELFObjectWriterImpl*) Impl)->ExecutePostLayoutBinding(Asm); 1215 ((ELFObjectWriterImpl*) Impl)->ExecutePostLayoutBinding(Asm);
1387 } 1216 }
1388 1217
(...skipping 11 matching lines...) Expand all
1400 bool IsPCRel, 1229 bool IsPCRel,
1401 const MCFragment *DF) const { 1230 const MCFragment *DF) const {
1402 return ((ELFObjectWriterImpl*) Impl)->IsFixupFullyResolved(Asm, Target, 1231 return ((ELFObjectWriterImpl*) Impl)->IsFixupFullyResolved(Asm, Target,
1403 IsPCRel, DF); 1232 IsPCRel, DF);
1404 } 1233 }
1405 1234
1406 void ELFObjectWriter::WriteObject(MCAssembler &Asm, 1235 void ELFObjectWriter::WriteObject(MCAssembler &Asm,
1407 const MCAsmLayout &Layout) { 1236 const MCAsmLayout &Layout) {
1408 ((ELFObjectWriterImpl*) Impl)->WriteObject(Asm, Layout); 1237 ((ELFObjectWriterImpl*) Impl)->WriteObject(Asm, Layout);
1409 } 1238 }
1239
1240
1241 //===- X86ELFObjectWriterImpl ---------------------------------------===//
1242
1243 X86ELFObjectWriterImpl::X86ELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _I s64Bit,
1244 uint16_t _EMachine, bool _HasRelAddend,
1245 Triple::OSType _OSType)
1246 : ELFObjectWriterImpl(_Writer, _Is64Bit, _EMachine, _HasRelAddend, _OSType)
1247 {}
1248
1249
1250 X86ELFObjectWriterImpl::~X86ELFObjectWriterImpl()
1251 {}
1252
1253 void X86ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
1254 const MCAsmLayout &Layout,
1255 const MCFragment *Fragment,
1256 const MCFixup &Fixup,
1257 MCValue Target,
1258 uint64_t &FixedValue) {
1259 int64_t Addend = 0;
1260 int Index = 0;
1261 int64_t Value = Target.getConstant();
1262 const MCSymbol *Symbol = 0;
1263 const MCSymbol *Renamed = 0;
1264
1265 bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
1266 if (!Target.isAbsolute()) {
1267 Symbol = &AliasedSymbol(Target.getSymA()->getSymbol());
1268 Renamed = Renames.lookup(Symbol);
1269 if (!Renamed)
1270 Renamed = &Target.getSymA()->getSymbol();
1271 MCSymbolData &SD = Asm.getSymbolData(*Symbol);
1272 MCFragment *F = SD.getFragment();
1273
1274 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1275 const MCSymbol &SymbolB = RefB->getSymbol();
1276 MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
1277 IsPCRel = true;
1278 MCSectionData *Sec = Fragment->getParent();
1279
1280 // Offset of the symbol in the section
1281 int64_t a = Layout.getSymbolAddress(&SDB) - Layout.getSectionAddress(Sec);
1282
1283 // Ofeset of the relocation in the section
1284 int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
1285 Value += b - a;
1286 }
1287
1288 // Check that this case has already been fully resolved before we get
1289 // here.
1290 if (Symbol->isDefined() && !SD.isExternal() &&
1291 IsPCRel &&
1292 &Fragment->getParent()->getSection() == &Symbol->getSection()) {
1293 llvm_unreachable("We don't need a relocation in this case.");
1294 return;
1295 }
1296
1297 bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target, *Fragment);
1298 if (!RelocOnSymbol) {
1299 Index = F->getParent()->getOrdinal();
1300
1301 MCSectionData *FSD = F->getParent();
1302 // Offset of the symbol in the section
1303 Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
1304 } else {
1305 UsedInReloc.insert(Renamed);
1306 MCSymbolData &RenamedSD = Asm.getSymbolData(*Renamed);
1307 if (RenamedSD.getFlags() & ELF_Other_Weakref) {
1308 WeakrefUsedInReloc.insert(Symbol);
1309 }
1310 Index = -1;
1311 }
1312 Addend = Value;
1313 // Compensate for the addend on i386.
1314 if (Is64Bit)
1315 Value = 0;
1316 }
1317
1318 FixedValue = Value;
1319
1320 // determine the type of the relocation
1321
1322 MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind();
1323 unsigned Type;
1324 if (Is64Bit) {
1325 if (IsPCRel) {
1326 switch (Modifier) {
1327 default:
1328 llvm_unreachable("Unimplemented");
1329 case MCSymbolRefExpr::VK_None:
1330 Type = ELF::R_X86_64_PC32;
1331 break;
1332 case MCSymbolRefExpr::VK_PLT:
1333 Type = ELF::R_X86_64_PLT32;
1334 break;
1335 case MCSymbolRefExpr::VK_GOTPCREL:
1336 Type = ELF::R_X86_64_GOTPCREL;
1337 break;
1338 case MCSymbolRefExpr::VK_GOTTPOFF:
1339 Type = ELF::R_X86_64_GOTTPOFF;
1340 break;
1341 case MCSymbolRefExpr::VK_TLSGD:
1342 Type = ELF::R_X86_64_TLSGD;
1343 break;
1344 case MCSymbolRefExpr::VK_TLSLD:
1345 Type = ELF::R_X86_64_TLSLD;
1346 break;
1347 }
1348 } else {
1349 switch ((unsigned)Fixup.getKind()) {
1350 default: llvm_unreachable("invalid fixup kind!");
1351 case FK_Data_8: Type = ELF::R_X86_64_64; break;
1352 case X86::reloc_signed_4byte:
1353 case X86::reloc_pcrel_4byte:
1354 assert(isInt<32>(Target.getConstant()));
1355 switch (Modifier) {
1356 default:
1357 llvm_unreachable("Unimplemented");
1358 case MCSymbolRefExpr::VK_None:
1359 Type = ELF::R_X86_64_32S;
1360 break;
1361 case MCSymbolRefExpr::VK_GOT:
1362 Type = ELF::R_X86_64_GOT32;
1363 break;
1364 case MCSymbolRefExpr::VK_GOTPCREL:
1365 Type = ELF::R_X86_64_GOTPCREL;
1366 break;
1367 case MCSymbolRefExpr::VK_TPOFF:
1368 Type = ELF::R_X86_64_TPOFF32;
1369 break;
1370 case MCSymbolRefExpr::VK_DTPOFF:
1371 Type = ELF::R_X86_64_DTPOFF32;
1372 break;
1373 }
1374 break;
1375 case FK_Data_4:
1376 Type = ELF::R_X86_64_32;
1377 break;
1378 case FK_Data_2: Type = ELF::R_X86_64_16; break;
1379 case X86::reloc_pcrel_1byte:
1380 case FK_Data_1: Type = ELF::R_X86_64_8; break;
1381 }
1382 }
1383 } else {
1384 if (IsPCRel) {
1385 switch (Modifier) {
1386 default:
1387 llvm_unreachable("Unimplemented");
1388 case MCSymbolRefExpr::VK_None:
1389 Type = ELF::R_386_PC32;
1390 break;
1391 case MCSymbolRefExpr::VK_PLT:
1392 Type = ELF::R_386_PLT32;
1393 break;
1394 }
1395 } else {
1396 switch ((unsigned)Fixup.getKind()) {
1397 default: llvm_unreachable("invalid fixup kind!");
1398
1399 case X86::reloc_global_offset_table:
1400 Type = ELF::R_386_GOTPC;
1401 break;
1402
1403 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
1404 // instead?
1405 case X86::reloc_signed_4byte:
1406 case X86::reloc_pcrel_4byte:
1407 case FK_Data_4:
1408 switch (Modifier) {
1409 default:
1410 llvm_unreachable("Unimplemented");
1411 case MCSymbolRefExpr::VK_None:
1412 Type = ELF::R_386_32;
1413 break;
1414 case MCSymbolRefExpr::VK_GOT:
1415 Type = ELF::R_386_GOT32;
1416 break;
1417 case MCSymbolRefExpr::VK_GOTOFF:
1418 Type = ELF::R_386_GOTOFF;
1419 break;
1420 case MCSymbolRefExpr::VK_TLSGD:
1421 Type = ELF::R_386_TLS_GD;
1422 break;
1423 case MCSymbolRefExpr::VK_TPOFF:
1424 Type = ELF::R_386_TLS_LE_32;
1425 break;
1426 case MCSymbolRefExpr::VK_INDNTPOFF:
1427 Type = ELF::R_386_TLS_IE;
1428 break;
1429 case MCSymbolRefExpr::VK_NTPOFF:
1430 Type = ELF::R_386_TLS_LE;
1431 break;
1432 case MCSymbolRefExpr::VK_GOTNTPOFF:
1433 Type = ELF::R_386_TLS_GOTIE;
1434 break;
1435 case MCSymbolRefExpr::VK_TLSLDM:
1436 Type = ELF::R_386_TLS_LDM;
1437 break;
1438 case MCSymbolRefExpr::VK_DTPOFF:
1439 Type = ELF::R_386_TLS_LDO_32;
1440 break;
1441 }
1442 break;
1443 case FK_Data_2: Type = ELF::R_386_16; break;
1444 case X86::reloc_pcrel_1byte:
1445 case FK_Data_1: Type = ELF::R_386_8; break;
1446 }
1447 }
1448 }
1449
1450 if (RelocNeedsGOT(Modifier))
1451 NeedsGOT = true;
1452
1453 ELFRelocationEntry ERE;
1454
1455 ERE.Index = Index;
1456 ERE.Type = Type;
1457 ERE.Symbol = Renamed;
1458
1459 ERE.r_offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
1460
1461 if (HasRelocationAddend)
1462 ERE.r_addend = Addend;
1463 else
1464 ERE.r_addend = 0; // Silence compiler warning.
1465
1466 Relocations[Fragment->getParent()].push_back(ERE);
1467 }
1468
1469
1470
1471 //===- ARMELFObjectWriterImpl ---------------------------------------===//
1472
1473 ARMELFObjectWriterImpl::ARMELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _I s64Bit,
1474 uint16_t _EMachine, bool _HasRelAddend,
1475 Triple::OSType _OSType)
1476 : ELFObjectWriterImpl(_Writer, _Is64Bit, _EMachine, _HasRelAddend, _OSType)
1477 {}
1478
1479
1480 ARMELFObjectWriterImpl::~ARMELFObjectWriterImpl()
1481 {}
1482
1483 void ARMELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
1484 const MCAsmLayout &Layout,
1485 const MCFragment *Fragment,
1486 const MCFixup &Fixup,
1487 MCValue Target,
1488 uint64_t &FixedValue) {
1489 assert(0 && "ARM RecordRelocation unimplemented");
1490 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698