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"
29 #include "../Target/X86/X86FixupKinds.h"
30 #include "../Target/ARM/ARMFixupKinds.h"
35 bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler
&Asm
, unsigned Kind
) {
36 const MCFixupKindInfo
&FKI
=
37 Asm
.getBackend().getFixupKindInfo((MCFixupKind
) Kind
);
39 return FKI
.Flags
& MCFixupKindInfo::FKF_IsPCRel
;
42 bool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant
) {
46 case MCSymbolRefExpr::VK_GOT
:
47 case MCSymbolRefExpr::VK_PLT
:
48 case MCSymbolRefExpr::VK_GOTPCREL
:
49 case MCSymbolRefExpr::VK_TPOFF
:
50 case MCSymbolRefExpr::VK_TLSGD
:
51 case MCSymbolRefExpr::VK_GOTTPOFF
:
52 case MCSymbolRefExpr::VK_INDNTPOFF
:
53 case MCSymbolRefExpr::VK_NTPOFF
:
54 case MCSymbolRefExpr::VK_GOTNTPOFF
:
55 case MCSymbolRefExpr::VK_TLSLDM
:
56 case MCSymbolRefExpr::VK_DTPOFF
:
57 case MCSymbolRefExpr::VK_TLSLD
:
62 ELFObjectWriter::~ELFObjectWriter()
65 // Emit the ELF header.
66 void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize
,
67 unsigned NumberOfSections
) {
73 // emitWord method behaves differently for ELF32 and ELF64, writing
74 // 4 bytes in the former and 8 in the latter.
76 Write8(0x7f); // e_ident[EI_MAG0]
77 Write8('E'); // e_ident[EI_MAG1]
78 Write8('L'); // e_ident[EI_MAG2]
79 Write8('F'); // e_ident[EI_MAG3]
81 Write8(is64Bit() ? ELF::ELFCLASS64
: ELF::ELFCLASS32
); // e_ident[EI_CLASS]
84 Write8(isLittleEndian() ? ELF::ELFDATA2LSB
: ELF::ELFDATA2MSB
);
86 Write8(ELF::EV_CURRENT
); // e_ident[EI_VERSION]
88 switch (TargetObjectWriter
->getOSType()) {
89 case Triple::FreeBSD
: Write8(ELF::ELFOSABI_FREEBSD
); break;
90 case Triple::Linux
: Write8(ELF::ELFOSABI_LINUX
); break;
91 default: Write8(ELF::ELFOSABI_NONE
); break;
93 Write8(0); // e_ident[EI_ABIVERSION]
95 WriteZeros(ELF::EI_NIDENT
- ELF::EI_PAD
);
97 Write16(ELF::ET_REL
); // e_type
99 Write16(TargetObjectWriter
->getEMachine()); // e_machine = target
101 Write32(ELF::EV_CURRENT
); // e_version
102 WriteWord(0); // e_entry, no entry point in .o file
103 WriteWord(0); // e_phoff, no program header for .o
104 WriteWord(SectionDataSize
+ (is64Bit() ? sizeof(ELF::Elf64_Ehdr
) :
105 sizeof(ELF::Elf32_Ehdr
))); // e_shoff = sec hdr table off in bytes
107 // e_flags = whatever the target wants
110 // e_ehsize = ELF header size
111 Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr
) : sizeof(ELF::Elf32_Ehdr
));
113 Write16(0); // e_phentsize = prog header entry size
114 Write16(0); // e_phnum = # prog header entries = 0
116 // e_shentsize = Section header entry size
117 Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr
) : sizeof(ELF::Elf32_Shdr
));
119 // e_shnum = # of section header ents
120 if (NumberOfSections
>= ELF::SHN_LORESERVE
)
123 Write16(NumberOfSections
);
125 // e_shstrndx = Section # of '.shstrtab'
126 if (NumberOfSections
>= ELF::SHN_LORESERVE
)
127 Write16(ELF::SHN_XINDEX
);
129 Write16(ShstrtabIndex
);
132 void ELFObjectWriter::WriteSymbolEntry(MCDataFragment
*SymtabF
,
133 MCDataFragment
*ShndxF
,
135 uint8_t info
, uint64_t value
,
136 uint64_t size
, uint8_t other
,
140 if (shndx
>= ELF::SHN_LORESERVE
&& !Reserved
)
141 String32(*ShndxF
, shndx
);
143 String32(*ShndxF
, 0);
146 uint16_t Index
= (shndx
>= ELF::SHN_LORESERVE
&& !Reserved
) ?
147 uint16_t(ELF::SHN_XINDEX
) : shndx
;
150 String32(*SymtabF
, name
); // st_name
151 String8(*SymtabF
, info
); // st_info
152 String8(*SymtabF
, other
); // st_other
153 String16(*SymtabF
, Index
); // st_shndx
154 String64(*SymtabF
, value
); // st_value
155 String64(*SymtabF
, size
); // st_size
157 String32(*SymtabF
, name
); // st_name
158 String32(*SymtabF
, value
); // st_value
159 String32(*SymtabF
, size
); // st_size
160 String8(*SymtabF
, info
); // st_info
161 String8(*SymtabF
, other
); // st_other
162 String16(*SymtabF
, Index
); // st_shndx
166 uint64_t ELFObjectWriter::SymbolValue(MCSymbolData
&Data
,
167 const MCAsmLayout
&Layout
) {
168 if (Data
.isCommon() && Data
.isExternal())
169 return Data
.getCommonAlignment();
171 const MCSymbol
&Symbol
= Data
.getSymbol();
173 if (Symbol
.isAbsolute() && Symbol
.isVariable()) {
174 if (const MCExpr
*Value
= Symbol
.getVariableValue()) {
176 if (Value
->EvaluateAsAbsolute(IntValue
, Layout
))
177 return (uint64_t)IntValue
;
181 if (!Symbol
.isInSection())
184 if (Data
.getFragment())
185 return Layout
.getSymbolOffset(&Data
);
190 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler
&Asm
,
191 const MCAsmLayout
&Layout
) {
192 // The presence of symbol versions causes undefined symbols and
193 // versions declared with @@@ to be renamed.
195 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
196 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
197 const MCSymbol
&Alias
= it
->getSymbol();
198 const MCSymbol
&Symbol
= Alias
.AliasedSymbol();
199 MCSymbolData
&SD
= Asm
.getSymbolData(Symbol
);
202 if (&Symbol
== &Alias
)
205 StringRef AliasName
= Alias
.getName();
206 size_t Pos
= AliasName
.find('@');
207 if (Pos
== StringRef::npos
)
210 // Aliases defined with .symvar copy the binding from the symbol they alias.
211 // This is the first place we are able to copy this information.
212 it
->setExternal(SD
.isExternal());
213 MCELF::SetBinding(*it
, MCELF::GetBinding(SD
));
215 StringRef Rest
= AliasName
.substr(Pos
);
216 if (!Symbol
.isUndefined() && !Rest
.startswith("@@@"))
219 // FIXME: produce a better error message.
220 if (Symbol
.isUndefined() && Rest
.startswith("@@") &&
221 !Rest
.startswith("@@@"))
222 report_fatal_error("A @@ version cannot be undefined");
224 Renames
.insert(std::make_pair(&Symbol
, &Alias
));
228 void ELFObjectWriter::WriteSymbol(MCDataFragment
*SymtabF
,
229 MCDataFragment
*ShndxF
,
231 const MCAsmLayout
&Layout
) {
232 MCSymbolData
&OrigData
= *MSD
.SymbolData
;
234 Layout
.getAssembler().getSymbolData(OrigData
.getSymbol().AliasedSymbol());
236 bool IsReserved
= Data
.isCommon() || Data
.getSymbol().isAbsolute() ||
237 Data
.getSymbol().isVariable();
239 uint8_t Binding
= MCELF::GetBinding(OrigData
);
240 uint8_t Visibility
= MCELF::GetVisibility(OrigData
);
241 uint8_t Type
= MCELF::GetType(Data
);
243 uint8_t Info
= (Binding
<< ELF_STB_Shift
) | (Type
<< ELF_STT_Shift
);
244 uint8_t Other
= Visibility
;
246 uint64_t Value
= SymbolValue(Data
, Layout
);
249 assert(!(Data
.isCommon() && !Data
.isExternal()));
251 const MCExpr
*ESize
= Data
.getSize();
254 if (!ESize
->EvaluateAsAbsolute(Res
, Layout
))
255 report_fatal_error("Size expression must be absolute.");
259 // Write out the symbol table entry
260 WriteSymbolEntry(SymtabF
, ShndxF
, MSD
.StringIndex
, Info
, Value
,
261 Size
, Other
, MSD
.SectionIndex
, IsReserved
);
264 void ELFObjectWriter::WriteSymbolTable(MCDataFragment
*SymtabF
,
265 MCDataFragment
*ShndxF
,
266 const MCAssembler
&Asm
,
267 const MCAsmLayout
&Layout
,
268 const SectionIndexMapTy
&SectionIndexMap
) {
269 // The string table must be emitted first because we need the index
270 // into the string table for all the symbol names.
271 assert(StringTable
.size() && "Missing string table");
273 // FIXME: Make sure the start of the symbol table is aligned.
275 // The first entry is the undefined symbol entry.
276 WriteSymbolEntry(SymtabF
, ShndxF
, 0, 0, 0, 0, 0, 0, false);
278 // Write the symbol table entries.
279 LastLocalSymbolIndex
= LocalSymbolData
.size() + 1;
280 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
) {
281 ELFSymbolData
&MSD
= LocalSymbolData
[i
];
282 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
285 // Write out a symbol table entry for each regular section.
286 for (MCAssembler::const_iterator i
= Asm
.begin(), e
= Asm
.end(); i
!= e
;
288 const MCSectionELF
&Section
=
289 static_cast<const MCSectionELF
&>(i
->getSection());
290 if (Section
.getType() == ELF::SHT_RELA
||
291 Section
.getType() == ELF::SHT_REL
||
292 Section
.getType() == ELF::SHT_STRTAB
||
293 Section
.getType() == ELF::SHT_SYMTAB
)
295 WriteSymbolEntry(SymtabF
, ShndxF
, 0, ELF::STT_SECTION
, 0, 0,
296 ELF::STV_DEFAULT
, SectionIndexMap
.lookup(&Section
), false);
297 LastLocalSymbolIndex
++;
300 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
) {
301 ELFSymbolData
&MSD
= ExternalSymbolData
[i
];
302 MCSymbolData
&Data
= *MSD
.SymbolData
;
303 assert(((Data
.getFlags() & ELF_STB_Global
) ||
304 (Data
.getFlags() & ELF_STB_Weak
)) &&
305 "External symbol requires STB_GLOBAL or STB_WEAK flag");
306 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
307 if (MCELF::GetBinding(Data
) == ELF::STB_LOCAL
)
308 LastLocalSymbolIndex
++;
311 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
) {
312 ELFSymbolData
&MSD
= UndefinedSymbolData
[i
];
313 MCSymbolData
&Data
= *MSD
.SymbolData
;
314 WriteSymbol(SymtabF
, ShndxF
, MSD
, Layout
);
315 if (MCELF::GetBinding(Data
) == ELF::STB_LOCAL
)
316 LastLocalSymbolIndex
++;
320 const MCSymbol
*ELFObjectWriter::SymbolToReloc(const MCAssembler
&Asm
,
321 const MCValue
&Target
,
322 const MCFragment
&F
) const {
323 const MCSymbol
&Symbol
= Target
.getSymA()->getSymbol();
324 const MCSymbol
&ASymbol
= Symbol
.AliasedSymbol();
325 const MCSymbol
*Renamed
= Renames
.lookup(&Symbol
);
326 const MCSymbolData
&SD
= Asm
.getSymbolData(Symbol
);
328 if (ASymbol
.isUndefined()) {
334 if (SD
.isExternal()) {
340 const MCSectionELF
&Section
=
341 static_cast<const MCSectionELF
&>(ASymbol
.getSection());
342 const SectionKind secKind
= Section
.getKind();
345 return ExplicitRelSym(Asm
, Target
, F
, true);
347 if (secKind
.isThreadLocal()) {
353 MCSymbolRefExpr::VariantKind Kind
= Target
.getSymA()->getKind();
354 const MCSectionELF
&Sec2
=
355 static_cast<const MCSectionELF
&>(F
.getParent()->getSection());
357 if (&Sec2
!= &Section
&&
358 (Kind
== MCSymbolRefExpr::VK_PLT
||
359 Kind
== MCSymbolRefExpr::VK_GOTPCREL
||
360 Kind
== MCSymbolRefExpr::VK_GOTOFF
)) {
366 if (Section
.getFlags() & ELF::SHF_MERGE
) {
367 if (Target
.getConstant() == 0)
374 return ExplicitRelSym(Asm
, Target
, F
, false);
378 void ELFObjectWriter::RecordRelocation(const MCAssembler
&Asm
,
379 const MCAsmLayout
&Layout
,
380 const MCFragment
*Fragment
,
381 const MCFixup
&Fixup
,
383 uint64_t &FixedValue
) {
386 int64_t Value
= Target
.getConstant();
387 const MCSymbol
*RelocSymbol
= NULL
;
389 bool IsPCRel
= isFixupKindPCRel(Asm
, Fixup
.getKind());
390 if (!Target
.isAbsolute()) {
391 const MCSymbol
&Symbol
= Target
.getSymA()->getSymbol();
392 const MCSymbol
&ASymbol
= Symbol
.AliasedSymbol();
393 RelocSymbol
= SymbolToReloc(Asm
, Target
, *Fragment
);
395 if (const MCSymbolRefExpr
*RefB
= Target
.getSymB()) {
396 const MCSymbol
&SymbolB
= RefB
->getSymbol();
397 MCSymbolData
&SDB
= Asm
.getSymbolData(SymbolB
);
400 // Offset of the symbol in the section
401 int64_t a
= Layout
.getSymbolOffset(&SDB
);
403 // Ofeset of the relocation in the section
404 int64_t b
= Layout
.getFragmentOffset(Fragment
) + Fixup
.getOffset();
409 MCSymbolData
&SD
= Asm
.getSymbolData(ASymbol
);
410 MCFragment
*F
= SD
.getFragment();
412 Index
= F
->getParent()->getOrdinal() + 1;
414 // Offset of the symbol in the section
415 Value
+= Layout
.getSymbolOffset(&SD
);
417 if (Asm
.getSymbolData(Symbol
).getFlags() & ELF_Other_Weakref
)
418 WeakrefUsedInReloc
.insert(RelocSymbol
);
420 UsedInReloc
.insert(RelocSymbol
);
424 // Compensate for the addend on i386.
430 unsigned Type
= GetRelocType(Target
, Fixup
, IsPCRel
,
431 (RelocSymbol
!= 0), Addend
);
433 uint64_t RelocOffset
= Layout
.getFragmentOffset(Fragment
) +
436 if (!hasRelocationAddend())
438 ELFRelocationEntry
ERE(RelocOffset
, Index
, Type
, RelocSymbol
, Addend
);
439 Relocations
[Fragment
->getParent()].push_back(ERE
);
444 ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler
&Asm
,
446 MCSymbolData
&SD
= Asm
.getSymbolData(*S
);
447 return SD
.getIndex();
450 bool ELFObjectWriter::isInSymtab(const MCAssembler
&Asm
,
451 const MCSymbolData
&Data
,
452 bool Used
, bool Renamed
) {
453 if (Data
.getFlags() & ELF_Other_Weakref
)
462 const MCSymbol
&Symbol
= Data
.getSymbol();
464 if (Symbol
.getName() == "_GLOBAL_OFFSET_TABLE_")
467 const MCSymbol
&A
= Symbol
.AliasedSymbol();
468 if (Symbol
.isVariable() && !A
.isVariable() && A
.isUndefined())
471 bool IsGlobal
= MCELF::GetBinding(Data
) == ELF::STB_GLOBAL
;
472 if (!Symbol
.isVariable() && Symbol
.isUndefined() && !IsGlobal
)
475 if (!Asm
.isSymbolLinkerVisible(Symbol
) && !Symbol
.isUndefined())
478 if (Symbol
.isTemporary())
484 bool ELFObjectWriter::isLocal(const MCSymbolData
&Data
, bool isSignature
,
485 bool isUsedInReloc
) {
486 if (Data
.isExternal())
489 const MCSymbol
&Symbol
= Data
.getSymbol();
490 const MCSymbol
&RefSymbol
= Symbol
.AliasedSymbol();
492 if (RefSymbol
.isUndefined() && !RefSymbol
.isVariable()) {
493 if (isSignature
&& !isUsedInReloc
)
502 void ELFObjectWriter::ComputeIndexMap(MCAssembler
&Asm
,
503 SectionIndexMapTy
&SectionIndexMap
,
504 const RelMapTy
&RelMap
) {
506 for (MCAssembler::iterator it
= Asm
.begin(),
507 ie
= Asm
.end(); it
!= ie
; ++it
) {
508 const MCSectionELF
&Section
=
509 static_cast<const MCSectionELF
&>(it
->getSection());
510 if (Section
.getType() != ELF::SHT_GROUP
)
512 SectionIndexMap
[&Section
] = Index
++;
515 for (MCAssembler::iterator it
= Asm
.begin(),
516 ie
= Asm
.end(); it
!= ie
; ++it
) {
517 const MCSectionELF
&Section
=
518 static_cast<const MCSectionELF
&>(it
->getSection());
519 if (Section
.getType() == ELF::SHT_GROUP
||
520 Section
.getType() == ELF::SHT_REL
||
521 Section
.getType() == ELF::SHT_RELA
)
523 SectionIndexMap
[&Section
] = Index
++;
524 const MCSectionELF
*RelSection
= RelMap
.lookup(&Section
);
526 SectionIndexMap
[RelSection
] = Index
++;
530 void ELFObjectWriter::ComputeSymbolTable(MCAssembler
&Asm
,
531 const SectionIndexMapTy
&SectionIndexMap
,
532 RevGroupMapTy RevGroupMap
,
533 unsigned NumRegularSections
) {
534 // FIXME: Is this the correct place to do this?
536 llvm::StringRef Name
= "_GLOBAL_OFFSET_TABLE_";
537 MCSymbol
*Sym
= Asm
.getContext().GetOrCreateSymbol(Name
);
538 MCSymbolData
&Data
= Asm
.getOrCreateSymbolData(*Sym
);
539 Data
.setExternal(true);
540 MCELF::SetBinding(Data
, ELF::STB_GLOBAL
);
543 // Index 0 is always the empty string.
544 StringMap
<uint64_t> StringIndexMap
;
545 StringTable
+= '\x00';
547 // FIXME: We could optimize suffixes in strtab in the same way we
548 // optimize them in shstrtab.
550 // Add the data for the symbols.
551 for (MCAssembler::symbol_iterator it
= Asm
.symbol_begin(),
552 ie
= Asm
.symbol_end(); it
!= ie
; ++it
) {
553 const MCSymbol
&Symbol
= it
->getSymbol();
555 bool Used
= UsedInReloc
.count(&Symbol
);
556 bool WeakrefUsed
= WeakrefUsedInReloc
.count(&Symbol
);
557 bool isSignature
= RevGroupMap
.count(&Symbol
);
559 if (!isInSymtab(Asm
, *it
,
560 Used
|| WeakrefUsed
|| isSignature
,
561 Renames
.count(&Symbol
)))
566 const MCSymbol
&RefSymbol
= Symbol
.AliasedSymbol();
568 // Undefined symbols are global, but this is the first place we
569 // are able to set it.
570 bool Local
= isLocal(*it
, isSignature
, Used
);
571 if (!Local
&& MCELF::GetBinding(*it
) == ELF::STB_LOCAL
) {
572 MCSymbolData
&SD
= Asm
.getSymbolData(RefSymbol
);
573 MCELF::SetBinding(*it
, ELF::STB_GLOBAL
);
574 MCELF::SetBinding(SD
, ELF::STB_GLOBAL
);
577 if (RefSymbol
.isUndefined() && !Used
&& WeakrefUsed
)
578 MCELF::SetBinding(*it
, ELF::STB_WEAK
);
580 if (it
->isCommon()) {
582 MSD
.SectionIndex
= ELF::SHN_COMMON
;
583 } else if (Symbol
.isAbsolute() || RefSymbol
.isVariable()) {
584 MSD
.SectionIndex
= ELF::SHN_ABS
;
585 } else if (RefSymbol
.isUndefined()) {
586 if (isSignature
&& !Used
)
587 MSD
.SectionIndex
= SectionIndexMap
.lookup(RevGroupMap
[&Symbol
]);
589 MSD
.SectionIndex
= ELF::SHN_UNDEF
;
591 const MCSectionELF
&Section
=
592 static_cast<const MCSectionELF
&>(RefSymbol
.getSection());
593 MSD
.SectionIndex
= SectionIndexMap
.lookup(&Section
);
594 if (MSD
.SectionIndex
>= ELF::SHN_LORESERVE
)
595 NeedsSymtabShndx
= true;
596 assert(MSD
.SectionIndex
&& "Invalid section index!");
599 // The @@@ in symbol version is replaced with @ in undefined symbols and
600 // @@ in defined ones.
601 StringRef Name
= Symbol
.getName();
604 size_t Pos
= Name
.find("@@@");
605 if (Pos
!= StringRef::npos
) {
606 Buf
+= Name
.substr(0, Pos
);
607 unsigned Skip
= MSD
.SectionIndex
== ELF::SHN_UNDEF
? 2 : 1;
608 Buf
+= Name
.substr(Pos
+ Skip
);
612 uint64_t &Entry
= StringIndexMap
[Name
];
614 Entry
= StringTable
.size();
616 StringTable
+= '\x00';
618 MSD
.StringIndex
= Entry
;
619 if (MSD
.SectionIndex
== ELF::SHN_UNDEF
)
620 UndefinedSymbolData
.push_back(MSD
);
622 LocalSymbolData
.push_back(MSD
);
624 ExternalSymbolData
.push_back(MSD
);
627 // Symbols are required to be in lexicographic order.
628 array_pod_sort(LocalSymbolData
.begin(), LocalSymbolData
.end());
629 array_pod_sort(ExternalSymbolData
.begin(), ExternalSymbolData
.end());
630 array_pod_sort(UndefinedSymbolData
.begin(), UndefinedSymbolData
.end());
632 // Set the symbol indices. Local symbols must come before all other
633 // symbols with non-local bindings.
635 for (unsigned i
= 0, e
= LocalSymbolData
.size(); i
!= e
; ++i
)
636 LocalSymbolData
[i
].SymbolData
->setIndex(Index
++);
638 Index
+= NumRegularSections
;
640 for (unsigned i
= 0, e
= ExternalSymbolData
.size(); i
!= e
; ++i
)
641 ExternalSymbolData
[i
].SymbolData
->setIndex(Index
++);
642 for (unsigned i
= 0, e
= UndefinedSymbolData
.size(); i
!= e
; ++i
)
643 UndefinedSymbolData
[i
].SymbolData
->setIndex(Index
++);
646 void ELFObjectWriter::CreateRelocationSections(MCAssembler
&Asm
,
649 for (MCAssembler::const_iterator it
= Asm
.begin(),
650 ie
= Asm
.end(); it
!= ie
; ++it
) {
651 const MCSectionData
&SD
= *it
;
652 if (Relocations
[&SD
].empty())
655 MCContext
&Ctx
= Asm
.getContext();
656 const MCSectionELF
&Section
=
657 static_cast<const MCSectionELF
&>(SD
.getSection());
659 const StringRef SectionName
= Section
.getSectionName();
660 std::string RelaSectionName
= hasRelocationAddend() ? ".rela" : ".rel";
661 RelaSectionName
+= SectionName
;
664 if (hasRelocationAddend())
665 EntrySize
= is64Bit() ? sizeof(ELF::Elf64_Rela
) : sizeof(ELF::Elf32_Rela
);
667 EntrySize
= is64Bit() ? sizeof(ELF::Elf64_Rel
) : sizeof(ELF::Elf32_Rel
);
669 const MCSectionELF
*RelaSection
=
670 Ctx
.getELFSection(RelaSectionName
, hasRelocationAddend() ?
671 ELF::SHT_RELA
: ELF::SHT_REL
, 0,
672 SectionKind::getReadOnly(),
674 RelMap
[&Section
] = RelaSection
;
675 Asm
.getOrCreateSectionData(*RelaSection
);
679 void ELFObjectWriter::WriteRelocations(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
680 const RelMapTy
&RelMap
) {
681 for (MCAssembler::const_iterator it
= Asm
.begin(),
682 ie
= Asm
.end(); it
!= ie
; ++it
) {
683 const MCSectionData
&SD
= *it
;
684 const MCSectionELF
&Section
=
685 static_cast<const MCSectionELF
&>(SD
.getSection());
687 const MCSectionELF
*RelaSection
= RelMap
.lookup(&Section
);
690 MCSectionData
&RelaSD
= Asm
.getOrCreateSectionData(*RelaSection
);
691 RelaSD
.setAlignment(is64Bit() ? 8 : 4);
693 MCDataFragment
*F
= new MCDataFragment(&RelaSD
);
694 WriteRelocationsFragment(Asm
, F
, &*it
);
698 void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name
, uint32_t Type
,
699 uint64_t Flags
, uint64_t Address
,
700 uint64_t Offset
, uint64_t Size
,
701 uint32_t Link
, uint32_t Info
,
703 uint64_t EntrySize
) {
704 Write32(Name
); // sh_name: index into string table
705 Write32(Type
); // sh_type
706 WriteWord(Flags
); // sh_flags
707 WriteWord(Address
); // sh_addr
708 WriteWord(Offset
); // sh_offset
709 WriteWord(Size
); // sh_size
710 Write32(Link
); // sh_link
711 Write32(Info
); // sh_info
712 WriteWord(Alignment
); // sh_addralign
713 WriteWord(EntrySize
); // sh_entsize
716 void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler
&Asm
,
718 const MCSectionData
*SD
) {
719 std::vector
<ELFRelocationEntry
> &Relocs
= Relocations
[SD
];
720 // sort by the r_offset just like gnu as does
721 array_pod_sort(Relocs
.begin(), Relocs
.end());
723 for (unsigned i
= 0, e
= Relocs
.size(); i
!= e
; ++i
) {
724 ELFRelocationEntry entry
= Relocs
[e
- i
- 1];
728 else if (entry
.Index
< 0)
729 entry
.Index
= getSymbolIndexInSymbolTable(Asm
, entry
.Symbol
);
731 entry
.Index
+= LocalSymbolData
.size();
733 String64(*F
, entry
.r_offset
);
735 struct ELF::Elf64_Rela ERE64
;
736 ERE64
.setSymbolAndType(entry
.Index
, entry
.Type
);
737 String64(*F
, ERE64
.r_info
);
739 if (hasRelocationAddend())
740 String64(*F
, entry
.r_addend
);
742 String32(*F
, entry
.r_offset
);
744 struct ELF::Elf32_Rela ERE32
;
745 ERE32
.setSymbolAndType(entry
.Index
, entry
.Type
);
746 String32(*F
, ERE32
.r_info
);
748 if (hasRelocationAddend())
749 String32(*F
, entry
.r_addend
);
754 static int compareBySuffix(const void *a
, const void *b
) {
755 const MCSectionELF
*secA
= *static_cast<const MCSectionELF
* const *>(a
);
756 const MCSectionELF
*secB
= *static_cast<const MCSectionELF
* const *>(b
);
757 const StringRef
&NameA
= secA
->getSectionName();
758 const StringRef
&NameB
= secB
->getSectionName();
759 const unsigned sizeA
= NameA
.size();
760 const unsigned sizeB
= NameB
.size();
761 const unsigned len
= std::min(sizeA
, sizeB
);
762 for (unsigned int i
= 0; i
< len
; ++i
) {
763 char ca
= NameA
[sizeA
- i
- 1];
764 char cb
= NameB
[sizeB
- i
- 1];
769 return sizeB
- sizeA
;
772 void ELFObjectWriter::CreateMetadataSections(MCAssembler
&Asm
,
774 SectionIndexMapTy
&SectionIndexMap
,
775 const RelMapTy
&RelMap
) {
776 MCContext
&Ctx
= Asm
.getContext();
779 unsigned EntrySize
= is64Bit() ? ELF::SYMENTRY_SIZE64
: ELF::SYMENTRY_SIZE32
;
781 // We construct .shstrtab, .symtab and .strtab in this order to match gnu as.
782 const MCSectionELF
*ShstrtabSection
=
783 Ctx
.getELFSection(".shstrtab", ELF::SHT_STRTAB
, 0,
784 SectionKind::getReadOnly());
785 MCSectionData
&ShstrtabSD
= Asm
.getOrCreateSectionData(*ShstrtabSection
);
786 ShstrtabSD
.setAlignment(1);
788 const MCSectionELF
*SymtabSection
=
789 Ctx
.getELFSection(".symtab", ELF::SHT_SYMTAB
, 0,
790 SectionKind::getReadOnly(),
792 MCSectionData
&SymtabSD
= Asm
.getOrCreateSectionData(*SymtabSection
);
793 SymtabSD
.setAlignment(is64Bit() ? 8 : 4);
795 MCSectionData
*SymtabShndxSD
= NULL
;
797 if (NeedsSymtabShndx
) {
798 const MCSectionELF
*SymtabShndxSection
=
799 Ctx
.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX
, 0,
800 SectionKind::getReadOnly(), 4, "");
801 SymtabShndxSD
= &Asm
.getOrCreateSectionData(*SymtabShndxSection
);
802 SymtabShndxSD
->setAlignment(4);
805 const MCSectionELF
*StrtabSection
;
806 StrtabSection
= Ctx
.getELFSection(".strtab", ELF::SHT_STRTAB
, 0,
807 SectionKind::getReadOnly());
808 MCSectionData
&StrtabSD
= Asm
.getOrCreateSectionData(*StrtabSection
);
809 StrtabSD
.setAlignment(1);
811 ComputeIndexMap(Asm
, SectionIndexMap
, RelMap
);
813 ShstrtabIndex
= SectionIndexMap
.lookup(ShstrtabSection
);
814 SymbolTableIndex
= SectionIndexMap
.lookup(SymtabSection
);
815 StringTableIndex
= SectionIndexMap
.lookup(StrtabSection
);
818 F
= new MCDataFragment(&SymtabSD
);
819 MCDataFragment
*ShndxF
= NULL
;
820 if (NeedsSymtabShndx
) {
821 ShndxF
= new MCDataFragment(SymtabShndxSD
);
823 WriteSymbolTable(F
, ShndxF
, Asm
, Layout
, SectionIndexMap
);
825 F
= new MCDataFragment(&StrtabSD
);
826 F
->getContents().append(StringTable
.begin(), StringTable
.end());
828 F
= new MCDataFragment(&ShstrtabSD
);
830 std::vector
<const MCSectionELF
*> Sections
;
831 for (MCAssembler::const_iterator it
= Asm
.begin(),
832 ie
= Asm
.end(); it
!= ie
; ++it
) {
833 const MCSectionELF
&Section
=
834 static_cast<const MCSectionELF
&>(it
->getSection());
835 Sections
.push_back(&Section
);
837 array_pod_sort(Sections
.begin(), Sections
.end(), compareBySuffix
);
839 // Section header string table.
841 // The first entry of a string table holds a null character so skip
844 F
->getContents() += '\x00';
846 for (unsigned int I
= 0, E
= Sections
.size(); I
!= E
; ++I
) {
847 const MCSectionELF
&Section
= *Sections
[I
];
849 StringRef Name
= Section
.getSectionName();
851 StringRef PreviousName
= Sections
[I
- 1]->getSectionName();
852 if (PreviousName
.endswith(Name
)) {
853 SectionStringTableIndex
[&Section
] = Index
- Name
.size() - 1;
857 // Remember the index into the string table so we can write it
858 // into the sh_name field of the section header table.
859 SectionStringTableIndex
[&Section
] = Index
;
861 Index
+= Name
.size() + 1;
862 F
->getContents() += Name
;
863 F
->getContents() += '\x00';
867 void ELFObjectWriter::CreateIndexedSections(MCAssembler
&Asm
,
869 GroupMapTy
&GroupMap
,
870 RevGroupMapTy
&RevGroupMap
,
871 SectionIndexMapTy
&SectionIndexMap
,
872 const RelMapTy
&RelMap
) {
873 // Create the .note.GNU-stack section if needed.
874 MCContext
&Ctx
= Asm
.getContext();
875 if (Asm
.getNoExecStack()) {
876 const MCSectionELF
*GnuStackSection
=
877 Ctx
.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS
, 0,
878 SectionKind::getReadOnly());
879 Asm
.getOrCreateSectionData(*GnuStackSection
);
883 for (MCAssembler::const_iterator it
= Asm
.begin(), ie
= Asm
.end();
885 const MCSectionELF
&Section
=
886 static_cast<const MCSectionELF
&>(it
->getSection());
887 if (!(Section
.getFlags() & ELF::SHF_GROUP
))
890 const MCSymbol
*SignatureSymbol
= Section
.getGroup();
891 Asm
.getOrCreateSymbolData(*SignatureSymbol
);
892 const MCSectionELF
*&Group
= RevGroupMap
[SignatureSymbol
];
894 Group
= Ctx
.CreateELFGroupSection();
895 MCSectionData
&Data
= Asm
.getOrCreateSectionData(*Group
);
896 Data
.setAlignment(4);
897 MCDataFragment
*F
= new MCDataFragment(&Data
);
898 String32(*F
, ELF::GRP_COMDAT
);
900 GroupMap
[Group
] = SignatureSymbol
;
903 ComputeIndexMap(Asm
, SectionIndexMap
, RelMap
);
905 // Add sections to the groups
906 for (MCAssembler::const_iterator it
= Asm
.begin(), ie
= Asm
.end();
908 const MCSectionELF
&Section
=
909 static_cast<const MCSectionELF
&>(it
->getSection());
910 if (!(Section
.getFlags() & ELF::SHF_GROUP
))
912 const MCSectionELF
*Group
= RevGroupMap
[Section
.getGroup()];
913 MCSectionData
&Data
= Asm
.getOrCreateSectionData(*Group
);
914 // FIXME: we could use the previous fragment
915 MCDataFragment
*F
= new MCDataFragment(&Data
);
916 unsigned Index
= SectionIndexMap
.lookup(&Section
);
921 void ELFObjectWriter::WriteSection(MCAssembler
&Asm
,
922 const SectionIndexMapTy
&SectionIndexMap
,
923 uint32_t GroupSymbolIndex
,
924 uint64_t Offset
, uint64_t Size
,
926 const MCSectionELF
&Section
) {
927 uint64_t sh_link
= 0;
928 uint64_t sh_info
= 0;
930 switch(Section
.getType()) {
931 case ELF::SHT_DYNAMIC
:
932 sh_link
= SectionStringTableIndex
[&Section
];
937 case ELF::SHT_RELA
: {
938 const MCSectionELF
*SymtabSection
;
939 const MCSectionELF
*InfoSection
;
940 SymtabSection
= Asm
.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB
,
942 SectionKind::getReadOnly());
943 sh_link
= SectionIndexMap
.lookup(SymtabSection
);
944 assert(sh_link
&& ".symtab not found");
946 // Remove ".rel" and ".rela" prefixes.
947 unsigned SecNameLen
= (Section
.getType() == ELF::SHT_REL
) ? 4 : 5;
948 StringRef SectionName
= Section
.getSectionName().substr(SecNameLen
);
950 InfoSection
= Asm
.getContext().getELFSection(SectionName
,
951 ELF::SHT_PROGBITS
, 0,
952 SectionKind::getReadOnly());
953 sh_info
= SectionIndexMap
.lookup(InfoSection
);
957 case ELF::SHT_SYMTAB
:
958 case ELF::SHT_DYNSYM
:
959 sh_link
= StringTableIndex
;
960 sh_info
= LastLocalSymbolIndex
;
963 case ELF::SHT_SYMTAB_SHNDX
:
964 sh_link
= SymbolTableIndex
;
967 case ELF::SHT_PROGBITS
:
968 case ELF::SHT_STRTAB
:
969 case ELF::SHT_NOBITS
:
972 case ELF::SHT_ARM_ATTRIBUTES
:
973 case ELF::SHT_INIT_ARRAY
:
974 case ELF::SHT_FINI_ARRAY
:
975 case ELF::SHT_PREINIT_ARRAY
:
976 case ELF::SHT_X86_64_UNWIND
:
980 case ELF::SHT_GROUP
: {
981 sh_link
= SymbolTableIndex
;
982 sh_info
= GroupSymbolIndex
;
987 assert(0 && "FIXME: sh_type value not supported!");
991 WriteSecHdrEntry(SectionStringTableIndex
[&Section
], Section
.getType(),
992 Section
.getFlags(), 0, Offset
, Size
, sh_link
, sh_info
,
993 Alignment
, Section
.getEntrySize());
996 bool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData
&SD
) {
997 return SD
.getOrdinal() == ~UINT32_C(0) &&
998 !SD
.getSection().isVirtualSection();
1001 uint64_t ELFObjectWriter::DataSectionSize(const MCSectionData
&SD
) {
1003 for (MCSectionData::const_iterator i
= SD
.begin(), e
= SD
.end(); i
!= e
;
1005 const MCFragment
&F
= *i
;
1006 assert(F
.getKind() == MCFragment::FT_Data
);
1007 Ret
+= cast
<MCDataFragment
>(F
).getContents().size();
1012 uint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout
&Layout
,
1013 const MCSectionData
&SD
) {
1014 if (IsELFMetaDataSection(SD
))
1015 return DataSectionSize(SD
);
1016 return Layout
.getSectionFileSize(&SD
);
1019 uint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout
&Layout
,
1020 const MCSectionData
&SD
) {
1021 if (IsELFMetaDataSection(SD
))
1022 return DataSectionSize(SD
);
1023 return Layout
.getSectionAddressSize(&SD
);
1026 void ELFObjectWriter::WriteDataSectionData(MCAssembler
&Asm
,
1027 const MCAsmLayout
&Layout
,
1028 const MCSectionELF
&Section
) {
1029 uint64_t FileOff
= OS
.tell();
1030 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1032 uint64_t Padding
= OffsetToAlignment(FileOff
, SD
.getAlignment());
1033 WriteZeros(Padding
);
1036 FileOff
+= GetSectionFileSize(Layout
, SD
);
1038 if (IsELFMetaDataSection(SD
)) {
1039 for (MCSectionData::const_iterator i
= SD
.begin(), e
= SD
.end(); i
!= e
;
1041 const MCFragment
&F
= *i
;
1042 assert(F
.getKind() == MCFragment::FT_Data
);
1043 WriteBytes(cast
<MCDataFragment
>(F
).getContents().str());
1046 Asm
.WriteSectionData(&SD
, Layout
);
1050 void ELFObjectWriter::WriteSectionHeader(MCAssembler
&Asm
,
1051 const GroupMapTy
&GroupMap
,
1052 const MCAsmLayout
&Layout
,
1053 const SectionIndexMapTy
&SectionIndexMap
,
1054 const SectionOffsetMapTy
&SectionOffsetMap
) {
1055 const unsigned NumSections
= Asm
.size() + 1;
1057 std::vector
<const MCSectionELF
*> Sections
;
1058 Sections
.resize(NumSections
- 1);
1060 for (SectionIndexMapTy::const_iterator i
=
1061 SectionIndexMap
.begin(), e
= SectionIndexMap
.end(); i
!= e
; ++i
) {
1062 const std::pair
<const MCSectionELF
*, uint32_t> &p
= *i
;
1063 Sections
[p
.second
- 1] = p
.first
;
1066 // Null section first.
1067 uint64_t FirstSectionSize
=
1068 NumSections
>= ELF::SHN_LORESERVE
? NumSections
: 0;
1069 uint32_t FirstSectionLink
=
1070 ShstrtabIndex
>= ELF::SHN_LORESERVE
? ShstrtabIndex
: 0;
1071 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize
, FirstSectionLink
, 0, 0, 0);
1073 for (unsigned i
= 0; i
< NumSections
- 1; ++i
) {
1074 const MCSectionELF
&Section
= *Sections
[i
];
1075 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1076 uint32_t GroupSymbolIndex
;
1077 if (Section
.getType() != ELF::SHT_GROUP
)
1078 GroupSymbolIndex
= 0;
1080 GroupSymbolIndex
= getSymbolIndexInSymbolTable(Asm
,
1081 GroupMap
.lookup(&Section
));
1083 uint64_t Size
= GetSectionAddressSize(Layout
, SD
);
1085 WriteSection(Asm
, SectionIndexMap
, GroupSymbolIndex
,
1086 SectionOffsetMap
.lookup(&Section
), Size
,
1087 SD
.getAlignment(), Section
);
1091 void ELFObjectWriter::ComputeSectionOrder(MCAssembler
&Asm
,
1092 std::vector
<const MCSectionELF
*> &Sections
) {
1093 for (MCAssembler::iterator it
= Asm
.begin(),
1094 ie
= Asm
.end(); it
!= ie
; ++it
) {
1095 const MCSectionELF
&Section
=
1096 static_cast<const MCSectionELF
&>(it
->getSection());
1097 if (Section
.getType() == ELF::SHT_GROUP
)
1098 Sections
.push_back(&Section
);
1101 for (MCAssembler::iterator it
= Asm
.begin(),
1102 ie
= Asm
.end(); it
!= ie
; ++it
) {
1103 const MCSectionELF
&Section
=
1104 static_cast<const MCSectionELF
&>(it
->getSection());
1105 if (Section
.getType() != ELF::SHT_GROUP
&&
1106 Section
.getType() != ELF::SHT_REL
&&
1107 Section
.getType() != ELF::SHT_RELA
)
1108 Sections
.push_back(&Section
);
1111 for (MCAssembler::iterator it
= Asm
.begin(),
1112 ie
= Asm
.end(); it
!= ie
; ++it
) {
1113 const MCSectionELF
&Section
=
1114 static_cast<const MCSectionELF
&>(it
->getSection());
1115 if (Section
.getType() == ELF::SHT_REL
||
1116 Section
.getType() == ELF::SHT_RELA
)
1117 Sections
.push_back(&Section
);
1121 void ELFObjectWriter::WriteObject(MCAssembler
&Asm
,
1122 const MCAsmLayout
&Layout
) {
1123 GroupMapTy GroupMap
;
1124 RevGroupMapTy RevGroupMap
;
1125 SectionIndexMapTy SectionIndexMap
;
1127 unsigned NumUserSections
= Asm
.size();
1129 DenseMap
<const MCSectionELF
*, const MCSectionELF
*> RelMap
;
1130 CreateRelocationSections(Asm
, const_cast<MCAsmLayout
&>(Layout
), RelMap
);
1132 const unsigned NumUserAndRelocSections
= Asm
.size();
1133 CreateIndexedSections(Asm
, const_cast<MCAsmLayout
&>(Layout
), GroupMap
,
1134 RevGroupMap
, SectionIndexMap
, RelMap
);
1135 const unsigned AllSections
= Asm
.size();
1136 const unsigned NumIndexedSections
= AllSections
- NumUserAndRelocSections
;
1138 unsigned NumRegularSections
= NumUserSections
+ NumIndexedSections
;
1140 // Compute symbol table information.
1141 ComputeSymbolTable(Asm
, SectionIndexMap
, RevGroupMap
, NumRegularSections
);
1144 WriteRelocations(Asm
, const_cast<MCAsmLayout
&>(Layout
), RelMap
);
1146 CreateMetadataSections(const_cast<MCAssembler
&>(Asm
),
1147 const_cast<MCAsmLayout
&>(Layout
),
1151 uint64_t NaturalAlignment
= is64Bit() ? 8 : 4;
1152 uint64_t HeaderSize
= is64Bit() ? sizeof(ELF::Elf64_Ehdr
) :
1153 sizeof(ELF::Elf32_Ehdr
);
1154 uint64_t FileOff
= HeaderSize
;
1156 std::vector
<const MCSectionELF
*> Sections
;
1157 ComputeSectionOrder(Asm
, Sections
);
1158 unsigned NumSections
= Sections
.size();
1159 SectionOffsetMapTy SectionOffsetMap
;
1160 for (unsigned i
= 0; i
< NumRegularSections
+ 1; ++i
) {
1161 const MCSectionELF
&Section
= *Sections
[i
];
1162 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1164 FileOff
= RoundUpToAlignment(FileOff
, SD
.getAlignment());
1166 // Remember the offset into the file for this section.
1167 SectionOffsetMap
[&Section
] = FileOff
;
1169 // Get the size of the section in the output file (including padding).
1170 FileOff
+= GetSectionFileSize(Layout
, SD
);
1173 FileOff
= RoundUpToAlignment(FileOff
, NaturalAlignment
);
1175 const unsigned SectionHeaderOffset
= FileOff
- HeaderSize
;
1177 uint64_t SectionHeaderEntrySize
= is64Bit() ?
1178 sizeof(ELF::Elf64_Shdr
) : sizeof(ELF::Elf32_Shdr
);
1179 FileOff
+= (NumSections
+ 1) * SectionHeaderEntrySize
;
1181 for (unsigned i
= NumRegularSections
+ 1; i
< NumSections
; ++i
) {
1182 const MCSectionELF
&Section
= *Sections
[i
];
1183 const MCSectionData
&SD
= Asm
.getOrCreateSectionData(Section
);
1185 FileOff
= RoundUpToAlignment(FileOff
, SD
.getAlignment());
1187 // Remember the offset into the file for this section.
1188 SectionOffsetMap
[&Section
] = FileOff
;
1190 // Get the size of the section in the output file (including padding).
1191 FileOff
+= GetSectionFileSize(Layout
, SD
);
1194 // Write out the ELF header ...
1195 WriteHeader(SectionHeaderOffset
, NumSections
+ 1);
1197 // ... then the regular sections ...
1198 // + because of .shstrtab
1199 for (unsigned i
= 0; i
< NumRegularSections
+ 1; ++i
)
1200 WriteDataSectionData(Asm
, Layout
, *Sections
[i
]);
1202 FileOff
= OS
.tell();
1203 uint64_t Padding
= OffsetToAlignment(FileOff
, NaturalAlignment
);
1204 WriteZeros(Padding
);
1206 // ... then the section header table ...
1207 WriteSectionHeader(Asm
, GroupMap
, Layout
, SectionIndexMap
,
1210 FileOff
= OS
.tell();
1212 // ... and then the remainting sections ...
1213 for (unsigned i
= NumRegularSections
+ 1; i
< NumSections
; ++i
)
1214 WriteDataSectionData(Asm
, Layout
, *Sections
[i
]);
1218 ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler
&Asm
,
1219 const MCSymbolData
&DataA
,
1220 const MCFragment
&FB
,
1222 bool IsPCRel
) const {
1223 if (DataA
.getFlags() & ELF_STB_Weak
)
1225 return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
1226 Asm
, DataA
, FB
,InSet
, IsPCRel
);
1229 MCObjectWriter
*llvm::createELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
1231 bool IsLittleEndian
) {
1232 switch (MOTW
->getEMachine()) {
1234 case ELF::EM_X86_64
:
1235 return new X86ELFObjectWriter(MOTW
, OS
, IsLittleEndian
); break;
1237 return new ARMELFObjectWriter(MOTW
, OS
, IsLittleEndian
); break;
1238 case ELF::EM_MBLAZE
:
1239 return new MBlazeELFObjectWriter(MOTW
, OS
, IsLittleEndian
); break;
1240 default: llvm_unreachable("Unsupported architecture"); break;
1245 /// START OF SUBCLASSES for ELFObjectWriter
1246 //===- ARMELFObjectWriter -------------------------------------------===//
1248 ARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
1250 bool IsLittleEndian
)
1251 : ELFObjectWriter(MOTW
, _OS
, IsLittleEndian
)
1254 ARMELFObjectWriter::~ARMELFObjectWriter()
1257 // FIXME: get the real EABI Version from the Triple.
1258 void ARMELFObjectWriter::WriteEFlags() {
1259 Write32(ELF::EF_ARM_EABIMASK
& DefaultEABIVersion
);
1262 // In ARM, _MergedGlobals and other most symbols get emitted directly.
1263 // I.e. not as an offset to a section symbol.
1264 // This code is a first-cut approximation of what ARM/gcc does.
1266 const MCSymbol
*ARMELFObjectWriter::ExplicitRelSym(const MCAssembler
&Asm
,
1267 const MCValue
&Target
,
1268 const MCFragment
&F
,
1270 const MCSymbol
&Symbol
= Target
.getSymA()->getSymbol();
1271 bool EmitThisSym
= false;
1274 EmitThisSym
= StringSwitch
<bool>(Symbol
.getName())
1275 .Case("_MergedGlobals", true)
1278 EmitThisSym
= StringSwitch
<bool>(Symbol
.getName())
1279 .Case("_MergedGlobals", true)
1280 .StartsWith(".L.str", true)
1285 if (! Symbol
.isTemporary())
1290 unsigned ARMELFObjectWriter::GetRelocType(const MCValue
&Target
,
1291 const MCFixup
&Fixup
,
1293 bool IsRelocWithSymbol
,
1295 MCSymbolRefExpr::VariantKind Modifier
= Target
.isAbsolute() ?
1296 MCSymbolRefExpr::VK_None
: Target
.getSymA()->getKind();
1300 switch ((unsigned)Fixup
.getKind()) {
1301 default: assert(0 && "Unimplemented");
1304 default: llvm_unreachable("Unsupported Modifier");
1305 case MCSymbolRefExpr::VK_None
:
1306 Type
= ELF::R_ARM_BASE_PREL
;
1308 case MCSymbolRefExpr::VK_ARM_TLSGD
:
1309 assert(0 && "unimplemented");
1311 case MCSymbolRefExpr::VK_ARM_GOTTPOFF
:
1312 Type
= ELF::R_ARM_TLS_IE32
;
1316 case ARM::fixup_arm_uncondbranch
:
1318 case MCSymbolRefExpr::VK_ARM_PLT
:
1319 Type
= ELF::R_ARM_PLT32
;
1322 Type
= ELF::R_ARM_CALL
;
1326 case ARM::fixup_arm_condbranch
:
1327 Type
= ELF::R_ARM_JUMP24
;
1329 case ARM::fixup_arm_movt_hi16
:
1330 case ARM::fixup_arm_movt_hi16_pcrel
:
1331 Type
= ELF::R_ARM_MOVT_PREL
;
1333 case ARM::fixup_arm_movw_lo16
:
1334 case ARM::fixup_arm_movw_lo16_pcrel
:
1335 Type
= ELF::R_ARM_MOVW_PREL_NC
;
1337 case ARM::fixup_t2_movt_hi16
:
1338 case ARM::fixup_t2_movt_hi16_pcrel
:
1339 Type
= ELF::R_ARM_THM_MOVT_PREL
;
1341 case ARM::fixup_t2_movw_lo16
:
1342 case ARM::fixup_t2_movw_lo16_pcrel
:
1343 Type
= ELF::R_ARM_THM_MOVW_PREL_NC
;
1347 switch ((unsigned)Fixup
.getKind()) {
1348 default: llvm_unreachable("invalid fixup kind!");
1351 default: llvm_unreachable("Unsupported Modifier"); break;
1352 case MCSymbolRefExpr::VK_ARM_GOT
:
1353 Type
= ELF::R_ARM_GOT_BREL
;
1355 case MCSymbolRefExpr::VK_ARM_TLSGD
:
1356 Type
= ELF::R_ARM_TLS_GD32
;
1358 case MCSymbolRefExpr::VK_ARM_TPOFF
:
1359 Type
= ELF::R_ARM_TLS_LE32
;
1361 case MCSymbolRefExpr::VK_ARM_GOTTPOFF
:
1362 Type
= ELF::R_ARM_TLS_IE32
;
1364 case MCSymbolRefExpr::VK_None
:
1365 Type
= ELF::R_ARM_ABS32
;
1367 case MCSymbolRefExpr::VK_ARM_GOTOFF
:
1368 Type
= ELF::R_ARM_GOTOFF32
;
1372 case ARM::fixup_arm_ldst_pcrel_12
:
1373 case ARM::fixup_arm_pcrel_10
:
1374 case ARM::fixup_arm_adr_pcrel_12
:
1375 case ARM::fixup_arm_thumb_bl
:
1376 case ARM::fixup_arm_thumb_cb
:
1377 case ARM::fixup_arm_thumb_cp
:
1378 case ARM::fixup_arm_thumb_br
:
1379 assert(0 && "Unimplemented");
1381 case ARM::fixup_arm_uncondbranch
:
1382 Type
= ELF::R_ARM_CALL
;
1384 case ARM::fixup_arm_condbranch
:
1385 Type
= ELF::R_ARM_JUMP24
;
1387 case ARM::fixup_arm_movt_hi16
:
1388 Type
= ELF::R_ARM_MOVT_ABS
;
1390 case ARM::fixup_arm_movw_lo16
:
1391 Type
= ELF::R_ARM_MOVW_ABS_NC
;
1393 case ARM::fixup_t2_movt_hi16
:
1394 Type
= ELF::R_ARM_THM_MOVT_ABS
;
1396 case ARM::fixup_t2_movw_lo16
:
1397 Type
= ELF::R_ARM_THM_MOVW_ABS_NC
;
1402 if (RelocNeedsGOT(Modifier
))
1408 //===- MBlazeELFObjectWriter -------------------------------------------===//
1410 MBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
1412 bool IsLittleEndian
)
1413 : ELFObjectWriter(MOTW
, _OS
, IsLittleEndian
) {
1416 MBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
1419 unsigned MBlazeELFObjectWriter::GetRelocType(const MCValue
&Target
,
1420 const MCFixup
&Fixup
,
1422 bool IsRelocWithSymbol
,
1424 // determine the type of the relocation
1427 switch ((unsigned)Fixup
.getKind()) {
1429 llvm_unreachable("Unimplemented");
1431 Type
= ELF::R_MICROBLAZE_64_PCREL
;
1434 Type
= ELF::R_MICROBLAZE_32_PCREL
;
1438 switch ((unsigned)Fixup
.getKind()) {
1439 default: llvm_unreachable("invalid fixup kind!");
1441 Type
= ((IsRelocWithSymbol
|| Addend
!=0)
1442 ? ELF::R_MICROBLAZE_32
1443 : ELF::R_MICROBLAZE_64
);
1446 Type
= ELF::R_MICROBLAZE_32
;
1453 //===- X86ELFObjectWriter -------------------------------------------===//
1456 X86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
1458 bool IsLittleEndian
)
1459 : ELFObjectWriter(MOTW
, _OS
, IsLittleEndian
)
1462 X86ELFObjectWriter::~X86ELFObjectWriter()
1465 unsigned X86ELFObjectWriter::GetRelocType(const MCValue
&Target
,
1466 const MCFixup
&Fixup
,
1468 bool IsRelocWithSymbol
,
1470 // determine the type of the relocation
1472 MCSymbolRefExpr::VariantKind Modifier
= Target
.isAbsolute() ?
1473 MCSymbolRefExpr::VK_None
: Target
.getSymA()->getKind();
1477 switch ((unsigned)Fixup
.getKind()) {
1478 default: llvm_unreachable("invalid fixup kind!");
1480 assert(Modifier
== MCSymbolRefExpr::VK_None
);
1481 Type
= ELF::R_X86_64_PC64
;
1483 case X86::reloc_signed_4byte
:
1484 case X86::reloc_riprel_4byte_movq_load
:
1485 case FK_Data_4
: // FIXME?
1486 case X86::reloc_riprel_4byte
:
1490 llvm_unreachable("Unimplemented");
1491 case MCSymbolRefExpr::VK_None
:
1492 Type
= ELF::R_X86_64_PC32
;
1494 case MCSymbolRefExpr::VK_PLT
:
1495 Type
= ELF::R_X86_64_PLT32
;
1497 case MCSymbolRefExpr::VK_GOTPCREL
:
1498 Type
= ELF::R_X86_64_GOTPCREL
;
1500 case MCSymbolRefExpr::VK_GOTTPOFF
:
1501 Type
= ELF::R_X86_64_GOTTPOFF
;
1503 case MCSymbolRefExpr::VK_TLSGD
:
1504 Type
= ELF::R_X86_64_TLSGD
;
1506 case MCSymbolRefExpr::VK_TLSLD
:
1507 Type
= ELF::R_X86_64_TLSLD
;
1512 assert(Modifier
== MCSymbolRefExpr::VK_None
);
1513 Type
= ELF::R_X86_64_PC16
;
1516 assert(Modifier
== MCSymbolRefExpr::VK_None
);
1517 Type
= ELF::R_X86_64_PC8
;
1521 switch ((unsigned)Fixup
.getKind()) {
1522 default: llvm_unreachable("invalid fixup kind!");
1523 case FK_Data_8
: Type
= ELF::R_X86_64_64
; break;
1524 case X86::reloc_signed_4byte
:
1525 assert(isInt
<32>(Target
.getConstant()));
1528 llvm_unreachable("Unimplemented");
1529 case MCSymbolRefExpr::VK_None
:
1530 Type
= ELF::R_X86_64_32S
;
1532 case MCSymbolRefExpr::VK_GOT
:
1533 Type
= ELF::R_X86_64_GOT32
;
1535 case MCSymbolRefExpr::VK_GOTPCREL
:
1536 Type
= ELF::R_X86_64_GOTPCREL
;
1538 case MCSymbolRefExpr::VK_TPOFF
:
1539 Type
= ELF::R_X86_64_TPOFF32
;
1541 case MCSymbolRefExpr::VK_DTPOFF
:
1542 Type
= ELF::R_X86_64_DTPOFF32
;
1547 Type
= ELF::R_X86_64_32
;
1549 case FK_Data_2
: Type
= ELF::R_X86_64_16
; break;
1551 case FK_Data_1
: Type
= ELF::R_X86_64_8
; break;
1558 llvm_unreachable("Unimplemented");
1559 case MCSymbolRefExpr::VK_None
:
1560 Type
= ELF::R_386_PC32
;
1562 case MCSymbolRefExpr::VK_PLT
:
1563 Type
= ELF::R_386_PLT32
;
1567 switch ((unsigned)Fixup
.getKind()) {
1568 default: llvm_unreachable("invalid fixup kind!");
1570 case X86::reloc_global_offset_table
:
1571 Type
= ELF::R_386_GOTPC
;
1574 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode
1576 case X86::reloc_signed_4byte
:
1581 llvm_unreachable("Unimplemented");
1582 case MCSymbolRefExpr::VK_None
:
1583 Type
= ELF::R_386_32
;
1585 case MCSymbolRefExpr::VK_GOT
:
1586 Type
= ELF::R_386_GOT32
;
1588 case MCSymbolRefExpr::VK_GOTOFF
:
1589 Type
= ELF::R_386_GOTOFF
;
1591 case MCSymbolRefExpr::VK_TLSGD
:
1592 Type
= ELF::R_386_TLS_GD
;
1594 case MCSymbolRefExpr::VK_TPOFF
:
1595 Type
= ELF::R_386_TLS_LE_32
;
1597 case MCSymbolRefExpr::VK_INDNTPOFF
:
1598 Type
= ELF::R_386_TLS_IE
;
1600 case MCSymbolRefExpr::VK_NTPOFF
:
1601 Type
= ELF::R_386_TLS_LE
;
1603 case MCSymbolRefExpr::VK_GOTNTPOFF
:
1604 Type
= ELF::R_386_TLS_GOTIE
;
1606 case MCSymbolRefExpr::VK_TLSLDM
:
1607 Type
= ELF::R_386_TLS_LDM
;
1609 case MCSymbolRefExpr::VK_DTPOFF
:
1610 Type
= ELF::R_386_TLS_LDO_32
;
1614 case FK_Data_2
: Type
= ELF::R_386_16
; break;
1616 case FK_Data_1
: Type
= ELF::R_386_8
; break;
1621 if (RelocNeedsGOT(Modifier
))