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 virtual const MCSymbol
*SymbolToReloc(const MCAssembler
&Asm
,
144 const MCValue
&Target
,
146 const MCFixup
&Fixup
,
149 // For arch-specific emission of explicit reloc symbol
150 virtual const MCSymbol
*ExplicitRelSym(const MCAssembler
&Asm
,
151 const MCValue
&Target
,
153 const MCFixup
&Fixup
,
154 bool IsPCRel
) const {
158 bool is64Bit() const { return TargetObjectWriter
->is64Bit(); }
159 bool hasRelocationAddend() const {
160 return TargetObjectWriter
->hasRelocationAddend();
164 ELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
165 raw_ostream
&_OS
, bool IsLittleEndian
)
166 : MCObjectWriter(_OS
, IsLittleEndian
),
167 TargetObjectWriter(MOTW
),
168 NeedsGOT(false), NeedsSymtabShndx(false){
171 virtual ~ELFObjectWriter();
173 void WriteWord(uint64_t W
) {
180 void StringLE16(char *buf
, uint16_t Value
) {
181 buf
[0] = char(Value
>> 0);
182 buf
[1] = char(Value
>> 8);
185 void StringLE32(char *buf
, uint32_t Value
) {
186 StringLE16(buf
, uint16_t(Value
>> 0));
187 StringLE16(buf
+ 2, uint16_t(Value
>> 16));
190 void StringLE64(char *buf
, uint64_t Value
) {
191 StringLE32(buf
, uint32_t(Value
>> 0));
192 StringLE32(buf
+ 4, uint32_t(Value
>> 32));
195 void StringBE16(char *buf
,uint16_t Value
) {
196 buf
[0] = char(Value
>> 8);
197 buf
[1] = char(Value
>> 0);
200 void StringBE32(char *buf
, uint32_t Value
) {
201 StringBE16(buf
, uint16_t(Value
>> 16));
202 StringBE16(buf
+ 2, uint16_t(Value
>> 0));
205 void StringBE64(char *buf
, uint64_t Value
) {
206 StringBE32(buf
, uint32_t(Value
>> 32));
207 StringBE32(buf
+ 4, uint32_t(Value
>> 0));
210 void String8(MCDataFragment
&F
, uint8_t Value
) {
213 F
.getContents() += StringRef(buf
, 1);
216 void String16(MCDataFragment
&F
, uint16_t Value
) {
218 if (isLittleEndian())
219 StringLE16(buf
, Value
);
221 StringBE16(buf
, Value
);
222 F
.getContents() += StringRef(buf
, 2);
225 void String32(MCDataFragment
&F
, uint32_t Value
) {
227 if (isLittleEndian())
228 StringLE32(buf
, Value
);
230 StringBE32(buf
, Value
);
231 F
.getContents() += StringRef(buf
, 4);
234 void String64(MCDataFragment
&F
, uint64_t Value
) {
236 if (isLittleEndian())
237 StringLE64(buf
, Value
);
239 StringBE64(buf
, Value
);
240 F
.getContents() += StringRef(buf
, 8);
243 virtual void WriteHeader(uint64_t SectionDataSize
, unsigned NumberOfSections
);
245 /// Default e_flags = 0
246 virtual void WriteEFlags() { Write32(0); }
248 virtual void WriteSymbolEntry(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
249 uint64_t name
, uint8_t info
,
250 uint64_t value
, uint64_t size
,
251 uint8_t other
, uint32_t shndx
,
254 virtual void WriteSymbol(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
256 const MCAsmLayout
&Layout
);
258 typedef DenseMap
<const MCSectionELF
*, uint32_t> SectionIndexMapTy
;
259 virtual void WriteSymbolTable(MCDataFragment
*SymtabF
, MCDataFragment
*ShndxF
,
260 const MCAssembler
&Asm
,
261 const MCAsmLayout
&Layout
,
262 const SectionIndexMapTy
&SectionIndexMap
);
264 virtual void RecordRelocation(const MCAssembler
&Asm
, const MCAsmLayout
&Layout
,
265 const MCFragment
*Fragment
, const MCFixup
&Fixup
,
266 MCValue Target
, uint64_t &FixedValue
);
268 virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler
&Asm
,
271 // Map from a group section to the signature symbol
272 typedef DenseMap
<const MCSectionELF
*, const MCSymbol
*> GroupMapTy
;
273 // Map from a signature symbol to the group section
274 typedef DenseMap
<const MCSymbol
*, const MCSectionELF
*> RevGroupMapTy
;
275 // Map from a section to the section with the relocations
276 typedef DenseMap
<const MCSectionELF
*, const MCSectionELF
*> RelMapTy
;
277 // Map from a section to its offset
278 typedef DenseMap
<const MCSectionELF
*, uint64_t> SectionOffsetMapTy
;
280 /// ComputeSymbolTable - Compute the symbol table data
282 /// \param StringTable [out] - The string table data.
283 /// \param StringIndexMap [out] - Map from symbol names to offsets in the
285 virtual void ComputeSymbolTable(MCAssembler
&Asm
,
286 const SectionIndexMapTy
&SectionIndexMap
,
287 RevGroupMapTy RevGroupMap
,
288 unsigned NumRegularSections
);
290 virtual void ComputeIndexMap(MCAssembler
&Asm
,
291 SectionIndexMapTy
&SectionIndexMap
,
292 const RelMapTy
&RelMap
);
294 void CreateRelocationSections(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
297 void WriteRelocations(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
298 const RelMapTy
&RelMap
);
300 virtual void CreateMetadataSections(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
301 SectionIndexMapTy
&SectionIndexMap
,
302 const RelMapTy
&RelMap
);
304 // Create the sections that show up in the symbol table. Currently
305 // those are the .note.GNU-stack section and the group sections.
306 virtual void CreateIndexedSections(MCAssembler
&Asm
, MCAsmLayout
&Layout
,
307 GroupMapTy
&GroupMap
,
308 RevGroupMapTy
&RevGroupMap
,
309 SectionIndexMapTy
&SectionIndexMap
,
310 const RelMapTy
&RelMap
);
312 virtual void ExecutePostLayoutBinding(MCAssembler
&Asm
,
313 const MCAsmLayout
&Layout
);
315 void WriteSectionHeader(MCAssembler
&Asm
, const GroupMapTy
&GroupMap
,
316 const MCAsmLayout
&Layout
,
317 const SectionIndexMapTy
&SectionIndexMap
,
318 const SectionOffsetMapTy
&SectionOffsetMap
);
320 void ComputeSectionOrder(MCAssembler
&Asm
,
321 std::vector
<const MCSectionELF
*> &Sections
);
323 virtual void WriteSecHdrEntry(uint32_t Name
, uint32_t Type
, uint64_t Flags
,
324 uint64_t Address
, uint64_t Offset
,
325 uint64_t Size
, uint32_t Link
, uint32_t Info
,
326 uint64_t Alignment
, uint64_t EntrySize
);
328 virtual void WriteRelocationsFragment(const MCAssembler
&Asm
,
330 const MCSectionData
*SD
);
333 IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler
&Asm
,
334 const MCSymbolData
&DataA
,
335 const MCFragment
&FB
,
339 virtual void WriteObject(MCAssembler
&Asm
, const MCAsmLayout
&Layout
);
340 virtual void WriteSection(MCAssembler
&Asm
,
341 const SectionIndexMapTy
&SectionIndexMap
,
342 uint32_t GroupSymbolIndex
,
343 uint64_t Offset
, uint64_t Size
, uint64_t Alignment
,
344 const MCSectionELF
&Section
);
347 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
348 bool IsPCRel
, bool IsRelocWithSymbol
,
352 //===- X86ELFObjectWriter -------------------------------------------===//
354 class X86ELFObjectWriter
: public ELFObjectWriter
{
356 X86ELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
358 bool IsLittleEndian
);
360 virtual ~X86ELFObjectWriter();
362 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
363 bool IsPCRel
, bool IsRelocWithSymbol
,
368 //===- ARMELFObjectWriter -------------------------------------------===//
370 class ARMELFObjectWriter
: public ELFObjectWriter
{
372 // FIXME: MCAssembler can't yet return the Subtarget,
373 enum { DefaultEABIVersion
= 0x05000000U
};
375 ARMELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
377 bool IsLittleEndian
);
379 virtual ~ARMELFObjectWriter();
381 virtual void WriteEFlags();
383 virtual const MCSymbol
*ExplicitRelSym(const MCAssembler
&Asm
,
384 const MCValue
&Target
,
386 const MCFixup
&Fixup
,
389 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
390 bool IsPCRel
, bool IsRelocWithSymbol
,
393 unsigned GetRelocTypeInner(const MCValue
&Target
,
394 const MCFixup
&Fixup
, bool IsPCRel
) const;
398 //===- MBlazeELFObjectWriter -------------------------------------------===//
400 class MBlazeELFObjectWriter
: public ELFObjectWriter
{
402 MBlazeELFObjectWriter(MCELFObjectTargetWriter
*MOTW
,
404 bool IsLittleEndian
);
406 virtual ~MBlazeELFObjectWriter();
408 virtual unsigned GetRelocType(const MCValue
&Target
, const MCFixup
&Fixup
,
409 bool IsPCRel
, bool IsRelocWithSymbol
,