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 "ELFObjectWriter.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/MC/MCAsmLayout.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCSectionELF.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/Support/Debug.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/ELF.h"
26 #include "llvm/Target/TargetAsmBackend.h"
27 #include "llvm/ADT/StringSwitch.h"
28 #include "llvm/Support/CommandLine.h"
29 #include "llvm/ADT/Statistic.h"
31 #include "../Target/X86/X86FixupKinds.h"
32 #include "../Target/ARM/ARMFixupKinds.h"
38 #define DEBUG_TYPE "reloc-info"
40 bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler
&Asm
, unsigned Kind
) {
41 const MCFixupKindInfo
&FKI
=
42 Asm
.getBackend().getFixupKindInfo((MCFixupKind
) Kind
);
44 return FKI
.Flags
& MCFixupKindInfo::FKF_IsPCRel
;
47 bool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant
) {
51 case MCSymbolRefExpr::VK_GOT
:
52 case MCSymbolRefExpr::VK_PLT
:
53 case MCSymbolRefExpr::VK_GOTPCREL
:
54 case MCSymbolRefExpr::VK_GOTOFF
:
55 case MCSymbolRefExpr::VK_TPOFF
:
56 case MCSymbolRefExpr::VK_TLSGD
:
57 case MCSymbolRefExpr::VK_GOTTPOFF
:
58 case MCSymbolRefExpr::VK_INDNTPOFF
:
59 case MCSymbolRefExpr::VK_NTPOFF
:
60 case MCSymbolRefExpr::VK_GOTNTPOFF
:
61 case MCSymbolRefExpr::VK_TLSLDM
:
62 case MCSymbolRefExpr::VK_DTPOFF
:
63 case MCSymbolRefExpr::VK_TLSLD
:
68 ELFObjectWriter::~ELFObjectWriter()
71 // Emit the ELF header.
72 void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize
,
73 unsigned NumberOfSections
) {
79 // emitWord method behaves differently for ELF32 and ELF64, writing
80 // 4 bytes in the former and 8 in the latter.
82 Write8(0x7f); // e_ident[EI_MAG0]
83 Write8('E'); // e_ident[EI_MAG1]
84 Write8('L'); // e_ident[EI_MAG2]
85 Write8('F'); // e_ident[EI_MAG3]
87 Write8(is64Bit() ? ELF::ELFCLASS64
: ELF::ELFCLASS32
); // e_ident[EI_CLASS]
90 Write8(isLittleEndian() ? ELF::ELFDATA2LSB
: ELF::ELFDATA2MSB
);
92 Write8(ELF::EV_CURRENT
); // e_ident[EI_VERSION]
94 switch (TargetObjectWriter
->getOSType()) {
95 case Triple::FreeBSD
: Write8(ELF::ELFOSABI_FREEBSD
); break;
96 case Triple::Linux
: Write8(ELF::ELFOSABI_LINUX
); break;
97 default: Write8(ELF::ELFOSABI_NONE
); break;
99 Write8(0); // e_ident[EI_ABIVERSION]
101 WriteZeros(ELF::EI_NIDENT
- ELF::EI_PAD
);
103 Write16(ELF::ET_REL
); // e_type
105 Write16(TargetObjectWriter
->getEMachine()); // e_machine = target
107 Write32(ELF::EV_CURRENT
); // e_version
108 WriteWord(0); // e_entry, no entry point in .o file
109 WriteWord(0); // e_phoff, no program header for .o
110 WriteWord(SectionDataSize
+ (is64Bit() ? sizeof(ELF::Elf64_Ehdr
) :
111 sizeof(ELF::Elf32_Ehdr
))); // e_shoff = sec hdr table off in bytes
113 // e_flags = whatever the target wants
116 // e_ehsize = ELF header size
117 Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr
) : sizeof(ELF::Elf32_Ehdr
));
119 Write16(0); // e_phentsize = prog header entry size
120 Write16(0); // e_phnum = # prog header entries = 0
122 // e_shentsize = Section header entry size
123 Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr
) : sizeof(ELF::Elf32_Shdr
));
125 // e_shnum = # of section header ents
126 if (NumberOfSections
>= ELF::SHN_LORESERVE
)
129 Write16(NumberOfSections
);
131 // e_shstrndx = Section # of '.shstrtab'
132 if (NumberOfSections
>= ELF::SHN_LORESERVE
)
133 Write16(ELF::SHN_XINDEX
);
135 Write16(ShstrtabIndex
);
138 void ELFObjectWriter::WriteSymbolEntry(MCDataFragment
*SymtabF
,
139 MCDataFragment
*ShndxF
,
141 uint8_t info
, uint64_t value
,
142 uint64_t size
, uint8_t other
,
146 if (shndx
>= ELF::SHN_LORESERVE
&& !Reserved
)
147 String32(*ShndxF
, shndx
);
149 String32(*ShndxF
, 0);
152 uint16_t Index
= (shndx
>= ELF::SHN_LORESERVE
&& !Reserved
) ?
153 uint16_t(ELF::SHN_XINDEX
) : shndx
;
156 String32(*SymtabF
, name
); // st_name
157 String8(*SymtabF
, info
); // st_info
158 String8(*SymtabF
, other
); // st_other
159 String16(*SymtabF
, Index
); // st_shndx
160 String64(*SymtabF
, value
); // st_value
161 String64(*SymtabF
, size
); // st_size
163 String32(*SymtabF
, name
); // st_name
164 String32(*SymtabF
, value
); // st_value
165 String32(*SymtabF
, size
); // st_size
166 String8(*SymtabF
, info
); // st_info
167 String8(*SymtabF
, other
); // st_other
168 String16(*SymtabF
, Index
); // st_shndx
172 uint64_t ELFObjectWriter::SymbolValue(MCSymbolData
&Data
,
173 const MCAsmLayout
&Layout
) {
174 if (Data
.isCommon() && Data
.isExternal())
175 return Data
.getCommonAlignment();
177 const MCSymbol
&Symbol
= Data
.getSymbol();
179 if (Symbol
.isAbsolute() && Symbol
.isVariable()) {
180 if (const MCExpr
*Value
= Symbol
.getVariableValue()) {
182 if (Value
->EvaluateAsAbsolute(IntValue
, Layout
))
183 return (uint64_t)IntValue
;
187 if (!Symbol
.isInSection())
191 if (Data
.getFragment()) {
192 if (Data
.getFlags() & ELF_Other_ThumbFunc
)
193 return Layout
.getSymbolOffset(&Data
)+1;
195 return Layout
.getSymbolOffset(&Data
);
201 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler
&Asm
,
202 const MCAsmLayout
&Layout
) {
203 // The presence of symbol versions causes undefined symbols and
204 // versions declared with @@@ to be renamed.
206 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
207 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
208 const MCSymbol
&Alias
= it
->getSymbol();
209 const MCSymbol
&Symbol
= Alias
.AliasedSymbol();
210 MCSymbolData
&SD
= Asm
.getSymbolData(Symbol
);
213 if (&Symbol
== &Alias
)
216 StringRef AliasName
= Alias
.getName();
217 size_t Pos
= AliasName
.find('@');
218 if (Pos
== StringRef::npos
)
221 // Aliases defined with .symvar copy the binding from the symbol they alias.
222 // This is the first place we are able to copy this information.
223 it
->setExternal(SD
.isExternal());
224 MCELF::SetBinding(*it
, MCELF::GetBinding(SD
));
226 StringRef Rest
= AliasName
.substr(Pos
);
227 if (!Symbol
.isUndefined() && !Rest
.startswith("@@@"))
230 // FIXME: produce a better error message.
231 if (Symbol
.isUndefined() && Rest
.startswith("@@") &&
232 !Rest
.startswith("@@@"))
233 report_fatal_error("A @@ version cannot be undefined");
235 Renames
.insert(std::make_pair(&Symbol
, &Alias
));
239 void ELFObjectWriter::WriteSymbol(MCDataFragment
*SymtabF
,
240 MCDataFragment
*ShndxF
,
242 const MCAsmLayout
&Layout
) {
243 MCSymbolData
&OrigData
= *MSD
.SymbolData
;
245 Layout
.getAssembler().getSymbolData(OrigData
.getSymbol().AliasedSymbol());
247 bool IsReserved
= Data
.isCommon() || Data
.getSymbol().isAbsolute() ||
248 Data
.getSymbol().isVariable();
250 uint8_t Binding
= MCELF::GetBinding(OrigData
);
251 uint8_t Visibility
= MCELF::GetVisibility(OrigData
);
252 uint8_t Type
= MCELF::GetType(Data
);
254 uint8_t Info
= (Binding
<< ELF_STB_Shift
) | (Type
<< ELF_STT_Shift
);
255 uint8_t Other
= Visibility
;
257 uint64_t Value
= SymbolValue(Data
, Layout
);
260 assert(!(Data
.isCommon() && !Data
.isExternal()));
262 const MCExpr
*ESize
= Data
.getSize();
265 if (!ESize
->EvaluateAsAbsolute(Res
, Layout
))
266 report_fatal_error("Size expression must be absolute.");
270 // Write out the symbol table entry
271 WriteSymbolEntry(SymtabF
, ShndxF
, MSD
.StringIndex
, Info
, Value
,
272 Size
, Other
, MSD
.SectionIndex
, IsReserved
);
275 void ELFObjectWriter::WriteSymbolTable(MCDataFragment
*SymtabF
,
276 MCDataFragment
*ShndxF
,
277 const MCAssembler
&Asm
,
278 const MCAsmLayout
&Layout
,
279 const SectionIndexMapTy
&SectionIndexMap
) {
280 // The string table must be emitted first because we need the index
281 // into the string table for all the symbol names.
282 assert(StringTable
.size() && "Missing string table");
284 // FIXME: Make sure the start of the symbol table is aligned.
286 // The first entry is the undefined symbol entry.
287 WriteSymbolEntry(SymtabF
, ShndxF
, 0, 0, 0, 0, 0, 0, false);
289 // Write the symbol table entries.
290 LastLocalSymbolIndex
= LocalSymbolData
.size() + 1;
291 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
) {
292 ELFSymbolData
&MSD
= LocalSymbolData
[i
];
293 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
296 // Write out a symbol table entry for each regular section.
297 for (MCAssembler::const_iterator i
= Asm
.begin(), e
= Asm
.end(); i
!= e
;
299 const MCSectionELF
&Section
=
300 static_cast<const MCSectionELF
&>(i
->getSection());
301 if (Section
.getType() == ELF::SHT_RELA
||
302 Section
.getType() == ELF::SHT_REL
||
303 Section
.getType() == ELF::SHT_STRTAB
||
304 Section
.getType() == ELF::SHT_SYMTAB
)
306 WriteSymbolEntry(SymtabF
, ShndxF
, 0, ELF::STT_SECTION
, 0, 0,
307 ELF::STV_DEFAULT
, SectionIndexMap
.lookup(&Section
), false);
308 LastLocalSymbolIndex
++;
311 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
) {
312 ELFSymbolData
&MSD
= ExternalSymbolData
[i
];
313 MCSymbolData
&Data
= *MSD
.SymbolData
;
314 assert(((Data
.getFlags() & ELF_STB_Global
) ||
315 (Data
.getFlags() & ELF_STB_Weak
)) &&
316 "External symbol requires STB_GLOBAL or STB_WEAK flag");
317 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
318 if (MCELF::GetBinding(Data
) == ELF::STB_LOCAL
)
319 LastLocalSymbolIndex
++;
322 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
) {
323 ELFSymbolData
&MSD
= UndefinedSymbolData
[i
];
324 MCSymbolData
&Data
= *MSD
.SymbolData
;
325 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
326 if (MCELF::GetBinding(Data
) == ELF::STB_LOCAL
)
327 LastLocalSymbolIndex
++;
331 const MCSymbol
*ELFObjectWriter::SymbolToReloc(const MCAssembler
&Asm
,
332 const MCValue
&Target
,
334 const MCFixup
&Fixup
,
335 bool IsPCRel
) const {
336 const MCSymbol
&Symbol
= Target
.getSymA()->getSymbol();
337 const MCSymbol
&ASymbol
= Symbol
.AliasedSymbol();
338 const MCSymbol
*Renamed
= Renames
.lookup(&Symbol
);
339 const MCSymbolData
&SD
= Asm
.getSymbolData(Symbol
);
341 if (ASymbol
.isUndefined()) {
347 if (SD
.isExternal()) {
353 const MCSectionELF
&Section
=
354 static_cast<const MCSectionELF
&>(ASymbol
.getSection());
355 const SectionKind secKind
= Section
.getKind();
358 return ExplicitRelSym(Asm
, Target
, F
, Fixup
, IsPCRel
);
360 if (secKind
.isThreadLocal()) {
366 MCSymbolRefExpr::VariantKind Kind
= Target
.getSymA()->getKind();
367 const MCSectionELF
&Sec2
=
368 static_cast<const MCSectionELF
&>(F
.getParent()->getSection());
370 if (&Sec2
!= &Section
&&
371 (Kind
== MCSymbolRefExpr::VK_PLT
||
372 Kind
== MCSymbolRefExpr::VK_GOTPCREL
||
373 Kind
== MCSymbolRefExpr::VK_GOTOFF
)) {
379 if (Section
.getFlags() & ELF::SHF_MERGE
) {
380 if (Target
.getConstant() == 0)
381 return ExplicitRelSym(Asm
, Target
, F
, Fixup
, IsPCRel
);
387 return ExplicitRelSym(Asm
, Target
, F
, Fixup
, IsPCRel
);
392 void ELFObjectWriter::RecordRelocation(const MCAssembler
&Asm
,
393 const MCAsmLayout
&Layout
,
394 const MCFragment
*Fragment
,
395 const MCFixup
&Fixup
,
397 uint64_t &FixedValue
) {
400 int64_t Value
= Target
.getConstant();
401 const MCSymbol
*RelocSymbol
= NULL
;
403 bool IsPCRel
= isFixupKindPCRel(Asm
, Fixup
.getKind());
404 if (!Target
.isAbsolute()) {
405 const MCSymbol
&Symbol
= Target
.getSymA()->getSymbol();
406 const MCSymbol
&ASymbol
= Symbol
.AliasedSymbol();
407 RelocSymbol
= SymbolToReloc(Asm
, Target
, *Fragment
, Fixup
, IsPCRel
);
409 if (const MCSymbolRefExpr
*RefB
= Target
.getSymB()) {
410 const MCSymbol
&SymbolB
= RefB
->getSymbol();
411 MCSymbolData
&SDB
= Asm
.getSymbolData(SymbolB
);
414 // Offset of the symbol in the section
415 int64_t a
= Layout
.getSymbolOffset(&SDB
);
417 // Ofeset of the relocation in the section
418 int64_t b
= Layout
.getFragmentOffset(Fragment
) + Fixup
.getOffset();
423 MCSymbolData
&SD
= Asm
.getSymbolData(ASymbol
);
424 MCFragment
*F
= SD
.getFragment();
426 Index
= F
->getParent()->getOrdinal() + 1;
428 // Offset of the symbol in the section
429 Value
+= Layout
.getSymbolOffset(&SD
);
431 if (Asm
.getSymbolData(Symbol
).getFlags() & ELF_Other_Weakref
)
432 WeakrefUsedInReloc
.insert(RelocSymbol
);
434 UsedInReloc
.insert(RelocSymbol
);
438 // Compensate for the addend on i386.
444 unsigned Type
= GetRelocType(Target
, Fixup
, IsPCRel
,
445 (RelocSymbol
!= 0), Addend
);
447 uint64_t RelocOffset
= Layout
.getFragmentOffset(Fragment
) +
450 if (!hasRelocationAddend())
452 ELFRelocationEntry
ERE(RelocOffset
, Index
, Type
, RelocSymbol
, Addend
);
453 Relocations
[Fragment
->getParent()].push_back(ERE
);
458 ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler
&Asm
,
460 MCSymbolData
&SD
= Asm
.getSymbolData(*S
);
461 return SD
.getIndex();
464 bool ELFObjectWriter::isInSymtab(const MCAssembler
&Asm
,
465 const MCSymbolData
&Data
,
466 bool Used
, bool Renamed
) {
467 if (Data
.getFlags() & ELF_Other_Weakref
)
476 const MCSymbol
&Symbol
= Data
.getSymbol();
478 if (Symbol
.getName() == "_GLOBAL_OFFSET_TABLE_")
481 const MCSymbol
&A
= Symbol
.AliasedSymbol();
482 if (Symbol
.isVariable() && !A
.isVariable() && A
.isUndefined())
485 bool IsGlobal
= MCELF::GetBinding(Data
) == ELF::STB_GLOBAL
;
486 if (!Symbol
.isVariable() && Symbol
.isUndefined() && !IsGlobal
)
489 if (!Asm
.isSymbolLinkerVisible(Symbol
) && !Symbol
.isUndefined())
492 if (Symbol
.isTemporary())
498 bool ELFObjectWriter::isLocal(const MCSymbolData
&Data
, bool isSignature
,
499 bool isUsedInReloc
) {
500 if (Data
.isExternal())
503 const MCSymbol
&Symbol
= Data
.getSymbol();
504 const MCSymbol
&RefSymbol
= Symbol
.AliasedSymbol();
506 if (RefSymbol
.isUndefined() && !RefSymbol
.isVariable()) {
507 if (isSignature
&& !isUsedInReloc
)
516 void ELFObjectWriter::ComputeIndexMap(MCAssembler
&Asm
,
517 SectionIndexMapTy
&SectionIndexMap
,
518 const RelMapTy
&RelMap
) {
520 for (MCAssembler::iterator it
= Asm
.begin(),
521 ie
= Asm
.end(); it
!= ie
; ++it
) {
522 const MCSectionELF
&Section
=
523 static_cast<const MCSectionELF
&>(it
->getSection());
524 if (Section
.getType() != ELF::SHT_GROUP
)
526 SectionIndexMap
[&Section
] = Index
++;
529 for (MCAssembler::iterator it
= Asm
.begin(),
530 ie
= Asm
.end(); it
!= ie
; ++it
) {
531 const MCSectionELF
&Section
=
532 static_cast<const MCSectionELF
&>(it
->getSection());
533 if (Section
.getType() == ELF::SHT_GROUP
||
534 Section
.getType() == ELF::SHT_REL
||
535 Section
.getType() == ELF::SHT_RELA
)
537 SectionIndexMap
[&Section
] = Index
++;
538 const MCSectionELF
*RelSection
= RelMap
.lookup(&Section
);
540 SectionIndexMap
[RelSection
] = Index
++;
544 void ELFObjectWriter::ComputeSymbolTable(MCAssembler
&Asm
,
545 const SectionIndexMapTy
&SectionIndexMap
,
546 RevGroupMapTy RevGroupMap
,
547 unsigned NumRegularSections
) {
548 // FIXME: Is this the correct place to do this?
549 // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
551 llvm::StringRef Name
= "_GLOBAL_OFFSET_TABLE_";
552 MCSymbol
*Sym
= Asm
.getContext().GetOrCreateSymbol(Name
);
553 MCSymbolData
&Data
= Asm
.getOrCreateSymbolData(*Sym
);
554 Data
.setExternal(true);
555 MCELF::SetBinding(Data
, ELF::STB_GLOBAL
);
558 // Index 0 is always the empty string.
559 StringMap
<uint64_t> StringIndexMap
;
560 StringTable
+= '\x00';
562 // FIXME: We could optimize suffixes in strtab in the same way we
563 // optimize them in shstrtab.
565 // Add the data for the symbols.
566 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
567 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
568 const MCSymbol
&Symbol
= it
->getSymbol();
570 bool Used
= UsedInReloc
.count(&Symbol
);
571 bool WeakrefUsed
= WeakrefUsedInReloc
.count(&Symbol
);
572 bool isSignature
= RevGroupMap
.count(&Symbol
);
574 if (!isInSymtab(Asm
, *it
,
575 Used
|| WeakrefUsed
|| isSignature
,
576 Renames
.count(&Symbol
)))
581 const MCSymbol
&RefSymbol
= Symbol
.AliasedSymbol();
583 // Undefined symbols are global, but this is the first place we
584 // are able to set it.
585 bool Local
= isLocal(*it
, isSignature
, Used
);
586 if (!Local
&& MCELF::GetBinding(*it
) == ELF::STB_LOCAL
) {
587 MCSymbolData
&SD
= Asm
.getSymbolData(RefSymbol
);
588 MCELF::SetBinding(*it
, ELF::STB_GLOBAL
);
589 MCELF::SetBinding(SD
, ELF::STB_GLOBAL
);
592 if (RefSymbol
.isUndefined() && !Used
&& WeakrefUsed
)
593 MCELF::SetBinding(*it
, ELF::STB_WEAK
);
595 if (it
->isCommon()) {
597 MSD
.SectionIndex
= ELF::SHN_COMMON
;
598 } else if (Symbol
.isAbsolute() || RefSymbol
.isVariable()) {
599 MSD
.SectionIndex
= ELF::SHN_ABS
;
600 } else if (RefSymbol
.isUndefined()) {
601 if (isSignature
&& !Used
)
602 MSD
.SectionIndex
= SectionIndexMap
.lookup(RevGroupMap
[&Symbol
]);
604 MSD
.SectionIndex
= ELF::SHN_UNDEF
;
606 const MCSectionELF
&Section
=
607 static_cast<const MCSectionELF
&>(RefSymbol
.getSection());
608 MSD
.SectionIndex
= SectionIndexMap
.lookup(&Section
);
609 if (MSD
.SectionIndex
>= ELF::SHN_LORESERVE
)
610 NeedsSymtabShndx
= true;
611 assert(MSD
.SectionIndex
&& "Invalid section index!");
614 // The @@@ in symbol version is replaced with @ in undefined symbols and
615 // @@ in defined ones.
616 StringRef Name
= Symbol
.getName();
619 size_t Pos
= Name
.find("@@@");
620 if (Pos
!= StringRef::npos
) {
621 Buf
+= Name
.substr(0, Pos
);
622 unsigned Skip
= MSD
.SectionIndex
== ELF::SHN_UNDEF
? 2 : 1;
623 Buf
+= Name
.substr(Pos
+ Skip
);
627 uint64_t &Entry
= StringIndexMap
[Name
];
629 Entry
= StringTable
.size();
631 StringTable
+= '\x00';
633 MSD
.StringIndex
= Entry
;
634 if (MSD
.SectionIndex
== ELF::SHN_UNDEF
)
635 UndefinedSymbolData
.push_back(MSD
);
637 LocalSymbolData
.push_back(MSD
);
639 ExternalSymbolData
.push_back(MSD
);
642 // Symbols are required to be in lexicographic order.
643 array_pod_sort(LocalSymbolData
.begin(), LocalSymbolData
.end());
644 array_pod_sort(ExternalSymbolData
.begin(), ExternalSymbolData
.end());
645 array_pod_sort(UndefinedSymbolData
.begin(), UndefinedSymbolData
.end());
647 // Set the symbol indices. Local symbols must come before all other
648 // symbols with non-local bindings.
650 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
)
651 LocalSymbolData
[i
].SymbolData
->setIndex(Index
++);
653 Index
+= NumRegularSections
;
655 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
)
656 ExternalSymbolData
[i
].SymbolData
->setIndex(Index
++);
657 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
)
658 UndefinedSymbolData
[i
].SymbolData
->setIndex(Index
++);
661 void ELFObjectWriter::CreateRelocationSections(MCAssembler
&Asm
,
664 for (MCAssembler::const_iterator it
= Asm
.begin(),
665 ie
= Asm
.end(); it
!= ie
; ++it
) {
666 const MCSectionData
&SD
= *it
;
667 if (Relocations
[&SD
].empty())
670 MCContext
&Ctx
= Asm
.getContext();
671 const MCSectionELF
&Section
=
672 static_cast<const MCSectionELF
&>(SD
.getSection());
674 const StringRef SectionName
= Section
.getSectionName();
675 std::string RelaSectionName
= hasRelocationAddend() ? ".rela" : ".rel";
676 RelaSectionName
+= SectionName
;
679 if (hasRelocationAddend())
680 EntrySize
= is64Bit() ? sizeof(ELF::Elf64_Rela
) : sizeof(ELF::Elf32_Rela
);
682 EntrySize
= is64Bit() ? sizeof(ELF::Elf64_Rel
) : sizeof(ELF::Elf32_Rel
);
684 const MCSectionELF
*RelaSection
=
685 Ctx
.getELFSection(RelaSectionName
, hasRelocationAddend() ?
686 ELF::SHT_RELA
: ELF::SHT_REL
, 0,
687 SectionKind::getReadOnly(),
689 RelMap
[&Section
] = RelaSection
;
690 Asm
.getOrCreateSectionData(*RelaSection
);
694 void ELFObjectWriter::WriteRelocations(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
695 const RelMapTy
&RelMap
) {
696 for (MCAssembler::const_iterator it
= Asm
.begin(),
697 ie
= Asm
.end(); it
!= ie
; ++it
) {
698 const MCSectionData
&SD
= *it
;
699 const MCSectionELF
&Section
=
700 static_cast<const MCSectionELF
&>(SD
.getSection());
702 const MCSectionELF
*RelaSection
= RelMap
.lookup(&Section
);
705 MCSectionData
&RelaSD
= Asm
.getOrCreateSectionData(*RelaSection
);
706 RelaSD
.setAlignment(is64Bit() ? 8 : 4);
708 MCDataFragment
*F
= new MCDataFragment(&RelaSD
);
709 WriteRelocationsFragment(Asm
, F
, &*it
);
713 void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name
, uint32_t Type
,
714 uint64_t Flags
, uint64_t Address
,
715 uint64_t Offset
, uint64_t Size
,
716 uint32_t Link
, uint32_t Info
,
718 uint64_t EntrySize
) {
719 Write32(Name
); // sh_name: index into string table
720 Write32(Type
); // sh_type
721 WriteWord(Flags
); // sh_flags
722 WriteWord(Address
); // sh_addr
723 WriteWord(Offset
); // sh_offset
724 WriteWord(Size
); // sh_size
725 Write32(Link
); // sh_link
726 Write32(Info
); // sh_info
727 WriteWord(Alignment
); // sh_addralign
728 WriteWord(EntrySize
); // sh_entsize
731 void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler
&Asm
,
733 const MCSectionData
*SD
) {
734 std::vector
<ELFRelocationEntry
> &Relocs
= Relocations
[SD
];
735 // sort by the r_offset just like gnu as does
736 array_pod_sort(Relocs
.begin(), Relocs
.end());
738 for (unsigned i
= 0, e
= Relocs
.size(); i
!= e
; ++i
) {
739 ELFRelocationEntry entry
= Relocs
[e
- i
- 1];
743 else if (entry
.Index
< 0)
744 entry
.Index
= getSymbolIndexInSymbolTable(Asm
, entry
.Symbol
);
746 entry
.Index
+= LocalSymbolData
.size();
748 String64(*F
, entry
.r_offset
);
750 struct ELF::Elf64_Rela ERE64
;
751 ERE64
.setSymbolAndType(entry
.Index
, entry
.Type
);
752 String64(*F
, ERE64
.r_info
);
754 if (hasRelocationAddend())
755 String64(*F
, entry
.r_addend
);
757 String32(*F
, entry
.r_offset
);
759 struct ELF::Elf32_Rela ERE32
;
760 ERE32
.setSymbolAndType(entry
.Index
, entry
.Type
);
761 String32(*F
, ERE32
.r_info
);
763 if (hasRelocationAddend())
764 String32(*F
, entry
.r_addend
);
769 static int compareBySuffix(const void *a
, const void *b
) {
770 const MCSectionELF
*secA
= *static_cast<const MCSectionELF
* const *>(a
);
771 const MCSectionELF
*secB
= *static_cast<const MCSectionELF
* const *>(b
);
772 const StringRef
&NameA
= secA
->getSectionName();
773 const StringRef
&NameB
= secB
->getSectionName();
774 const unsigned sizeA
= NameA
.size();
775 const unsigned sizeB
= NameB
.size();
776 const unsigned len
= std::min(sizeA
, sizeB
);
777 for (unsigned int i
= 0; i
< len
; ++i
) {
778 char ca
= NameA
[sizeA
- i
- 1];
779 char cb
= NameB
[sizeB
- i
- 1];
784 return sizeB
- sizeA
;
787 void ELFObjectWriter::CreateMetadataSections(MCAssembler
&Asm
,
789 SectionIndexMapTy
&SectionIndexMap
,
790 const RelMapTy
&RelMap
) {
791 MCContext
&Ctx
= Asm
.getContext();
794 unsigned EntrySize
= is64Bit() ? ELF::SYMENTRY_SIZE64
: ELF::SYMENTRY_SIZE32
;
796 // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
797 const MCSectionELF
*ShstrtabSection
=
798 Ctx
.getELFSection(".shstrtab", ELF::SHT_STRTAB
, 0,
799 SectionKind::getReadOnly());
800 MCSectionData
&ShstrtabSD
= Asm
.getOrCreateSectionData(*ShstrtabSection
);
801 ShstrtabSD
.setAlignment(1);
803 const MCSectionELF
*SymtabSection
=
804 Ctx
.getELFSection(".symtab", ELF::SHT_SYMTAB
, 0,
805 SectionKind::getReadOnly(),
807 MCSectionData
&SymtabSD
= Asm
.getOrCreateSectionData(*SymtabSection
);
808 SymtabSD
.setAlignment(is64Bit() ? 8 : 4);
810 MCSectionData
*SymtabShndxSD
= NULL
;
812 if (NeedsSymtabShndx
) {
813 const MCSectionELF
*SymtabShndxSection
=
814 Ctx
.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX
, 0,
815 SectionKind::getReadOnly(), 4, "");
816 SymtabShndxSD
= &Asm
.getOrCreateSectionData(*SymtabShndxSection
);
817 SymtabShndxSD
->setAlignment(4);
820 const MCSectionELF
*StrtabSection
;
821 StrtabSection
= Ctx
.getELFSection(".strtab", ELF::SHT_STRTAB
, 0,
822 SectionKind::getReadOnly());
823 MCSectionData
&StrtabSD
= Asm
.getOrCreateSectionData(*StrtabSection
);
824 StrtabSD
.setAlignment(1);
826 ComputeIndexMap(Asm
, SectionIndexMap
, RelMap
);
828 ShstrtabIndex
= SectionIndexMap
.lookup(ShstrtabSection
);
829 SymbolTableIndex
= SectionIndexMap
.lookup(SymtabSection
);
830 StringTableIndex
= SectionIndexMap
.lookup(StrtabSection
);
833 F
= new MCDataFragment(&SymtabSD
);
834 MCDataFragment
*ShndxF
= NULL
;
835 if (NeedsSymtabShndx
) {
836 ShndxF
= new MCDataFragment(SymtabShndxSD
);
838 WriteSymbolTable(F
, ShndxF
, Asm
, Layout
, SectionIndexMap
);
840 F
= new MCDataFragment(&StrtabSD
);
841 F
->getContents().append(StringTable
.begin(), StringTable
.end());
843 F
= new MCDataFragment(&ShstrtabSD
);
845 std::vector
<const MCSectionELF
*> Sections
;
846 for (MCAssembler::const_iterator it
= Asm
.begin(),
847 ie
= Asm
.end(); it
!= ie
; ++it
) {
848 const MCSectionELF
&Section
=
849 static_cast<const MCSectionELF
&>(it
->getSection());
850 Sections
.push_back(&Section
);
852 array_pod_sort(Sections
.begin(), Sections
.end(), compareBySuffix
);
854 // Section header string table.
856 // The first entry of a string table holds a null character so skip
859 F
->getContents() += '\x00';
861 for (unsigned int I
= 0, E
= Sections
.size(); I
!= E
; ++I
) {
862 const MCSectionELF
&Section
= *Sections
[I
];
864 StringRef Name
= Section
.getSectionName();
866 StringRef PreviousName
= Sections
[I
- 1]->getSectionName();
867 if (PreviousName
.endswith(Name
)) {
868 SectionStringTableIndex
[&Section
] = Index
- Name
.size() - 1;
872 // Remember the index into the string table so we can write it
873 // into the sh_name field of the section header table.
874 SectionStringTableIndex
[&Section
] = Index
;
876 Index
+= Name
.size() + 1;
877 F
->getContents() += Name
;
878 F
->getContents() += '\x00';
882 void ELFObjectWriter::CreateIndexedSections(MCAssembler
&Asm
,
884 GroupMapTy
&GroupMap
,
885 RevGroupMapTy
&RevGroupMap
,
886 SectionIndexMapTy
&SectionIndexMap
,
887 const RelMapTy
&RelMap
) {
888 // Create the .note.GNU-stack section if needed.
889 MCContext
&Ctx
= Asm
.getContext();
890 if (Asm
.getNoExecStack()) {
891 const MCSectionELF
*GnuStackSection
=
892 Ctx
.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS
, 0,
893 SectionKind::getReadOnly());
894 Asm
.getOrCreateSectionData(*GnuStackSection
);
898 for (MCAssembler::const_iterator it
= Asm
.begin(), ie
= Asm
.end();
900 const MCSectionELF
&Section
=
901 static_cast<const MCSectionELF
&>(it
->getSection());
902 if (!(Section
.getFlags() & ELF::SHF_GROUP
))
905 const MCSymbol
*SignatureSymbol
= Section
.getGroup();
906 Asm
.getOrCreateSymbolData(*SignatureSymbol
);
907 const MCSectionELF
*&Group
= RevGroupMap
[SignatureSymbol
];
909 Group
= Ctx
.CreateELFGroupSection();
910 MCSectionData
&Data
= Asm
.getOrCreateSectionData(*Group
);
911 Data
.setAlignment(4);
912 MCDataFragment
*F
= new MCDataFragment(&Data
);
913 String32(*F
, ELF::GRP_COMDAT
);
915 GroupMap
[Group
] = SignatureSymbol
;
918 ComputeIndexMap(Asm
, SectionIndexMap
, RelMap
);
920 // Add sections to the groups
921 for (MCAssembler::const_iterator it
= Asm
.begin(), ie
= Asm
.end();
923 const MCSectionELF
&Section
=
924 static_cast<const MCSectionELF
&>(it
->getSection());
925 if (!(Section
.getFlags() & ELF::SHF_GROUP
))
927 const MCSectionELF
*Group
= RevGroupMap
[Section
.getGroup()];
928 MCSectionData
&Data
= Asm
.getOrCreateSectionData(*Group
);
929 // FIXME: we could use the previous fragment
930 MCDataFragment
*F
= new MCDataFragment(&Data
);
931 unsigned Index
= SectionIndexMap
.lookup(&Section
);
936 void ELFObjectWriter::WriteSection(MCAssembler
&Asm
,
937 const SectionIndexMapTy
&SectionIndexMap
,
938 uint32_t GroupSymbolIndex
,
939 uint64_t Offset
, uint64_t Size
,
941 const MCSectionELF
&Section
) {
942 uint64_t sh_link
= 0;
943 uint64_t sh_info
= 0;
945 switch(Section
.getType()) {
946 case ELF::SHT_DYNAMIC
:
947 sh_link
= SectionStringTableIndex
[&Section
];
952 case ELF::SHT_RELA
: {
953 const MCSectionELF
*SymtabSection
;
954 const MCSectionELF
*InfoSection
;
955 SymtabSection
= Asm
.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB
,
957 SectionKind::getReadOnly());
958 sh_link
= SectionIndexMap
.lookup(SymtabSection
);
959 assert(sh_link
&& ".symtab not found");
961 // Remove ".rel" and ".rela" prefixes.
962 unsigned SecNameLen
= (Section
.getType() == ELF::SHT_REL
) ? 4 : 5;
963 StringRef SectionName
= Section
.getSectionName().substr(SecNameLen
);
965 InfoSection
= Asm
.getContext().getELFSection(SectionName
,
966 ELF::SHT_PROGBITS
, 0,
967 SectionKind::getReadOnly());
968 sh_info
= SectionIndexMap
.lookup(InfoSection
);
972 case ELF::SHT_SYMTAB
:
973 case ELF::SHT_DYNSYM
:
974 sh_link
= StringTableIndex
;
975 sh_info
= LastLocalSymbolIndex
;
978 case ELF::SHT_SYMTAB_SHNDX
:
979 sh_link
= SymbolTableIndex
;
982 case ELF::SHT_PROGBITS
:
983 case ELF::SHT_STRTAB
:
984 case ELF::SHT_NOBITS
:
987 case ELF::SHT_ARM_ATTRIBUTES
:
988 case ELF::SHT_INIT_ARRAY
:
989 case ELF::SHT_FINI_ARRAY
:
990 case ELF::SHT_PREINIT_ARRAY
:
991 case ELF::SHT_X86_64_UNWIND
:
995 case ELF::SHT_GROUP
: {
996 sh_link
= SymbolTableIndex
;
997 sh_info
= GroupSymbolIndex
;
1002 assert(0 && "FIXME: sh_type value not supported!");
1006 WriteSecHdrEntry(SectionStringTableIndex
[&Section
], Section
.getType(),
1007 Section
.getFlags(), 0, Offset
, Size
, sh_link
, sh_info
,
1008 Alignment
, Section
.getEntrySize());
1011 bool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData
&SD
) {
1012 return SD
.getOrdinal() == ~UINT32_C(0) &&
1013 !SD
.getSection().isVirtualSection();
1016 uint64_t ELFObjectWriter::DataSectionSize(const MCSectionData
&SD
) {
1018 for (MCSectionData::const_iterator i
= SD
.begin(), e
= SD
.end(); i
!= e
;
1020 const MCFragment
&F
= *i
;
1021 assert(F
.getKind() == MCFragment::FT_Data
);
1022 Ret
+= cast
<MCDataFragment
>(F
).getContents().size();
1027 uint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout
&Layout
,
1028 const MCSectionData
&SD
) {
1029 if (IsELFMetaDataSection(SD
))
1030 return DataSectionSize(SD
);
1031 return Layout
.getSectionFileSize(&SD
);
1034 uint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout
&Layout
,
1035 const MCSectionData
&SD
) {
1036 if (IsELFMetaDataSection(SD
))
1037 return DataSectionSize(SD
);
1038 return Layout
.getSectionAddressSize(&SD
);
1041 void ELFObjectWriter::WriteDataSectionData(MCAssembler
&Asm
,
1042 const MCAsmLayout
&Layout
,
1043 const MCSectionELF
&Section
) {
1044 uint64_t FileOff
= OS
.tell();
1045 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1047 uint64_t Padding
= OffsetToAlignment(FileOff
, SD
.getAlignment());
1048 WriteZeros(Padding
);
1051 FileOff
+= GetSectionFileSize(Layout
, SD
);
1053 if (IsELFMetaDataSection(SD
)) {
1054 for (MCSectionData::const_iterator i
= SD
.begin(), e
= SD
.end(); i
!= e
;
1056 const MCFragment
&F
= *i
;
1057 assert(F
.getKind() == MCFragment::FT_Data
);
1058 WriteBytes(cast
<MCDataFragment
>(F
).getContents().str());
1061 Asm
.WriteSectionData(&SD
, Layout
);
1065 void ELFObjectWriter::WriteSectionHeader(MCAssembler
&Asm
,
1066 const GroupMapTy
&GroupMap
,
1067 const MCAsmLayout
&Layout
,
1068 const SectionIndexMapTy
&SectionIndexMap
,
1069 const SectionOffsetMapTy
&SectionOffsetMap
) {
1070 const unsigned NumSections
= Asm
.size() + 1;
1072 std::vector
<const MCSectionELF
*> Sections
;
1073 Sections
.resize(NumSections
- 1);
1075 for (SectionIndexMapTy::const_iterator i
=
1076 SectionIndexMap
.begin(), e
= SectionIndexMap
.end(); i
!= e
; ++i
) {
1077 const std::pair
<const MCSectionELF
*, uint32_t> &p
= *i
;
1078 Sections
[p
.second
- 1] = p
.first
;
1081 // Null section first.
1082 uint64_t FirstSectionSize
=
1083 NumSections
>= ELF::SHN_LORESERVE
? NumSections
: 0;
1084 uint32_t FirstSectionLink
=
1085 ShstrtabIndex
>= ELF::SHN_LORESERVE
? ShstrtabIndex
: 0;
1086 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize
, FirstSectionLink
, 0, 0, 0);
1088 for (unsigned i
= 0; i
< NumSections
- 1; ++i
) {
1089 const MCSectionELF
&Section
= *Sections
[i
];
1090 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1091 uint32_t GroupSymbolIndex
;
1092 if (Section
.getType() != ELF::SHT_GROUP
)
1093 GroupSymbolIndex
= 0;
1095 GroupSymbolIndex
= getSymbolIndexInSymbolTable(Asm
,
1096 GroupMap
.lookup(&Section
));
1098 uint64_t Size
= GetSectionAddressSize(Layout
, SD
);
1100 WriteSection(Asm
, SectionIndexMap
, GroupSymbolIndex
,
1101 SectionOffsetMap
.lookup(&Section
), Size
,
1102 SD
.getAlignment(), Section
);
1106 void ELFObjectWriter::ComputeSectionOrder(MCAssembler
&Asm
,
1107 std::vector
<const MCSectionELF
*> &Sections
) {
1108 for (MCAssembler::iterator it
= Asm
.begin(),
1109 ie
= Asm
.end(); it
!= ie
; ++it
) {
1110 const MCSectionELF
&Section
=
1111 static_cast<const MCSectionELF
&>(it
->getSection());
1112 if (Section
.getType() == ELF::SHT_GROUP
)
1113 Sections
.push_back(&Section
);
1116 for (MCAssembler::iterator it
= Asm
.begin(),
1117 ie
= Asm
.end(); it
!= ie
; ++it
) {
1118 const MCSectionELF
&Section
=
1119 static_cast<const MCSectionELF
&>(it
->getSection());
1120 if (Section
.getType() != ELF::SHT_GROUP
&&
1121 Section
.getType() != ELF::SHT_REL
&&
1122 Section
.getType() != ELF::SHT_RELA
)
1123 Sections
.push_back(&Section
);
1126 for (MCAssembler::iterator it
= Asm
.begin(),
1127 ie
= Asm
.end(); it
!= ie
; ++it
) {
1128 const MCSectionELF
&Section
=
1129 static_cast<const MCSectionELF
&>(it
->getSection());
1130 if (Section
.getType() == ELF::SHT_REL
||
1131 Section
.getType() == ELF::SHT_RELA
)
1132 Sections
.push_back(&Section
);
1136 void ELFObjectWriter::WriteObject(MCAssembler
&Asm
,
1137 const MCAsmLayout
&Layout
) {
1138 GroupMapTy GroupMap
;
1139 RevGroupMapTy RevGroupMap
;
1140 SectionIndexMapTy SectionIndexMap
;
1142 unsigned NumUserSections
= Asm
.size();
1144 DenseMap
<const MCSectionELF
*, const MCSectionELF
*> RelMap
;
1145 CreateRelocationSections(Asm
, const_cast<MCAsmLayout
&>(Layout
), RelMap
);
1147 const unsigned NumUserAndRelocSections
= Asm
.size();
1148 CreateIndexedSections(Asm
, const_cast<MCAsmLayout
&>(Layout
), GroupMap
,
1149 RevGroupMap
, SectionIndexMap
, RelMap
);
1150 const unsigned AllSections
= Asm
.size();
1151 const unsigned NumIndexedSections
= AllSections
- NumUserAndRelocSections
;
1153 unsigned NumRegularSections
= NumUserSections
+ NumIndexedSections
;
1155 // Compute symbol table information.
1156 ComputeSymbolTable(Asm
, SectionIndexMap
, RevGroupMap
, NumRegularSections
);
1159 WriteRelocations(Asm
, const_cast<MCAsmLayout
&>(Layout
), RelMap
);
1161 CreateMetadataSections(const_cast<MCAssembler
&>(Asm
),
1162 const_cast<MCAsmLayout
&>(Layout
),
1166 uint64_t NaturalAlignment
= is64Bit() ? 8 : 4;
1167 uint64_t HeaderSize
= is64Bit() ? sizeof(ELF::Elf64_Ehdr
) :
1168 sizeof(ELF::Elf32_Ehdr
);
1169 uint64_t FileOff
= HeaderSize
;
1171 std::vector
<const MCSectionELF
*> Sections
;
1172 ComputeSectionOrder(Asm
, Sections
);
1173 unsigned NumSections
= Sections
.size();
1174 SectionOffsetMapTy SectionOffsetMap
;
1175 for (unsigned i
= 0; i
< NumRegularSections
+ 1; ++i
) {
1176 const MCSectionELF
&Section
= *Sections
[i
];
1177 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1179 FileOff
= RoundUpToAlignment(FileOff
, SD
.getAlignment());
1181 // Remember the offset into the file for this section.
1182 SectionOffsetMap
[&Section
] = FileOff
;
1184 // Get the size of the section in the output file (including padding).
1185 FileOff
+= GetSectionFileSize(Layout
, SD
);
1188 FileOff
= RoundUpToAlignment(FileOff
, NaturalAlignment
);
1190 const unsigned SectionHeaderOffset
= FileOff
- HeaderSize
;
1192 uint64_t SectionHeaderEntrySize
= is64Bit() ?
1193 sizeof(ELF::Elf64_Shdr
) : sizeof(ELF::Elf32_Shdr
);
1194 FileOff
+= (NumSections
+ 1) * SectionHeaderEntrySize
;
1196 for (unsigned i
= NumRegularSections
+ 1; i
< NumSections
; ++i
) {
1197 const MCSectionELF
&Section
= *Sections
[i
];
1198 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1200 FileOff
= RoundUpToAlignment(FileOff
, SD
.getAlignment());
1202 // Remember the offset into the file for this section.
1203 SectionOffsetMap
[&Section
] = FileOff
;
1205 // Get the size of the section in the output file (including padding).
1206 FileOff
+= GetSectionFileSize(Layout
, SD
);
1209 // Write out the ELF header ...
1210 WriteHeader(SectionHeaderOffset
, NumSections
+ 1);
1212 // ... then the regular sections ...
1213 // + because of .shstrtab
1214 for (unsigned i
= 0; i
< NumRegularSections
+ 1; ++i
)
1215 WriteDataSectionData(Asm
, Layout
, *Sections
[i
]);
1217 FileOff
= OS
.tell();
1218 uint64_t Padding
= OffsetToAlignment(FileOff
, NaturalAlignment
);
1219 WriteZeros(Padding
);
1221 // ... then the section header table ...
1222 WriteSectionHeader(Asm
, GroupMap
, Layout
, SectionIndexMap
,
1225 FileOff
= OS
.tell();
1227 // ... and then the remainting sections ...
1228 for (unsigned i
= NumRegularSections
+ 1; i
< NumSections
; ++i
)
1229 WriteDataSectionData(Asm
, Layout
, *Sections
[i
]);
1233 ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler
&Asm
,
1234 const MCSymbolData
&DataA
,
1235 const MCFragment
&FB
,
1237 bool IsPCRel
) const {
1238 if (DataA
.getFlags() & ELF_STB_Weak
)
1240 return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
1241 Asm
, DataA
, FB
,InSet
, IsPCRel
);
1244 MCObjectWriter
*llvm::createELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
1246 bool IsLittleEndian
) {
1247 switch (MOTW
->getEMachine()) {
1249 case ELF::EM_X86_64
:
1250 return new X86ELFObjectWriter(MOTW
, OS
, IsLittleEndian
); break;
1252 return new ARMELFObjectWriter(MOTW
, OS
, IsLittleEndian
); break;
1253 case ELF::EM_MBLAZE
:
1254 return new MBlazeELFObjectWriter(MOTW
, OS
, IsLittleEndian
); break;
1255 default: llvm_unreachable("Unsupported architecture"); break;
1260 /// START OF SUBCLASSES for ELFObjectWriter
1261 //===- ARMELFObjectWriter -------------------------------------------===//
1263 ARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
1265 bool IsLittleEndian
)
1266 : ELFObjectWriter(MOTW
, _OS
, IsLittleEndian
)
1269 ARMELFObjectWriter::~ARMELFObjectWriter()
1272 // FIXME: get the real EABI Version from the Triple.
1273 void ARMELFObjectWriter::WriteEFlags() {
1274 Write32(ELF::EF_ARM_EABIMASK
& DefaultEABIVersion
);
1277 // In ARM, _MergedGlobals and other most symbols get emitted directly.
1278 // I.e. not as an offset to a section symbol.
1279 // This code is an approximation of what ARM/gcc does.
1281 STATISTIC(PCRelCount
, "Total number of PIC Relocations");
1282 STATISTIC(NonPCRelCount
, "Total number of non-PIC relocations");
1284 const MCSymbol
*ARMELFObjectWriter::ExplicitRelSym(const MCAssembler
&Asm
,
1285 const MCValue
&Target
,
1286 const MCFragment
&F
,
1287 const MCFixup
&Fixup
,
1288 bool IsPCRel
) const {
1289 const MCSymbol
&Symbol
= Target
.getSymA()->getSymbol();
1290 bool EmitThisSym
= false;
1292 const MCSectionELF
&Section
=
1293 static_cast<const MCSectionELF
&>(Symbol
.getSection());
1294 bool InNormalSection
= true;
1295 unsigned RelocType
= 0;
1296 RelocType
= GetRelocTypeInner(Target
, Fixup
, IsPCRel
);
1299 const MCSymbolRefExpr::VariantKind Kind
= Target
.getSymA()->getKind();
1300 MCSymbolRefExpr::VariantKind Kind2
;
1301 Kind2
= Target
.getSymB() ? Target
.getSymB()->getKind() :
1302 MCSymbolRefExpr::VK_None
;
1303 dbgs() << "considering symbol "
1304 << Section
.getSectionName() << "/"
1305 << Symbol
.getName() << "/"
1306 << " Rel:" << (unsigned)RelocType
1307 << " Kind: " << (int)Kind
<< "/" << (int)Kind2
1309 << Symbol
.isAbsolute() << "/" << Symbol
.isDefined() << "/"
1310 << Symbol
.isVariable() << "/" << Symbol
.isTemporary()
1311 << " Counts:" << PCRelCount
<< "/" << NonPCRelCount
<< "\n");
1313 if (IsPCRel
) { ++PCRelCount
;
1314 switch (RelocType
) {
1316 // Most relocation types are emitted as explicit symbols
1318 StringSwitch
<bool>(Section
.getSectionName())
1319 .Case(".data.rel.ro.local", false)
1320 .Case(".data.rel", false)
1321 .Case(".bss", false)
1325 case ELF::R_ARM_ABS32
:
1326 // But things get strange with R_ARM_ABS32
1327 // In this case, most things that go in .rodata show up
1328 // as section relative relocations
1330 StringSwitch
<bool>(Section
.getSectionName())
1331 .Case(".data.rel.ro.local", false)
1332 .Case(".data.rel", false)
1333 .Case(".rodata", false)
1334 .Case(".bss", false)
1336 EmitThisSym
= false;
1342 StringSwitch
<bool>(Section
.getSectionName())
1343 .Case(".data.rel.ro.local", false)
1344 .Case(".rodata", false)
1345 .Case(".data.rel", false)
1346 .Case(".bss", false)
1349 switch (RelocType
) {
1350 default: EmitThisSym
= true; break;
1351 case ELF::R_ARM_ABS32
: EmitThisSym
= false; break;
1357 if (! Symbol
.isTemporary() && InNormalSection
) {
1363 // Need to examine the Fixup when determining whether to
1364 // emit the relocation as an explicit symbol or as a section relative
1366 unsigned ARMELFObjectWriter::GetRelocType(const MCValue
&Target
,
1367 const MCFixup
&Fixup
,
1369 bool IsRelocWithSymbol
,
1371 MCSymbolRefExpr::VariantKind Modifier
= Target
.isAbsolute() ?
1372 MCSymbolRefExpr::VK_None
: Target
.getSymA()->getKind();
1374 unsigned Type
= GetRelocTypeInner(Target
, Fixup
, IsPCRel
);
1376 if (RelocNeedsGOT(Modifier
))
1382 unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue
&Target
,
1383 const MCFixup
&Fixup
,
1384 bool IsPCRel
) const {
1385 MCSymbolRefExpr::VariantKind Modifier
= Target
.isAbsolute() ?
1386 MCSymbolRefExpr::VK_None
: Target
.getSymA()->getKind();
1390 switch ((unsigned)Fixup
.getKind()) {
1391 default: assert(0 && "Unimplemented");
1394 default: llvm_unreachable("Unsupported Modifier");
1395 case MCSymbolRefExpr::VK_None
:
1396 Type
= ELF::R_ARM_REL32
;
1398 case MCSymbolRefExpr::VK_ARM_TLSGD
:
1399 assert(0 && "unimplemented");
1401 case MCSymbolRefExpr::VK_ARM_GOTTPOFF
:
1402 Type
= ELF::R_ARM_TLS_IE32
;
1406 case ARM::fixup_arm_uncondbranch
:
1408 case MCSymbolRefExpr::VK_ARM_PLT
:
1409 Type
= ELF::R_ARM_PLT32
;
1412 Type
= ELF::R_ARM_CALL
;
1416 case ARM::fixup_arm_condbranch
:
1417 Type
= ELF::R_ARM_JUMP24
;
1419 case ARM::fixup_arm_movt_hi16
:
1420 case ARM::fixup_arm_movt_hi16_pcrel
:
1421 Type
= ELF::R_ARM_MOVT_PREL
;
1423 case ARM::fixup_arm_movw_lo16
:
1424 case ARM::fixup_arm_movw_lo16_pcrel
:
1425 Type
= ELF::R_ARM_MOVW_PREL_NC
;
1427 case ARM::fixup_t2_movt_hi16
:
1428 case ARM::fixup_t2_movt_hi16_pcrel
:
1429 Type
= ELF::R_ARM_THM_MOVT_PREL
;
1431 case ARM::fixup_t2_movw_lo16
:
1432 case ARM::fixup_t2_movw_lo16_pcrel
:
1433 Type
= ELF::R_ARM_THM_MOVW_PREL_NC
;
1435 case ARM::fixup_arm_thumb_bl
:
1436 case ARM::fixup_arm_thumb_blx
:
1438 case MCSymbolRefExpr::VK_ARM_PLT
:
1439 Type
= ELF::R_ARM_THM_CALL
;
1442 Type
= ELF::R_ARM_NONE
;
1448 switch ((unsigned)Fixup
.getKind()) {
1449 default: llvm_unreachable("invalid fixup kind!");
1452 default: llvm_unreachable("Unsupported Modifier"); break;
1453 case MCSymbolRefExpr::VK_ARM_GOT
:
1454 Type
= ELF::R_ARM_GOT_BREL
;
1456 case MCSymbolRefExpr::VK_ARM_TLSGD
:
1457 Type
= ELF::R_ARM_TLS_GD32
;
1459 case MCSymbolRefExpr::VK_ARM_TPOFF
:
1460 Type
= ELF::R_ARM_TLS_LE32
;
1462 case MCSymbolRefExpr::VK_ARM_GOTTPOFF
:
1463 Type
= ELF::R_ARM_TLS_IE32
;
1465 case MCSymbolRefExpr::VK_None
:
1466 Type
= ELF::R_ARM_ABS32
;
1468 case MCSymbolRefExpr::VK_ARM_GOTOFF
:
1469 Type
= ELF::R_ARM_GOTOFF32
;
1473 case ARM::fixup_arm_ldst_pcrel_12
:
1474 case ARM::fixup_arm_pcrel_10
:
1475 case ARM::fixup_arm_adr_pcrel_12
:
1476 case ARM::fixup_arm_thumb_bl
:
1477 case ARM::fixup_arm_thumb_cb
:
1478 case ARM::fixup_arm_thumb_cp
:
1479 case ARM::fixup_arm_thumb_br
:
1480 assert(0 && "Unimplemented");
1482 case ARM::fixup_arm_uncondbranch
:
1483 Type
= ELF::R_ARM_CALL
;
1485 case ARM::fixup_arm_condbranch
:
1486 Type
= ELF::R_ARM_JUMP24
;
1488 case ARM::fixup_arm_movt_hi16
:
1489 Type
= ELF::R_ARM_MOVT_ABS
;
1491 case ARM::fixup_arm_movw_lo16
:
1492 Type
= ELF::R_ARM_MOVW_ABS_NC
;
1494 case ARM::fixup_t2_movt_hi16
:
1495 Type
= ELF::R_ARM_THM_MOVT_ABS
;
1497 case ARM::fixup_t2_movw_lo16
:
1498 Type
= ELF::R_ARM_THM_MOVW_ABS_NC
;
1506 //===- MBlazeELFObjectWriter -------------------------------------------===//
1508 MBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
1510 bool IsLittleEndian
)
1511 : ELFObjectWriter(MOTW
, _OS
, IsLittleEndian
) {
1514 MBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
1517 unsigned MBlazeELFObjectWriter::GetRelocType(const MCValue
&Target
,
1518 const MCFixup
&Fixup
,
1520 bool IsRelocWithSymbol
,
1522 // determine the type of the relocation
1525 switch ((unsigned)Fixup
.getKind()) {
1527 llvm_unreachable("Unimplemented");
1529 Type
= ELF::R_MICROBLAZE_64_PCREL
;
1532 Type
= ELF::R_MICROBLAZE_32_PCREL
;
1536 switch ((unsigned)Fixup
.getKind()) {
1537 default: llvm_unreachable("invalid fixup kind!");
1539 Type
= ((IsRelocWithSymbol
|| Addend
!=0)
1540 ? ELF::R_MICROBLAZE_32
1541 : ELF::R_MICROBLAZE_64
);
1544 Type
= ELF::R_MICROBLAZE_32
;
1551 //===- X86ELFObjectWriter -------------------------------------------===//
1554 X86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
1556 bool IsLittleEndian
)
1557 : ELFObjectWriter(MOTW
, _OS
, IsLittleEndian
)
1560 X86ELFObjectWriter::~X86ELFObjectWriter()
1563 unsigned X86ELFObjectWriter::GetRelocType(const MCValue
&Target
,
1564 const MCFixup
&Fixup
,
1566 bool IsRelocWithSymbol
,
1568 // determine the type of the relocation
1570 MCSymbolRefExpr::VariantKind Modifier
= Target
.isAbsolute() ?
1571 MCSymbolRefExpr::VK_None
: Target
.getSymA()->getKind();
1575 switch ((unsigned)Fixup
.getKind()) {
1576 default: llvm_unreachable("invalid fixup kind!");
1578 case FK_Data_8
: Type
= ELF::R_X86_64_PC64
; break;
1579 case FK_Data_4
: Type
= ELF::R_X86_64_PC32
; break;
1580 case FK_Data_2
: Type
= ELF::R_X86_64_PC16
; break;
1583 assert(Modifier
== MCSymbolRefExpr::VK_None
);
1584 Type
= ELF::R_X86_64_PC64
;
1586 case X86::reloc_signed_4byte
:
1587 case X86::reloc_riprel_4byte_movq_load
:
1588 case X86::reloc_riprel_4byte
:
1592 llvm_unreachable("Unimplemented");
1593 case MCSymbolRefExpr::VK_None
:
1594 Type
= ELF::R_X86_64_PC32
;
1596 case MCSymbolRefExpr::VK_PLT
:
1597 Type
= ELF::R_X86_64_PLT32
;
1599 case MCSymbolRefExpr::VK_GOTPCREL
:
1600 Type
= ELF::R_X86_64_GOTPCREL
;
1602 case MCSymbolRefExpr::VK_GOTTPOFF
:
1603 Type
= ELF::R_X86_64_GOTTPOFF
;
1605 case MCSymbolRefExpr::VK_TLSGD
:
1606 Type
= ELF::R_X86_64_TLSGD
;
1608 case MCSymbolRefExpr::VK_TLSLD
:
1609 Type
= ELF::R_X86_64_TLSLD
;
1614 assert(Modifier
== MCSymbolRefExpr::VK_None
);
1615 Type
= ELF::R_X86_64_PC16
;
1618 assert(Modifier
== MCSymbolRefExpr::VK_None
);
1619 Type
= ELF::R_X86_64_PC8
;
1623 switch ((unsigned)Fixup
.getKind()) {
1624 default: llvm_unreachable("invalid fixup kind!");
1625 case FK_Data_8
: Type
= ELF::R_X86_64_64
; break;
1626 case X86::reloc_signed_4byte
:
1627 assert(isInt
<32>(Target
.getConstant()));
1630 llvm_unreachable("Unimplemented");
1631 case MCSymbolRefExpr::VK_None
:
1632 Type
= ELF::R_X86_64_32S
;
1634 case MCSymbolRefExpr::VK_GOT
:
1635 Type
= ELF::R_X86_64_GOT32
;
1637 case MCSymbolRefExpr::VK_GOTPCREL
:
1638 Type
= ELF::R_X86_64_GOTPCREL
;
1640 case MCSymbolRefExpr::VK_TPOFF
:
1641 Type
= ELF::R_X86_64_TPOFF32
;
1643 case MCSymbolRefExpr::VK_DTPOFF
:
1644 Type
= ELF::R_X86_64_DTPOFF32
;
1649 Type
= ELF::R_X86_64_32
;
1651 case FK_Data_2
: Type
= ELF::R_X86_64_16
; break;
1653 case FK_Data_1
: Type
= ELF::R_X86_64_8
; break;
1660 llvm_unreachable("Unimplemented");
1661 case MCSymbolRefExpr::VK_None
:
1662 Type
= ELF::R_386_PC32
;
1664 case MCSymbolRefExpr::VK_PLT
:
1665 Type
= ELF::R_386_PLT32
;
1669 switch ((unsigned)Fixup
.getKind()) {
1670 default: llvm_unreachable("invalid fixup kind!");
1672 case X86::reloc_global_offset_table
:
1673 Type
= ELF::R_386_GOTPC
;
1676 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
1678 case X86::reloc_signed_4byte
:
1683 llvm_unreachable("Unimplemented");
1684 case MCSymbolRefExpr::VK_None
:
1685 Type
= ELF::R_386_32
;
1687 case MCSymbolRefExpr::VK_GOT
:
1688 Type
= ELF::R_386_GOT32
;
1690 case MCSymbolRefExpr::VK_GOTOFF
:
1691 Type
= ELF::R_386_GOTOFF
;
1693 case MCSymbolRefExpr::VK_TLSGD
:
1694 Type
= ELF::R_386_TLS_GD
;
1696 case MCSymbolRefExpr::VK_TPOFF
:
1697 Type
= ELF::R_386_TLS_LE_32
;
1699 case MCSymbolRefExpr::VK_INDNTPOFF
:
1700 Type
= ELF::R_386_TLS_IE
;
1702 case MCSymbolRefExpr::VK_NTPOFF
:
1703 Type
= ELF::R_386_TLS_LE
;
1705 case MCSymbolRefExpr::VK_GOTNTPOFF
:
1706 Type
= ELF::R_386_TLS_GOTIE
;
1708 case MCSymbolRefExpr::VK_TLSLDM
:
1709 Type
= ELF::R_386_TLS_LDM
;
1711 case MCSymbolRefExpr::VK_DTPOFF
:
1712 Type
= ELF::R_386_TLS_LDO_32
;
1714 case MCSymbolRefExpr::VK_GOTTPOFF
:
1715 Type
= ELF::R_386_TLS_IE_32
;
1719 case FK_Data_2
: Type
= ELF::R_386_16
; break;
1721 case FK_Data_1
: Type
= ELF::R_386_8
; break;
1726 if (RelocNeedsGOT(Modifier
))