1 //===- lib/MC/ELFObjectWriter.h - 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 #ifndef LLVM_MC_ELFOBJECTWRITER_H
15 #define LLVM_MC_ELFOBJECTWRITER_H
18 #include "llvm/ADT/OwningPtr.h"
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/ADT/SmallString.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/MC/MCAssembler.h"
23 #include "llvm/MC/MCELFObjectWriter.h"
24 #include "llvm/MC/MCELFSymbolFlags.h"
25 #include "llvm/MC/MCObjectWriter.h"
26 #include "llvm/MC/MCExpr.h"
27 #include "llvm/MC/MCSymbol.h"
37 class ELFObjectWriter
: public MCObjectWriter
{
40 static bool isFixupKindPCRel(const MCAssembler
&Asm
, unsigned Kind
);
41 static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant
);
42 static uint64_t SymbolValue(MCSymbolData
&Data
, const MCAsmLayout
&Layout
);
43 static bool isInSymtab(const MCAssembler
&Asm
, const MCSymbolData
&Data
,
44 bool Used
, bool Renamed
);
45 static bool isLocal(const MCSymbolData
&Data
, bool isSignature
,
47 static bool IsELFMetaDataSection(const MCSectionData
&SD
);
48 static uint64_t DataSectionSize(const MCSectionData
&SD
);
49 static uint64_t GetSectionFileSize(const MCAsmLayout
&Layout
,
50 const MCSectionData
&SD
);
51 static uint64_t GetSectionAddressSize(const MCAsmLayout
&Layout
,
52 const MCSectionData
&SD
);
54 void WriteDataSectionData(MCAssembler
&Asm
,
55 const MCAsmLayout
&Layout
,
56 const MCSectionELF
&Section
);
58 /*static bool isFixupKindX86RIPRel(unsigned Kind) {
59 return Kind == X86::reloc_riprel_4byte ||
60 Kind == X86::reloc_riprel_4byte_movq_load;
63 /// ELFSymbolData - Helper struct for containing some precomputed
64 /// information on symbols.
65 struct ELFSymbolData
{
66 MCSymbolData
*SymbolData
;
68 uint32_t SectionIndex
;
70 // Support lexicographic sorting.
71 bool operator<(const ELFSymbolData
&RHS
) const {
72 if (MCELF::GetType(*SymbolData
) == ELF::STT_FILE
)
74 if (MCELF::GetType(*RHS
.SymbolData
) == ELF::STT_FILE
)
76 return SymbolData
->getSymbol().getName() <
77 RHS
.SymbolData
->getSymbol().getName();
81 /// @name Relocation Data
84 struct ELFRelocationEntry
{
85 // Make these big enough for both 32-bit and 64-bit
89 const MCSymbol
*Symbol
;
93 : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {}
95 ELFRelocationEntry(uint64_t RelocOffset
, int Idx
,
96 unsigned RelType
, const MCSymbol
*Sym
,
98 : r_offset(RelocOffset
), Index(Idx
), Type(RelType
),
99 Symbol(Sym
), r_addend(Addend
) {}
101 // Support lexicographic sorting.
102 bool operator<(const ELFRelocationEntry
&RE
) const {
103 return RE
.r_offset
< r_offset
;
107 /// The target specific ELF writer instance.
108 llvm::OwningPtr
<MCELFObjectTargetWriter
> TargetObjectWriter
;
110 SmallPtrSet
<const MCSymbol
*, 16> UsedInReloc
;
111 SmallPtrSet
<const MCSymbol
*, 16> WeakrefUsedInReloc
;
112 DenseMap
<const MCSymbol
*, const MCSymbol
*> Renames
;
114 llvm::DenseMap
<const MCSectionData
*,
115 std::vector
<ELFRelocationEntry
> > Relocations
;
116 DenseMap
<const MCSection
*, uint64_t> SectionStringTableIndex
;
119 /// @name Symbol Table Data
122 SmallString
<256> StringTable
;
123 std::vector
<ELFSymbolData
> LocalSymbolData
;
124 std::vector
<ELFSymbolData
> ExternalSymbolData
;
125 std::vector
<ELFSymbolData
> UndefinedSymbolData
;
131 bool NeedsSymtabShndx
;
133 // This holds the symbol table index of the last local symbol.
134 unsigned LastLocalSymbolIndex
;
135 // This holds the .strtab section index.
136 unsigned StringTableIndex
;
137 // This holds the .symtab section index.
138 unsigned SymbolTableIndex
;
140 unsigned ShstrtabIndex
;
143 const MCSymbol
*SymbolToReloc(const MCAssembler
&Asm
,
144 const MCValue
&Target
,
145 const MCFragment
&F
) const;
147 // For arch-specific emission of explicit reloc symbol
148 virtual const MCSymbol
*ExplicitRelSym(const MCAssembler
&Asm
,
149 const MCValue
&Target
,
155 bool is64Bit() const { return TargetObjectWriter
->is64Bit(); }
156 bool hasRelocationAddend() const {
157 return TargetObjectWriter
->hasRelocationAddend();
161 ELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
162 raw_ostream
&_OS
, bool IsLittleEndian
)
163 : MCObjectWriter(_OS
, IsLittleEndian
),
164 TargetObjectWriter(MOTW
),
165 NeedsGOT(false), NeedsSymtabShndx(false){
168 virtual ~ELFObjectWriter();
170 void WriteWord(uint64_t W
) {
177 void StringLE16(char *buf
, uint16_t Value
) {
178 buf
[0] = char(Value
>> 0);
179 buf
[1] = char(Value
>> 8);
182 void StringLE32(char *buf
, uint32_t Value
) {
183 StringLE16(buf
, uint16_t(Value
>> 0));
184 StringLE16(buf
+ 2, uint16_t(Value
>> 16));
187 void StringLE64(char *buf
, uint64_t Value
) {
188 StringLE32(buf
, uint32_t(Value
>> 0));
189 StringLE32(buf
+ 4, uint32_t(Value
>> 32));
192 void StringBE16(char *buf
,uint16_t Value
) {
193 buf
[0] = char(Value
>> 8);
194 buf
[1] = char(Value
>> 0);
197 void StringBE32(char *buf
, uint32_t Value
) {
198 StringBE16(buf
, uint16_t(Value
>> 16));
199 StringBE16(buf
+ 2, uint16_t(Value
>> 0));
202 void StringBE64(char *buf
, uint64_t Value
) {
203 StringBE32(buf
, uint32_t(Value
>> 32));
204 StringBE32(buf
+ 4, uint32_t(Value
>> 0));
207 void String8(MCDataFragment
&F
, uint8_t Value
) {
210 F
.getContents() += StringRef(buf
, 1);
213 void String16(MCDataFragment
&F
, uint16_t Value
) {
215 if (isLittleEndian())
216 StringLE16(buf
, Value
);
218 StringBE16(buf
, Value
);
219 F
.getContents() += StringRef(buf
, 2);
222 void String32(MCDataFragment
&F
, uint32_t Value
) {
224 if (isLittleEndian())
225 StringLE32(buf
, Value
);
227 StringBE32(buf
, Value
);
228 F
.getContents() += StringRef(buf
, 4);
231 void String64(MCDataFragment
&F
, uint64_t Value
) {
233 if (isLittleEndian())
234 StringLE64(buf
, Value
);
236 StringBE64(buf
, Value
);
237 F
.getContents() += StringRef(buf
, 8);
240 virtual void WriteHeader(uint64_t SectionDataSize
, unsigned NumberOfSections
);
242 /// Default e_flags = 0
243 virtual void WriteEFlags() { Write32(0); }
245 virtual void WriteSymbolEntry(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
246 uint64_t name
, uint8_t info
,
247 uint64_t value
, uint64_t size
,
248 uint8_t other
, uint32_t shndx
,
251 virtual void WriteSymbol(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
253 const MCAsmLayout
&Layout
);
255 typedef DenseMap
<const MCSectionELF
*, uint32_t> SectionIndexMapTy
;
256 virtual void WriteSymbolTable(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
257 const MCAssembler
&Asm
,
258 const MCAsmLayout
&Layout
,
259 const SectionIndexMapTy
&SectionIndexMap
);
261 virtual void RecordRelocation(const MCAssembler
&Asm
, const MCAsmLayout
&Layout
,
262 const MCFragment
*Fragment
, const MCFixup
&Fixup
,
263 MCValue Target
, uint64_t &FixedValue
);
265 virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler
&Asm
,
268 // Map from a group section to the signature symbol
269 typedef DenseMap
<const MCSectionELF
*, const MCSymbol
*> GroupMapTy
;
270 // Map from a signature symbol to the group section
271 typedef DenseMap
<const MCSymbol
*, const MCSectionELF
*> RevGroupMapTy
;
272 // Map from a section to the section with the relocations
273 typedef DenseMap
<const MCSectionELF
*, const MCSectionELF
*> RelMapTy
;
274 // Map from a section to its offset
275 typedef DenseMap
<const MCSectionELF
*, uint64_t> SectionOffsetMapTy
;
277 /// ComputeSymbolTable - Compute the symbol table data
279 /// \param StringTable [out] - The string table data.
280 /// \param StringIndexMap [out] - Map from symbol names to offsets in the
282 virtual void ComputeSymbolTable(MCAssembler
&Asm
,
283 const SectionIndexMapTy
&SectionIndexMap
,
284 RevGroupMapTy RevGroupMap
,
285 unsigned NumRegularSections
);
287 virtual void ComputeIndexMap(MCAssembler
&Asm
,
288 SectionIndexMapTy
&SectionIndexMap
,
289 const RelMapTy
&RelMap
);
291 void CreateRelocationSections(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
294 void WriteRelocations(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
295 const RelMapTy
&RelMap
);
297 virtual void CreateMetadataSections(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
298 SectionIndexMapTy
&SectionIndexMap
,
299 const RelMapTy
&RelMap
);
301 // Create the sections that show up in the symbol table. Currently
302 // those are the .note.GNU-stack section and the group sections.
303 virtual void CreateIndexedSections(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
304 GroupMapTy
&GroupMap
,
305 RevGroupMapTy
&RevGroupMap
,
306 SectionIndexMapTy
&SectionIndexMap
,
307 const RelMapTy
&RelMap
);
309 virtual void ExecutePostLayoutBinding(MCAssembler
&Asm
,
310 const MCAsmLayout
&Layout
);
312 void WriteSectionHeader(MCAssembler
&Asm
, const GroupMapTy
&GroupMap
,
313 const MCAsmLayout
&Layout
,
314 const SectionIndexMapTy
&SectionIndexMap
,
315 const SectionOffsetMapTy
&SectionOffsetMap
);
317 void ComputeSectionOrder(MCAssembler
&Asm
,
318 std::vector
<const MCSectionELF
*> &Sections
);
320 virtual void WriteSecHdrEntry(uint32_t Name
, uint32_t Type
, uint64_t Flags
,
321 uint64_t Address
, uint64_t Offset
,
322 uint64_t Size
, uint32_t Link
, uint32_t Info
,
323 uint64_t Alignment
, uint64_t EntrySize
);
325 virtual void WriteRelocationsFragment(const MCAssembler
&Asm
,
327 const MCSectionData
*SD
);
330 IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler
&Asm
,
331 const MCSymbolData
&DataA
,
332 const MCFragment
&FB
,
336 virtual void WriteObject(MCAssembler
&Asm
, const MCAsmLayout
&Layout
);
337 virtual void WriteSection(MCAssembler
&Asm
,
338 const SectionIndexMapTy
&SectionIndexMap
,
339 uint32_t GroupSymbolIndex
,
340 uint64_t Offset
, uint64_t Size
, uint64_t Alignment
,
341 const MCSectionELF
&Section
);
344 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
345 bool IsPCRel
, bool IsRelocWithSymbol
,
349 //===- X86ELFObjectWriter -------------------------------------------===//
351 class X86ELFObjectWriter
: public ELFObjectWriter
{
353 X86ELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
355 bool IsLittleEndian
);
357 virtual ~X86ELFObjectWriter();
359 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
360 bool IsPCRel
, bool IsRelocWithSymbol
,
365 //===- ARMELFObjectWriter -------------------------------------------===//
367 class ARMELFObjectWriter
: public ELFObjectWriter
{
369 // FIXME: MCAssembler can't yet return the Subtarget,
370 enum { DefaultEABIVersion
= 0x05000000U
};
372 ARMELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
374 bool IsLittleEndian
);
376 virtual ~ARMELFObjectWriter();
378 virtual void WriteEFlags();
380 virtual const MCSymbol
*ExplicitRelSym(const MCAssembler
&Asm
,
381 const MCValue
&Target
,
385 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
386 bool IsPCRel
, bool IsRelocWithSymbol
,
390 //===- MBlazeELFObjectWriter -------------------------------------------===//
392 class MBlazeELFObjectWriter
: public ELFObjectWriter
{
394 MBlazeELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
396 bool IsLittleEndian
);
398 virtual ~MBlazeELFObjectWriter();
400 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
401 bool IsPCRel
, bool IsRelocWithSymbol
,