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/MC/ELFObjectWriter.h"
15 #include "llvm/ADT/SmallPtrSet.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringMap.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/MC/MCAssembler.h"
20 #include "llvm/MC/MCAsmLayout.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCELFSymbolFlags.h"
23 #include "llvm/MC/MCExpr.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"
38 static unsigned GetType(const MCSymbolData
&SD
) {
39 uint32_t Type
= (SD
.getFlags() & (0xf << ELF_STT_Shift
)) >> ELF_STT_Shift
;
40 assert(Type
== ELF::STT_NOTYPE
|| Type
== ELF::STT_OBJECT
||
41 Type
== ELF::STT_FUNC
|| Type
== ELF::STT_SECTION
||
42 Type
== ELF::STT_FILE
|| Type
== ELF::STT_COMMON
||
43 Type
== ELF::STT_TLS
);
47 static unsigned GetBinding(const MCSymbolData
&SD
) {
48 uint32_t Binding
= (SD
.getFlags() & (0xf << ELF_STB_Shift
)) >> ELF_STB_Shift
;
49 assert(Binding
== ELF::STB_LOCAL
|| Binding
== ELF::STB_GLOBAL
||
50 Binding
== ELF::STB_WEAK
);
54 static void SetBinding(MCSymbolData
&SD
, unsigned Binding
) {
55 assert(Binding
== ELF::STB_LOCAL
|| Binding
== ELF::STB_GLOBAL
||
56 Binding
== ELF::STB_WEAK
);
57 uint32_t OtherFlags
= SD
.getFlags() & ~(0xf << ELF_STB_Shift
);
58 SD
.setFlags(OtherFlags
| (Binding
<< ELF_STB_Shift
));
61 static unsigned GetVisibility(MCSymbolData
&SD
) {
63 (SD
.getFlags() & (0xf << ELF_STV_Shift
)) >> ELF_STV_Shift
;
64 assert(Visibility
== ELF::STV_DEFAULT
|| Visibility
== ELF::STV_INTERNAL
||
65 Visibility
== ELF::STV_HIDDEN
|| Visibility
== ELF::STV_PROTECTED
);
69 static bool isFixupKindX86PCRel(unsigned Kind
) {
73 case X86::reloc_pcrel_1byte
:
74 case X86::reloc_pcrel_4byte
:
75 case X86::reloc_riprel_4byte
:
76 case X86::reloc_riprel_4byte_movq_load
:
81 static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant
) {
85 case MCSymbolRefExpr::VK_GOT
:
86 case MCSymbolRefExpr::VK_PLT
:
87 case MCSymbolRefExpr::VK_GOTPCREL
:
88 case MCSymbolRefExpr::VK_TPOFF
:
89 case MCSymbolRefExpr::VK_TLSGD
:
90 case MCSymbolRefExpr::VK_GOTTPOFF
:
91 case MCSymbolRefExpr::VK_INDNTPOFF
:
92 case MCSymbolRefExpr::VK_NTPOFF
:
93 case MCSymbolRefExpr::VK_GOTNTPOFF
:
94 case MCSymbolRefExpr::VK_TLSLDM
:
95 case MCSymbolRefExpr::VK_DTPOFF
:
96 case MCSymbolRefExpr::VK_TLSLD
:
103 class ELFObjectWriterImpl
{
104 /*static bool isFixupKindX86RIPRel(unsigned Kind) {
105 return Kind == X86::reloc_riprel_4byte ||
106 Kind == X86::reloc_riprel_4byte_movq_load;
110 /// ELFSymbolData - Helper struct for containing some precomputed information
112 struct ELFSymbolData
{
113 MCSymbolData
*SymbolData
;
114 uint64_t StringIndex
;
115 uint32_t SectionIndex
;
117 // Support lexicographic sorting.
118 bool operator<(const ELFSymbolData
&RHS
) const {
119 if (GetType(*SymbolData
) == ELF::STT_FILE
)
121 if (GetType(*RHS
.SymbolData
) == ELF::STT_FILE
)
123 return SymbolData
->getSymbol().getName() <
124 RHS
.SymbolData
->getSymbol().getName();
128 /// @name Relocation Data
131 struct ELFRelocationEntry
{
132 // Make these big enough for both 32-bit and 64-bit
136 const MCSymbol
*Symbol
;
139 // Support lexicographic sorting.
140 bool operator<(const ELFRelocationEntry
&RE
) const {
141 return RE
.r_offset
< r_offset
;
145 SmallPtrSet
<const MCSymbol
*, 16> UsedInReloc
;
146 SmallPtrSet
<const MCSymbol
*, 16> WeakrefUsedInReloc
;
147 DenseMap
<const MCSymbol
*, const MCSymbol
*> Renames
;
149 llvm::DenseMap
<const MCSectionData
*,
150 std::vector
<ELFRelocationEntry
> > Relocations
;
151 DenseMap
<const MCSection
*, uint64_t> SectionStringTableIndex
;
154 /// @name Symbol Table Data
157 SmallString
<256> StringTable
;
158 std::vector
<ELFSymbolData
> LocalSymbolData
;
159 std::vector
<ELFSymbolData
> ExternalSymbolData
;
160 std::vector
<ELFSymbolData
> UndefinedSymbolData
;
164 int NumRegularSections
;
168 bool NeedsSymtabShndx
;
170 ELFObjectWriter
*Writer
;
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 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
) {
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);
210 void WriteWord(uint64_t W
) {
217 void String8(char *buf
, uint8_t Value
) {
221 void StringLE16(char *buf
, uint16_t Value
) {
222 buf
[0] = char(Value
>> 0);
223 buf
[1] = char(Value
>> 8);
226 void StringLE32(char *buf
, uint32_t Value
) {
227 StringLE16(buf
, uint16_t(Value
>> 0));
228 StringLE16(buf
+ 2, uint16_t(Value
>> 16));
231 void StringLE64(char *buf
, uint64_t Value
) {
232 StringLE32(buf
, uint32_t(Value
>> 0));
233 StringLE32(buf
+ 4, uint32_t(Value
>> 32));
236 void StringBE16(char *buf
,uint16_t Value
) {
237 buf
[0] = char(Value
>> 8);
238 buf
[1] = char(Value
>> 0);
241 void StringBE32(char *buf
, uint32_t Value
) {
242 StringBE16(buf
, uint16_t(Value
>> 16));
243 StringBE16(buf
+ 2, uint16_t(Value
>> 0));
246 void StringBE64(char *buf
, uint64_t Value
) {
247 StringBE32(buf
, uint32_t(Value
>> 32));
248 StringBE32(buf
+ 4, uint32_t(Value
>> 0));
251 void String16(char *buf
, uint16_t Value
) {
252 if (Writer
->isLittleEndian())
253 StringLE16(buf
, Value
);
255 StringBE16(buf
, Value
);
258 void String32(char *buf
, uint32_t Value
) {
259 if (Writer
->isLittleEndian())
260 StringLE32(buf
, Value
);
262 StringBE32(buf
, Value
);
265 void String64(char *buf
, uint64_t Value
) {
266 if (Writer
->isLittleEndian())
267 StringLE64(buf
, Value
);
269 StringBE64(buf
, Value
);
272 void WriteHeader(uint64_t SectionDataSize
, unsigned NumberOfSections
);
274 void WriteSymbolEntry(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
275 uint64_t name
, uint8_t info
,
276 uint64_t value
, uint64_t size
,
277 uint8_t other
, uint32_t shndx
,
280 void WriteSymbol(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
282 const MCAsmLayout
&Layout
);
284 void WriteSymbolTable(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
285 const MCAssembler
&Asm
,
286 const MCAsmLayout
&Layout
,
287 unsigned NumRegularSections
);
289 void RecordRelocation(const MCAssembler
&Asm
, const MCAsmLayout
&Layout
,
290 const MCFragment
*Fragment
, const MCFixup
&Fixup
,
291 MCValue Target
, uint64_t &FixedValue
);
293 uint64_t getSymbolIndexInSymbolTable(const MCAssembler
&Asm
,
296 /// ComputeSymbolTable - Compute the symbol table data
298 /// \param StringTable [out] - The string table data.
299 /// \param StringIndexMap [out] - Map from symbol names to offsets in the
301 void ComputeSymbolTable(MCAssembler
&Asm
);
303 void WriteRelocation(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
304 const MCSectionData
&SD
);
306 void WriteRelocations(MCAssembler
&Asm
, MCAsmLayout
&Layout
) {
307 for (MCAssembler::const_iterator it
= Asm
.begin(),
308 ie
= Asm
.end(); it
!= ie
; ++it
) {
309 WriteRelocation(Asm
, Layout
, *it
);
313 void CreateMetadataSections(MCAssembler
&Asm
, MCAsmLayout
&Layout
);
315 void ExecutePostLayoutBinding(MCAssembler
&Asm
);
317 void WriteSecHdrEntry(uint32_t Name
, uint32_t Type
, uint64_t Flags
,
318 uint64_t Address
, uint64_t Offset
,
319 uint64_t Size
, uint32_t Link
, uint32_t Info
,
320 uint64_t Alignment
, uint64_t EntrySize
);
322 void WriteRelocationsFragment(const MCAssembler
&Asm
, MCDataFragment
*F
,
323 const MCSectionData
*SD
);
325 bool IsFixupFullyResolved(const MCAssembler
&Asm
,
326 const MCValue Target
,
328 const MCFragment
*DF
) const;
330 void WriteObject(MCAssembler
&Asm
, const MCAsmLayout
&Layout
);
335 // Emit the ELF header.
336 void ELFObjectWriterImpl::WriteHeader(uint64_t SectionDataSize
,
337 unsigned NumberOfSections
) {
343 // emitWord method behaves differently for ELF32 and ELF64, writing
344 // 4 bytes in the former and 8 in the latter.
346 Write8(0x7f); // e_ident[EI_MAG0]
347 Write8('E'); // e_ident[EI_MAG1]
348 Write8('L'); // e_ident[EI_MAG2]
349 Write8('F'); // e_ident[EI_MAG3]
351 Write8(Is64Bit
? ELF::ELFCLASS64
: ELF::ELFCLASS32
); // e_ident[EI_CLASS]
354 Write8(Writer
->isLittleEndian() ? ELF::ELFDATA2LSB
: ELF::ELFDATA2MSB
);
356 Write8(ELF::EV_CURRENT
); // e_ident[EI_VERSION]
359 case Triple::FreeBSD
: Write8(ELF::ELFOSABI_FREEBSD
); break;
360 case Triple::Linux
: Write8(ELF::ELFOSABI_LINUX
); break;
361 default: Write8(ELF::ELFOSABI_NONE
); break;
363 Write8(0); // e_ident[EI_ABIVERSION]
365 WriteZeros(ELF::EI_NIDENT
- ELF::EI_PAD
);
367 Write16(ELF::ET_REL
); // e_type
369 Write16(EMachine
); // e_machine = target
371 Write32(ELF::EV_CURRENT
); // e_version
372 WriteWord(0); // e_entry, no entry point in .o file
373 WriteWord(0); // e_phoff, no program header for .o
374 WriteWord(SectionDataSize
+ (Is64Bit
? sizeof(ELF::Elf64_Ehdr
) :
375 sizeof(ELF::Elf32_Ehdr
))); // e_shoff = sec hdr table off in bytes
377 // FIXME: Make this configurable.
378 Write32(0); // e_flags = whatever the target wants
380 // e_ehsize = ELF header size
381 Write16(Is64Bit
? sizeof(ELF::Elf64_Ehdr
) : sizeof(ELF::Elf32_Ehdr
));
383 Write16(0); // e_phentsize = prog header entry size
384 Write16(0); // e_phnum = # prog header entries = 0
386 // e_shentsize = Section header entry size
387 Write16(Is64Bit
? sizeof(ELF::Elf64_Shdr
) : sizeof(ELF::Elf32_Shdr
));
389 // e_shnum = # of section header ents
390 if (NumberOfSections
>= ELF::SHN_LORESERVE
)
393 Write16(NumberOfSections
);
395 // e_shstrndx = Section # of '.shstrtab'
396 if (NumberOfSections
>= ELF::SHN_LORESERVE
)
397 Write16(ELF::SHN_XINDEX
);
399 Write16(ShstrtabIndex
);
402 void ELFObjectWriterImpl::WriteSymbolEntry(MCDataFragment
*SymtabF
,
403 MCDataFragment
*ShndxF
,
405 uint8_t info
, uint64_t value
,
406 uint64_t size
, uint8_t other
,
411 if (shndx
>= ELF::SHN_LORESERVE
&& !Reserved
)
412 String32(buf
, shndx
);
415 ShndxF
->getContents() += StringRef(buf
, 4);
422 SymtabF
->getContents() += StringRef(buf
, 4); // st_name
425 SymtabF
->getContents() += StringRef(buf
, 1); // st_info
428 SymtabF
->getContents() += StringRef(buf
, 1); // st_other
430 if (shndx
>= ELF::SHN_LORESERVE
&& !Reserved
)
431 String16(buf
, ELF::SHN_XINDEX
);
433 String16(buf
, shndx
);
435 SymtabF
->getContents() += StringRef(buf
, 2); // st_shndx
437 String64(buf
, value
);
438 SymtabF
->getContents() += StringRef(buf
, 8); // st_value
441 SymtabF
->getContents() += StringRef(buf
, 8); // st_size
446 SymtabF
->getContents() += StringRef(buf
, 4); // st_name
448 String32(buf
, value
);
449 SymtabF
->getContents() += StringRef(buf
, 4); // st_value
452 SymtabF
->getContents() += StringRef(buf
, 4); // st_size
455 SymtabF
->getContents() += StringRef(buf
, 1); // st_info
458 SymtabF
->getContents() += StringRef(buf
, 1); // st_other
460 if (shndx
>= ELF::SHN_LORESERVE
&& !Reserved
)
461 String16(buf
, ELF::SHN_XINDEX
);
463 String16(buf
, shndx
);
465 SymtabF
->getContents() += StringRef(buf
, 2); // st_shndx
469 static uint64_t SymbolValue(MCSymbolData
&Data
, const MCAsmLayout
&Layout
) {
470 if (Data
.isCommon() && Data
.isExternal())
471 return Data
.getCommonAlignment();
473 const MCSymbol
&Symbol
= Data
.getSymbol();
474 if (!Symbol
.isInSection())
477 if (MCFragment
*FF
= Data
.getFragment())
478 return Layout
.getSymbolAddress(&Data
) -
479 Layout
.getSectionAddress(FF
->getParent());
484 static const MCSymbol
&AliasedSymbol(const MCSymbol
&Symbol
) {
485 const MCSymbol
*S
= &Symbol
;
486 while (S
->isVariable()) {
487 const MCExpr
*Value
= S
->getVariableValue();
488 if (Value
->getKind() != MCExpr::SymbolRef
)
490 const MCSymbolRefExpr
*Ref
= static_cast<const MCSymbolRefExpr
*>(Value
);
491 S
= &Ref
->getSymbol();
496 void ELFObjectWriterImpl::ExecutePostLayoutBinding(MCAssembler
&Asm
) {
497 // The presence of symbol versions causes undefined symbols and
498 // versions declared with @@@ to be renamed.
500 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
501 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
502 const MCSymbol
&Alias
= it
->getSymbol();
503 const MCSymbol
&Symbol
= AliasedSymbol(Alias
);
504 MCSymbolData
&SD
= Asm
.getSymbolData(Symbol
);
506 // Undefined symbols are global, but this is the first place we
507 // are able to set it.
508 if (Symbol
.isUndefined() && !Symbol
.isVariable()) {
509 if (GetBinding(SD
) == ELF::STB_LOCAL
) {
510 SetBinding(SD
, ELF::STB_GLOBAL
);
511 SetBinding(*it
, ELF::STB_GLOBAL
);
516 if (&Symbol
== &Alias
)
519 StringRef AliasName
= Alias
.getName();
520 size_t Pos
= AliasName
.find('@');
521 if (Pos
== StringRef::npos
)
524 // Aliases defined with .symvar copy the binding from the symbol they alias.
525 // This is the first place we are able to copy this information.
526 it
->setExternal(SD
.isExternal());
527 SetBinding(*it
, GetBinding(SD
));
529 StringRef Rest
= AliasName
.substr(Pos
);
530 if (!Symbol
.isUndefined() && !Rest
.startswith("@@@"))
533 // FIXME: produce a better error message.
534 if (Symbol
.isUndefined() && Rest
.startswith("@@") &&
535 !Rest
.startswith("@@@"))
536 report_fatal_error("A @@ version cannot be undefined");
538 Renames
.insert(std::make_pair(&Symbol
, &Alias
));
542 void ELFObjectWriterImpl::WriteSymbol(MCDataFragment
*SymtabF
,
543 MCDataFragment
*ShndxF
,
545 const MCAsmLayout
&Layout
) {
546 MCSymbolData
&OrigData
= *MSD
.SymbolData
;
548 Layout
.getAssembler().getSymbolData(AliasedSymbol(OrigData
.getSymbol()));
550 bool IsReserved
= Data
.isCommon() || Data
.getSymbol().isAbsolute() ||
551 Data
.getSymbol().isVariable();
553 uint8_t Binding
= GetBinding(OrigData
);
554 uint8_t Visibility
= GetVisibility(OrigData
);
555 uint8_t Type
= GetType(Data
);
557 uint8_t Info
= (Binding
<< ELF_STB_Shift
) | (Type
<< ELF_STT_Shift
);
558 uint8_t Other
= Visibility
;
560 uint64_t Value
= SymbolValue(Data
, Layout
);
564 assert(!(Data
.isCommon() && !Data
.isExternal()));
566 ESize
= Data
.getSize();
567 if (Data
.getSize()) {
569 if (ESize
->getKind() == MCExpr::Binary
) {
570 const MCBinaryExpr
*BE
= static_cast<const MCBinaryExpr
*>(ESize
);
572 if (BE
->EvaluateAsRelocatable(Res
, &Layout
)) {
573 assert(!Res
.getSymA() || !Res
.getSymA()->getSymbol().isDefined());
574 assert(!Res
.getSymB() || !Res
.getSymB()->getSymbol().isDefined());
575 Size
= Res
.getConstant();
577 } else if (ESize
->getKind() == MCExpr::Constant
) {
578 Size
= static_cast<const MCConstantExpr
*>(ESize
)->getValue();
580 assert(0 && "Unsupported size expression");
584 // Write out the symbol table entry
585 WriteSymbolEntry(SymtabF
, ShndxF
, MSD
.StringIndex
, Info
, Value
,
586 Size
, Other
, MSD
.SectionIndex
, IsReserved
);
589 void ELFObjectWriterImpl::WriteSymbolTable(MCDataFragment
*SymtabF
,
590 MCDataFragment
*ShndxF
,
591 const MCAssembler
&Asm
,
592 const MCAsmLayout
&Layout
,
593 unsigned NumRegularSections
) {
594 // The string table must be emitted first because we need the index
595 // into the string table for all the symbol names.
596 assert(StringTable
.size() && "Missing string table");
598 // FIXME: Make sure the start of the symbol table is aligned.
600 // The first entry is the undefined symbol entry.
601 WriteSymbolEntry(SymtabF
, ShndxF
, 0, 0, 0, 0, 0, 0, false);
603 // Write the symbol table entries.
604 LastLocalSymbolIndex
= LocalSymbolData
.size() + 1;
605 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
) {
606 ELFSymbolData
&MSD
= LocalSymbolData
[i
];
607 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
610 // Write out a symbol table entry for each regular section.
612 for (MCAssembler::const_iterator it
= Asm
.begin();
613 Index
<= NumRegularSections
; ++it
, ++Index
) {
614 const MCSectionELF
&Section
=
615 static_cast<const MCSectionELF
&>(it
->getSection());
616 // Leave out relocations so we don't have indexes within
617 // the relocations messed up
618 if (Section
.getType() == ELF::SHT_RELA
|| Section
.getType() == ELF::SHT_REL
)
620 WriteSymbolEntry(SymtabF
, ShndxF
, 0, ELF::STT_SECTION
, 0, 0,
621 ELF::STV_DEFAULT
, Index
, false);
622 LastLocalSymbolIndex
++;
625 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
) {
626 ELFSymbolData
&MSD
= ExternalSymbolData
[i
];
627 MCSymbolData
&Data
= *MSD
.SymbolData
;
628 assert(((Data
.getFlags() & ELF_STB_Global
) ||
629 (Data
.getFlags() & ELF_STB_Weak
)) &&
630 "External symbol requires STB_GLOBAL or STB_WEAK flag");
631 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
632 if (GetBinding(Data
) == ELF::STB_LOCAL
)
633 LastLocalSymbolIndex
++;
636 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
) {
637 ELFSymbolData
&MSD
= UndefinedSymbolData
[i
];
638 MCSymbolData
&Data
= *MSD
.SymbolData
;
639 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
640 if (GetBinding(Data
) == ELF::STB_LOCAL
)
641 LastLocalSymbolIndex
++;
645 static bool ShouldRelocOnSymbol(const MCSymbolData
&SD
,
646 const MCValue
&Target
,
647 const MCFragment
&F
) {
648 const MCSymbol
&Symbol
= SD
.getSymbol();
649 if (Symbol
.isUndefined())
652 const MCSectionELF
&Section
=
653 static_cast<const MCSectionELF
&>(Symbol
.getSection());
658 MCSymbolRefExpr::VariantKind Kind
= Target
.getSymA()->getKind();
659 const MCSectionELF
&Sec2
=
660 static_cast<const MCSectionELF
&>(F
.getParent()->getSection());
662 if (Section
.getKind().isBSS())
665 if (&Sec2
!= &Section
&&
666 (Kind
== MCSymbolRefExpr::VK_PLT
||
667 Kind
== MCSymbolRefExpr::VK_GOTPCREL
||
668 Kind
== MCSymbolRefExpr::VK_GOTOFF
))
671 if (Section
.getFlags() & MCSectionELF::SHF_MERGE
)
672 return Target
.getConstant() != 0;
677 // FIXME: this is currently X86/X86_64 only
678 void ELFObjectWriterImpl::RecordRelocation(const MCAssembler
&Asm
,
679 const MCAsmLayout
&Layout
,
680 const MCFragment
*Fragment
,
681 const MCFixup
&Fixup
,
683 uint64_t &FixedValue
) {
686 int64_t Value
= Target
.getConstant();
687 const MCSymbol
*Symbol
= 0;
688 const MCSymbol
*Renamed
= 0;
690 bool IsPCRel
= isFixupKindX86PCRel(Fixup
.getKind());
691 if (!Target
.isAbsolute()) {
692 Symbol
= &AliasedSymbol(Target
.getSymA()->getSymbol());
693 Renamed
= Renames
.lookup(Symbol
);
695 Renamed
= &Target
.getSymA()->getSymbol();
696 MCSymbolData
&SD
= Asm
.getSymbolData(*Symbol
);
697 MCFragment
*F
= SD
.getFragment();
699 if (const MCSymbolRefExpr
*RefB
= Target
.getSymB()) {
700 const MCSymbol
&SymbolB
= RefB
->getSymbol();
701 MCSymbolData
&SDB
= Asm
.getSymbolData(SymbolB
);
703 MCSectionData
*Sec
= Fragment
->getParent();
705 // Offset of the symbol in the section
706 int64_t a
= Layout
.getSymbolAddress(&SDB
) - Layout
.getSectionAddress(Sec
);
708 // Ofeset of the relocation in the section
709 int64_t b
= Layout
.getFragmentOffset(Fragment
) + Fixup
.getOffset();
713 // Check that this case has already been fully resolved before we get
715 if (Symbol
->isDefined() && !SD
.isExternal() &&
717 &Fragment
->getParent()->getSection() == &Symbol
->getSection()) {
718 llvm_unreachable("We don't need a relocation in this case.");
722 bool RelocOnSymbol
= ShouldRelocOnSymbol(SD
, Target
, *Fragment
);
723 if (!RelocOnSymbol
) {
724 Index
= F
->getParent()->getOrdinal();
726 MCSectionData
*FSD
= F
->getParent();
727 // Offset of the symbol in the section
728 Value
+= Layout
.getSymbolAddress(&SD
) - Layout
.getSectionAddress(FSD
);
730 UsedInReloc
.insert(Renamed
);
731 MCSymbolData
&RenamedSD
= Asm
.getSymbolData(*Renamed
);
732 if (RenamedSD
.getFlags() & ELF_Other_Weakref
) {
733 WeakrefUsedInReloc
.insert(Symbol
);
738 // Compensate for the addend on i386.
745 // determine the type of the relocation
747 MCSymbolRefExpr::VariantKind Modifier
= Target
.getSymA()->getKind();
753 llvm_unreachable("Unimplemented");
754 case MCSymbolRefExpr::VK_None
:
755 Type
= ELF::R_X86_64_PC32
;
757 case MCSymbolRefExpr::VK_PLT
:
758 Type
= ELF::R_X86_64_PLT32
;
760 case MCSymbolRefExpr::VK_GOTPCREL
:
761 Type
= ELF::R_X86_64_GOTPCREL
;
763 case MCSymbolRefExpr::VK_GOTTPOFF
:
764 Type
= ELF::R_X86_64_GOTTPOFF
;
766 case MCSymbolRefExpr::VK_TLSGD
:
767 Type
= ELF::R_X86_64_TLSGD
;
769 case MCSymbolRefExpr::VK_TLSLD
:
770 Type
= ELF::R_X86_64_TLSLD
;
774 switch ((unsigned)Fixup
.getKind()) {
775 default: llvm_unreachable("invalid fixup kind!");
776 case FK_Data_8
: Type
= ELF::R_X86_64_64
; break;
777 case X86::reloc_signed_4byte
:
778 case X86::reloc_pcrel_4byte
:
779 assert(isInt
<32>(Target
.getConstant()));
782 llvm_unreachable("Unimplemented");
783 case MCSymbolRefExpr::VK_None
:
784 Type
= ELF::R_X86_64_32S
;
786 case MCSymbolRefExpr::VK_GOT
:
787 Type
= ELF::R_X86_64_GOT32
;
789 case MCSymbolRefExpr::VK_GOTPCREL
:
790 Type
= ELF::R_X86_64_GOTPCREL
;
792 case MCSymbolRefExpr::VK_TPOFF
:
793 Type
= ELF::R_X86_64_TPOFF32
;
795 case MCSymbolRefExpr::VK_DTPOFF
:
796 Type
= ELF::R_X86_64_DTPOFF32
;
801 Type
= ELF::R_X86_64_32
;
803 case FK_Data_2
: Type
= ELF::R_X86_64_16
; break;
804 case X86::reloc_pcrel_1byte
:
805 case FK_Data_1
: Type
= ELF::R_X86_64_8
; break;
812 llvm_unreachable("Unimplemented");
813 case MCSymbolRefExpr::VK_None
:
814 Type
= ELF::R_386_PC32
;
816 case MCSymbolRefExpr::VK_PLT
:
817 Type
= ELF::R_386_PLT32
;
821 switch ((unsigned)Fixup
.getKind()) {
822 default: llvm_unreachable("invalid fixup kind!");
824 case X86::reloc_global_offset_table
:
825 Type
= ELF::R_386_GOTPC
;
828 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
830 case X86::reloc_signed_4byte
:
831 case X86::reloc_pcrel_4byte
:
835 llvm_unreachable("Unimplemented");
836 case MCSymbolRefExpr::VK_None
:
837 Type
= ELF::R_386_32
;
839 case MCSymbolRefExpr::VK_GOT
:
840 Type
= ELF::R_386_GOT32
;
842 case MCSymbolRefExpr::VK_GOTOFF
:
843 Type
= ELF::R_386_GOTOFF
;
845 case MCSymbolRefExpr::VK_TLSGD
:
846 Type
= ELF::R_386_TLS_GD
;
848 case MCSymbolRefExpr::VK_TPOFF
:
849 Type
= ELF::R_386_TLS_LE_32
;
851 case MCSymbolRefExpr::VK_INDNTPOFF
:
852 Type
= ELF::R_386_TLS_IE
;
854 case MCSymbolRefExpr::VK_NTPOFF
:
855 Type
= ELF::R_386_TLS_LE
;
857 case MCSymbolRefExpr::VK_GOTNTPOFF
:
858 Type
= ELF::R_386_TLS_GOTIE
;
860 case MCSymbolRefExpr::VK_TLSLDM
:
861 Type
= ELF::R_386_TLS_LDM
;
863 case MCSymbolRefExpr::VK_DTPOFF
:
864 Type
= ELF::R_386_TLS_LDO_32
;
868 case FK_Data_2
: Type
= ELF::R_386_16
; break;
869 case X86::reloc_pcrel_1byte
:
870 case FK_Data_1
: Type
= ELF::R_386_8
; break;
875 if (RelocNeedsGOT(Modifier
))
878 ELFRelocationEntry ERE
;
882 ERE
.Symbol
= Renamed
;
884 ERE
.r_offset
= Layout
.getFragmentOffset(Fragment
) + Fixup
.getOffset();
886 if (HasRelocationAddend
)
887 ERE
.r_addend
= Addend
;
889 ERE
.r_addend
= 0; // Silence compiler warning.
891 Relocations
[Fragment
->getParent()].push_back(ERE
);
895 ELFObjectWriterImpl::getSymbolIndexInSymbolTable(const MCAssembler
&Asm
,
897 MCSymbolData
&SD
= Asm
.getSymbolData(*S
);
900 if (!SD
.isExternal() && !S
->isUndefined())
901 return SD
.getIndex() + /* empty symbol */ 1;
903 // External or undefined symbol.
904 return SD
.getIndex() + NumRegularSections
+ /* empty symbol */ 1;
907 static bool isInSymtab(const MCAssembler
&Asm
, const MCSymbolData
&Data
,
908 bool Used
, bool Renamed
) {
909 if (Data
.getFlags() & ELF_Other_Weakref
)
918 const MCSymbol
&Symbol
= Data
.getSymbol();
920 if (Symbol
.getName() == "_GLOBAL_OFFSET_TABLE_")
923 const MCSymbol
&A
= AliasedSymbol(Symbol
);
924 if (!A
.isVariable() && A
.isUndefined() && !Data
.isCommon())
927 if (!Asm
.isSymbolLinkerVisible(Symbol
) && !Symbol
.isUndefined())
930 if (Symbol
.isTemporary())
936 static bool isLocal(const MCSymbolData
&Data
) {
937 if (Data
.isExternal())
940 const MCSymbol
&Symbol
= Data
.getSymbol();
941 if (Symbol
.isUndefined() && !Symbol
.isVariable())
947 void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler
&Asm
) {
948 // FIXME: Is this the correct place to do this?
950 llvm::StringRef Name
= "_GLOBAL_OFFSET_TABLE_";
951 MCSymbol
*Sym
= Asm
.getContext().GetOrCreateSymbol(Name
);
952 MCSymbolData
&Data
= Asm
.getOrCreateSymbolData(*Sym
);
953 Data
.setExternal(true);
954 SetBinding(Data
, ELF::STB_GLOBAL
);
957 // Build section lookup table.
958 NumRegularSections
= Asm
.size();
959 DenseMap
<const MCSection
*, uint32_t> SectionIndexMap
;
961 for (MCAssembler::iterator it
= Asm
.begin(),
962 ie
= Asm
.end(); it
!= ie
; ++it
, ++Index
)
963 SectionIndexMap
[&it
->getSection()] = Index
;
965 // Index 0 is always the empty string.
966 StringMap
<uint64_t> StringIndexMap
;
967 StringTable
+= '\x00';
969 // Add the data for the symbols.
970 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
971 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
972 const MCSymbol
&Symbol
= it
->getSymbol();
974 bool Used
= UsedInReloc
.count(&Symbol
);
975 bool WeakrefUsed
= WeakrefUsedInReloc
.count(&Symbol
);
976 if (!isInSymtab(Asm
, *it
, Used
|| WeakrefUsed
,
977 Renames
.count(&Symbol
)))
982 bool Local
= isLocal(*it
);
983 const MCSymbol
&RefSymbol
= AliasedSymbol(Symbol
);
985 if (RefSymbol
.isUndefined() && !Used
&& WeakrefUsed
)
986 SetBinding(*it
, ELF::STB_WEAK
);
988 if (it
->isCommon()) {
990 MSD
.SectionIndex
= ELF::SHN_COMMON
;
991 } else if (Symbol
.isAbsolute() || RefSymbol
.isVariable()) {
992 MSD
.SectionIndex
= ELF::SHN_ABS
;
993 } else if (RefSymbol
.isUndefined()) {
994 MSD
.SectionIndex
= ELF::SHN_UNDEF
;
996 MSD
.SectionIndex
= SectionIndexMap
.lookup(&RefSymbol
.getSection());
997 if (MSD
.SectionIndex
>= ELF::SHN_LORESERVE
)
998 NeedsSymtabShndx
= true;
999 assert(MSD
.SectionIndex
&& "Invalid section index!");
1002 // The @@@ in symbol version is replaced with @ in undefined symbols and
1003 // @@ in defined ones.
1004 StringRef Name
= Symbol
.getName();
1005 size_t Pos
= Name
.find("@@@");
1006 std::string FinalName
;
1007 if (Pos
!= StringRef::npos
) {
1008 StringRef Prefix
= Name
.substr(0, Pos
);
1009 unsigned n
= MSD
.SectionIndex
== ELF::SHN_UNDEF
? 2 : 1;
1010 StringRef Suffix
= Name
.substr(Pos
+ n
);
1011 FinalName
= Prefix
.str() + Suffix
.str();
1013 FinalName
= Name
.str();
1016 uint64_t &Entry
= StringIndexMap
[FinalName
];
1018 Entry
= StringTable
.size();
1019 StringTable
+= FinalName
;
1020 StringTable
+= '\x00';
1022 MSD
.StringIndex
= Entry
;
1023 if (MSD
.SectionIndex
== ELF::SHN_UNDEF
)
1024 UndefinedSymbolData
.push_back(MSD
);
1026 LocalSymbolData
.push_back(MSD
);
1028 ExternalSymbolData
.push_back(MSD
);
1031 // Symbols are required to be in lexicographic order.
1032 array_pod_sort(LocalSymbolData
.begin(), LocalSymbolData
.end());
1033 array_pod_sort(ExternalSymbolData
.begin(), ExternalSymbolData
.end());
1034 array_pod_sort(UndefinedSymbolData
.begin(), UndefinedSymbolData
.end());
1036 // Set the symbol indices. Local symbols must come before all other
1037 // symbols with non-local bindings.
1039 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
)
1040 LocalSymbolData
[i
].SymbolData
->setIndex(Index
++);
1041 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
)
1042 ExternalSymbolData
[i
].SymbolData
->setIndex(Index
++);
1043 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
)
1044 UndefinedSymbolData
[i
].SymbolData
->setIndex(Index
++);
1047 void ELFObjectWriterImpl::WriteRelocation(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
1048 const MCSectionData
&SD
) {
1049 if (!Relocations
[&SD
].empty()) {
1050 MCContext
&Ctx
= Asm
.getContext();
1051 const MCSection
*RelaSection
;
1052 const MCSectionELF
&Section
=
1053 static_cast<const MCSectionELF
&>(SD
.getSection());
1055 const StringRef SectionName
= Section
.getSectionName();
1056 std::string RelaSectionName
= HasRelocationAddend
? ".rela" : ".rel";
1057 RelaSectionName
+= SectionName
;
1060 if (HasRelocationAddend
)
1061 EntrySize
= Is64Bit
? sizeof(ELF::Elf64_Rela
) : sizeof(ELF::Elf32_Rela
);
1063 EntrySize
= Is64Bit
? sizeof(ELF::Elf64_Rel
) : sizeof(ELF::Elf32_Rel
);
1065 RelaSection
= Ctx
.getELFSection(RelaSectionName
, HasRelocationAddend
?
1066 ELF::SHT_RELA
: ELF::SHT_REL
, 0,
1067 SectionKind::getReadOnly(),
1070 MCSectionData
&RelaSD
= Asm
.getOrCreateSectionData(*RelaSection
);
1071 RelaSD
.setAlignment(Is64Bit
? 8 : 4);
1073 MCDataFragment
*F
= new MCDataFragment(&RelaSD
);
1075 WriteRelocationsFragment(Asm
, F
, &SD
);
1077 Asm
.AddSectionToTheEnd(*Writer
, RelaSD
, Layout
);
1081 void ELFObjectWriterImpl::WriteSecHdrEntry(uint32_t Name
, uint32_t Type
,
1082 uint64_t Flags
, uint64_t Address
,
1083 uint64_t Offset
, uint64_t Size
,
1084 uint32_t Link
, uint32_t Info
,
1086 uint64_t EntrySize
) {
1087 Write32(Name
); // sh_name: index into string table
1088 Write32(Type
); // sh_type
1089 WriteWord(Flags
); // sh_flags
1090 WriteWord(Address
); // sh_addr
1091 WriteWord(Offset
); // sh_offset
1092 WriteWord(Size
); // sh_size
1093 Write32(Link
); // sh_link
1094 Write32(Info
); // sh_info
1095 WriteWord(Alignment
); // sh_addralign
1096 WriteWord(EntrySize
); // sh_entsize
1099 void ELFObjectWriterImpl::WriteRelocationsFragment(const MCAssembler
&Asm
,
1101 const MCSectionData
*SD
) {
1102 std::vector
<ELFRelocationEntry
> &Relocs
= Relocations
[SD
];
1103 // sort by the r_offset just like gnu as does
1104 array_pod_sort(Relocs
.begin(), Relocs
.end());
1106 for (unsigned i
= 0, e
= Relocs
.size(); i
!= e
; ++i
) {
1107 ELFRelocationEntry entry
= Relocs
[e
- i
- 1];
1109 if (entry
.Index
< 0)
1110 entry
.Index
= getSymbolIndexInSymbolTable(Asm
, entry
.Symbol
);
1112 entry
.Index
+= LocalSymbolData
.size() + 1;
1116 String64(buf
, entry
.r_offset
);
1117 F
->getContents() += StringRef(buf
, 8);
1119 struct ELF::Elf64_Rela ERE64
;
1120 ERE64
.setSymbolAndType(entry
.Index
, entry
.Type
);
1121 String64(buf
, ERE64
.r_info
);
1122 F
->getContents() += StringRef(buf
, 8);
1124 if (HasRelocationAddend
) {
1125 String64(buf
, entry
.r_addend
);
1126 F
->getContents() += StringRef(buf
, 8);
1131 String32(buf
, entry
.r_offset
);
1132 F
->getContents() += StringRef(buf
, 4);
1134 struct ELF::Elf32_Rela ERE32
;
1135 ERE32
.setSymbolAndType(entry
.Index
, entry
.Type
);
1136 String32(buf
, ERE32
.r_info
);
1137 F
->getContents() += StringRef(buf
, 4);
1139 if (HasRelocationAddend
) {
1140 String32(buf
, entry
.r_addend
);
1141 F
->getContents() += StringRef(buf
, 4);
1147 void ELFObjectWriterImpl::CreateMetadataSections(MCAssembler
&Asm
,
1148 MCAsmLayout
&Layout
) {
1149 MCContext
&Ctx
= Asm
.getContext();
1152 unsigned EntrySize
= Is64Bit
? ELF::SYMENTRY_SIZE64
: ELF::SYMENTRY_SIZE32
;
1154 unsigned NumRegularSections
= Asm
.size();
1156 // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
1157 const MCSection
*ShstrtabSection
=
1158 Ctx
.getELFSection(".shstrtab", ELF::SHT_STRTAB
, 0,
1159 SectionKind::getReadOnly(), false);
1160 MCSectionData
&ShstrtabSD
= Asm
.getOrCreateSectionData(*ShstrtabSection
);
1161 ShstrtabSD
.setAlignment(1);
1162 ShstrtabIndex
= Asm
.size();
1164 const MCSection
*SymtabSection
=
1165 Ctx
.getELFSection(".symtab", ELF::SHT_SYMTAB
, 0,
1166 SectionKind::getReadOnly(),
1168 MCSectionData
&SymtabSD
= Asm
.getOrCreateSectionData(*SymtabSection
);
1169 SymtabSD
.setAlignment(Is64Bit
? 8 : 4);
1170 SymbolTableIndex
= Asm
.size();
1172 MCSectionData
*SymtabShndxSD
= NULL
;
1174 if (NeedsSymtabShndx
) {
1175 const MCSection
*SymtabShndxSection
=
1176 Ctx
.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX
, 0,
1177 SectionKind::getReadOnly(), false, 4);
1178 SymtabShndxSD
= &Asm
.getOrCreateSectionData(*SymtabShndxSection
);
1179 SymtabShndxSD
->setAlignment(4);
1182 const MCSection
*StrtabSection
;
1183 StrtabSection
= Ctx
.getELFSection(".strtab", ELF::SHT_STRTAB
, 0,
1184 SectionKind::getReadOnly(), false);
1185 MCSectionData
&StrtabSD
= Asm
.getOrCreateSectionData(*StrtabSection
);
1186 StrtabSD
.setAlignment(1);
1187 StringTableIndex
= Asm
.size();
1189 WriteRelocations(Asm
, Layout
);
1192 F
= new MCDataFragment(&SymtabSD
);
1193 MCDataFragment
*ShndxF
= NULL
;
1194 if (NeedsSymtabShndx
) {
1195 ShndxF
= new MCDataFragment(SymtabShndxSD
);
1196 Asm
.AddSectionToTheEnd(*Writer
, *SymtabShndxSD
, Layout
);
1198 WriteSymbolTable(F
, ShndxF
, Asm
, Layout
, NumRegularSections
);
1199 Asm
.AddSectionToTheEnd(*Writer
, SymtabSD
, Layout
);
1201 F
= new MCDataFragment(&StrtabSD
);
1202 F
->getContents().append(StringTable
.begin(), StringTable
.end());
1203 Asm
.AddSectionToTheEnd(*Writer
, StrtabSD
, Layout
);
1205 F
= new MCDataFragment(&ShstrtabSD
);
1207 // Section header string table.
1209 // The first entry of a string table holds a null character so skip
1212 F
->getContents() += '\x00';
1214 for (MCAssembler::const_iterator it
= Asm
.begin(),
1215 ie
= Asm
.end(); it
!= ie
; ++it
) {
1216 const MCSectionELF
&Section
=
1217 static_cast<const MCSectionELF
&>(it
->getSection());
1218 // FIXME: We could merge suffixes like in .text and .rela.text.
1220 // Remember the index into the string table so we can write it
1221 // into the sh_name field of the section header table.
1222 SectionStringTableIndex
[&it
->getSection()] = Index
;
1224 Index
+= Section
.getSectionName().size() + 1;
1225 F
->getContents() += Section
.getSectionName();
1226 F
->getContents() += '\x00';
1229 Asm
.AddSectionToTheEnd(*Writer
, ShstrtabSD
, Layout
);
1232 bool ELFObjectWriterImpl::IsFixupFullyResolved(const MCAssembler
&Asm
,
1233 const MCValue Target
,
1235 const MCFragment
*DF
) const {
1236 // If this is a PCrel relocation, find the section this fixup value is
1238 const MCSection
*BaseSection
= 0;
1240 BaseSection
= &DF
->getParent()->getSection();
1241 assert(BaseSection
);
1244 const MCSection
*SectionA
= 0;
1245 const MCSymbol
*SymbolA
= 0;
1246 if (const MCSymbolRefExpr
*A
= Target
.getSymA()) {
1247 SymbolA
= &A
->getSymbol();
1248 SectionA
= &SymbolA
->getSection();
1251 const MCSection
*SectionB
= 0;
1252 if (const MCSymbolRefExpr
*B
= Target
.getSymB()) {
1253 SectionB
= &B
->getSymbol().getSection();
1257 return SectionA
== SectionB
;
1259 const MCSymbolData
&DataA
= Asm
.getSymbolData(*SymbolA
);
1260 if (DataA
.isExternal())
1263 return !SectionB
&& BaseSection
== SectionA
;
1266 void ELFObjectWriterImpl::WriteObject(MCAssembler
&Asm
,
1267 const MCAsmLayout
&Layout
) {
1268 // Compute symbol table information.
1269 ComputeSymbolTable(Asm
);
1271 CreateMetadataSections(const_cast<MCAssembler
&>(Asm
),
1272 const_cast<MCAsmLayout
&>(Layout
));
1274 // Add 1 for the null section.
1275 unsigned NumSections
= Asm
.size() + 1;
1276 uint64_t NaturalAlignment
= Is64Bit
? 8 : 4;
1277 uint64_t HeaderSize
= Is64Bit
? sizeof(ELF::Elf64_Ehdr
) : sizeof(ELF::Elf32_Ehdr
);
1278 uint64_t FileOff
= HeaderSize
;
1280 for (MCAssembler::const_iterator it
= Asm
.begin(),
1281 ie
= Asm
.end(); it
!= ie
; ++it
) {
1282 const MCSectionData
&SD
= *it
;
1284 FileOff
= RoundUpToAlignment(FileOff
, SD
.getAlignment());
1286 // Get the size of the section in the output file (including padding).
1287 uint64_t Size
= Layout
.getSectionFileSize(&SD
);
1292 FileOff
= RoundUpToAlignment(FileOff
, NaturalAlignment
);
1294 // Write out the ELF header ...
1295 WriteHeader(FileOff
- HeaderSize
, NumSections
);
1297 FileOff
= HeaderSize
;
1299 // ... then all of the sections ...
1300 DenseMap
<const MCSection
*, uint64_t> SectionOffsetMap
;
1302 DenseMap
<const MCSection
*, uint32_t> SectionIndexMap
;
1305 for (MCAssembler::const_iterator it
= Asm
.begin(),
1306 ie
= Asm
.end(); it
!= ie
; ++it
) {
1307 const MCSectionData
&SD
= *it
;
1309 uint64_t Padding
= OffsetToAlignment(FileOff
, SD
.getAlignment());
1310 WriteZeros(Padding
);
1313 // Remember the offset into the file for this section.
1314 SectionOffsetMap
[&it
->getSection()] = FileOff
;
1315 SectionIndexMap
[&it
->getSection()] = Index
++;
1317 FileOff
+= Layout
.getSectionFileSize(&SD
);
1319 Asm
.WriteSectionData(it
, Layout
, Writer
);
1322 uint64_t Padding
= OffsetToAlignment(FileOff
, NaturalAlignment
);
1323 WriteZeros(Padding
);
1326 // ... and then the section header table.
1327 // Should we align the section header table?
1329 // Null section first.
1330 uint64_t FirstSectionSize
=
1331 NumSections
>= ELF::SHN_LORESERVE
? NumSections
: 0;
1332 uint32_t FirstSectionLink
=
1333 ShstrtabIndex
>= ELF::SHN_LORESERVE
? ShstrtabIndex
: 0;
1334 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize
, FirstSectionLink
, 0, 0, 0);
1336 for (MCAssembler::const_iterator it
= Asm
.begin(),
1337 ie
= Asm
.end(); it
!= ie
; ++it
) {
1338 const MCSectionData
&SD
= *it
;
1339 const MCSectionELF
&Section
=
1340 static_cast<const MCSectionELF
&>(SD
.getSection());
1342 uint64_t sh_link
= 0;
1343 uint64_t sh_info
= 0;
1345 switch(Section
.getType()) {
1346 case ELF::SHT_DYNAMIC
:
1347 sh_link
= SectionStringTableIndex
[&it
->getSection()];
1352 case ELF::SHT_RELA
: {
1353 const MCSection
*SymtabSection
;
1354 const MCSection
*InfoSection
;
1356 SymtabSection
= Asm
.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB
, 0,
1357 SectionKind::getReadOnly(),
1359 sh_link
= SectionIndexMap
[SymtabSection
];
1361 // Remove ".rel" and ".rela" prefixes.
1362 unsigned SecNameLen
= (Section
.getType() == ELF::SHT_REL
) ? 4 : 5;
1363 StringRef SectionName
= Section
.getSectionName().substr(SecNameLen
);
1365 InfoSection
= Asm
.getContext().getELFSection(SectionName
,
1366 ELF::SHT_PROGBITS
, 0,
1367 SectionKind::getReadOnly(),
1369 sh_info
= SectionIndexMap
[InfoSection
];
1373 case ELF::SHT_SYMTAB
:
1374 case ELF::SHT_DYNSYM
:
1375 sh_link
= StringTableIndex
;
1376 sh_info
= LastLocalSymbolIndex
;
1379 case ELF::SHT_SYMTAB_SHNDX
:
1380 sh_link
= SymbolTableIndex
;
1383 case ELF::SHT_PROGBITS
:
1384 case ELF::SHT_STRTAB
:
1385 case ELF::SHT_NOBITS
:
1387 case ELF::SHT_ARM_ATTRIBUTES
:
1392 assert(0 && "FIXME: sh_type value not supported!");
1396 WriteSecHdrEntry(SectionStringTableIndex
[&it
->getSection()],
1397 Section
.getType(), Section
.getFlags(),
1399 SectionOffsetMap
.lookup(&SD
.getSection()),
1400 Layout
.getSectionSize(&SD
), sh_link
,
1401 sh_info
, SD
.getAlignment(),
1402 Section
.getEntrySize());
1406 ELFObjectWriter::ELFObjectWriter(raw_ostream
&OS
,
1408 Triple::OSType OSType
,
1410 bool IsLittleEndian
,
1411 bool HasRelocationAddend
)
1412 : MCObjectWriter(OS
, IsLittleEndian
)
1414 Impl
= new ELFObjectWriterImpl(this, Is64Bit
, EMachine
,
1415 HasRelocationAddend
, OSType
);
1418 ELFObjectWriter::~ELFObjectWriter() {
1419 delete (ELFObjectWriterImpl
*) Impl
;
1422 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler
&Asm
) {
1423 ((ELFObjectWriterImpl
*) Impl
)->ExecutePostLayoutBinding(Asm
);
1426 void ELFObjectWriter::RecordRelocation(const MCAssembler
&Asm
,
1427 const MCAsmLayout
&Layout
,
1428 const MCFragment
*Fragment
,
1429 const MCFixup
&Fixup
, MCValue Target
,
1430 uint64_t &FixedValue
) {
1431 ((ELFObjectWriterImpl
*) Impl
)->RecordRelocation(Asm
, Layout
, Fragment
, Fixup
,
1432 Target
, FixedValue
);
1435 bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler
&Asm
,
1436 const MCValue Target
,
1438 const MCFragment
*DF
) const {
1439 return ((ELFObjectWriterImpl
*) Impl
)->IsFixupFullyResolved(Asm
, Target
,
1443 void ELFObjectWriter::WriteObject(MCAssembler
&Asm
,
1444 const MCAsmLayout
&Layout
) {
1445 ((ELFObjectWriterImpl
*) Impl
)->WriteObject(Asm
, Layout
);