1 //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements ELF object file writer information.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ADT/SmallPtrSet.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/MC/MCAssembler.h"
19 #include "llvm/MC/MCAsmLayout.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCELFSymbolFlags.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCELFObjectWriter.h"
24 #include "llvm/MC/MCObjectWriter.h"
25 #include "llvm/MC/MCSectionELF.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCValue.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include "llvm/Support/ELF.h"
31 #include "llvm/Target/TargetAsmBackend.h"
33 #include "../Target/X86/X86FixupKinds.h"
34 #include "../Target/ARM/ARMFixupKinds.h"
39 static unsigned GetType(const MCSymbolData
&SD
) {
40 uint32_t Type
= (SD
.getFlags() & (0xf << ELF_STT_Shift
)) >> ELF_STT_Shift
;
41 assert(Type
== ELF::STT_NOTYPE
|| Type
== ELF::STT_OBJECT
||
42 Type
== ELF::STT_FUNC
|| Type
== ELF::STT_SECTION
||
43 Type
== ELF::STT_FILE
|| Type
== ELF::STT_COMMON
||
44 Type
== ELF::STT_TLS
);
48 static unsigned GetBinding(const MCSymbolData
&SD
) {
49 uint32_t Binding
= (SD
.getFlags() & (0xf << ELF_STB_Shift
)) >> ELF_STB_Shift
;
50 assert(Binding
== ELF::STB_LOCAL
|| Binding
== ELF::STB_GLOBAL
||
51 Binding
== ELF::STB_WEAK
);
55 static void SetBinding(MCSymbolData
&SD
, unsigned Binding
) {
56 assert(Binding
== ELF::STB_LOCAL
|| Binding
== ELF::STB_GLOBAL
||
57 Binding
== ELF::STB_WEAK
);
58 uint32_t OtherFlags
= SD
.getFlags() & ~(0xf << ELF_STB_Shift
);
59 SD
.setFlags(OtherFlags
| (Binding
<< ELF_STB_Shift
));
62 static unsigned GetVisibility(MCSymbolData
&SD
) {
64 (SD
.getFlags() & (0xf << ELF_STV_Shift
)) >> ELF_STV_Shift
;
65 assert(Visibility
== ELF::STV_DEFAULT
|| Visibility
== ELF::STV_INTERNAL
||
66 Visibility
== ELF::STV_HIDDEN
|| Visibility
== ELF::STV_PROTECTED
);
71 static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant
) {
75 case MCSymbolRefExpr::VK_GOT
:
76 case MCSymbolRefExpr::VK_PLT
:
77 case MCSymbolRefExpr::VK_GOTPCREL
:
78 case MCSymbolRefExpr::VK_TPOFF
:
79 case MCSymbolRefExpr::VK_TLSGD
:
80 case MCSymbolRefExpr::VK_GOTTPOFF
:
81 case MCSymbolRefExpr::VK_INDNTPOFF
:
82 case MCSymbolRefExpr::VK_NTPOFF
:
83 case MCSymbolRefExpr::VK_GOTNTPOFF
:
84 case MCSymbolRefExpr::VK_TLSLDM
:
85 case MCSymbolRefExpr::VK_DTPOFF
:
86 case MCSymbolRefExpr::VK_TLSLD
:
91 static bool isFixupKindPCRel(const MCAssembler
&Asm
, unsigned Kind
) {
92 const MCFixupKindInfo
&FKI
=
93 Asm
.getBackend().getFixupKindInfo((MCFixupKind
) Kind
);
95 return FKI
.Flags
& MCFixupKindInfo::FKF_IsPCRel
;
99 class ELFObjectWriter
: public MCObjectWriter
{
101 /*static bool isFixupKindX86RIPRel(unsigned Kind) {
102 return Kind == X86::reloc_riprel_4byte ||
103 Kind == X86::reloc_riprel_4byte_movq_load;
107 /// ELFSymbolData - Helper struct for containing some precomputed information
109 struct ELFSymbolData
{
110 MCSymbolData
*SymbolData
;
111 uint64_t StringIndex
;
112 uint32_t SectionIndex
;
114 // Support lexicographic sorting.
115 bool operator<(const ELFSymbolData
&RHS
) const {
116 if (GetType(*SymbolData
) == ELF::STT_FILE
)
118 if (GetType(*RHS
.SymbolData
) == ELF::STT_FILE
)
120 return SymbolData
->getSymbol().getName() <
121 RHS
.SymbolData
->getSymbol().getName();
125 /// @name Relocation Data
128 struct ELFRelocationEntry
{
129 // Make these big enough for both 32-bit and 64-bit
133 const MCSymbol
*Symbol
;
137 : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {}
139 ELFRelocationEntry(uint64_t RelocOffset
, int Idx
,
140 unsigned RelType
, const MCSymbol
*Sym
,
142 : r_offset(RelocOffset
), Index(Idx
), Type(RelType
),
143 Symbol(Sym
), r_addend(Addend
) {}
145 // Support lexicographic sorting.
146 bool operator<(const ELFRelocationEntry
&RE
) const {
147 return RE
.r_offset
< r_offset
;
151 SmallPtrSet
<const MCSymbol
*, 16> UsedInReloc
;
152 SmallPtrSet
<const MCSymbol
*, 16> WeakrefUsedInReloc
;
153 DenseMap
<const MCSymbol
*, const MCSymbol
*> Renames
;
155 llvm::DenseMap
<const MCSectionData
*,
156 std::vector
<ELFRelocationEntry
> > Relocations
;
157 DenseMap
<const MCSection
*, uint64_t> SectionStringTableIndex
;
160 /// @name Symbol Table Data
163 SmallString
<256> StringTable
;
164 std::vector
<ELFSymbolData
> LocalSymbolData
;
165 std::vector
<ELFSymbolData
> ExternalSymbolData
;
166 std::vector
<ELFSymbolData
> UndefinedSymbolData
;
172 bool NeedsSymtabShndx
;
174 unsigned Is64Bit
: 1;
176 bool HasRelocationAddend
;
178 Triple::OSType OSType
;
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
;
189 unsigned ShstrtabIndex
;
192 const MCSymbol
*SymbolToReloc(const MCAssembler
&Asm
,
193 const MCValue
&Target
,
194 const MCFragment
&F
) const;
197 ELFObjectWriter(raw_ostream
&_OS
, bool _Is64Bit
, bool IsLittleEndian
,
198 uint16_t _EMachine
, bool _HasRelAddend
,
199 Triple::OSType _OSType
)
200 : MCObjectWriter(_OS
, IsLittleEndian
),
201 NeedsGOT(false), NeedsSymtabShndx(false),
202 Is64Bit(_Is64Bit
), HasRelocationAddend(_HasRelAddend
),
203 OSType(_OSType
), EMachine(_EMachine
) {
206 virtual ~ELFObjectWriter();
208 void WriteWord(uint64_t W
) {
215 void StringLE16(char *buf
, uint16_t Value
) {
216 buf
[0] = char(Value
>> 0);
217 buf
[1] = char(Value
>> 8);
220 void StringLE32(char *buf
, uint32_t Value
) {
221 StringLE16(buf
, uint16_t(Value
>> 0));
222 StringLE16(buf
+ 2, uint16_t(Value
>> 16));
225 void StringLE64(char *buf
, uint64_t Value
) {
226 StringLE32(buf
, uint32_t(Value
>> 0));
227 StringLE32(buf
+ 4, uint32_t(Value
>> 32));
230 void StringBE16(char *buf
,uint16_t Value
) {
231 buf
[0] = char(Value
>> 8);
232 buf
[1] = char(Value
>> 0);
235 void StringBE32(char *buf
, uint32_t Value
) {
236 StringBE16(buf
, uint16_t(Value
>> 16));
237 StringBE16(buf
+ 2, uint16_t(Value
>> 0));
240 void StringBE64(char *buf
, uint64_t Value
) {
241 StringBE32(buf
, uint32_t(Value
>> 32));
242 StringBE32(buf
+ 4, uint32_t(Value
>> 0));
245 void String8(MCDataFragment
&F
, uint8_t Value
) {
248 F
.getContents() += StringRef(buf
, 1);
251 void String16(MCDataFragment
&F
, uint16_t Value
) {
253 if (isLittleEndian())
254 StringLE16(buf
, Value
);
256 StringBE16(buf
, Value
);
257 F
.getContents() += StringRef(buf
, 2);
260 void String32(MCDataFragment
&F
, uint32_t Value
) {
262 if (isLittleEndian())
263 StringLE32(buf
, Value
);
265 StringBE32(buf
, Value
);
266 F
.getContents() += StringRef(buf
, 4);
269 void String64(MCDataFragment
&F
, uint64_t Value
) {
271 if (isLittleEndian())
272 StringLE64(buf
, Value
);
274 StringBE64(buf
, Value
);
275 F
.getContents() += StringRef(buf
, 8);
278 virtual void WriteHeader(uint64_t SectionDataSize
, unsigned NumberOfSections
);
280 virtual void WriteSymbolEntry(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
281 uint64_t name
, uint8_t info
,
282 uint64_t value
, uint64_t size
,
283 uint8_t other
, uint32_t shndx
,
286 virtual void WriteSymbol(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
288 const MCAsmLayout
&Layout
);
290 typedef DenseMap
<const MCSectionELF
*, uint32_t> SectionIndexMapTy
;
291 virtual void WriteSymbolTable(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
292 const MCAssembler
&Asm
,
293 const MCAsmLayout
&Layout
,
294 const SectionIndexMapTy
&SectionIndexMap
);
296 virtual void RecordRelocation(const MCAssembler
&Asm
, const MCAsmLayout
&Layout
,
297 const MCFragment
*Fragment
, const MCFixup
&Fixup
,
298 MCValue Target
, uint64_t &FixedValue
);
300 virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler
&Asm
,
303 // Map from a group section to the signature symbol
304 typedef DenseMap
<const MCSectionELF
*, const MCSymbol
*> GroupMapTy
;
305 // Map from a signature symbol to the group section
306 typedef DenseMap
<const MCSymbol
*, const MCSectionELF
*> RevGroupMapTy
;
308 /// ComputeSymbolTable - Compute the symbol table data
310 /// \param StringTable [out] - The string table data.
311 /// \param StringIndexMap [out] - Map from symbol names to offsets in the
313 virtual void ComputeSymbolTable(MCAssembler
&Asm
,
314 const SectionIndexMapTy
&SectionIndexMap
,
315 RevGroupMapTy RevGroupMap
);
317 virtual void ComputeIndexMap(MCAssembler
&Asm
,
318 SectionIndexMapTy
&SectionIndexMap
);
320 virtual void WriteRelocation(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
321 const MCSectionData
&SD
);
323 virtual void WriteRelocations(MCAssembler
&Asm
, MCAsmLayout
&Layout
) {
324 for (MCAssembler::const_iterator it
= Asm
.begin(),
325 ie
= Asm
.end(); it
!= ie
; ++it
) {
326 WriteRelocation(Asm
, Layout
, *it
);
330 virtual void CreateMetadataSections(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
331 const SectionIndexMapTy
&SectionIndexMap
);
333 virtual void CreateGroupSections(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
334 GroupMapTy
&GroupMap
, RevGroupMapTy
&RevGroupMap
);
336 virtual void ExecutePostLayoutBinding(MCAssembler
&Asm
,
337 const MCAsmLayout
&Layout
);
339 virtual void WriteSecHdrEntry(uint32_t Name
, uint32_t Type
, uint64_t Flags
,
340 uint64_t Address
, uint64_t Offset
,
341 uint64_t Size
, uint32_t Link
, uint32_t Info
,
342 uint64_t Alignment
, uint64_t EntrySize
);
344 virtual void WriteRelocationsFragment(const MCAssembler
&Asm
,
346 const MCSectionData
*SD
);
349 IsSymbolRefDifferenceFullyResolved(const MCAssembler
&Asm
,
350 const MCSymbolRefExpr
*A
,
351 const MCSymbolRefExpr
*B
) const {
352 // FIXME: Implement this!
356 virtual bool IsFixupFullyResolved(const MCAssembler
&Asm
,
357 const MCValue Target
,
359 const MCFragment
*DF
) const;
361 virtual void WriteObject(MCAssembler
&Asm
, const MCAsmLayout
&Layout
);
362 virtual void WriteSection(MCAssembler
&Asm
,
363 const SectionIndexMapTy
&SectionIndexMap
,
364 uint32_t GroupSymbolIndex
,
365 uint64_t Offset
, uint64_t Size
, uint64_t Alignment
,
366 const MCSectionELF
&Section
);
369 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
370 bool IsPCRel
, bool IsRelocWithSymbol
,
374 //===- X86ELFObjectWriter -------------------------------------------===//
376 class X86ELFObjectWriter
: public ELFObjectWriter
{
378 X86ELFObjectWriter(raw_ostream
&_OS
, bool _Is64Bit
, bool IsLittleEndian
,
379 uint16_t _EMachine
, bool _HasRelAddend
,
380 Triple::OSType _OSType
);
382 virtual ~X86ELFObjectWriter();
384 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
385 bool IsPCRel
, bool IsRelocWithSymbol
,
390 //===- ARMELFObjectWriter -------------------------------------------===//
392 class ARMELFObjectWriter
: public ELFObjectWriter
{
394 ARMELFObjectWriter(raw_ostream
&_OS
, bool _Is64Bit
, bool IsLittleEndian
,
395 uint16_t _EMachine
, bool _HasRelAddend
,
396 Triple::OSType _OSType
);
398 virtual ~ARMELFObjectWriter();
400 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
401 bool IsPCRel
, bool IsRelocWithSymbol
,
405 //===- MBlazeELFObjectWriter -------------------------------------------===//
407 class MBlazeELFObjectWriter
: public ELFObjectWriter
{
409 MBlazeELFObjectWriter(raw_ostream
&_OS
, bool _Is64Bit
, bool IsLittleEndian
,
410 uint16_t _EMachine
, bool _HasRelAddend
,
411 Triple::OSType _OSType
);
413 virtual ~MBlazeELFObjectWriter();
415 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
416 bool IsPCRel
, bool IsRelocWithSymbol
,
421 ELFObjectWriter::~ELFObjectWriter()
424 // Emit the ELF header.
425 void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize
,
426 unsigned NumberOfSections
) {
432 // emitWord method behaves differently for ELF32 and ELF64, writing
433 // 4 bytes in the former and 8 in the latter.
435 Write8(0x7f); // e_ident[EI_MAG0]
436 Write8('E'); // e_ident[EI_MAG1]
437 Write8('L'); // e_ident[EI_MAG2]
438 Write8('F'); // e_ident[EI_MAG3]
440 Write8(Is64Bit
? ELF::ELFCLASS64
: ELF::ELFCLASS32
); // e_ident[EI_CLASS]
443 Write8(isLittleEndian() ? ELF::ELFDATA2LSB
: ELF::ELFDATA2MSB
);
445 Write8(ELF::EV_CURRENT
); // e_ident[EI_VERSION]
448 case Triple::FreeBSD
: Write8(ELF::ELFOSABI_FREEBSD
); break;
449 case Triple::Linux
: Write8(ELF::ELFOSABI_LINUX
); break;
450 default: Write8(ELF::ELFOSABI_NONE
); break;
452 Write8(0); // e_ident[EI_ABIVERSION]
454 WriteZeros(ELF::EI_NIDENT
- ELF::EI_PAD
);
456 Write16(ELF::ET_REL
); // e_type
458 Write16(EMachine
); // e_machine = target
460 Write32(ELF::EV_CURRENT
); // e_version
461 WriteWord(0); // e_entry, no entry point in .o file
462 WriteWord(0); // e_phoff, no program header for .o
463 WriteWord(SectionDataSize
+ (Is64Bit
? sizeof(ELF::Elf64_Ehdr
) :
464 sizeof(ELF::Elf32_Ehdr
))); // e_shoff = sec hdr table off in bytes
466 // FIXME: Make this configurable.
467 Write32(0); // e_flags = whatever the target wants
469 // e_ehsize = ELF header size
470 Write16(Is64Bit
? sizeof(ELF::Elf64_Ehdr
) : sizeof(ELF::Elf32_Ehdr
));
472 Write16(0); // e_phentsize = prog header entry size
473 Write16(0); // e_phnum = # prog header entries = 0
475 // e_shentsize = Section header entry size
476 Write16(Is64Bit
? sizeof(ELF::Elf64_Shdr
) : sizeof(ELF::Elf32_Shdr
));
478 // e_shnum = # of section header ents
479 if (NumberOfSections
>= ELF::SHN_LORESERVE
)
482 Write16(NumberOfSections
);
484 // e_shstrndx = Section # of '.shstrtab'
485 if (NumberOfSections
>= ELF::SHN_LORESERVE
)
486 Write16(ELF::SHN_XINDEX
);
488 Write16(ShstrtabIndex
);
491 void ELFObjectWriter::WriteSymbolEntry(MCDataFragment
*SymtabF
,
492 MCDataFragment
*ShndxF
,
494 uint8_t info
, uint64_t value
,
495 uint64_t size
, uint8_t other
,
499 if (shndx
>= ELF::SHN_LORESERVE
&& !Reserved
)
500 String32(*ShndxF
, shndx
);
502 String32(*ShndxF
, 0);
505 uint16_t Index
= (shndx
>= ELF::SHN_LORESERVE
&& !Reserved
) ?
506 uint16_t(ELF::SHN_XINDEX
) : shndx
;
509 String32(*SymtabF
, name
); // st_name
510 String8(*SymtabF
, info
); // st_info
511 String8(*SymtabF
, other
); // st_other
512 String16(*SymtabF
, Index
); // st_shndx
513 String64(*SymtabF
, value
); // st_value
514 String64(*SymtabF
, size
); // st_size
516 String32(*SymtabF
, name
); // st_name
517 String32(*SymtabF
, value
); // st_value
518 String32(*SymtabF
, size
); // st_size
519 String8(*SymtabF
, info
); // st_info
520 String8(*SymtabF
, other
); // st_other
521 String16(*SymtabF
, Index
); // st_shndx
525 static uint64_t SymbolValue(MCSymbolData
&Data
, const MCAsmLayout
&Layout
) {
526 if (Data
.isCommon() && Data
.isExternal())
527 return Data
.getCommonAlignment();
529 const MCSymbol
&Symbol
= Data
.getSymbol();
530 if (!Symbol
.isInSection())
533 if (Data
.getFragment())
534 return Layout
.getSymbolOffset(&Data
);
539 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler
&Asm
,
540 const MCAsmLayout
&Layout
) {
541 // The presence of symbol versions causes undefined symbols and
542 // versions declared with @@@ to be renamed.
544 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
545 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
546 const MCSymbol
&Alias
= it
->getSymbol();
547 const MCSymbol
&Symbol
= Alias
.AliasedSymbol();
548 MCSymbolData
&SD
= Asm
.getSymbolData(Symbol
);
551 if (&Symbol
== &Alias
)
554 StringRef AliasName
= Alias
.getName();
555 size_t Pos
= AliasName
.find('@');
556 if (Pos
== StringRef::npos
)
559 // Aliases defined with .symvar copy the binding from the symbol they alias.
560 // This is the first place we are able to copy this information.
561 it
->setExternal(SD
.isExternal());
562 SetBinding(*it
, GetBinding(SD
));
564 StringRef Rest
= AliasName
.substr(Pos
);
565 if (!Symbol
.isUndefined() && !Rest
.startswith("@@@"))
568 // FIXME: produce a better error message.
569 if (Symbol
.isUndefined() && Rest
.startswith("@@") &&
570 !Rest
.startswith("@@@"))
571 report_fatal_error("A @@ version cannot be undefined");
573 Renames
.insert(std::make_pair(&Symbol
, &Alias
));
577 void ELFObjectWriter::WriteSymbol(MCDataFragment
*SymtabF
,
578 MCDataFragment
*ShndxF
,
580 const MCAsmLayout
&Layout
) {
581 MCSymbolData
&OrigData
= *MSD
.SymbolData
;
583 Layout
.getAssembler().getSymbolData(OrigData
.getSymbol().AliasedSymbol());
585 bool IsReserved
= Data
.isCommon() || Data
.getSymbol().isAbsolute() ||
586 Data
.getSymbol().isVariable();
588 uint8_t Binding
= GetBinding(OrigData
);
589 uint8_t Visibility
= GetVisibility(OrigData
);
590 uint8_t Type
= GetType(Data
);
592 uint8_t Info
= (Binding
<< ELF_STB_Shift
) | (Type
<< ELF_STT_Shift
);
593 uint8_t Other
= Visibility
;
595 uint64_t Value
= SymbolValue(Data
, Layout
);
599 assert(!(Data
.isCommon() && !Data
.isExternal()));
601 ESize
= Data
.getSize();
602 if (Data
.getSize()) {
604 if (ESize
->getKind() == MCExpr::Binary
) {
605 const MCBinaryExpr
*BE
= static_cast<const MCBinaryExpr
*>(ESize
);
607 if (BE
->EvaluateAsRelocatable(Res
, &Layout
)) {
608 assert(!Res
.getSymA() || !Res
.getSymA()->getSymbol().isDefined());
609 assert(!Res
.getSymB() || !Res
.getSymB()->getSymbol().isDefined());
610 Size
= Res
.getConstant();
612 } else if (ESize
->getKind() == MCExpr::Constant
) {
613 Size
= static_cast<const MCConstantExpr
*>(ESize
)->getValue();
615 assert(0 && "Unsupported size expression");
619 // Write out the symbol table entry
620 WriteSymbolEntry(SymtabF
, ShndxF
, MSD
.StringIndex
, Info
, Value
,
621 Size
, Other
, MSD
.SectionIndex
, IsReserved
);
624 void ELFObjectWriter::WriteSymbolTable(MCDataFragment
*SymtabF
,
625 MCDataFragment
*ShndxF
,
626 const MCAssembler
&Asm
,
627 const MCAsmLayout
&Layout
,
628 const SectionIndexMapTy
&SectionIndexMap
) {
629 // The string table must be emitted first because we need the index
630 // into the string table for all the symbol names.
631 assert(StringTable
.size() && "Missing string table");
633 // FIXME: Make sure the start of the symbol table is aligned.
635 // The first entry is the undefined symbol entry.
636 WriteSymbolEntry(SymtabF
, ShndxF
, 0, 0, 0, 0, 0, 0, false);
638 // Write the symbol table entries.
639 LastLocalSymbolIndex
= LocalSymbolData
.size() + 1;
640 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
) {
641 ELFSymbolData
&MSD
= LocalSymbolData
[i
];
642 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
645 // Write out a symbol table entry for each regular section.
646 for (MCAssembler::const_iterator i
= Asm
.begin(), e
= Asm
.end(); i
!= e
;
648 const MCSectionELF
&Section
=
649 static_cast<const MCSectionELF
&>(i
->getSection());
650 if (Section
.getType() == ELF::SHT_RELA
||
651 Section
.getType() == ELF::SHT_REL
||
652 Section
.getType() == ELF::SHT_STRTAB
||
653 Section
.getType() == ELF::SHT_SYMTAB
)
655 WriteSymbolEntry(SymtabF
, ShndxF
, 0, ELF::STT_SECTION
, 0, 0,
656 ELF::STV_DEFAULT
, SectionIndexMap
.lookup(&Section
), false);
657 LastLocalSymbolIndex
++;
660 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
) {
661 ELFSymbolData
&MSD
= ExternalSymbolData
[i
];
662 MCSymbolData
&Data
= *MSD
.SymbolData
;
663 assert(((Data
.getFlags() & ELF_STB_Global
) ||
664 (Data
.getFlags() & ELF_STB_Weak
)) &&
665 "External symbol requires STB_GLOBAL or STB_WEAK flag");
666 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
667 if (GetBinding(Data
) == ELF::STB_LOCAL
)
668 LastLocalSymbolIndex
++;
671 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
) {
672 ELFSymbolData
&MSD
= UndefinedSymbolData
[i
];
673 MCSymbolData
&Data
= *MSD
.SymbolData
;
674 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
675 if (GetBinding(Data
) == ELF::STB_LOCAL
)
676 LastLocalSymbolIndex
++;
680 const MCSymbol
*ELFObjectWriter::SymbolToReloc(const MCAssembler
&Asm
,
681 const MCValue
&Target
,
682 const MCFragment
&F
) const {
683 const MCSymbol
&Symbol
= Target
.getSymA()->getSymbol();
684 const MCSymbol
&ASymbol
= Symbol
.AliasedSymbol();
685 const MCSymbol
*Renamed
= Renames
.lookup(&Symbol
);
686 const MCSymbolData
&SD
= Asm
.getSymbolData(Symbol
);
688 if (ASymbol
.isUndefined()) {
694 if (SD
.isExternal()) {
700 const MCSectionELF
&Section
=
701 static_cast<const MCSectionELF
&>(ASymbol
.getSection());
702 const SectionKind secKind
= Section
.getKind();
707 if (secKind
.isThreadLocal()) {
713 MCSymbolRefExpr::VariantKind Kind
= Target
.getSymA()->getKind();
714 const MCSectionELF
&Sec2
=
715 static_cast<const MCSectionELF
&>(F
.getParent()->getSection());
717 if (&Sec2
!= &Section
&&
718 (Kind
== MCSymbolRefExpr::VK_PLT
||
719 Kind
== MCSymbolRefExpr::VK_GOTPCREL
||
720 Kind
== MCSymbolRefExpr::VK_GOTOFF
)) {
726 if (Section
.getFlags() & MCSectionELF::SHF_MERGE
) {
727 if (Target
.getConstant() == 0)
738 void ELFObjectWriter::RecordRelocation(const MCAssembler
&Asm
,
739 const MCAsmLayout
&Layout
,
740 const MCFragment
*Fragment
,
741 const MCFixup
&Fixup
,
743 uint64_t &FixedValue
) {
746 int64_t Value
= Target
.getConstant();
747 const MCSymbol
*RelocSymbol
= NULL
;
749 bool IsPCRel
= isFixupKindPCRel(Asm
, Fixup
.getKind());
750 if (!Target
.isAbsolute()) {
751 const MCSymbol
&Symbol
= Target
.getSymA()->getSymbol();
752 const MCSymbol
&ASymbol
= Symbol
.AliasedSymbol();
753 RelocSymbol
= SymbolToReloc(Asm
, Target
, *Fragment
);
755 if (const MCSymbolRefExpr
*RefB
= Target
.getSymB()) {
756 const MCSymbol
&SymbolB
= RefB
->getSymbol();
757 MCSymbolData
&SDB
= Asm
.getSymbolData(SymbolB
);
760 // Offset of the symbol in the section
761 int64_t a
= Layout
.getSymbolOffset(&SDB
);
763 // Ofeset of the relocation in the section
764 int64_t b
= Layout
.getFragmentOffset(Fragment
) + Fixup
.getOffset();
769 MCSymbolData
&SD
= Asm
.getSymbolData(ASymbol
);
770 MCFragment
*F
= SD
.getFragment();
772 Index
= F
->getParent()->getOrdinal() + 1;
774 // Offset of the symbol in the section
775 Value
+= Layout
.getSymbolOffset(&SD
);
777 if (Asm
.getSymbolData(Symbol
).getFlags() & ELF_Other_Weakref
)
778 WeakrefUsedInReloc
.insert(RelocSymbol
);
780 UsedInReloc
.insert(RelocSymbol
);
784 // Compensate for the addend on i386.
790 unsigned Type
= GetRelocType(Target
, Fixup
, IsPCRel
,
791 (RelocSymbol
!= 0), Addend
);
793 uint64_t RelocOffset
= Layout
.getFragmentOffset(Fragment
) +
796 if (!HasRelocationAddend
) Addend
= 0;
797 ELFRelocationEntry
ERE(RelocOffset
, Index
, Type
, RelocSymbol
, Addend
);
798 Relocations
[Fragment
->getParent()].push_back(ERE
);
803 ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler
&Asm
,
805 MCSymbolData
&SD
= Asm
.getSymbolData(*S
);
806 return SD
.getIndex();
809 static bool isInSymtab(const MCAssembler
&Asm
, const MCSymbolData
&Data
,
810 bool Used
, bool Renamed
) {
811 if (Data
.getFlags() & ELF_Other_Weakref
)
820 const MCSymbol
&Symbol
= Data
.getSymbol();
822 if (Symbol
.getName() == "_GLOBAL_OFFSET_TABLE_")
825 const MCSymbol
&A
= Symbol
.AliasedSymbol();
826 if (!A
.isVariable() && A
.isUndefined() && !Data
.isCommon())
829 if (!Asm
.isSymbolLinkerVisible(Symbol
) && !Symbol
.isUndefined())
832 if (Symbol
.isTemporary())
838 static bool isLocal(const MCSymbolData
&Data
, bool isSignature
,
839 bool isUsedInReloc
) {
840 if (Data
.isExternal())
843 const MCSymbol
&Symbol
= Data
.getSymbol();
844 const MCSymbol
&RefSymbol
= Symbol
.AliasedSymbol();
846 if (RefSymbol
.isUndefined() && !RefSymbol
.isVariable()) {
847 if (isSignature
&& !isUsedInReloc
)
856 void ELFObjectWriter::ComputeIndexMap(MCAssembler
&Asm
,
857 SectionIndexMapTy
&SectionIndexMap
) {
859 for (MCAssembler::iterator it
= Asm
.begin(),
860 ie
= Asm
.end(); it
!= ie
; ++it
) {
861 const MCSectionELF
&Section
=
862 static_cast<const MCSectionELF
&>(it
->getSection());
863 if (Section
.getType() != ELF::SHT_GROUP
)
865 SectionIndexMap
[&Section
] = Index
++;
868 for (MCAssembler::iterator it
= Asm
.begin(),
869 ie
= Asm
.end(); it
!= ie
; ++it
) {
870 const MCSectionELF
&Section
=
871 static_cast<const MCSectionELF
&>(it
->getSection());
872 if (Section
.getType() == ELF::SHT_GROUP
)
874 SectionIndexMap
[&Section
] = Index
++;
878 void ELFObjectWriter::ComputeSymbolTable(MCAssembler
&Asm
,
879 const SectionIndexMapTy
&SectionIndexMap
,
880 RevGroupMapTy RevGroupMap
) {
881 // FIXME: Is this the correct place to do this?
883 llvm::StringRef Name
= "_GLOBAL_OFFSET_TABLE_";
884 MCSymbol
*Sym
= Asm
.getContext().GetOrCreateSymbol(Name
);
885 MCSymbolData
&Data
= Asm
.getOrCreateSymbolData(*Sym
);
886 Data
.setExternal(true);
887 SetBinding(Data
, ELF::STB_GLOBAL
);
890 // Build section lookup table.
891 int NumRegularSections
= Asm
.size();
893 // Index 0 is always the empty string.
894 StringMap
<uint64_t> StringIndexMap
;
895 StringTable
+= '\x00';
897 // Add the data for the symbols.
898 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
899 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
900 const MCSymbol
&Symbol
= it
->getSymbol();
902 bool Used
= UsedInReloc
.count(&Symbol
);
903 bool WeakrefUsed
= WeakrefUsedInReloc
.count(&Symbol
);
904 bool isSignature
= RevGroupMap
.count(&Symbol
);
906 if (!isInSymtab(Asm
, *it
,
907 Used
|| WeakrefUsed
|| isSignature
,
908 Renames
.count(&Symbol
)))
913 const MCSymbol
&RefSymbol
= Symbol
.AliasedSymbol();
915 // Undefined symbols are global, but this is the first place we
916 // are able to set it.
917 bool Local
= isLocal(*it
, isSignature
, Used
);
918 if (!Local
&& GetBinding(*it
) == ELF::STB_LOCAL
) {
919 MCSymbolData
&SD
= Asm
.getSymbolData(RefSymbol
);
920 SetBinding(*it
, ELF::STB_GLOBAL
);
921 SetBinding(SD
, ELF::STB_GLOBAL
);
924 if (RefSymbol
.isUndefined() && !Used
&& WeakrefUsed
)
925 SetBinding(*it
, ELF::STB_WEAK
);
927 if (it
->isCommon()) {
929 MSD
.SectionIndex
= ELF::SHN_COMMON
;
930 } else if (Symbol
.isAbsolute() || RefSymbol
.isVariable()) {
931 MSD
.SectionIndex
= ELF::SHN_ABS
;
932 } else if (RefSymbol
.isUndefined()) {
933 if (isSignature
&& !Used
)
934 MSD
.SectionIndex
= SectionIndexMap
.lookup(RevGroupMap
[&Symbol
]);
936 MSD
.SectionIndex
= ELF::SHN_UNDEF
;
938 const MCSectionELF
&Section
=
939 static_cast<const MCSectionELF
&>(RefSymbol
.getSection());
940 MSD
.SectionIndex
= SectionIndexMap
.lookup(&Section
);
941 if (MSD
.SectionIndex
>= ELF::SHN_LORESERVE
)
942 NeedsSymtabShndx
= true;
943 assert(MSD
.SectionIndex
&& "Invalid section index!");
946 // The @@@ in symbol version is replaced with @ in undefined symbols and
947 // @@ in defined ones.
948 StringRef Name
= Symbol
.getName();
951 size_t Pos
= Name
.find("@@@");
952 if (Pos
!= StringRef::npos
) {
953 Buf
+= Name
.substr(0, Pos
);
954 unsigned Skip
= MSD
.SectionIndex
== ELF::SHN_UNDEF
? 2 : 1;
955 Buf
+= Name
.substr(Pos
+ Skip
);
959 uint64_t &Entry
= StringIndexMap
[Name
];
961 Entry
= StringTable
.size();
963 StringTable
+= '\x00';
965 MSD
.StringIndex
= Entry
;
966 if (MSD
.SectionIndex
== ELF::SHN_UNDEF
)
967 UndefinedSymbolData
.push_back(MSD
);
969 LocalSymbolData
.push_back(MSD
);
971 ExternalSymbolData
.push_back(MSD
);
974 // Symbols are required to be in lexicographic order.
975 array_pod_sort(LocalSymbolData
.begin(), LocalSymbolData
.end());
976 array_pod_sort(ExternalSymbolData
.begin(), ExternalSymbolData
.end());
977 array_pod_sort(UndefinedSymbolData
.begin(), UndefinedSymbolData
.end());
979 // Set the symbol indices. Local symbols must come before all other
980 // symbols with non-local bindings.
982 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
)
983 LocalSymbolData
[i
].SymbolData
->setIndex(Index
++);
985 Index
+= NumRegularSections
;
987 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
)
988 ExternalSymbolData
[i
].SymbolData
->setIndex(Index
++);
989 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
)
990 UndefinedSymbolData
[i
].SymbolData
->setIndex(Index
++);
993 void ELFObjectWriter::WriteRelocation(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
994 const MCSectionData
&SD
) {
995 if (!Relocations
[&SD
].empty()) {
996 MCContext
&Ctx
= Asm
.getContext();
997 const MCSectionELF
*RelaSection
;
998 const MCSectionELF
&Section
=
999 static_cast<const MCSectionELF
&>(SD
.getSection());
1001 const StringRef SectionName
= Section
.getSectionName();
1002 std::string RelaSectionName
= HasRelocationAddend
? ".rela" : ".rel";
1003 RelaSectionName
+= SectionName
;
1006 if (HasRelocationAddend
)
1007 EntrySize
= Is64Bit
? sizeof(ELF::Elf64_Rela
) : sizeof(ELF::Elf32_Rela
);
1009 EntrySize
= Is64Bit
? sizeof(ELF::Elf64_Rel
) : sizeof(ELF::Elf32_Rel
);
1011 RelaSection
= Ctx
.getELFSection(RelaSectionName
, HasRelocationAddend
?
1012 ELF::SHT_RELA
: ELF::SHT_REL
, 0,
1013 SectionKind::getReadOnly(),
1016 MCSectionData
&RelaSD
= Asm
.getOrCreateSectionData(*RelaSection
);
1017 RelaSD
.setAlignment(Is64Bit
? 8 : 4);
1019 MCDataFragment
*F
= new MCDataFragment(&RelaSD
);
1021 WriteRelocationsFragment(Asm
, F
, &SD
);
1025 void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name
, uint32_t Type
,
1026 uint64_t Flags
, uint64_t Address
,
1027 uint64_t Offset
, uint64_t Size
,
1028 uint32_t Link
, uint32_t Info
,
1030 uint64_t EntrySize
) {
1031 Write32(Name
); // sh_name: index into string table
1032 Write32(Type
); // sh_type
1033 WriteWord(Flags
); // sh_flags
1034 WriteWord(Address
); // sh_addr
1035 WriteWord(Offset
); // sh_offset
1036 WriteWord(Size
); // sh_size
1037 Write32(Link
); // sh_link
1038 Write32(Info
); // sh_info
1039 WriteWord(Alignment
); // sh_addralign
1040 WriteWord(EntrySize
); // sh_entsize
1043 void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler
&Asm
,
1045 const MCSectionData
*SD
) {
1046 std::vector
<ELFRelocationEntry
> &Relocs
= Relocations
[SD
];
1047 // sort by the r_offset just like gnu as does
1048 array_pod_sort(Relocs
.begin(), Relocs
.end());
1050 for (unsigned i
= 0, e
= Relocs
.size(); i
!= e
; ++i
) {
1051 ELFRelocationEntry entry
= Relocs
[e
- i
- 1];
1055 else if (entry
.Index
< 0)
1056 entry
.Index
= getSymbolIndexInSymbolTable(Asm
, entry
.Symbol
);
1058 entry
.Index
+= LocalSymbolData
.size();
1060 String64(*F
, entry
.r_offset
);
1062 struct ELF::Elf64_Rela ERE64
;
1063 ERE64
.setSymbolAndType(entry
.Index
, entry
.Type
);
1064 String64(*F
, ERE64
.r_info
);
1066 if (HasRelocationAddend
)
1067 String64(*F
, entry
.r_addend
);
1069 String32(*F
, entry
.r_offset
);
1071 struct ELF::Elf32_Rela ERE32
;
1072 ERE32
.setSymbolAndType(entry
.Index
, entry
.Type
);
1073 String32(*F
, ERE32
.r_info
);
1075 if (HasRelocationAddend
)
1076 String32(*F
, entry
.r_addend
);
1081 void ELFObjectWriter::CreateMetadataSections(MCAssembler
&Asm
,
1082 MCAsmLayout
&Layout
,
1083 const SectionIndexMapTy
&SectionIndexMap
) {
1084 MCContext
&Ctx
= Asm
.getContext();
1087 unsigned EntrySize
= Is64Bit
? ELF::SYMENTRY_SIZE64
: ELF::SYMENTRY_SIZE32
;
1089 // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
1090 const MCSectionELF
*ShstrtabSection
=
1091 Ctx
.getELFSection(".shstrtab", ELF::SHT_STRTAB
, 0,
1092 SectionKind::getReadOnly());
1093 MCSectionData
&ShstrtabSD
= Asm
.getOrCreateSectionData(*ShstrtabSection
);
1094 ShstrtabSD
.setAlignment(1);
1095 ShstrtabIndex
= Asm
.size();
1097 const MCSectionELF
*SymtabSection
=
1098 Ctx
.getELFSection(".symtab", ELF::SHT_SYMTAB
, 0,
1099 SectionKind::getReadOnly(),
1101 MCSectionData
&SymtabSD
= Asm
.getOrCreateSectionData(*SymtabSection
);
1102 SymtabSD
.setAlignment(Is64Bit
? 8 : 4);
1103 SymbolTableIndex
= Asm
.size();
1105 MCSectionData
*SymtabShndxSD
= NULL
;
1107 if (NeedsSymtabShndx
) {
1108 const MCSectionELF
*SymtabShndxSection
=
1109 Ctx
.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX
, 0,
1110 SectionKind::getReadOnly(), 4, "");
1111 SymtabShndxSD
= &Asm
.getOrCreateSectionData(*SymtabShndxSection
);
1112 SymtabShndxSD
->setAlignment(4);
1115 const MCSection
*StrtabSection
;
1116 StrtabSection
= Ctx
.getELFSection(".strtab", ELF::SHT_STRTAB
, 0,
1117 SectionKind::getReadOnly());
1118 MCSectionData
&StrtabSD
= Asm
.getOrCreateSectionData(*StrtabSection
);
1119 StrtabSD
.setAlignment(1);
1120 StringTableIndex
= Asm
.size();
1122 WriteRelocations(Asm
, Layout
);
1125 F
= new MCDataFragment(&SymtabSD
);
1126 MCDataFragment
*ShndxF
= NULL
;
1127 if (NeedsSymtabShndx
) {
1128 ShndxF
= new MCDataFragment(SymtabShndxSD
);
1130 WriteSymbolTable(F
, ShndxF
, Asm
, Layout
, SectionIndexMap
);
1132 F
= new MCDataFragment(&StrtabSD
);
1133 F
->getContents().append(StringTable
.begin(), StringTable
.end());
1135 F
= new MCDataFragment(&ShstrtabSD
);
1137 // Section header string table.
1139 // The first entry of a string table holds a null character so skip
1142 F
->getContents() += '\x00';
1144 StringMap
<uint64_t> SecStringMap
;
1145 for (MCAssembler::const_iterator it
= Asm
.begin(),
1146 ie
= Asm
.end(); it
!= ie
; ++it
) {
1147 const MCSectionELF
&Section
=
1148 static_cast<const MCSectionELF
&>(it
->getSection());
1149 // FIXME: We could merge suffixes like in .text and .rela.text.
1151 StringRef Name
= Section
.getSectionName();
1152 if (SecStringMap
.count(Name
)) {
1153 SectionStringTableIndex
[&Section
] = SecStringMap
[Name
];
1156 // Remember the index into the string table so we can write it
1157 // into the sh_name field of the section header table.
1158 SectionStringTableIndex
[&Section
] = Index
;
1159 SecStringMap
[Name
] = Index
;
1161 Index
+= Name
.size() + 1;
1162 F
->getContents() += Name
;
1163 F
->getContents() += '\x00';
1167 bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler
&Asm
,
1168 const MCValue Target
,
1170 const MCFragment
*DF
) const {
1171 // If this is a PCrel relocation, find the section this fixup value is
1173 const MCSection
*BaseSection
= 0;
1175 BaseSection
= &DF
->getParent()->getSection();
1176 assert(BaseSection
);
1179 const MCSection
*SectionA
= 0;
1180 const MCSymbol
*SymbolA
= 0;
1181 if (const MCSymbolRefExpr
*A
= Target
.getSymA()) {
1182 SymbolA
= &A
->getSymbol();
1183 SectionA
= &SymbolA
->AliasedSymbol().getSection();
1186 const MCSection
*SectionB
= 0;
1187 const MCSymbol
*SymbolB
= 0;
1188 if (const MCSymbolRefExpr
*B
= Target
.getSymB()) {
1189 SymbolB
= &B
->getSymbol();
1190 SectionB
= &SymbolB
->AliasedSymbol().getSection();
1194 return SectionA
== SectionB
;
1199 // Absolute address but PCrel instruction, so we need a relocation.
1203 // FIXME: This is in here just to match gnu as output. If the two ends
1204 // are in the same section, there is nothing that the linker can do to
1206 const MCSymbolData
&DataA
= Asm
.getSymbolData(*SymbolA
);
1207 if (DataA
.isExternal())
1210 return BaseSection
== SectionA
;
1213 void ELFObjectWriter::CreateGroupSections(MCAssembler
&Asm
,
1214 MCAsmLayout
&Layout
,
1215 GroupMapTy
&GroupMap
,
1216 RevGroupMapTy
&RevGroupMap
) {
1218 for (MCAssembler::const_iterator it
= Asm
.begin(), ie
= Asm
.end();
1220 const MCSectionELF
&Section
=
1221 static_cast<const MCSectionELF
&>(it
->getSection());
1222 if (!(Section
.getFlags() & MCSectionELF::SHF_GROUP
))
1225 const MCSymbol
*SignatureSymbol
= Section
.getGroup();
1226 Asm
.getOrCreateSymbolData(*SignatureSymbol
);
1227 const MCSectionELF
*&Group
= RevGroupMap
[SignatureSymbol
];
1229 Group
= Asm
.getContext().CreateELFGroupSection();
1230 MCSectionData
&Data
= Asm
.getOrCreateSectionData(*Group
);
1231 Data
.setAlignment(4);
1232 MCDataFragment
*F
= new MCDataFragment(&Data
);
1233 String32(*F
, ELF::GRP_COMDAT
);
1235 GroupMap
[Group
] = SignatureSymbol
;
1238 // Add sections to the groups
1240 unsigned NumGroups
= RevGroupMap
.size();
1241 for (MCAssembler::const_iterator it
= Asm
.begin(), ie
= Asm
.end();
1242 it
!= ie
; ++it
, ++Index
) {
1243 const MCSectionELF
&Section
=
1244 static_cast<const MCSectionELF
&>(it
->getSection());
1245 if (!(Section
.getFlags() & MCSectionELF::SHF_GROUP
))
1247 const MCSectionELF
*Group
= RevGroupMap
[Section
.getGroup()];
1248 MCSectionData
&Data
= Asm
.getOrCreateSectionData(*Group
);
1249 // FIXME: we could use the previous fragment
1250 MCDataFragment
*F
= new MCDataFragment(&Data
);
1251 String32(*F
, NumGroups
+ Index
);
1255 void ELFObjectWriter::WriteSection(MCAssembler
&Asm
,
1256 const SectionIndexMapTy
&SectionIndexMap
,
1257 uint32_t GroupSymbolIndex
,
1258 uint64_t Offset
, uint64_t Size
,
1260 const MCSectionELF
&Section
) {
1261 uint64_t sh_link
= 0;
1262 uint64_t sh_info
= 0;
1264 switch(Section
.getType()) {
1265 case ELF::SHT_DYNAMIC
:
1266 sh_link
= SectionStringTableIndex
[&Section
];
1271 case ELF::SHT_RELA
: {
1272 const MCSectionELF
*SymtabSection
;
1273 const MCSectionELF
*InfoSection
;
1274 SymtabSection
= Asm
.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB
,
1276 SectionKind::getReadOnly());
1277 sh_link
= SectionIndexMap
.lookup(SymtabSection
);
1278 assert(sh_link
&& ".symtab not found");
1280 // Remove ".rel" and ".rela" prefixes.
1281 unsigned SecNameLen
= (Section
.getType() == ELF::SHT_REL
) ? 4 : 5;
1282 StringRef SectionName
= Section
.getSectionName().substr(SecNameLen
);
1284 InfoSection
= Asm
.getContext().getELFSection(SectionName
,
1285 ELF::SHT_PROGBITS
, 0,
1286 SectionKind::getReadOnly());
1287 sh_info
= SectionIndexMap
.lookup(InfoSection
);
1291 case ELF::SHT_SYMTAB
:
1292 case ELF::SHT_DYNSYM
:
1293 sh_link
= StringTableIndex
;
1294 sh_info
= LastLocalSymbolIndex
;
1297 case ELF::SHT_SYMTAB_SHNDX
:
1298 sh_link
= SymbolTableIndex
;
1301 case ELF::SHT_PROGBITS
:
1302 case ELF::SHT_STRTAB
:
1303 case ELF::SHT_NOBITS
:
1305 case ELF::SHT_ARM_ATTRIBUTES
:
1309 case ELF::SHT_GROUP
: {
1310 sh_link
= SymbolTableIndex
;
1311 sh_info
= GroupSymbolIndex
;
1316 assert(0 && "FIXME: sh_type value not supported!");
1320 WriteSecHdrEntry(SectionStringTableIndex
[&Section
], Section
.getType(),
1321 Section
.getFlags(), 0, Offset
, Size
, sh_link
, sh_info
,
1322 Alignment
, Section
.getEntrySize());
1325 static bool IsELFMetaDataSection(const MCSectionData
&SD
) {
1326 return SD
.getOrdinal() == ~UINT32_C(0) &&
1327 !SD
.getSection().isVirtualSection();
1330 static uint64_t DataSectionSize(const MCSectionData
&SD
) {
1332 for (MCSectionData::const_iterator i
= SD
.begin(), e
= SD
.end(); i
!= e
;
1334 const MCFragment
&F
= *i
;
1335 assert(F
.getKind() == MCFragment::FT_Data
);
1336 Ret
+= cast
<MCDataFragment
>(F
).getContents().size();
1341 static uint64_t GetSectionFileSize(const MCAsmLayout
&Layout
,
1342 const MCSectionData
&SD
) {
1343 if (IsELFMetaDataSection(SD
))
1344 return DataSectionSize(SD
);
1345 return Layout
.getSectionFileSize(&SD
);
1348 static uint64_t GetSectionAddressSize(const MCAsmLayout
&Layout
,
1349 const MCSectionData
&SD
) {
1350 if (IsELFMetaDataSection(SD
))
1351 return DataSectionSize(SD
);
1352 return Layout
.getSectionAddressSize(&SD
);
1355 static void WriteDataSectionData(ELFObjectWriter
*W
, const MCSectionData
&SD
) {
1356 for (MCSectionData::const_iterator i
= SD
.begin(), e
= SD
.end(); i
!= e
;
1358 const MCFragment
&F
= *i
;
1359 assert(F
.getKind() == MCFragment::FT_Data
);
1360 W
->WriteBytes(cast
<MCDataFragment
>(F
).getContents().str());
1364 void ELFObjectWriter::WriteObject(MCAssembler
&Asm
,
1365 const MCAsmLayout
&Layout
) {
1366 GroupMapTy GroupMap
;
1367 RevGroupMapTy RevGroupMap
;
1368 CreateGroupSections(Asm
, const_cast<MCAsmLayout
&>(Layout
), GroupMap
,
1371 SectionIndexMapTy SectionIndexMap
;
1373 ComputeIndexMap(Asm
, SectionIndexMap
);
1375 // Compute symbol table information.
1376 ComputeSymbolTable(Asm
, SectionIndexMap
, RevGroupMap
);
1378 CreateMetadataSections(const_cast<MCAssembler
&>(Asm
),
1379 const_cast<MCAsmLayout
&>(Layout
),
1382 // Update to include the metadata sections.
1383 ComputeIndexMap(Asm
, SectionIndexMap
);
1385 // Add 1 for the null section.
1386 unsigned NumSections
= Asm
.size() + 1;
1387 uint64_t NaturalAlignment
= Is64Bit
? 8 : 4;
1388 uint64_t HeaderSize
= Is64Bit
? sizeof(ELF::Elf64_Ehdr
) : sizeof(ELF::Elf32_Ehdr
);
1389 uint64_t FileOff
= HeaderSize
;
1391 std::vector
<const MCSectionELF
*> Sections
;
1392 Sections
.resize(NumSections
);
1394 for (SectionIndexMapTy::const_iterator i
=
1395 SectionIndexMap
.begin(), e
= SectionIndexMap
.end(); i
!= e
; ++i
) {
1396 const std::pair
<const MCSectionELF
*, uint32_t> &p
= *i
;
1397 Sections
[p
.second
] = p
.first
;
1400 for (unsigned i
= 1; i
< NumSections
; ++i
) {
1401 const MCSectionELF
&Section
= *Sections
[i
];
1402 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1404 FileOff
= RoundUpToAlignment(FileOff
, SD
.getAlignment());
1406 // Get the size of the section in the output file (including padding).
1407 FileOff
+= GetSectionFileSize(Layout
, SD
);
1410 FileOff
= RoundUpToAlignment(FileOff
, NaturalAlignment
);
1412 // Write out the ELF header ...
1413 WriteHeader(FileOff
- HeaderSize
, NumSections
);
1415 FileOff
= HeaderSize
;
1417 // ... then all of the sections ...
1418 DenseMap
<const MCSection
*, uint64_t> SectionOffsetMap
;
1420 for (unsigned i
= 1; i
< NumSections
; ++i
) {
1421 const MCSectionELF
&Section
= *Sections
[i
];
1422 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1424 uint64_t Padding
= OffsetToAlignment(FileOff
, SD
.getAlignment());
1425 WriteZeros(Padding
);
1428 // Remember the offset into the file for this section.
1429 SectionOffsetMap
[&Section
] = FileOff
;
1431 FileOff
+= GetSectionFileSize(Layout
, SD
);
1433 if (IsELFMetaDataSection(SD
))
1434 WriteDataSectionData(this, SD
);
1436 Asm
.WriteSectionData(&SD
, Layout
);
1439 uint64_t Padding
= OffsetToAlignment(FileOff
, NaturalAlignment
);
1440 WriteZeros(Padding
);
1443 // ... and then the section header table.
1444 // Should we align the section header table?
1446 // Null section first.
1447 uint64_t FirstSectionSize
=
1448 NumSections
>= ELF::SHN_LORESERVE
? NumSections
: 0;
1449 uint32_t FirstSectionLink
=
1450 ShstrtabIndex
>= ELF::SHN_LORESERVE
? ShstrtabIndex
: 0;
1451 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize
, FirstSectionLink
, 0, 0, 0);
1453 for (unsigned i
= 1; i
< NumSections
; ++i
) {
1454 const MCSectionELF
&Section
= *Sections
[i
];
1455 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1456 uint32_t GroupSymbolIndex
;
1457 if (Section
.getType() != ELF::SHT_GROUP
)
1458 GroupSymbolIndex
= 0;
1460 GroupSymbolIndex
= getSymbolIndexInSymbolTable(Asm
, GroupMap
[&Section
]);
1462 uint64_t Size
= GetSectionAddressSize(Layout
, SD
);
1464 WriteSection(Asm
, SectionIndexMap
, GroupSymbolIndex
,
1465 SectionOffsetMap
[&Section
], Size
,
1466 SD
.getAlignment(), Section
);
1470 MCObjectWriter
*llvm::createELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
1473 Triple::OSType OSType
,
1475 bool IsLittleEndian
,
1476 bool HasRelocationAddend
) {
1479 case ELF::EM_X86_64
:
1480 return new X86ELFObjectWriter(OS
, Is64Bit
, IsLittleEndian
, EMachine
,
1481 HasRelocationAddend
, OSType
); break;
1483 return new ARMELFObjectWriter(OS
, Is64Bit
, IsLittleEndian
, EMachine
,
1484 HasRelocationAddend
, OSType
); break;
1485 case ELF::EM_MBLAZE
:
1486 return new MBlazeELFObjectWriter(OS
, Is64Bit
, IsLittleEndian
, EMachine
,
1487 HasRelocationAddend
, OSType
); break;
1488 default: llvm_unreachable("Unsupported architecture"); break;
1493 /// START OF SUBCLASSES for ELFObjectWriter
1494 //===- ARMELFObjectWriter -------------------------------------------===//
1496 ARMELFObjectWriter::ARMELFObjectWriter(raw_ostream
&_OS
, bool _Is64Bit
,
1497 bool _IsLittleEndian
,
1498 uint16_t _EMachine
, bool _HasRelocationAddend
,
1499 Triple::OSType _OSType
)
1500 : ELFObjectWriter(_OS
, _Is64Bit
, _IsLittleEndian
, _EMachine
,
1501 _HasRelocationAddend
, _OSType
)
1504 ARMELFObjectWriter::~ARMELFObjectWriter()
1507 unsigned ARMELFObjectWriter::GetRelocType(const MCValue
&Target
,
1508 const MCFixup
&Fixup
,
1510 bool IsRelocWithSymbol
,
1512 MCSymbolRefExpr::VariantKind Modifier
= Target
.isAbsolute() ?
1513 MCSymbolRefExpr::VK_None
: Target
.getSymA()->getKind();
1517 switch ((unsigned)Fixup
.getKind()) {
1518 default: assert(0 && "Unimplemented");
1521 default: llvm_unreachable("Unsupported Modifier");
1522 case MCSymbolRefExpr::VK_None
:
1523 Type
= ELF::R_ARM_BASE_PREL
; break;
1524 case MCSymbolRefExpr::VK_ARM_TLSGD
:
1525 assert(0 && "unimplemented"); break;
1526 case MCSymbolRefExpr::VK_ARM_GOTTPOFF
:
1527 Type
= ELF::R_ARM_TLS_IE32
;
1529 case ARM::fixup_arm_branch
:
1531 case MCSymbolRefExpr::VK_ARM_PLT
:
1532 Type
= ELF::R_ARM_PLT32
; break;
1534 Type
= ELF::R_ARM_CALL
; break;
1538 switch ((unsigned)Fixup
.getKind()) {
1539 default: llvm_unreachable("invalid fixup kind!");
1542 default: llvm_unreachable("Unsupported Modifier"); break;
1543 case MCSymbolRefExpr::VK_ARM_GOT
:
1544 Type
= ELF::R_ARM_GOT_BREL
; break;
1545 case MCSymbolRefExpr::VK_ARM_TLSGD
:
1546 Type
= ELF::R_ARM_TLS_GD32
; break;
1547 case MCSymbolRefExpr::VK_ARM_TPOFF
:
1548 Type
= ELF::R_ARM_TLS_LE32
; break;
1549 case MCSymbolRefExpr::VK_ARM_GOTTPOFF
:
1550 Type
= ELF::R_ARM_TLS_IE32
; break;
1551 case MCSymbolRefExpr::VK_None
:
1552 Type
= ELF::R_ARM_ABS32
; break;
1553 case MCSymbolRefExpr::VK_ARM_GOTOFF
:
1554 Type
= ELF::R_ARM_GOTOFF32
; break;
1556 case ARM::fixup_arm_ldst_pcrel_12
:
1557 case ARM::fixup_arm_pcrel_10
:
1558 case ARM::fixup_arm_adr_pcrel_12
:
1559 case ARM::fixup_arm_thumb_bl
:
1560 case ARM::fixup_arm_thumb_cb
:
1561 case ARM::fixup_arm_thumb_cp
:
1562 case ARM::fixup_arm_thumb_br
:
1563 assert(0 && "Unimplemented"); break;
1564 case ARM::fixup_arm_branch
:
1565 // FIXME: Differentiate between R_ARM_CALL and
1566 // R_ARM_JUMP24 (latter used for conditional jumps)
1567 Type
= ELF::R_ARM_CALL
; break;
1568 case ARM::fixup_arm_movt_hi16
:
1569 Type
= ELF::R_ARM_MOVT_ABS
; break;
1570 case ARM::fixup_arm_movw_lo16
:
1571 Type
= ELF::R_ARM_MOVW_ABS_NC
; break;
1575 if (RelocNeedsGOT(Modifier
))
1581 //===- MBlazeELFObjectWriter -------------------------------------------===//
1583 MBlazeELFObjectWriter::MBlazeELFObjectWriter(raw_ostream
&_OS
, bool _Is64Bit
,
1584 bool _IsLittleEndian
,
1586 bool _HasRelocationAddend
,
1587 Triple::OSType _OSType
)
1588 : ELFObjectWriter(_OS
, _Is64Bit
, _IsLittleEndian
, _EMachine
,
1589 _HasRelocationAddend
, _OSType
) {
1592 MBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
1595 unsigned MBlazeELFObjectWriter::GetRelocType(const MCValue
&Target
,
1596 const MCFixup
&Fixup
,
1598 bool IsRelocWithSymbol
,
1600 // determine the type of the relocation
1603 switch ((unsigned)Fixup
.getKind()) {
1605 llvm_unreachable("Unimplemented");
1607 Type
= ELF::R_MICROBLAZE_64_PCREL
;
1610 Type
= ELF::R_MICROBLAZE_32_PCREL
;
1614 switch ((unsigned)Fixup
.getKind()) {
1615 default: llvm_unreachable("invalid fixup kind!");
1617 Type
= ((IsRelocWithSymbol
|| Addend
!=0)
1618 ? ELF::R_MICROBLAZE_32
1619 : ELF::R_MICROBLAZE_64
);
1622 Type
= ELF::R_MICROBLAZE_32
;
1629 //===- X86ELFObjectWriter -------------------------------------------===//
1632 X86ELFObjectWriter::X86ELFObjectWriter(raw_ostream
&_OS
, bool _Is64Bit
,
1633 bool _IsLittleEndian
,
1634 uint16_t _EMachine
, bool _HasRelocationAddend
,
1635 Triple::OSType _OSType
)
1636 : ELFObjectWriter(_OS
, _Is64Bit
, _IsLittleEndian
, _EMachine
,
1637 _HasRelocationAddend
, _OSType
)
1640 X86ELFObjectWriter::~X86ELFObjectWriter()
1643 unsigned X86ELFObjectWriter::GetRelocType(const MCValue
&Target
,
1644 const MCFixup
&Fixup
,
1646 bool IsRelocWithSymbol
,
1648 // determine the type of the relocation
1650 MCSymbolRefExpr::VariantKind Modifier
= Target
.isAbsolute() ?
1651 MCSymbolRefExpr::VK_None
: Target
.getSymA()->getKind();
1657 llvm_unreachable("Unimplemented");
1658 case MCSymbolRefExpr::VK_None
:
1659 Type
= ELF::R_X86_64_PC32
;
1661 case MCSymbolRefExpr::VK_PLT
:
1662 Type
= ELF::R_X86_64_PLT32
;
1664 case MCSymbolRefExpr::VK_GOTPCREL
:
1665 Type
= ELF::R_X86_64_GOTPCREL
;
1667 case MCSymbolRefExpr::VK_GOTTPOFF
:
1668 Type
= ELF::R_X86_64_GOTTPOFF
;
1670 case MCSymbolRefExpr::VK_TLSGD
:
1671 Type
= ELF::R_X86_64_TLSGD
;
1673 case MCSymbolRefExpr::VK_TLSLD
:
1674 Type
= ELF::R_X86_64_TLSLD
;
1678 switch ((unsigned)Fixup
.getKind()) {
1679 default: llvm_unreachable("invalid fixup kind!");
1680 case FK_Data_8
: Type
= ELF::R_X86_64_64
; break;
1681 case X86::reloc_signed_4byte
:
1683 assert(isInt
<32>(Target
.getConstant()));
1686 llvm_unreachable("Unimplemented");
1687 case MCSymbolRefExpr::VK_None
:
1688 Type
= ELF::R_X86_64_32S
;
1690 case MCSymbolRefExpr::VK_GOT
:
1691 Type
= ELF::R_X86_64_GOT32
;
1693 case MCSymbolRefExpr::VK_GOTPCREL
:
1694 Type
= ELF::R_X86_64_GOTPCREL
;
1696 case MCSymbolRefExpr::VK_TPOFF
:
1697 Type
= ELF::R_X86_64_TPOFF32
;
1699 case MCSymbolRefExpr::VK_DTPOFF
:
1700 Type
= ELF::R_X86_64_DTPOFF32
;
1705 Type
= ELF::R_X86_64_32
;
1707 case FK_Data_2
: Type
= ELF::R_X86_64_16
; break;
1709 case FK_Data_1
: Type
= ELF::R_X86_64_8
; break;
1716 llvm_unreachable("Unimplemented");
1717 case MCSymbolRefExpr::VK_None
:
1718 Type
= ELF::R_386_PC32
;
1720 case MCSymbolRefExpr::VK_PLT
:
1721 Type
= ELF::R_386_PLT32
;
1725 switch ((unsigned)Fixup
.getKind()) {
1726 default: llvm_unreachable("invalid fixup kind!");
1728 case X86::reloc_global_offset_table
:
1729 Type
= ELF::R_386_GOTPC
;
1732 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
1734 case X86::reloc_signed_4byte
:
1739 llvm_unreachable("Unimplemented");
1740 case MCSymbolRefExpr::VK_None
:
1741 Type
= ELF::R_386_32
;
1743 case MCSymbolRefExpr::VK_GOT
:
1744 Type
= ELF::R_386_GOT32
;
1746 case MCSymbolRefExpr::VK_GOTOFF
:
1747 Type
= ELF::R_386_GOTOFF
;
1749 case MCSymbolRefExpr::VK_TLSGD
:
1750 Type
= ELF::R_386_TLS_GD
;
1752 case MCSymbolRefExpr::VK_TPOFF
:
1753 Type
= ELF::R_386_TLS_LE_32
;
1755 case MCSymbolRefExpr::VK_INDNTPOFF
:
1756 Type
= ELF::R_386_TLS_IE
;
1758 case MCSymbolRefExpr::VK_NTPOFF
:
1759 Type
= ELF::R_386_TLS_LE
;
1761 case MCSymbolRefExpr::VK_GOTNTPOFF
:
1762 Type
= ELF::R_386_TLS_GOTIE
;
1764 case MCSymbolRefExpr::VK_TLSLDM
:
1765 Type
= ELF::R_386_TLS_LDM
;
1767 case MCSymbolRefExpr::VK_DTPOFF
:
1768 Type
= ELF::R_386_TLS_LDO_32
;
1772 case FK_Data_2
: Type
= ELF::R_386_16
; break;
1774 case FK_Data_1
: Type
= ELF::R_386_8
; break;
1779 if (RelocNeedsGOT(Modifier
))