File: | lib/MC/ELFObjectWriter.cpp |
Location: | line 1307, column 36 |
Description: | Potential leak of memory pointed to by 'F' |
1 | //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | // | |||
10 | // This file implements ELF object file writer information. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "llvm/MC/MCELFObjectWriter.h" | |||
15 | #include "llvm/ADT/STLExtras.h" | |||
16 | #include "llvm/ADT/SmallPtrSet.h" | |||
17 | #include "llvm/ADT/SmallString.h" | |||
18 | #include "llvm/ADT/StringMap.h" | |||
19 | #include "llvm/MC/MCAsmBackend.h" | |||
20 | #include "llvm/MC/MCAsmInfo.h" | |||
21 | #include "llvm/MC/MCAsmLayout.h" | |||
22 | #include "llvm/MC/MCAssembler.h" | |||
23 | #include "llvm/MC/MCContext.h" | |||
24 | #include "llvm/MC/MCELF.h" | |||
25 | #include "llvm/MC/MCELFSymbolFlags.h" | |||
26 | #include "llvm/MC/MCExpr.h" | |||
27 | #include "llvm/MC/MCFixupKindInfo.h" | |||
28 | #include "llvm/MC/MCObjectWriter.h" | |||
29 | #include "llvm/MC/MCSectionELF.h" | |||
30 | #include "llvm/MC/MCValue.h" | |||
31 | #include "llvm/MC/StringTableBuilder.h" | |||
32 | #include "llvm/Support/Compression.h" | |||
33 | #include "llvm/Support/Debug.h" | |||
34 | #include "llvm/Support/ELF.h" | |||
35 | #include "llvm/Support/Endian.h" | |||
36 | #include "llvm/Support/ErrorHandling.h" | |||
37 | #include <vector> | |||
38 | using namespace llvm; | |||
39 | ||||
40 | #undef DEBUG_TYPE"reloc-info" | |||
41 | #define DEBUG_TYPE"reloc-info" "reloc-info" | |||
42 | ||||
43 | namespace { | |||
44 | class FragmentWriter { | |||
45 | bool IsLittleEndian; | |||
46 | ||||
47 | public: | |||
48 | FragmentWriter(bool IsLittleEndian); | |||
49 | template <typename T> void write(MCDataFragment &F, T Val); | |||
50 | }; | |||
51 | ||||
52 | typedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy; | |||
53 | ||||
54 | class SymbolTableWriter { | |||
55 | MCAssembler &Asm; | |||
56 | FragmentWriter &FWriter; | |||
57 | bool Is64Bit; | |||
58 | SectionIndexMapTy &SectionIndexMap; | |||
59 | ||||
60 | // The symbol .symtab fragment we are writting to. | |||
61 | MCDataFragment *SymtabF; | |||
62 | ||||
63 | // .symtab_shndx fragment we are writting to. | |||
64 | MCDataFragment *ShndxF; | |||
65 | ||||
66 | // The numbel of symbols written so far. | |||
67 | unsigned NumWritten; | |||
68 | ||||
69 | void createSymtabShndx(); | |||
70 | ||||
71 | template <typename T> void write(MCDataFragment &F, T Value); | |||
72 | ||||
73 | public: | |||
74 | SymbolTableWriter(MCAssembler &Asm, FragmentWriter &FWriter, bool Is64Bit, | |||
75 | SectionIndexMapTy &SectionIndexMap, | |||
76 | MCDataFragment *SymtabF); | |||
77 | ||||
78 | void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size, | |||
79 | uint8_t other, uint32_t shndx, bool Reserved); | |||
80 | }; | |||
81 | ||||
82 | struct ELFRelocationEntry { | |||
83 | uint64_t Offset; // Where is the relocation. | |||
84 | const MCSymbol *Symbol; // The symbol to relocate with. | |||
85 | unsigned Type; // The type of the relocation. | |||
86 | uint64_t Addend; // The addend to use. | |||
87 | ||||
88 | ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type, | |||
89 | uint64_t Addend) | |||
90 | : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {} | |||
91 | }; | |||
92 | ||||
93 | class ELFObjectWriter : public MCObjectWriter { | |||
94 | FragmentWriter FWriter; | |||
95 | ||||
96 | protected: | |||
97 | ||||
98 | static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); | |||
99 | static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant); | |||
100 | static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout); | |||
101 | static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolData &Data, | |||
102 | bool Used, bool Renamed); | |||
103 | static bool isLocal(const MCSymbolData &Data, bool isUsedInReloc); | |||
104 | static bool IsELFMetaDataSection(const MCSectionData &SD); | |||
105 | static uint64_t DataSectionSize(const MCSectionData &SD); | |||
106 | static uint64_t GetSectionFileSize(const MCAsmLayout &Layout, | |||
107 | const MCSectionData &SD); | |||
108 | static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout, | |||
109 | const MCSectionData &SD); | |||
110 | ||||
111 | void WriteDataSectionData(MCAssembler &Asm, | |||
112 | const MCAsmLayout &Layout, | |||
113 | const MCSectionELF &Section); | |||
114 | ||||
115 | /*static bool isFixupKindX86RIPRel(unsigned Kind) { | |||
116 | return Kind == X86::reloc_riprel_4byte || | |||
117 | Kind == X86::reloc_riprel_4byte_movq_load; | |||
118 | }*/ | |||
119 | ||||
120 | /// ELFSymbolData - Helper struct for containing some precomputed | |||
121 | /// information on symbols. | |||
122 | struct ELFSymbolData { | |||
123 | MCSymbolData *SymbolData; | |||
124 | uint64_t StringIndex; | |||
125 | uint32_t SectionIndex; | |||
126 | StringRef Name; | |||
127 | ||||
128 | // Support lexicographic sorting. | |||
129 | bool operator<(const ELFSymbolData &RHS) const { | |||
130 | unsigned LHSType = MCELF::GetType(*SymbolData); | |||
131 | unsigned RHSType = MCELF::GetType(*RHS.SymbolData); | |||
132 | if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION) | |||
133 | return false; | |||
134 | if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION) | |||
135 | return true; | |||
136 | if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION) | |||
137 | return SectionIndex < RHS.SectionIndex; | |||
138 | return Name < RHS.Name; | |||
139 | } | |||
140 | }; | |||
141 | ||||
142 | /// The target specific ELF writer instance. | |||
143 | std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter; | |||
144 | ||||
145 | SmallPtrSet<const MCSymbol *, 16> UsedInReloc; | |||
146 | SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; | |||
147 | DenseMap<const MCSymbol *, const MCSymbol *> Renames; | |||
148 | ||||
149 | llvm::DenseMap<const MCSectionData *, std::vector<ELFRelocationEntry>> | |||
150 | Relocations; | |||
151 | StringTableBuilder ShStrTabBuilder; | |||
152 | ||||
153 | /// @} | |||
154 | /// @name Symbol Table Data | |||
155 | /// @{ | |||
156 | ||||
157 | StringTableBuilder StrTabBuilder; | |||
158 | std::vector<uint64_t> FileSymbolData; | |||
159 | std::vector<ELFSymbolData> LocalSymbolData; | |||
160 | std::vector<ELFSymbolData> ExternalSymbolData; | |||
161 | std::vector<ELFSymbolData> UndefinedSymbolData; | |||
162 | ||||
163 | /// @} | |||
164 | ||||
165 | bool NeedsGOT; | |||
166 | ||||
167 | // This holds the symbol table index of the last local symbol. | |||
168 | unsigned LastLocalSymbolIndex; | |||
169 | // This holds the .strtab section index. | |||
170 | unsigned StringTableIndex; | |||
171 | // This holds the .symtab section index. | |||
172 | unsigned SymbolTableIndex; | |||
173 | ||||
174 | unsigned ShstrtabIndex; | |||
175 | ||||
176 | ||||
177 | // TargetObjectWriter wrappers. | |||
178 | bool is64Bit() const { return TargetObjectWriter->is64Bit(); } | |||
179 | bool hasRelocationAddend() const { | |||
180 | return TargetObjectWriter->hasRelocationAddend(); | |||
181 | } | |||
182 | unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, | |||
183 | bool IsPCRel) const { | |||
184 | return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel); | |||
185 | } | |||
186 | ||||
187 | public: | |||
188 | ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_ostream &_OS, | |||
189 | bool IsLittleEndian) | |||
190 | : MCObjectWriter(_OS, IsLittleEndian), FWriter(IsLittleEndian), | |||
191 | TargetObjectWriter(MOTW), NeedsGOT(false) {} | |||
192 | ||||
193 | virtual ~ELFObjectWriter(); | |||
194 | ||||
195 | void WriteWord(uint64_t W) { | |||
196 | if (is64Bit()) | |||
197 | Write64(W); | |||
198 | else | |||
199 | Write32(W); | |||
200 | } | |||
201 | ||||
202 | template <typename T> void write(MCDataFragment &F, T Value) { | |||
203 | FWriter.write(F, Value); | |||
204 | } | |||
205 | ||||
206 | void WriteHeader(const MCAssembler &Asm, | |||
207 | uint64_t SectionDataSize, | |||
208 | unsigned NumberOfSections); | |||
209 | ||||
210 | void WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, | |||
211 | const MCAsmLayout &Layout); | |||
212 | ||||
213 | void WriteSymbolTable(MCDataFragment *SymtabF, MCAssembler &Asm, | |||
214 | const MCAsmLayout &Layout, | |||
215 | SectionIndexMapTy &SectionIndexMap); | |||
216 | ||||
217 | bool shouldRelocateWithSymbol(const MCAssembler &Asm, | |||
218 | const MCSymbolRefExpr *RefA, | |||
219 | const MCSymbolData *SD, uint64_t C, | |||
220 | unsigned Type) const; | |||
221 | ||||
222 | void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, | |||
223 | const MCFragment *Fragment, const MCFixup &Fixup, | |||
224 | MCValue Target, bool &IsPCRel, | |||
225 | uint64_t &FixedValue) override; | |||
226 | ||||
227 | uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, | |||
228 | const MCSymbol *S); | |||
229 | ||||
230 | // Map from a group section to the signature symbol | |||
231 | typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy; | |||
232 | // Map from a signature symbol to the group section | |||
233 | typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy; | |||
234 | // Map from a section to the section with the relocations | |||
235 | typedef DenseMap<const MCSectionELF*, const MCSectionELF*> RelMapTy; | |||
236 | // Map from a section to its offset | |||
237 | typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy; | |||
238 | ||||
239 | /// Compute the symbol table data | |||
240 | /// | |||
241 | /// \param Asm - The assembler. | |||
242 | /// \param SectionIndexMap - Maps a section to its index. | |||
243 | /// \param RevGroupMap - Maps a signature symbol to the group section. | |||
244 | /// \param NumRegularSections - Number of non-relocation sections. | |||
245 | void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, | |||
246 | const SectionIndexMapTy &SectionIndexMap, | |||
247 | const RevGroupMapTy &RevGroupMap, | |||
248 | unsigned NumRegularSections); | |||
249 | ||||
250 | void ComputeIndexMap(MCAssembler &Asm, | |||
251 | SectionIndexMapTy &SectionIndexMap, | |||
252 | const RelMapTy &RelMap); | |||
253 | ||||
254 | void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout, | |||
255 | RelMapTy &RelMap); | |||
256 | ||||
257 | void CompressDebugSections(MCAssembler &Asm, MCAsmLayout &Layout); | |||
258 | ||||
259 | void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, | |||
260 | const RelMapTy &RelMap); | |||
261 | ||||
262 | void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, | |||
263 | SectionIndexMapTy &SectionIndexMap, | |||
264 | const RelMapTy &RelMap); | |||
265 | ||||
266 | // Create the sections that show up in the symbol table. Currently | |||
267 | // those are the .note.GNU-stack section and the group sections. | |||
268 | void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout, | |||
269 | GroupMapTy &GroupMap, | |||
270 | RevGroupMapTy &RevGroupMap, | |||
271 | SectionIndexMapTy &SectionIndexMap, | |||
272 | const RelMapTy &RelMap); | |||
273 | ||||
274 | void ExecutePostLayoutBinding(MCAssembler &Asm, | |||
275 | const MCAsmLayout &Layout) override; | |||
276 | ||||
277 | void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap, | |||
278 | const MCAsmLayout &Layout, | |||
279 | const SectionIndexMapTy &SectionIndexMap, | |||
280 | const SectionOffsetMapTy &SectionOffsetMap); | |||
281 | ||||
282 | void ComputeSectionOrder(MCAssembler &Asm, | |||
283 | std::vector<const MCSectionELF*> &Sections); | |||
284 | ||||
285 | void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, | |||
286 | uint64_t Address, uint64_t Offset, | |||
287 | uint64_t Size, uint32_t Link, uint32_t Info, | |||
288 | uint64_t Alignment, uint64_t EntrySize); | |||
289 | ||||
290 | void WriteRelocationsFragment(const MCAssembler &Asm, | |||
291 | MCDataFragment *F, | |||
292 | const MCSectionData *SD); | |||
293 | ||||
294 | bool | |||
295 | IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, | |||
296 | const MCSymbolData &DataA, | |||
297 | const MCFragment &FB, | |||
298 | bool InSet, | |||
299 | bool IsPCRel) const override; | |||
300 | ||||
301 | void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; | |||
302 | void WriteSection(MCAssembler &Asm, | |||
303 | const SectionIndexMapTy &SectionIndexMap, | |||
304 | uint32_t GroupSymbolIndex, | |||
305 | uint64_t Offset, uint64_t Size, uint64_t Alignment, | |||
306 | const MCSectionELF &Section); | |||
307 | }; | |||
308 | } | |||
309 | ||||
310 | FragmentWriter::FragmentWriter(bool IsLittleEndian) | |||
311 | : IsLittleEndian(IsLittleEndian) {} | |||
312 | ||||
313 | template <typename T> void FragmentWriter::write(MCDataFragment &F, T Val) { | |||
314 | if (IsLittleEndian) | |||
315 | Val = support::endian::byte_swap<T, support::little>(Val); | |||
316 | else | |||
317 | Val = support::endian::byte_swap<T, support::big>(Val); | |||
318 | const char *Start = (const char *)&Val; | |||
319 | F.getContents().append(Start, Start + sizeof(T)); | |||
320 | } | |||
321 | ||||
322 | void SymbolTableWriter::createSymtabShndx() { | |||
323 | if (ShndxF) | |||
324 | return; | |||
325 | ||||
326 | MCContext &Ctx = Asm.getContext(); | |||
327 | const MCSectionELF *SymtabShndxSection = | |||
328 | Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, ""); | |||
329 | MCSectionData *SymtabShndxSD = | |||
330 | &Asm.getOrCreateSectionData(*SymtabShndxSection); | |||
331 | SymtabShndxSD->setAlignment(4); | |||
332 | ShndxF = new MCDataFragment(SymtabShndxSD); | |||
333 | unsigned Index = SectionIndexMap.size() + 1; | |||
334 | SectionIndexMap[SymtabShndxSection] = Index; | |||
335 | ||||
336 | for (unsigned I = 0; I < NumWritten; ++I) | |||
337 | write(*ShndxF, uint32_t(0)); | |||
338 | } | |||
339 | ||||
340 | template <typename T> | |||
341 | void SymbolTableWriter::write(MCDataFragment &F, T Value) { | |||
342 | FWriter.write(F, Value); | |||
343 | } | |||
344 | ||||
345 | SymbolTableWriter::SymbolTableWriter(MCAssembler &Asm, FragmentWriter &FWriter, | |||
346 | bool Is64Bit, | |||
347 | SectionIndexMapTy &SectionIndexMap, | |||
348 | MCDataFragment *SymtabF) | |||
349 | : Asm(Asm), FWriter(FWriter), Is64Bit(Is64Bit), | |||
350 | SectionIndexMap(SectionIndexMap), SymtabF(SymtabF), ShndxF(nullptr), | |||
351 | NumWritten(0) {} | |||
352 | ||||
353 | void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value, | |||
354 | uint64_t size, uint8_t other, | |||
355 | uint32_t shndx, bool Reserved) { | |||
356 | bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved; | |||
357 | ||||
358 | if (LargeIndex) | |||
359 | createSymtabShndx(); | |||
360 | ||||
361 | if (ShndxF) { | |||
362 | if (LargeIndex) | |||
363 | write(*ShndxF, shndx); | |||
364 | else | |||
365 | write(*ShndxF, uint32_t(0)); | |||
366 | } | |||
367 | ||||
368 | uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx; | |||
369 | ||||
370 | raw_svector_ostream OS(SymtabF->getContents()); | |||
371 | ||||
372 | if (Is64Bit) { | |||
373 | write(*SymtabF, name); // st_name | |||
374 | write(*SymtabF, info); // st_info | |||
375 | write(*SymtabF, other); // st_other | |||
376 | write(*SymtabF, Index); // st_shndx | |||
377 | write(*SymtabF, value); // st_value | |||
378 | write(*SymtabF, size); // st_size | |||
379 | } else { | |||
380 | write(*SymtabF, name); // st_name | |||
381 | write(*SymtabF, uint32_t(value)); // st_value | |||
382 | write(*SymtabF, uint32_t(size)); // st_size | |||
383 | write(*SymtabF, info); // st_info | |||
384 | write(*SymtabF, other); // st_other | |||
385 | write(*SymtabF, Index); // st_shndx | |||
386 | } | |||
387 | ||||
388 | ++NumWritten; | |||
389 | } | |||
390 | ||||
391 | bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { | |||
392 | const MCFixupKindInfo &FKI = | |||
393 | Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); | |||
394 | ||||
395 | return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; | |||
396 | } | |||
397 | ||||
398 | bool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { | |||
399 | switch (Variant) { | |||
400 | default: | |||
401 | return false; | |||
402 | case MCSymbolRefExpr::VK_GOT: | |||
403 | case MCSymbolRefExpr::VK_PLT: | |||
404 | case MCSymbolRefExpr::VK_GOTPCREL: | |||
405 | case MCSymbolRefExpr::VK_GOTOFF: | |||
406 | case MCSymbolRefExpr::VK_TPOFF: | |||
407 | case MCSymbolRefExpr::VK_TLSGD: | |||
408 | case MCSymbolRefExpr::VK_GOTTPOFF: | |||
409 | case MCSymbolRefExpr::VK_INDNTPOFF: | |||
410 | case MCSymbolRefExpr::VK_NTPOFF: | |||
411 | case MCSymbolRefExpr::VK_GOTNTPOFF: | |||
412 | case MCSymbolRefExpr::VK_TLSLDM: | |||
413 | case MCSymbolRefExpr::VK_DTPOFF: | |||
414 | case MCSymbolRefExpr::VK_TLSLD: | |||
415 | return true; | |||
416 | } | |||
417 | } | |||
418 | ||||
419 | ELFObjectWriter::~ELFObjectWriter() | |||
420 | {} | |||
421 | ||||
422 | // Emit the ELF header. | |||
423 | void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, | |||
424 | uint64_t SectionDataSize, | |||
425 | unsigned NumberOfSections) { | |||
426 | // ELF Header | |||
427 | // ---------- | |||
428 | // | |||
429 | // Note | |||
430 | // ---- | |||
431 | // emitWord method behaves differently for ELF32 and ELF64, writing | |||
432 | // 4 bytes in the former and 8 in the latter. | |||
433 | ||||
434 | Write8(0x7f); // e_ident[EI_MAG0] | |||
435 | Write8('E'); // e_ident[EI_MAG1] | |||
436 | Write8('L'); // e_ident[EI_MAG2] | |||
437 | Write8('F'); // e_ident[EI_MAG3] | |||
438 | ||||
439 | Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] | |||
440 | ||||
441 | // e_ident[EI_DATA] | |||
442 | Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); | |||
443 | ||||
444 | Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] | |||
445 | // e_ident[EI_OSABI] | |||
446 | Write8(TargetObjectWriter->getOSABI()); | |||
447 | Write8(0); // e_ident[EI_ABIVERSION] | |||
448 | ||||
449 | WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); | |||
450 | ||||
451 | Write16(ELF::ET_REL); // e_type | |||
452 | ||||
453 | Write16(TargetObjectWriter->getEMachine()); // e_machine = target | |||
454 | ||||
455 | Write32(ELF::EV_CURRENT); // e_version | |||
456 | WriteWord(0); // e_entry, no entry point in .o file | |||
457 | WriteWord(0); // e_phoff, no program header for .o | |||
458 | WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) : | |||
459 | sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes | |||
460 | ||||
461 | // e_flags = whatever the target wants | |||
462 | Write32(Asm.getELFHeaderEFlags()); | |||
463 | ||||
464 | // e_ehsize = ELF header size | |||
465 | Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); | |||
466 | ||||
467 | Write16(0); // e_phentsize = prog header entry size | |||
468 | Write16(0); // e_phnum = # prog header entries = 0 | |||
469 | ||||
470 | // e_shentsize = Section header entry size | |||
471 | Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); | |||
472 | ||||
473 | // e_shnum = # of section header ents | |||
474 | if (NumberOfSections >= ELF::SHN_LORESERVE) | |||
475 | Write16(ELF::SHN_UNDEF); | |||
476 | else | |||
477 | Write16(NumberOfSections); | |||
478 | ||||
479 | // e_shstrndx = Section # of '.shstrtab' | |||
480 | if (ShstrtabIndex >= ELF::SHN_LORESERVE) | |||
481 | Write16(ELF::SHN_XINDEX); | |||
482 | else | |||
483 | Write16(ShstrtabIndex); | |||
484 | } | |||
485 | ||||
486 | uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, | |||
487 | const MCAsmLayout &Layout) { | |||
488 | if (Data.isCommon() && Data.isExternal()) | |||
489 | return Data.getCommonAlignment(); | |||
490 | ||||
491 | uint64_t Res; | |||
492 | if (!Layout.getSymbolOffset(&Data, Res)) | |||
493 | return 0; | |||
494 | ||||
495 | if (Layout.getAssembler().isThumbFunc(&Data.getSymbol())) | |||
496 | Res |= 1; | |||
497 | ||||
498 | return Res; | |||
499 | } | |||
500 | ||||
501 | void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, | |||
502 | const MCAsmLayout &Layout) { | |||
503 | // The presence of symbol versions causes undefined symbols and | |||
504 | // versions declared with @@@ to be renamed. | |||
505 | ||||
506 | for (MCSymbolData &OriginalData : Asm.symbols()) { | |||
507 | const MCSymbol &Alias = OriginalData.getSymbol(); | |||
508 | ||||
509 | // Not an alias. | |||
510 | if (!Alias.isVariable()) | |||
511 | continue; | |||
512 | auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue()); | |||
513 | if (!Ref) | |||
514 | continue; | |||
515 | const MCSymbol &Symbol = Ref->getSymbol(); | |||
516 | MCSymbolData &SD = Asm.getSymbolData(Symbol); | |||
517 | ||||
518 | StringRef AliasName = Alias.getName(); | |||
519 | size_t Pos = AliasName.find('@'); | |||
520 | if (Pos == StringRef::npos) | |||
521 | continue; | |||
522 | ||||
523 | // Aliases defined with .symvar copy the binding from the symbol they alias. | |||
524 | // This is the first place we are able to copy this information. | |||
525 | OriginalData.setExternal(SD.isExternal()); | |||
526 | MCELF::SetBinding(OriginalData, MCELF::GetBinding(SD)); | |||
527 | ||||
528 | StringRef Rest = AliasName.substr(Pos); | |||
529 | if (!Symbol.isUndefined() && !Rest.startswith("@@@")) | |||
530 | continue; | |||
531 | ||||
532 | // FIXME: produce a better error message. | |||
533 | if (Symbol.isUndefined() && Rest.startswith("@@") && | |||
534 | !Rest.startswith("@@@")) | |||
535 | report_fatal_error("A @@ version cannot be undefined"); | |||
536 | ||||
537 | Renames.insert(std::make_pair(&Symbol, &Alias)); | |||
538 | } | |||
539 | } | |||
540 | ||||
541 | static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { | |||
542 | uint8_t Type = newType; | |||
543 | ||||
544 | // Propagation rules: | |||
545 | // IFUNC > FUNC > OBJECT > NOTYPE | |||
546 | // TLS_OBJECT > OBJECT > NOTYPE | |||
547 | // | |||
548 | // dont let the new type degrade the old type | |||
549 | switch (origType) { | |||
550 | default: | |||
551 | break; | |||
552 | case ELF::STT_GNU_IFUNC: | |||
553 | if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT || | |||
554 | Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS) | |||
555 | Type = ELF::STT_GNU_IFUNC; | |||
556 | break; | |||
557 | case ELF::STT_FUNC: | |||
558 | if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || | |||
559 | Type == ELF::STT_TLS) | |||
560 | Type = ELF::STT_FUNC; | |||
561 | break; | |||
562 | case ELF::STT_OBJECT: | |||
563 | if (Type == ELF::STT_NOTYPE) | |||
564 | Type = ELF::STT_OBJECT; | |||
565 | break; | |||
566 | case ELF::STT_TLS: | |||
567 | if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || | |||
568 | Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC) | |||
569 | Type = ELF::STT_TLS; | |||
570 | break; | |||
571 | } | |||
572 | ||||
573 | return Type; | |||
574 | } | |||
575 | ||||
576 | void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, | |||
577 | const MCAsmLayout &Layout) { | |||
578 | MCSymbolData &OrigData = *MSD.SymbolData; | |||
579 | assert((!OrigData.getFragment() ||(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &OrigData.getSymbol().getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &OrigData.getSymbol().getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 582, __PRETTY_FUNCTION__)) | |||
580 | (&OrigData.getFragment()->getParent()->getSection() ==(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &OrigData.getSymbol().getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &OrigData.getSymbol().getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 582, __PRETTY_FUNCTION__)) | |||
581 | &OrigData.getSymbol().getSection())) &&(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &OrigData.getSymbol().getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &OrigData.getSymbol().getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 582, __PRETTY_FUNCTION__)) | |||
582 | "The symbol's section doesn't match the fragment's symbol")(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &OrigData.getSymbol().getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &OrigData.getSymbol().getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 582, __PRETTY_FUNCTION__)); | |||
583 | const MCSymbol *Base = Layout.getBaseSymbol(OrigData.getSymbol()); | |||
584 | ||||
585 | // This has to be in sync with when computeSymbolTable uses SHN_ABS or | |||
586 | // SHN_COMMON. | |||
587 | bool IsReserved = !Base || OrigData.isCommon(); | |||
588 | ||||
589 | // Binding and Type share the same byte as upper and lower nibbles | |||
590 | uint8_t Binding = MCELF::GetBinding(OrigData); | |||
591 | uint8_t Type = MCELF::GetType(OrigData); | |||
592 | MCSymbolData *BaseSD = nullptr; | |||
593 | if (Base) { | |||
594 | BaseSD = &Layout.getAssembler().getSymbolData(*Base); | |||
595 | Type = mergeTypeForSet(Type, MCELF::GetType(*BaseSD)); | |||
596 | } | |||
597 | uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); | |||
598 | ||||
599 | // Other and Visibility share the same byte with Visibility using the lower | |||
600 | // 2 bits | |||
601 | uint8_t Visibility = MCELF::GetVisibility(OrigData); | |||
602 | uint8_t Other = MCELF::getOther(OrigData) << (ELF_STO_Shift - ELF_STV_Shift); | |||
603 | Other |= Visibility; | |||
604 | ||||
605 | uint64_t Value = SymbolValue(OrigData, Layout); | |||
606 | uint64_t Size = 0; | |||
607 | ||||
608 | const MCExpr *ESize = OrigData.getSize(); | |||
609 | if (!ESize && Base) | |||
610 | ESize = BaseSD->getSize(); | |||
611 | ||||
612 | if (ESize) { | |||
613 | int64_t Res; | |||
614 | if (!ESize->EvaluateAsAbsolute(Res, Layout)) | |||
615 | report_fatal_error("Size expression must be absolute."); | |||
616 | Size = Res; | |||
617 | } | |||
618 | ||||
619 | // Write out the symbol table entry | |||
620 | Writer.writeSymbol(MSD.StringIndex, Info, Value, Size, Other, | |||
621 | MSD.SectionIndex, IsReserved); | |||
622 | } | |||
623 | ||||
624 | void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, | |||
625 | MCAssembler &Asm, | |||
626 | const MCAsmLayout &Layout, | |||
627 | SectionIndexMapTy &SectionIndexMap) { | |||
628 | // The string table must be emitted first because we need the index | |||
629 | // into the string table for all the symbol names. | |||
630 | ||||
631 | // FIXME: Make sure the start of the symbol table is aligned. | |||
632 | ||||
633 | SymbolTableWriter Writer(Asm, FWriter, is64Bit(), SectionIndexMap, SymtabF); | |||
634 | ||||
635 | // The first entry is the undefined symbol entry. | |||
636 | Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); | |||
637 | ||||
638 | for (unsigned i = 0, e = FileSymbolData.size(); i != e; ++i) { | |||
639 | Writer.writeSymbol(FileSymbolData[i], ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, | |||
640 | ELF::STV_DEFAULT, ELF::SHN_ABS, true); | |||
641 | } | |||
642 | ||||
643 | // Write the symbol table entries. | |||
644 | LastLocalSymbolIndex = FileSymbolData.size() + LocalSymbolData.size() + 1; | |||
645 | ||||
646 | for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { | |||
647 | ELFSymbolData &MSD = LocalSymbolData[i]; | |||
648 | WriteSymbol(Writer, MSD, Layout); | |||
649 | } | |||
650 | ||||
651 | for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { | |||
652 | ELFSymbolData &MSD = ExternalSymbolData[i]; | |||
653 | MCSymbolData &Data = *MSD.SymbolData; | |||
654 | assert(((Data.getFlags() & ELF_STB_Global) ||((((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && "External symbol requires STB_GLOBAL or STB_WEAK flag" ) ? static_cast<void> (0) : __assert_fail ("((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && \"External symbol requires STB_GLOBAL or STB_WEAK flag\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 656, __PRETTY_FUNCTION__)) | |||
655 | (Data.getFlags() & ELF_STB_Weak)) &&((((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && "External symbol requires STB_GLOBAL or STB_WEAK flag" ) ? static_cast<void> (0) : __assert_fail ("((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && \"External symbol requires STB_GLOBAL or STB_WEAK flag\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 656, __PRETTY_FUNCTION__)) | |||
656 | "External symbol requires STB_GLOBAL or STB_WEAK flag")((((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && "External symbol requires STB_GLOBAL or STB_WEAK flag" ) ? static_cast<void> (0) : __assert_fail ("((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && \"External symbol requires STB_GLOBAL or STB_WEAK flag\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 656, __PRETTY_FUNCTION__)); | |||
657 | WriteSymbol(Writer, MSD, Layout); | |||
658 | if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) | |||
659 | LastLocalSymbolIndex++; | |||
660 | } | |||
661 | ||||
662 | for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { | |||
663 | ELFSymbolData &MSD = UndefinedSymbolData[i]; | |||
664 | MCSymbolData &Data = *MSD.SymbolData; | |||
665 | WriteSymbol(Writer, MSD, Layout); | |||
666 | if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) | |||
667 | LastLocalSymbolIndex++; | |||
668 | } | |||
669 | } | |||
670 | ||||
671 | // It is always valid to create a relocation with a symbol. It is preferable | |||
672 | // to use a relocation with a section if that is possible. Using the section | |||
673 | // allows us to omit some local symbols from the symbol table. | |||
674 | bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, | |||
675 | const MCSymbolRefExpr *RefA, | |||
676 | const MCSymbolData *SD, | |||
677 | uint64_t C, | |||
678 | unsigned Type) const { | |||
679 | // A PCRel relocation to an absolute value has no symbol (or section). We | |||
680 | // represent that with a relocation to a null section. | |||
681 | if (!RefA) | |||
682 | return false; | |||
683 | ||||
684 | MCSymbolRefExpr::VariantKind Kind = RefA->getKind(); | |||
685 | switch (Kind) { | |||
686 | default: | |||
687 | break; | |||
688 | // The .odp creation emits a relocation against the symbol ".TOC." which | |||
689 | // create a R_PPC64_TOC relocation. However the relocation symbol name | |||
690 | // in final object creation should be NULL, since the symbol does not | |||
691 | // really exist, it is just the reference to TOC base for the current | |||
692 | // object file. Since the symbol is undefined, returning false results | |||
693 | // in a relocation with a null section which is the desired result. | |||
694 | case MCSymbolRefExpr::VK_PPC_TOCBASE: | |||
695 | return false; | |||
696 | ||||
697 | // These VariantKind cause the relocation to refer to something other than | |||
698 | // the symbol itself, like a linker generated table. Since the address of | |||
699 | // symbol is not relevant, we cannot replace the symbol with the | |||
700 | // section and patch the difference in the addend. | |||
701 | case MCSymbolRefExpr::VK_GOT: | |||
702 | case MCSymbolRefExpr::VK_PLT: | |||
703 | case MCSymbolRefExpr::VK_GOTPCREL: | |||
704 | case MCSymbolRefExpr::VK_Mips_GOT: | |||
705 | case MCSymbolRefExpr::VK_PPC_GOT_LO: | |||
706 | case MCSymbolRefExpr::VK_PPC_GOT_HI: | |||
707 | case MCSymbolRefExpr::VK_PPC_GOT_HA: | |||
708 | return true; | |||
709 | } | |||
710 | ||||
711 | // An undefined symbol is not in any section, so the relocation has to point | |||
712 | // to the symbol itself. | |||
713 | const MCSymbol &Sym = SD->getSymbol(); | |||
714 | if (Sym.isUndefined()) | |||
715 | return true; | |||
716 | ||||
717 | unsigned Binding = MCELF::GetBinding(*SD); | |||
718 | switch(Binding) { | |||
719 | default: | |||
720 | llvm_unreachable("Invalid Binding")::llvm::llvm_unreachable_internal("Invalid Binding", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 720); | |||
721 | case ELF::STB_LOCAL: | |||
722 | break; | |||
723 | case ELF::STB_WEAK: | |||
724 | // If the symbol is weak, it might be overridden by a symbol in another | |||
725 | // file. The relocation has to point to the symbol so that the linker | |||
726 | // can update it. | |||
727 | return true; | |||
728 | case ELF::STB_GLOBAL: | |||
729 | // Global ELF symbols can be preempted by the dynamic linker. The relocation | |||
730 | // has to point to the symbol for a reason analogous to the STB_WEAK case. | |||
731 | return true; | |||
732 | } | |||
733 | ||||
734 | // If a relocation points to a mergeable section, we have to be careful. | |||
735 | // If the offset is zero, a relocation with the section will encode the | |||
736 | // same information. With a non-zero offset, the situation is different. | |||
737 | // For example, a relocation can point 42 bytes past the end of a string. | |||
738 | // If we change such a relocation to use the section, the linker would think | |||
739 | // that it pointed to another string and subtracting 42 at runtime will | |||
740 | // produce the wrong value. | |||
741 | auto &Sec = cast<MCSectionELF>(Sym.getSection()); | |||
742 | unsigned Flags = Sec.getFlags(); | |||
743 | if (Flags & ELF::SHF_MERGE) { | |||
744 | if (C != 0) | |||
745 | return true; | |||
746 | ||||
747 | // It looks like gold has a bug (http://sourceware.org/PR16794) and can | |||
748 | // only handle section relocations to mergeable sections if using RELA. | |||
749 | if (!hasRelocationAddend()) | |||
750 | return true; | |||
751 | } | |||
752 | ||||
753 | // Most TLS relocations use a got, so they need the symbol. Even those that | |||
754 | // are just an offset (@tpoff), require a symbol in gold versions before | |||
755 | // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed | |||
756 | // http://sourceware.org/PR16773. | |||
757 | if (Flags & ELF::SHF_TLS) | |||
758 | return true; | |||
759 | ||||
760 | // If the symbol is a thumb function the final relocation must set the lowest | |||
761 | // bit. With a symbol that is done by just having the symbol have that bit | |||
762 | // set, so we would lose the bit if we relocated with the section. | |||
763 | // FIXME: We could use the section but add the bit to the relocation value. | |||
764 | if (Asm.isThumbFunc(&Sym)) | |||
765 | return true; | |||
766 | ||||
767 | if (TargetObjectWriter->needsRelocateWithSymbol(*SD, Type)) | |||
768 | return true; | |||
769 | return false; | |||
770 | } | |||
771 | ||||
772 | static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { | |||
773 | const MCSymbol &Sym = Ref.getSymbol(); | |||
774 | ||||
775 | if (Ref.getKind() == MCSymbolRefExpr::VK_WEAKREF) | |||
776 | return &Sym; | |||
777 | ||||
778 | if (!Sym.isVariable()) | |||
779 | return nullptr; | |||
780 | ||||
781 | const MCExpr *Expr = Sym.getVariableValue(); | |||
782 | const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr); | |||
783 | if (!Inner) | |||
784 | return nullptr; | |||
785 | ||||
786 | if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) | |||
787 | return &Inner->getSymbol(); | |||
788 | return nullptr; | |||
789 | } | |||
790 | ||||
791 | void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, | |||
792 | const MCAsmLayout &Layout, | |||
793 | const MCFragment *Fragment, | |||
794 | const MCFixup &Fixup, MCValue Target, | |||
795 | bool &IsPCRel, uint64_t &FixedValue) { | |||
796 | const MCSectionData *FixupSection = Fragment->getParent(); | |||
797 | uint64_t C = Target.getConstant(); | |||
798 | uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); | |||
799 | ||||
800 | if (const MCSymbolRefExpr *RefB = Target.getSymB()) { | |||
801 | assert(RefB->getKind() == MCSymbolRefExpr::VK_None &&((RefB->getKind() == MCSymbolRefExpr::VK_None && "Should not have constructed this" ) ? static_cast<void> (0) : __assert_fail ("RefB->getKind() == MCSymbolRefExpr::VK_None && \"Should not have constructed this\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 802, __PRETTY_FUNCTION__)) | |||
802 | "Should not have constructed this")((RefB->getKind() == MCSymbolRefExpr::VK_None && "Should not have constructed this" ) ? static_cast<void> (0) : __assert_fail ("RefB->getKind() == MCSymbolRefExpr::VK_None && \"Should not have constructed this\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 802, __PRETTY_FUNCTION__)); | |||
803 | ||||
804 | // Let A, B and C being the components of Target and R be the location of | |||
805 | // the fixup. If the fixup is not pcrel, we want to compute (A - B + C). | |||
806 | // If it is pcrel, we want to compute (A - B + C - R). | |||
807 | ||||
808 | // In general, ELF has no relocations for -B. It can only represent (A + C) | |||
809 | // or (A + C - R). If B = R + K and the relocation is not pcrel, we can | |||
810 | // replace B to implement it: (A - R - K + C) | |||
811 | if (IsPCRel) | |||
812 | Asm.getContext().FatalError( | |||
813 | Fixup.getLoc(), | |||
814 | "No relocation available to represent this relative expression"); | |||
815 | ||||
816 | const MCSymbol &SymB = RefB->getSymbol(); | |||
817 | ||||
818 | if (SymB.isUndefined()) | |||
819 | Asm.getContext().FatalError( | |||
820 | Fixup.getLoc(), | |||
821 | Twine("symbol '") + SymB.getName() + | |||
822 | "' can not be undefined in a subtraction expression"); | |||
823 | ||||
824 | assert(!SymB.isAbsolute() && "Should have been folded")((!SymB.isAbsolute() && "Should have been folded") ? static_cast <void> (0) : __assert_fail ("!SymB.isAbsolute() && \"Should have been folded\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 824, __PRETTY_FUNCTION__)); | |||
825 | const MCSection &SecB = SymB.getSection(); | |||
826 | if (&SecB != &FixupSection->getSection()) | |||
827 | Asm.getContext().FatalError( | |||
828 | Fixup.getLoc(), "Cannot represent a difference across sections"); | |||
829 | ||||
830 | const MCSymbolData &SymBD = Asm.getSymbolData(SymB); | |||
831 | uint64_t SymBOffset = Layout.getSymbolOffset(&SymBD); | |||
832 | uint64_t K = SymBOffset - FixupOffset; | |||
833 | IsPCRel = true; | |||
834 | C -= K; | |||
835 | } | |||
836 | ||||
837 | // We either rejected the fixup or folded B into C at this point. | |||
838 | const MCSymbolRefExpr *RefA = Target.getSymA(); | |||
839 | const MCSymbol *SymA = RefA ? &RefA->getSymbol() : nullptr; | |||
840 | const MCSymbolData *SymAD = SymA ? &Asm.getSymbolData(*SymA) : nullptr; | |||
841 | ||||
842 | unsigned Type = GetRelocType(Target, Fixup, IsPCRel); | |||
843 | bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymAD, C, Type); | |||
844 | if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) | |||
845 | C += Layout.getSymbolOffset(SymAD); | |||
846 | ||||
847 | uint64_t Addend = 0; | |||
848 | if (hasRelocationAddend()) { | |||
849 | Addend = C; | |||
850 | C = 0; | |||
851 | } | |||
852 | ||||
853 | FixedValue = C; | |||
854 | ||||
855 | // FIXME: What is this!?!? | |||
856 | MCSymbolRefExpr::VariantKind Modifier = | |||
857 | RefA ? RefA->getKind() : MCSymbolRefExpr::VK_None; | |||
858 | if (RelocNeedsGOT(Modifier)) | |||
859 | NeedsGOT = true; | |||
860 | ||||
861 | if (!RelocateWithSymbol) { | |||
862 | const MCSection *SecA = | |||
863 | (SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr; | |||
864 | auto *ELFSec = cast_or_null<MCSectionELF>(SecA); | |||
865 | MCSymbol *SectionSymbol = | |||
866 | ELFSec ? Asm.getContext().getOrCreateSectionSymbol(*ELFSec) | |||
867 | : nullptr; | |||
868 | ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend); | |||
869 | Relocations[FixupSection].push_back(Rec); | |||
870 | return; | |||
871 | } | |||
872 | ||||
873 | if (SymA) { | |||
874 | if (const MCSymbol *R = Renames.lookup(SymA)) | |||
875 | SymA = R; | |||
876 | ||||
877 | if (const MCSymbol *WeakRef = getWeakRef(*RefA)) | |||
878 | WeakrefUsedInReloc.insert(WeakRef); | |||
879 | else | |||
880 | UsedInReloc.insert(SymA); | |||
881 | } | |||
882 | ELFRelocationEntry Rec(FixupOffset, SymA, Type, Addend); | |||
883 | Relocations[FixupSection].push_back(Rec); | |||
884 | return; | |||
885 | } | |||
886 | ||||
887 | ||||
888 | uint64_t | |||
889 | ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, | |||
890 | const MCSymbol *S) { | |||
891 | const MCSymbolData &SD = Asm.getSymbolData(*S); | |||
892 | return SD.getIndex(); | |||
893 | } | |||
894 | ||||
895 | bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout, | |||
896 | const MCSymbolData &Data, bool Used, | |||
897 | bool Renamed) { | |||
898 | const MCSymbol &Symbol = Data.getSymbol(); | |||
899 | if (Symbol.isVariable()) { | |||
900 | const MCExpr *Expr = Symbol.getVariableValue(); | |||
901 | if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) { | |||
902 | if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF) | |||
903 | return false; | |||
904 | } | |||
905 | } | |||
906 | ||||
907 | if (Used) | |||
908 | return true; | |||
909 | ||||
910 | if (Renamed) | |||
911 | return false; | |||
912 | ||||
913 | if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") | |||
914 | return true; | |||
915 | ||||
916 | if (Symbol.isVariable()) { | |||
917 | const MCSymbol *Base = Layout.getBaseSymbol(Symbol); | |||
918 | if (Base && Base->isUndefined()) | |||
919 | return false; | |||
920 | } | |||
921 | ||||
922 | bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; | |||
923 | if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) | |||
924 | return false; | |||
925 | ||||
926 | if (Symbol.isTemporary()) | |||
927 | return false; | |||
928 | ||||
929 | return true; | |||
930 | } | |||
931 | ||||
932 | bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isUsedInReloc) { | |||
933 | if (Data.isExternal()) | |||
934 | return false; | |||
935 | ||||
936 | const MCSymbol &Symbol = Data.getSymbol(); | |||
937 | if (Symbol.isDefined()) | |||
938 | return true; | |||
939 | ||||
940 | if (isUsedInReloc) | |||
941 | return false; | |||
942 | ||||
943 | return true; | |||
944 | } | |||
945 | ||||
946 | void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, | |||
947 | SectionIndexMapTy &SectionIndexMap, | |||
948 | const RelMapTy &RelMap) { | |||
949 | unsigned Index = 1; | |||
950 | for (MCAssembler::iterator it = Asm.begin(), | |||
951 | ie = Asm.end(); it != ie; ++it) { | |||
952 | const MCSectionELF &Section = | |||
953 | static_cast<const MCSectionELF &>(it->getSection()); | |||
954 | if (Section.getType() != ELF::SHT_GROUP) | |||
955 | continue; | |||
956 | SectionIndexMap[&Section] = Index++; | |||
957 | } | |||
958 | ||||
959 | for (MCAssembler::iterator it = Asm.begin(), | |||
960 | ie = Asm.end(); it != ie; ++it) { | |||
961 | const MCSectionELF &Section = | |||
962 | static_cast<const MCSectionELF &>(it->getSection()); | |||
963 | if (Section.getType() == ELF::SHT_GROUP || | |||
964 | Section.getType() == ELF::SHT_REL || | |||
965 | Section.getType() == ELF::SHT_RELA) | |||
966 | continue; | |||
967 | SectionIndexMap[&Section] = Index++; | |||
968 | const MCSectionELF *RelSection = RelMap.lookup(&Section); | |||
969 | if (RelSection) | |||
970 | SectionIndexMap[RelSection] = Index++; | |||
971 | } | |||
972 | } | |||
973 | ||||
974 | void | |||
975 | ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, | |||
976 | const SectionIndexMapTy &SectionIndexMap, | |||
977 | const RevGroupMapTy &RevGroupMap, | |||
978 | unsigned NumRegularSections) { | |||
979 | // FIXME: Is this the correct place to do this? | |||
980 | // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? | |||
981 | if (NeedsGOT) { | |||
982 | StringRef Name = "_GLOBAL_OFFSET_TABLE_"; | |||
983 | MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); | |||
984 | MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); | |||
985 | Data.setExternal(true); | |||
986 | MCELF::SetBinding(Data, ELF::STB_GLOBAL); | |||
987 | } | |||
988 | ||||
989 | // Add the data for the symbols. | |||
990 | for (MCSymbolData &SD : Asm.symbols()) { | |||
991 | const MCSymbol &Symbol = SD.getSymbol(); | |||
992 | ||||
993 | bool Used = UsedInReloc.count(&Symbol); | |||
994 | bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); | |||
995 | bool isSignature = RevGroupMap.count(&Symbol); | |||
996 | ||||
997 | if (!isInSymtab(Layout, SD, | |||
998 | Used || WeakrefUsed || isSignature, | |||
999 | Renames.count(&Symbol))) | |||
1000 | continue; | |||
1001 | ||||
1002 | ELFSymbolData MSD; | |||
1003 | MSD.SymbolData = &SD; | |||
1004 | const MCSymbol *BaseSymbol = Layout.getBaseSymbol(Symbol); | |||
1005 | ||||
1006 | // Undefined symbols are global, but this is the first place we | |||
1007 | // are able to set it. | |||
1008 | bool Local = isLocal(SD, Used); | |||
1009 | if (!Local && MCELF::GetBinding(SD) == ELF::STB_LOCAL) { | |||
1010 | assert(BaseSymbol)((BaseSymbol) ? static_cast<void> (0) : __assert_fail ( "BaseSymbol", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 1010, __PRETTY_FUNCTION__)); | |||
1011 | MCSymbolData &BaseData = Asm.getSymbolData(*BaseSymbol); | |||
1012 | MCELF::SetBinding(SD, ELF::STB_GLOBAL); | |||
1013 | MCELF::SetBinding(BaseData, ELF::STB_GLOBAL); | |||
1014 | } | |||
1015 | ||||
1016 | if (!BaseSymbol) { | |||
1017 | MSD.SectionIndex = ELF::SHN_ABS; | |||
1018 | } else if (SD.isCommon()) { | |||
1019 | assert(!Local)((!Local) ? static_cast<void> (0) : __assert_fail ("!Local" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 1019, __PRETTY_FUNCTION__)); | |||
1020 | MSD.SectionIndex = ELF::SHN_COMMON; | |||
1021 | } else if (BaseSymbol->isUndefined()) { | |||
1022 | if (isSignature && !Used) | |||
1023 | MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap.lookup(&Symbol)); | |||
1024 | else | |||
1025 | MSD.SectionIndex = ELF::SHN_UNDEF; | |||
1026 | if (!Used && WeakrefUsed) | |||
1027 | MCELF::SetBinding(SD, ELF::STB_WEAK); | |||
1028 | } else { | |||
1029 | const MCSectionELF &Section = | |||
1030 | static_cast<const MCSectionELF&>(BaseSymbol->getSection()); | |||
1031 | MSD.SectionIndex = SectionIndexMap.lookup(&Section); | |||
1032 | assert(MSD.SectionIndex && "Invalid section index!")((MSD.SectionIndex && "Invalid section index!") ? static_cast <void> (0) : __assert_fail ("MSD.SectionIndex && \"Invalid section index!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 1032, __PRETTY_FUNCTION__)); | |||
1033 | } | |||
1034 | ||||
1035 | // The @@@ in symbol version is replaced with @ in undefined symbols and @@ | |||
1036 | // in defined ones. | |||
1037 | // | |||
1038 | // FIXME: All name handling should be done before we get to the writer, | |||
1039 | // including dealing with GNU-style version suffixes. Fixing this isn’t | |||
1040 | // trivial. | |||
1041 | // | |||
1042 | // We thus have to be careful to not perform the symbol version replacement | |||
1043 | // blindly: | |||
1044 | // | |||
1045 | // The ELF format is used on Windows by the MCJIT engine. Thus, on | |||
1046 | // Windows, the ELFObjectWriter can encounter symbols mangled using the MS | |||
1047 | // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC | |||
1048 | // C++ name mangling can legally have "@@@" as a sub-string. In that case, | |||
1049 | // the EFLObjectWriter should not interpret the "@@@" sub-string as | |||
1050 | // specifying GNU-style symbol versioning. The ELFObjectWriter therefore | |||
1051 | // checks for the MSVC C++ name mangling prefix which is either "?", "@?", | |||
1052 | // "__imp_?" or "__imp_@?". | |||
1053 | // | |||
1054 | // It would have been interesting to perform the MS mangling prefix check | |||
1055 | // only when the target triple is of the form *-pc-windows-elf. But, it | |||
1056 | // seems that this information is not easily accessible from the | |||
1057 | // ELFObjectWriter. | |||
1058 | StringRef Name = Symbol.getName(); | |||
1059 | if (!Name.startswith("?") && !Name.startswith("@?") && | |||
1060 | !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) { | |||
1061 | // This symbol isn't following the MSVC C++ name mangling convention. We | |||
1062 | // can thus safely interpret the @@@ in symbol names as specifying symbol | |||
1063 | // versioning. | |||
1064 | SmallString<32> Buf; | |||
1065 | size_t Pos = Name.find("@@@"); | |||
1066 | if (Pos != StringRef::npos) { | |||
1067 | Buf += Name.substr(0, Pos); | |||
1068 | unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; | |||
1069 | Buf += Name.substr(Pos + Skip); | |||
1070 | Name = Buf; | |||
1071 | } | |||
1072 | } | |||
1073 | ||||
1074 | // Sections have their own string table | |||
1075 | if (MCELF::GetType(SD) != ELF::STT_SECTION) | |||
1076 | MSD.Name = StrTabBuilder.add(Name); | |||
1077 | ||||
1078 | if (MSD.SectionIndex == ELF::SHN_UNDEF) | |||
1079 | UndefinedSymbolData.push_back(MSD); | |||
1080 | else if (Local) | |||
1081 | LocalSymbolData.push_back(MSD); | |||
1082 | else | |||
1083 | ExternalSymbolData.push_back(MSD); | |||
1084 | } | |||
1085 | ||||
1086 | for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) | |||
1087 | StrTabBuilder.add(*i); | |||
1088 | ||||
1089 | StrTabBuilder.finalize(StringTableBuilder::ELF); | |||
1090 | ||||
1091 | for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) | |||
1092 | FileSymbolData.push_back(StrTabBuilder.getOffset(*i)); | |||
1093 | ||||
1094 | for (ELFSymbolData &MSD : LocalSymbolData) | |||
1095 | MSD.StringIndex = MCELF::GetType(*MSD.SymbolData) == ELF::STT_SECTION | |||
1096 | ? 0 | |||
1097 | : StrTabBuilder.getOffset(MSD.Name); | |||
1098 | for (ELFSymbolData &MSD : ExternalSymbolData) | |||
1099 | MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); | |||
1100 | for (ELFSymbolData& MSD : UndefinedSymbolData) | |||
1101 | MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); | |||
1102 | ||||
1103 | // Symbols are required to be in lexicographic order. | |||
1104 | array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); | |||
1105 | array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); | |||
1106 | array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); | |||
1107 | ||||
1108 | // Set the symbol indices. Local symbols must come before all other | |||
1109 | // symbols with non-local bindings. | |||
1110 | unsigned Index = FileSymbolData.size() + 1; | |||
1111 | for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) | |||
1112 | LocalSymbolData[i].SymbolData->setIndex(Index++); | |||
1113 | ||||
1114 | for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) | |||
1115 | ExternalSymbolData[i].SymbolData->setIndex(Index++); | |||
1116 | for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) | |||
1117 | UndefinedSymbolData[i].SymbolData->setIndex(Index++); | |||
1118 | } | |||
1119 | ||||
1120 | void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, | |||
1121 | MCAsmLayout &Layout, | |||
1122 | RelMapTy &RelMap) { | |||
1123 | for (MCAssembler::const_iterator it = Asm.begin(), | |||
1124 | ie = Asm.end(); it != ie; ++it) { | |||
1125 | const MCSectionData &SD = *it; | |||
1126 | if (Relocations[&SD].empty()) | |||
1127 | continue; | |||
1128 | ||||
1129 | MCContext &Ctx = Asm.getContext(); | |||
1130 | const MCSectionELF &Section = | |||
1131 | static_cast<const MCSectionELF&>(SD.getSection()); | |||
1132 | ||||
1133 | const StringRef SectionName = Section.getSectionName(); | |||
1134 | std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; | |||
1135 | RelaSectionName += SectionName; | |||
1136 | ||||
1137 | unsigned EntrySize; | |||
1138 | if (hasRelocationAddend()) | |||
1139 | EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); | |||
1140 | else | |||
1141 | EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); | |||
1142 | ||||
1143 | unsigned Flags = 0; | |||
1144 | StringRef Group = ""; | |||
1145 | if (Section.getFlags() & ELF::SHF_GROUP) { | |||
1146 | Flags = ELF::SHF_GROUP; | |||
1147 | Group = Section.getGroup()->getName(); | |||
1148 | } | |||
1149 | ||||
1150 | const MCSectionELF *RelaSection = | |||
1151 | Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? | |||
1152 | ELF::SHT_RELA : ELF::SHT_REL, Flags, | |||
1153 | EntrySize, Group); | |||
1154 | RelMap[&Section] = RelaSection; | |||
1155 | Asm.getOrCreateSectionData(*RelaSection); | |||
1156 | } | |||
1157 | } | |||
1158 | ||||
1159 | static SmallVector<char, 128> | |||
1160 | getUncompressedData(MCAsmLayout &Layout, | |||
1161 | MCSectionData::FragmentListType &Fragments) { | |||
1162 | SmallVector<char, 128> UncompressedData; | |||
1163 | for (const MCFragment &F : Fragments) { | |||
1164 | const SmallVectorImpl<char> *Contents; | |||
1165 | switch (F.getKind()) { | |||
1166 | case MCFragment::FT_Data: | |||
1167 | Contents = &cast<MCDataFragment>(F).getContents(); | |||
1168 | break; | |||
1169 | case MCFragment::FT_Dwarf: | |||
1170 | Contents = &cast<MCDwarfLineAddrFragment>(F).getContents(); | |||
1171 | break; | |||
1172 | case MCFragment::FT_DwarfFrame: | |||
1173 | Contents = &cast<MCDwarfCallFrameFragment>(F).getContents(); | |||
1174 | break; | |||
1175 | default: | |||
1176 | llvm_unreachable(::llvm::llvm_unreachable_internal("Not expecting any other fragment types in a debug_* section" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 1177) | |||
1177 | "Not expecting any other fragment types in a debug_* section")::llvm::llvm_unreachable_internal("Not expecting any other fragment types in a debug_* section" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 1177); | |||
1178 | } | |||
1179 | UncompressedData.append(Contents->begin(), Contents->end()); | |||
1180 | } | |||
1181 | return UncompressedData; | |||
1182 | } | |||
1183 | ||||
1184 | // Include the debug info compression header: | |||
1185 | // "ZLIB" followed by 8 bytes representing the uncompressed size of the section, | |||
1186 | // useful for consumers to preallocate a buffer to decompress into. | |||
1187 | static bool | |||
1188 | prependCompressionHeader(uint64_t Size, | |||
1189 | SmallVectorImpl<char> &CompressedContents) { | |||
1190 | static const StringRef Magic = "ZLIB"; | |||
1191 | if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) | |||
1192 | return false; | |||
1193 | if (sys::IsLittleEndianHost) | |||
1194 | sys::swapByteOrder(Size); | |||
1195 | CompressedContents.insert(CompressedContents.begin(), | |||
1196 | Magic.size() + sizeof(Size), 0); | |||
1197 | std::copy(Magic.begin(), Magic.end(), CompressedContents.begin()); | |||
1198 | std::copy(reinterpret_cast<char *>(&Size), | |||
1199 | reinterpret_cast<char *>(&Size + 1), | |||
1200 | CompressedContents.begin() + Magic.size()); | |||
1201 | return true; | |||
1202 | } | |||
1203 | ||||
1204 | // Return a single fragment containing the compressed contents of the whole | |||
1205 | // section. Null if the section was not compressed for any reason. | |||
1206 | static std::unique_ptr<MCDataFragment> | |||
1207 | getCompressedFragment(MCAsmLayout &Layout, | |||
1208 | MCSectionData::FragmentListType &Fragments) { | |||
1209 | std::unique_ptr<MCDataFragment> CompressedFragment(new MCDataFragment()); | |||
1210 | ||||
1211 | // Gather the uncompressed data from all the fragments, recording the | |||
1212 | // alignment fragment, if seen, and any fixups. | |||
1213 | SmallVector<char, 128> UncompressedData = | |||
1214 | getUncompressedData(Layout, Fragments); | |||
1215 | ||||
1216 | SmallVectorImpl<char> &CompressedContents = CompressedFragment->getContents(); | |||
1217 | ||||
1218 | zlib::Status Success = zlib::compress( | |||
1219 | StringRef(UncompressedData.data(), UncompressedData.size()), | |||
1220 | CompressedContents); | |||
1221 | if (Success != zlib::StatusOK) | |||
1222 | return nullptr; | |||
1223 | ||||
1224 | if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) | |||
1225 | return nullptr; | |||
1226 | ||||
1227 | return CompressedFragment; | |||
1228 | } | |||
1229 | ||||
1230 | typedef DenseMap<const MCSectionData *, std::vector<MCSymbolData *>> | |||
1231 | DefiningSymbolMap; | |||
1232 | ||||
1233 | static void UpdateSymbols(const MCAsmLayout &Layout, | |||
1234 | const std::vector<MCSymbolData *> &Symbols, | |||
1235 | MCFragment &NewFragment) { | |||
1236 | for (MCSymbolData *Sym : Symbols) { | |||
1237 | Sym->setOffset(Sym->getOffset() + | |||
1238 | Layout.getFragmentOffset(Sym->getFragment())); | |||
1239 | Sym->setFragment(&NewFragment); | |||
1240 | } | |||
1241 | } | |||
1242 | ||||
1243 | static void CompressDebugSection(MCAssembler &Asm, MCAsmLayout &Layout, | |||
1244 | const DefiningSymbolMap &DefiningSymbols, | |||
1245 | const MCSectionELF &Section, | |||
1246 | MCSectionData &SD) { | |||
1247 | StringRef SectionName = Section.getSectionName(); | |||
1248 | MCSectionData::FragmentListType &Fragments = SD.getFragmentList(); | |||
1249 | ||||
1250 | std::unique_ptr<MCDataFragment> CompressedFragment = | |||
1251 | getCompressedFragment(Layout, Fragments); | |||
1252 | ||||
1253 | // Leave the section as-is if the fragments could not be compressed. | |||
1254 | if (!CompressedFragment) | |||
1255 | return; | |||
1256 | ||||
1257 | // Update the fragment+offsets of any symbols referring to fragments in this | |||
1258 | // section to refer to the new fragment. | |||
1259 | auto I = DefiningSymbols.find(&SD); | |||
1260 | if (I != DefiningSymbols.end()) | |||
1261 | UpdateSymbols(Layout, I->second, *CompressedFragment); | |||
1262 | ||||
1263 | // Invalidate the layout for the whole section since it will have new and | |||
1264 | // different fragments now. | |||
1265 | Layout.invalidateFragmentsFrom(&Fragments.front()); | |||
1266 | Fragments.clear(); | |||
1267 | ||||
1268 | // Complete the initialization of the new fragment | |||
1269 | CompressedFragment->setParent(&SD); | |||
1270 | CompressedFragment->setLayoutOrder(0); | |||
1271 | Fragments.push_back(CompressedFragment.release()); | |||
1272 | ||||
1273 | // Rename from .debug_* to .zdebug_* | |||
1274 | Asm.getContext().renameELFSection(&Section, | |||
1275 | (".z" + SectionName.drop_front(1)).str()); | |||
1276 | } | |||
1277 | ||||
1278 | void ELFObjectWriter::CompressDebugSections(MCAssembler &Asm, | |||
1279 | MCAsmLayout &Layout) { | |||
1280 | if (!Asm.getContext().getAsmInfo()->compressDebugSections()) | |||
1281 | return; | |||
1282 | ||||
1283 | DefiningSymbolMap DefiningSymbols; | |||
1284 | ||||
1285 | for (MCSymbolData &SD : Asm.symbols()) | |||
1286 | if (MCFragment *F = SD.getFragment()) | |||
1287 | DefiningSymbols[F->getParent()].push_back(&SD); | |||
1288 | ||||
1289 | for (MCSectionData &SD : Asm) { | |||
1290 | const MCSectionELF &Section = | |||
1291 | static_cast<const MCSectionELF &>(SD.getSection()); | |||
1292 | StringRef SectionName = Section.getSectionName(); | |||
1293 | ||||
1294 | // Compressing debug_frame requires handling alignment fragments which is | |||
1295 | // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow | |||
1296 | // for writing to arbitrary buffers) for little benefit. | |||
1297 | if (!SectionName.startswith(".debug_") || SectionName == ".debug_frame") | |||
1298 | continue; | |||
1299 | ||||
1300 | CompressDebugSection(Asm, Layout, DefiningSymbols, Section, SD); | |||
1301 | } | |||
1302 | } | |||
1303 | ||||
1304 | void ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, | |||
1305 | const RelMapTy &RelMap) { | |||
1306 | for (MCAssembler::const_iterator it = Asm.begin(), | |||
| ||||
1307 | ie = Asm.end(); it != ie; ++it) { | |||
| ||||
1308 | const MCSectionData &SD = *it; | |||
1309 | const MCSectionELF &Section = | |||
1310 | static_cast<const MCSectionELF&>(SD.getSection()); | |||
1311 | ||||
1312 | const MCSectionELF *RelaSection = RelMap.lookup(&Section); | |||
1313 | if (!RelaSection) | |||
1314 | continue; | |||
1315 | MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); | |||
1316 | RelaSD.setAlignment(is64Bit() ? 8 : 4); | |||
1317 | ||||
1318 | MCDataFragment *F = new MCDataFragment(&RelaSD); | |||
1319 | WriteRelocationsFragment(Asm, F, &*it); | |||
1320 | } | |||
1321 | } | |||
1322 | ||||
1323 | void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, | |||
1324 | uint64_t Flags, uint64_t Address, | |||
1325 | uint64_t Offset, uint64_t Size, | |||
1326 | uint32_t Link, uint32_t Info, | |||
1327 | uint64_t Alignment, | |||
1328 | uint64_t EntrySize) { | |||
1329 | Write32(Name); // sh_name: index into string table | |||
1330 | Write32(Type); // sh_type | |||
1331 | WriteWord(Flags); // sh_flags | |||
1332 | WriteWord(Address); // sh_addr | |||
1333 | WriteWord(Offset); // sh_offset | |||
1334 | WriteWord(Size); // sh_size | |||
1335 | Write32(Link); // sh_link | |||
1336 | Write32(Info); // sh_info | |||
1337 | WriteWord(Alignment); // sh_addralign | |||
1338 | WriteWord(EntrySize); // sh_entsize | |||
1339 | } | |||
1340 | ||||
1341 | // ELF doesn't require relocations to be in any order. We sort by the r_offset, | |||
1342 | // just to match gnu as for easier comparison. The use type is an arbitrary way | |||
1343 | // of making the sort deterministic. | |||
1344 | static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) { | |||
1345 | const ELFRelocationEntry &A = *AP; | |||
1346 | const ELFRelocationEntry &B = *BP; | |||
1347 | if (A.Offset != B.Offset) | |||
1348 | return B.Offset - A.Offset; | |||
1349 | if (B.Type != A.Type) | |||
1350 | return A.Type - B.Type; | |||
1351 | llvm_unreachable("ELFRelocs might be unstable!")::llvm::llvm_unreachable_internal("ELFRelocs might be unstable!" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 1351); | |||
1352 | } | |||
1353 | ||||
1354 | static void sortRelocs(const MCAssembler &Asm, | |||
1355 | std::vector<ELFRelocationEntry> &Relocs) { | |||
1356 | array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel); | |||
1357 | } | |||
1358 | ||||
1359 | void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, | |||
1360 | MCDataFragment *F, | |||
1361 | const MCSectionData *SD) { | |||
1362 | std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; | |||
1363 | ||||
1364 | sortRelocs(Asm, Relocs); | |||
1365 | ||||
1366 | for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { | |||
1367 | const ELFRelocationEntry &Entry = Relocs[e - i - 1]; | |||
1368 | unsigned Index = | |||
1369 | Entry.Symbol ? getSymbolIndexInSymbolTable(Asm, Entry.Symbol) : 0; | |||
1370 | ||||
1371 | if (is64Bit()) { | |||
1372 | write(*F, Entry.Offset); | |||
1373 | if (TargetObjectWriter->isN64()) { | |||
1374 | write(*F, uint32_t(Index)); | |||
1375 | ||||
1376 | write(*F, TargetObjectWriter->getRSsym(Entry.Type)); | |||
1377 | write(*F, TargetObjectWriter->getRType3(Entry.Type)); | |||
1378 | write(*F, TargetObjectWriter->getRType2(Entry.Type)); | |||
1379 | write(*F, TargetObjectWriter->getRType(Entry.Type)); | |||
1380 | } else { | |||
1381 | struct ELF::Elf64_Rela ERE64; | |||
1382 | ERE64.setSymbolAndType(Index, Entry.Type); | |||
1383 | write(*F, ERE64.r_info); | |||
1384 | } | |||
1385 | if (hasRelocationAddend()) | |||
1386 | write(*F, Entry.Addend); | |||
1387 | } else { | |||
1388 | write(*F, uint32_t(Entry.Offset)); | |||
1389 | ||||
1390 | struct ELF::Elf32_Rela ERE32; | |||
1391 | ERE32.setSymbolAndType(Index, Entry.Type); | |||
1392 | write(*F, ERE32.r_info); | |||
1393 | ||||
1394 | if (hasRelocationAddend()) | |||
1395 | write(*F, uint32_t(Entry.Addend)); | |||
1396 | } | |||
1397 | } | |||
1398 | } | |||
1399 | ||||
1400 | void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, | |||
1401 | MCAsmLayout &Layout, | |||
1402 | SectionIndexMapTy &SectionIndexMap, | |||
1403 | const RelMapTy &RelMap) { | |||
1404 | MCContext &Ctx = Asm.getContext(); | |||
1405 | MCDataFragment *F; | |||
1406 | ||||
1407 | unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; | |||
1408 | ||||
1409 | // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. | |||
1410 | const MCSectionELF *ShstrtabSection = | |||
1411 | Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0); | |||
1412 | MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); | |||
1413 | ShstrtabSD.setAlignment(1); | |||
1414 | ||||
1415 | const MCSectionELF *SymtabSection = | |||
1416 | Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, | |||
1417 | EntrySize, ""); | |||
1418 | MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); | |||
1419 | SymtabSD.setAlignment(is64Bit() ? 8 : 4); | |||
1420 | ||||
1421 | const MCSectionELF *StrtabSection; | |||
1422 | StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0); | |||
1423 | MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); | |||
1424 | StrtabSD.setAlignment(1); | |||
1425 | ||||
1426 | ComputeIndexMap(Asm, SectionIndexMap, RelMap); | |||
1427 | ||||
1428 | ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); | |||
1429 | SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); | |||
1430 | StringTableIndex = SectionIndexMap.lookup(StrtabSection); | |||
1431 | ||||
1432 | // Symbol table | |||
1433 | F = new MCDataFragment(&SymtabSD); | |||
1434 | WriteSymbolTable(F, Asm, Layout, SectionIndexMap); | |||
1435 | ||||
1436 | F = new MCDataFragment(&StrtabSD); | |||
1437 | F->getContents().append(StrTabBuilder.data().begin(), | |||
1438 | StrTabBuilder.data().end()); | |||
1439 | ||||
1440 | F = new MCDataFragment(&ShstrtabSD); | |||
1441 | ||||
1442 | // Section header string table. | |||
1443 | for (auto it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { | |||
1444 | const MCSectionELF &Section = | |||
1445 | static_cast<const MCSectionELF&>(it->getSection()); | |||
1446 | ShStrTabBuilder.add(Section.getSectionName()); | |||
1447 | } | |||
1448 | ShStrTabBuilder.finalize(StringTableBuilder::ELF); | |||
1449 | F->getContents().append(ShStrTabBuilder.data().begin(), | |||
1450 | ShStrTabBuilder.data().end()); | |||
1451 | } | |||
1452 | ||||
1453 | void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, | |||
1454 | MCAsmLayout &Layout, | |||
1455 | GroupMapTy &GroupMap, | |||
1456 | RevGroupMapTy &RevGroupMap, | |||
1457 | SectionIndexMapTy &SectionIndexMap, | |||
1458 | const RelMapTy &RelMap) { | |||
1459 | MCContext &Ctx = Asm.getContext(); | |||
1460 | ||||
1461 | // Build the groups | |||
1462 | for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); | |||
1463 | it != ie; ++it) { | |||
1464 | const MCSectionELF &Section = | |||
1465 | static_cast<const MCSectionELF&>(it->getSection()); | |||
1466 | if (!(Section.getFlags() & ELF::SHF_GROUP)) | |||
1467 | continue; | |||
1468 | ||||
1469 | const MCSymbol *SignatureSymbol = Section.getGroup(); | |||
1470 | Asm.getOrCreateSymbolData(*SignatureSymbol); | |||
1471 | const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; | |||
1472 | if (!Group) { | |||
1473 | Group = Ctx.CreateELFGroupSection(); | |||
1474 | MCSectionData &Data = Asm.getOrCreateSectionData(*Group); | |||
1475 | Data.setAlignment(4); | |||
1476 | MCDataFragment *F = new MCDataFragment(&Data); | |||
1477 | write(*F, uint32_t(ELF::GRP_COMDAT)); | |||
1478 | } | |||
1479 | GroupMap[Group] = SignatureSymbol; | |||
1480 | } | |||
1481 | ||||
1482 | ComputeIndexMap(Asm, SectionIndexMap, RelMap); | |||
1483 | ||||
1484 | // Add sections to the groups | |||
1485 | for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); | |||
1486 | it != ie; ++it) { | |||
1487 | const MCSectionELF &Section = | |||
1488 | static_cast<const MCSectionELF&>(it->getSection()); | |||
1489 | if (!(Section.getFlags() & ELF::SHF_GROUP)) | |||
1490 | continue; | |||
1491 | const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; | |||
1492 | MCSectionData &Data = Asm.getOrCreateSectionData(*Group); | |||
1493 | // FIXME: we could use the previous fragment | |||
1494 | MCDataFragment *F = new MCDataFragment(&Data); | |||
1495 | uint32_t Index = SectionIndexMap.lookup(&Section); | |||
1496 | write(*F, Index); | |||
1497 | } | |||
1498 | } | |||
1499 | ||||
1500 | void ELFObjectWriter::WriteSection(MCAssembler &Asm, | |||
1501 | const SectionIndexMapTy &SectionIndexMap, | |||
1502 | uint32_t GroupSymbolIndex, | |||
1503 | uint64_t Offset, uint64_t Size, | |||
1504 | uint64_t Alignment, | |||
1505 | const MCSectionELF &Section) { | |||
1506 | uint64_t sh_link = 0; | |||
1507 | uint64_t sh_info = 0; | |||
1508 | ||||
1509 | switch(Section.getType()) { | |||
1510 | case ELF::SHT_DYNAMIC: | |||
1511 | sh_link = ShStrTabBuilder.getOffset(Section.getSectionName()); | |||
1512 | sh_info = 0; | |||
1513 | break; | |||
1514 | ||||
1515 | case ELF::SHT_REL: | |||
1516 | case ELF::SHT_RELA: { | |||
1517 | const MCSectionELF *SymtabSection; | |||
1518 | const MCSectionELF *InfoSection; | |||
1519 | SymtabSection = | |||
1520 | Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 0); | |||
1521 | sh_link = SectionIndexMap.lookup(SymtabSection); | |||
1522 | assert(sh_link && ".symtab not found")((sh_link && ".symtab not found") ? static_cast<void > (0) : __assert_fail ("sh_link && \".symtab not found\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 1522, __PRETTY_FUNCTION__)); | |||
1523 | ||||
1524 | // Remove ".rel" and ".rela" prefixes. | |||
1525 | unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; | |||
1526 | StringRef SectionName = Section.getSectionName().substr(SecNameLen); | |||
1527 | StringRef GroupName = | |||
1528 | Section.getGroup() ? Section.getGroup()->getName() : ""; | |||
1529 | ||||
1530 | InfoSection = Asm.getContext().getELFSection(SectionName, ELF::SHT_PROGBITS, | |||
1531 | 0, 0, GroupName); | |||
1532 | sh_info = SectionIndexMap.lookup(InfoSection); | |||
1533 | break; | |||
1534 | } | |||
1535 | ||||
1536 | case ELF::SHT_SYMTAB: | |||
1537 | case ELF::SHT_DYNSYM: | |||
1538 | sh_link = StringTableIndex; | |||
1539 | sh_info = LastLocalSymbolIndex; | |||
1540 | break; | |||
1541 | ||||
1542 | case ELF::SHT_SYMTAB_SHNDX: | |||
1543 | sh_link = SymbolTableIndex; | |||
1544 | break; | |||
1545 | ||||
1546 | case ELF::SHT_PROGBITS: | |||
1547 | case ELF::SHT_STRTAB: | |||
1548 | case ELF::SHT_NOBITS: | |||
1549 | case ELF::SHT_NOTE: | |||
1550 | case ELF::SHT_NULL: | |||
1551 | case ELF::SHT_ARM_ATTRIBUTES: | |||
1552 | case ELF::SHT_INIT_ARRAY: | |||
1553 | case ELF::SHT_FINI_ARRAY: | |||
1554 | case ELF::SHT_PREINIT_ARRAY: | |||
1555 | case ELF::SHT_X86_64_UNWIND: | |||
1556 | case ELF::SHT_MIPS_REGINFO: | |||
1557 | case ELF::SHT_MIPS_OPTIONS: | |||
1558 | case ELF::SHT_MIPS_ABIFLAGS: | |||
1559 | // Nothing to do. | |||
1560 | break; | |||
1561 | ||||
1562 | case ELF::SHT_GROUP: | |||
1563 | sh_link = SymbolTableIndex; | |||
1564 | sh_info = GroupSymbolIndex; | |||
1565 | break; | |||
1566 | ||||
1567 | default: | |||
1568 | llvm_unreachable("FIXME: sh_type value not supported!")::llvm::llvm_unreachable_internal("FIXME: sh_type value not supported!" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 1568); | |||
1569 | } | |||
1570 | ||||
1571 | if (TargetObjectWriter->getEMachine() == ELF::EM_ARM && | |||
1572 | Section.getType() == ELF::SHT_ARM_EXIDX) { | |||
1573 | StringRef SecName(Section.getSectionName()); | |||
1574 | if (SecName == ".ARM.exidx") { | |||
1575 | sh_link = SectionIndexMap.lookup(Asm.getContext().getELFSection( | |||
1576 | ".text", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC)); | |||
1577 | } else if (SecName.startswith(".ARM.exidx")) { | |||
1578 | StringRef GroupName = | |||
1579 | Section.getGroup() ? Section.getGroup()->getName() : ""; | |||
1580 | sh_link = SectionIndexMap.lookup(Asm.getContext().getELFSection( | |||
1581 | SecName.substr(sizeof(".ARM.exidx") - 1), ELF::SHT_PROGBITS, | |||
1582 | ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, 0, GroupName)); | |||
1583 | } | |||
1584 | } | |||
1585 | ||||
1586 | WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()), | |||
1587 | Section.getType(), | |||
1588 | Section.getFlags(), 0, Offset, Size, sh_link, sh_info, | |||
1589 | Alignment, Section.getEntrySize()); | |||
1590 | } | |||
1591 | ||||
1592 | bool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { | |||
1593 | return SD.getOrdinal() == ~UINT32_C(0)0U && | |||
1594 | !SD.getSection().isVirtualSection(); | |||
1595 | } | |||
1596 | ||||
1597 | uint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { | |||
1598 | uint64_t Ret = 0; | |||
1599 | for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; | |||
1600 | ++i) { | |||
1601 | const MCFragment &F = *i; | |||
1602 | assert(F.getKind() == MCFragment::FT_Data)((F.getKind() == MCFragment::FT_Data) ? static_cast<void> (0) : __assert_fail ("F.getKind() == MCFragment::FT_Data", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 1602, __PRETTY_FUNCTION__)); | |||
1603 | Ret += cast<MCDataFragment>(F).getContents().size(); | |||
1604 | } | |||
1605 | return Ret; | |||
1606 | } | |||
1607 | ||||
1608 | uint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, | |||
1609 | const MCSectionData &SD) { | |||
1610 | if (IsELFMetaDataSection(SD)) | |||
1611 | return DataSectionSize(SD); | |||
1612 | return Layout.getSectionFileSize(&SD); | |||
1613 | } | |||
1614 | ||||
1615 | uint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, | |||
1616 | const MCSectionData &SD) { | |||
1617 | if (IsELFMetaDataSection(SD)) | |||
1618 | return DataSectionSize(SD); | |||
1619 | return Layout.getSectionAddressSize(&SD); | |||
1620 | } | |||
1621 | ||||
1622 | void ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, | |||
1623 | const MCAsmLayout &Layout, | |||
1624 | const MCSectionELF &Section) { | |||
1625 | const MCSectionData &SD = Asm.getOrCreateSectionData(Section); | |||
1626 | ||||
1627 | uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment()); | |||
1628 | WriteZeros(Padding); | |||
1629 | ||||
1630 | if (IsELFMetaDataSection(SD)) { | |||
1631 | for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; | |||
1632 | ++i) { | |||
1633 | const MCFragment &F = *i; | |||
1634 | assert(F.getKind() == MCFragment::FT_Data)((F.getKind() == MCFragment::FT_Data) ? static_cast<void> (0) : __assert_fail ("F.getKind() == MCFragment::FT_Data", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn228872/lib/MC/ELFObjectWriter.cpp" , 1634, __PRETTY_FUNCTION__)); | |||
1635 | WriteBytes(cast<MCDataFragment>(F).getContents()); | |||
1636 | } | |||
1637 | } else { | |||
1638 | Asm.writeSectionData(&SD, Layout); | |||
1639 | } | |||
1640 | } | |||
1641 | ||||
1642 | void ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, | |||
1643 | const GroupMapTy &GroupMap, | |||
1644 | const MCAsmLayout &Layout, | |||
1645 | const SectionIndexMapTy &SectionIndexMap, | |||
1646 | const SectionOffsetMapTy &SectionOffsetMap) { | |||
1647 | const unsigned NumSections = Asm.size() + 1; | |||
1648 | ||||
1649 | std::vector<const MCSectionELF*> Sections; | |||
1650 | Sections.resize(NumSections - 1); | |||
1651 | ||||
1652 | for (SectionIndexMapTy::const_iterator i= | |||
1653 | SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { | |||
1654 | const std::pair<const MCSectionELF*, uint32_t> &p = *i; | |||
1655 | Sections[p.second - 1] = p.first; | |||
1656 | } | |||
1657 | ||||
1658 | // Null section first. | |||
1659 | uint64_t FirstSectionSize = | |||
1660 | NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; | |||
1661 | uint32_t FirstSectionLink = | |||
1662 | ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; | |||
1663 | WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); | |||
1664 | ||||
1665 | for (unsigned i = 0; i < NumSections - 1; ++i) { | |||
1666 | const MCSectionELF &Section = *Sections[i]; | |||
1667 | const MCSectionData &SD = Asm.getOrCreateSectionData(Section); | |||
1668 | uint32_t GroupSymbolIndex; | |||
1669 | if (Section.getType() != ELF::SHT_GROUP) | |||
1670 | GroupSymbolIndex = 0; | |||
1671 | else | |||
1672 | GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, | |||
1673 | GroupMap.lookup(&Section)); | |||
1674 | ||||
1675 | uint64_t Size = GetSectionAddressSize(Layout, SD); | |||
1676 | ||||
1677 | WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, | |||
1678 | SectionOffsetMap.lookup(&Section), Size, | |||
1679 | SD.getAlignment(), Section); | |||
1680 | } | |||
1681 | } | |||
1682 | ||||
1683 | void ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, | |||
1684 | std::vector<const MCSectionELF*> &Sections) { | |||
1685 | for (MCAssembler::iterator it = Asm.begin(), | |||
1686 | ie = Asm.end(); it != ie; ++it) { | |||
1687 | const MCSectionELF &Section = | |||
1688 | static_cast<const MCSectionELF &>(it->getSection()); | |||
1689 | if (Section.getType() == ELF::SHT_GROUP) | |||
1690 | Sections.push_back(&Section); | |||
1691 | } | |||
1692 | ||||
1693 | for (MCAssembler::iterator it = Asm.begin(), | |||
1694 | ie = Asm.end(); it != ie; ++it) { | |||
1695 | const MCSectionELF &Section = | |||
1696 | static_cast<const MCSectionELF &>(it->getSection()); | |||
1697 | if (Section.getType() != ELF::SHT_GROUP && | |||
1698 | Section.getType() != ELF::SHT_REL && | |||
1699 | Section.getType() != ELF::SHT_RELA) | |||
1700 | Sections.push_back(&Section); | |||
1701 | } | |||
1702 | ||||
1703 | for (MCAssembler::iterator it = Asm.begin(), | |||
1704 | ie = Asm.end(); it != ie; ++it) { | |||
1705 | const MCSectionELF &Section = | |||
1706 | static_cast<const MCSectionELF &>(it->getSection()); | |||
1707 | if (Section.getType() == ELF::SHT_REL || | |||
1708 | Section.getType() == ELF::SHT_RELA) | |||
1709 | Sections.push_back(&Section); | |||
1710 | } | |||
1711 | } | |||
1712 | ||||
1713 | void ELFObjectWriter::WriteObject(MCAssembler &Asm, | |||
1714 | const MCAsmLayout &Layout) { | |||
1715 | GroupMapTy GroupMap; | |||
1716 | RevGroupMapTy RevGroupMap; | |||
1717 | SectionIndexMapTy SectionIndexMap; | |||
1718 | ||||
1719 | unsigned NumUserSections = Asm.size(); | |||
1720 | ||||
1721 | CompressDebugSections(Asm, const_cast<MCAsmLayout &>(Layout)); | |||
1722 | ||||
1723 | DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; | |||
1724 | CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); | |||
1725 | ||||
1726 | const unsigned NumUserAndRelocSections = Asm.size(); | |||
1727 | CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, | |||
1728 | RevGroupMap, SectionIndexMap, RelMap); | |||
1729 | const unsigned AllSections = Asm.size(); | |||
1730 | const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; | |||
1731 | ||||
1732 | unsigned NumRegularSections = NumUserSections + NumIndexedSections; | |||
1733 | ||||
1734 | // Compute symbol table information. | |||
1735 | computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap, | |||
1736 | NumRegularSections); | |||
1737 | ||||
1738 | WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); | |||
1739 | ||||
1740 | CreateMetadataSections(const_cast<MCAssembler&>(Asm), | |||
1741 | const_cast<MCAsmLayout&>(Layout), | |||
1742 | SectionIndexMap, | |||
1743 | RelMap); | |||
1744 | ||||
1745 | uint64_t NaturalAlignment = is64Bit() ? 8 : 4; | |||
1746 | uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : | |||
1747 | sizeof(ELF::Elf32_Ehdr); | |||
1748 | uint64_t FileOff = HeaderSize; | |||
1749 | ||||
1750 | std::vector<const MCSectionELF*> Sections; | |||
1751 | ComputeSectionOrder(Asm, Sections); | |||
1752 | unsigned NumSections = Sections.size(); | |||
1753 | SectionOffsetMapTy SectionOffsetMap; | |||
1754 | for (unsigned i = 0; i < NumRegularSections + 1; ++i) { | |||
1755 | const MCSectionELF &Section = *Sections[i]; | |||
1756 | const MCSectionData &SD = Asm.getOrCreateSectionData(Section); | |||
1757 | ||||
1758 | FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); | |||
1759 | ||||
1760 | // Remember the offset into the file for this section. | |||
1761 | SectionOffsetMap[&Section] = FileOff; | |||
1762 | ||||
1763 | // Get the size of the section in the output file (including padding). | |||
1764 | FileOff += GetSectionFileSize(Layout, SD); | |||
1765 | } | |||
1766 | ||||
1767 | FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); | |||
1768 | ||||
1769 | const unsigned SectionHeaderOffset = FileOff - HeaderSize; | |||
1770 | ||||
1771 | uint64_t SectionHeaderEntrySize = is64Bit() ? | |||
1772 | sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); | |||
1773 | FileOff += (NumSections + 1) * SectionHeaderEntrySize; | |||
1774 | ||||
1775 | for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { | |||
1776 | const MCSectionELF &Section = *Sections[i]; | |||
1777 | const MCSectionData &SD = Asm.getOrCreateSectionData(Section); | |||
1778 | ||||
1779 | FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); | |||
1780 | ||||
1781 | // Remember the offset into the file for this section. | |||
1782 | SectionOffsetMap[&Section] = FileOff; | |||
1783 | ||||
1784 | // Get the size of the section in the output file (including padding). | |||
1785 | FileOff += GetSectionFileSize(Layout, SD); | |||
1786 | } | |||
1787 | ||||
1788 | // Write out the ELF header ... | |||
1789 | WriteHeader(Asm, SectionHeaderOffset, NumSections + 1); | |||
1790 | ||||
1791 | // ... then the regular sections ... | |||
1792 | // + because of .shstrtab | |||
1793 | for (unsigned i = 0; i < NumRegularSections + 1; ++i) | |||
1794 | WriteDataSectionData(Asm, Layout, *Sections[i]); | |||
1795 | ||||
1796 | uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment); | |||
1797 | WriteZeros(Padding); | |||
1798 | ||||
1799 | // ... then the section header table ... | |||
1800 | WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, | |||
1801 | SectionOffsetMap); | |||
1802 | ||||
1803 | // ... and then the remaining sections ... | |||
1804 | for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) | |||
1805 | WriteDataSectionData(Asm, Layout, *Sections[i]); | |||
1806 | } | |||
1807 | ||||
1808 | bool | |||
1809 | ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, | |||
1810 | const MCSymbolData &DataA, | |||
1811 | const MCFragment &FB, | |||
1812 | bool InSet, | |||
1813 | bool IsPCRel) const { | |||
1814 | if (DataA.getFlags() & ELF_STB_Weak || MCELF::GetType(DataA) == ELF::STT_GNU_IFUNC) | |||
1815 | return false; | |||
1816 | return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( | |||
1817 | Asm, DataA, FB,InSet, IsPCRel); | |||
1818 | } | |||
1819 | ||||
1820 | MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, | |||
1821 | raw_ostream &OS, | |||
1822 | bool IsLittleEndian) { | |||
1823 | return new ELFObjectWriter(MOTW, OS, IsLittleEndian); | |||
1824 | } |