File: | lib/MC/ELFObjectWriter.cpp |
Location: | line 1407, column 5 |
Description: | Value stored to 'ComputedSymtab' is never read |
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 | |
45 | typedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy; |
46 | |
47 | class ELFObjectWriter; |
48 | |
49 | class SymbolTableWriter { |
50 | ELFObjectWriter &EWriter; |
51 | bool Is64Bit; |
52 | |
53 | // indexes we are going to write to .symtab_shndx. |
54 | std::vector<uint32_t> ShndxIndexes; |
55 | |
56 | // The numbel of symbols written so far. |
57 | unsigned NumWritten; |
58 | |
59 | void createSymtabShndx(); |
60 | |
61 | template <typename T> void write(T Value); |
62 | |
63 | public: |
64 | SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit); |
65 | |
66 | void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size, |
67 | uint8_t other, uint32_t shndx, bool Reserved); |
68 | |
69 | ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; } |
70 | }; |
71 | |
72 | class ELFObjectWriter : public MCObjectWriter { |
73 | static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); |
74 | static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant); |
75 | static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout); |
76 | static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbol &Symbol, |
77 | bool Used, bool Renamed); |
78 | static bool isLocal(const MCSymbol &Symbol, bool isUsedInReloc); |
79 | |
80 | /// Helper struct for containing some precomputed information on symbols. |
81 | struct ELFSymbolData { |
82 | const MCSymbol *Symbol; |
83 | uint64_t StringIndex; |
84 | uint32_t SectionIndex; |
85 | StringRef Name; |
86 | |
87 | // Support lexicographic sorting. |
88 | bool operator<(const ELFSymbolData &RHS) const { |
89 | unsigned LHSType = MCELF::GetType(Symbol->getData()); |
90 | unsigned RHSType = MCELF::GetType(RHS.Symbol->getData()); |
91 | if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION) |
92 | return false; |
93 | if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION) |
94 | return true; |
95 | if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION) |
96 | return SectionIndex < RHS.SectionIndex; |
97 | return Name < RHS.Name; |
98 | } |
99 | }; |
100 | |
101 | /// The target specific ELF writer instance. |
102 | std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter; |
103 | |
104 | SmallPtrSet<const MCSymbol *, 16> UsedInReloc; |
105 | SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; |
106 | DenseMap<const MCSymbol *, const MCSymbol *> Renames; |
107 | |
108 | llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> |
109 | Relocations; |
110 | StringTableBuilder ShStrTabBuilder; |
111 | |
112 | /// @} |
113 | /// @name Symbol Table Data |
114 | /// @{ |
115 | |
116 | StringTableBuilder StrTabBuilder; |
117 | std::vector<uint64_t> FileSymbolData; |
118 | std::vector<ELFSymbolData> LocalSymbolData; |
119 | std::vector<ELFSymbolData> ExternalSymbolData; |
120 | std::vector<ELFSymbolData> UndefinedSymbolData; |
121 | |
122 | /// @} |
123 | |
124 | bool NeedsGOT; |
125 | |
126 | // This holds the symbol table index of the last local symbol. |
127 | unsigned LastLocalSymbolIndex; |
128 | // This holds the .strtab section index. |
129 | unsigned StringTableIndex; |
130 | // This holds the .symtab section index. |
131 | unsigned SymbolTableIndex; |
132 | |
133 | unsigned ShstrtabIndex; |
134 | |
135 | // Sections in the order they are to be output in the section table. |
136 | std::vector<MCSectionELF *> SectionTable; |
137 | unsigned addToSectionTable(MCSectionELF *Sec); |
138 | |
139 | // TargetObjectWriter wrappers. |
140 | bool is64Bit() const { return TargetObjectWriter->is64Bit(); } |
141 | bool hasRelocationAddend() const { |
142 | return TargetObjectWriter->hasRelocationAddend(); |
143 | } |
144 | unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, |
145 | bool IsPCRel) const { |
146 | return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel); |
147 | } |
148 | |
149 | public: |
150 | ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS, |
151 | bool IsLittleEndian) |
152 | : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW), |
153 | NeedsGOT(false) {} |
154 | |
155 | void reset() override { |
156 | UsedInReloc.clear(); |
157 | WeakrefUsedInReloc.clear(); |
158 | Renames.clear(); |
159 | Relocations.clear(); |
160 | ShStrTabBuilder.clear(); |
161 | StrTabBuilder.clear(); |
162 | FileSymbolData.clear(); |
163 | LocalSymbolData.clear(); |
164 | ExternalSymbolData.clear(); |
165 | UndefinedSymbolData.clear(); |
166 | NeedsGOT = false; |
167 | SectionTable.clear(); |
168 | MCObjectWriter::reset(); |
169 | } |
170 | |
171 | ~ELFObjectWriter() override; |
172 | |
173 | void WriteWord(uint64_t W) { |
174 | if (is64Bit()) |
175 | Write64(W); |
176 | else |
177 | Write32(W); |
178 | } |
179 | |
180 | template <typename T> void write(T Val) { |
181 | if (IsLittleEndian) |
182 | support::endian::Writer<support::little>(OS).write(Val); |
183 | else |
184 | support::endian::Writer<support::big>(OS).write(Val); |
185 | } |
186 | |
187 | void writeHeader(const MCAssembler &Asm); |
188 | |
189 | void WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, |
190 | const MCAsmLayout &Layout); |
191 | |
192 | // Start and end offset of each section |
193 | typedef std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>> |
194 | SectionOffsetsTy; |
195 | |
196 | void writeSymbolTable(MCContext &Ctx, const MCAsmLayout &Layout, |
197 | SectionOffsetsTy &SectionOffsets); |
198 | |
199 | bool shouldRelocateWithSymbol(const MCAssembler &Asm, |
200 | const MCSymbolRefExpr *RefA, |
201 | const MCSymbol *Sym, uint64_t C, |
202 | unsigned Type) const; |
203 | |
204 | void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, |
205 | const MCFragment *Fragment, const MCFixup &Fixup, |
206 | MCValue Target, bool &IsPCRel, |
207 | uint64_t &FixedValue) override; |
208 | |
209 | uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, |
210 | const MCSymbol *S); |
211 | |
212 | // Map from a signature symbol to the group section index |
213 | typedef DenseMap<const MCSymbol *, unsigned> RevGroupMapTy; |
214 | |
215 | /// Compute the symbol table data |
216 | /// |
217 | /// \param Asm - The assembler. |
218 | /// \param SectionIndexMap - Maps a section to its index. |
219 | /// \param RevGroupMap - Maps a signature symbol to the group section. |
220 | void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, |
221 | const SectionIndexMapTy &SectionIndexMap, |
222 | const RevGroupMapTy &RevGroupMap); |
223 | |
224 | MCSectionELF *createRelocationSection(MCAssembler &Asm, |
225 | const MCSectionELF &Sec); |
226 | |
227 | const MCSectionELF *createSectionHeaderStringTable(); |
228 | const MCSectionELF *createStringTable(MCContext &Ctx); |
229 | |
230 | void ExecutePostLayoutBinding(MCAssembler &Asm, |
231 | const MCAsmLayout &Layout) override; |
232 | |
233 | void writeSectionHeader(const MCAssembler &Asm, const MCAsmLayout &Layout, |
234 | const SectionIndexMapTy &SectionIndexMap, |
235 | const SectionOffsetsTy &SectionOffsets); |
236 | |
237 | void writeSectionData(const MCAssembler &Asm, const MCSectionData &SD, |
238 | const MCAsmLayout &Layout); |
239 | |
240 | void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, |
241 | uint64_t Address, uint64_t Offset, uint64_t Size, |
242 | uint32_t Link, uint32_t Info, uint64_t Alignment, |
243 | uint64_t EntrySize); |
244 | |
245 | void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec); |
246 | |
247 | bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, |
248 | const MCSymbol &SymA, |
249 | const MCFragment &FB, |
250 | bool InSet, |
251 | bool IsPCRel) const override; |
252 | |
253 | bool isWeak(const MCSymbol &Sym) const override; |
254 | |
255 | void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; |
256 | void writeSection(const SectionIndexMapTy &SectionIndexMap, |
257 | uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size, |
258 | const MCSectionELF &Section); |
259 | }; |
260 | } |
261 | |
262 | unsigned ELFObjectWriter::addToSectionTable(MCSectionELF *Sec) { |
263 | SectionTable.push_back(Sec); |
264 | ShStrTabBuilder.add(Sec->getSectionName()); |
265 | return SectionTable.size(); |
266 | } |
267 | |
268 | void SymbolTableWriter::createSymtabShndx() { |
269 | if (!ShndxIndexes.empty()) |
270 | return; |
271 | |
272 | ShndxIndexes.resize(NumWritten); |
273 | } |
274 | |
275 | template <typename T> void SymbolTableWriter::write(T Value) { |
276 | EWriter.write(Value); |
277 | } |
278 | |
279 | SymbolTableWriter::SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit) |
280 | : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {} |
281 | |
282 | void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value, |
283 | uint64_t size, uint8_t other, |
284 | uint32_t shndx, bool Reserved) { |
285 | bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved; |
286 | |
287 | if (LargeIndex) |
288 | createSymtabShndx(); |
289 | |
290 | if (!ShndxIndexes.empty()) { |
291 | if (LargeIndex) |
292 | ShndxIndexes.push_back(shndx); |
293 | else |
294 | ShndxIndexes.push_back(0); |
295 | } |
296 | |
297 | uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx; |
298 | |
299 | if (Is64Bit) { |
300 | write(name); // st_name |
301 | write(info); // st_info |
302 | write(other); // st_other |
303 | write(Index); // st_shndx |
304 | write(value); // st_value |
305 | write(size); // st_size |
306 | } else { |
307 | write(name); // st_name |
308 | write(uint32_t(value)); // st_value |
309 | write(uint32_t(size)); // st_size |
310 | write(info); // st_info |
311 | write(other); // st_other |
312 | write(Index); // st_shndx |
313 | } |
314 | |
315 | ++NumWritten; |
316 | } |
317 | |
318 | bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { |
319 | const MCFixupKindInfo &FKI = |
320 | Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); |
321 | |
322 | return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; |
323 | } |
324 | |
325 | bool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { |
326 | switch (Variant) { |
327 | default: |
328 | return false; |
329 | case MCSymbolRefExpr::VK_GOT: |
330 | case MCSymbolRefExpr::VK_PLT: |
331 | case MCSymbolRefExpr::VK_GOTPCREL: |
332 | case MCSymbolRefExpr::VK_GOTOFF: |
333 | case MCSymbolRefExpr::VK_TPOFF: |
334 | case MCSymbolRefExpr::VK_TLSGD: |
335 | case MCSymbolRefExpr::VK_GOTTPOFF: |
336 | case MCSymbolRefExpr::VK_INDNTPOFF: |
337 | case MCSymbolRefExpr::VK_NTPOFF: |
338 | case MCSymbolRefExpr::VK_GOTNTPOFF: |
339 | case MCSymbolRefExpr::VK_TLSLDM: |
340 | case MCSymbolRefExpr::VK_DTPOFF: |
341 | case MCSymbolRefExpr::VK_TLSLD: |
342 | return true; |
343 | } |
344 | } |
345 | |
346 | ELFObjectWriter::~ELFObjectWriter() |
347 | {} |
348 | |
349 | // Emit the ELF header. |
350 | void ELFObjectWriter::writeHeader(const MCAssembler &Asm) { |
351 | // ELF Header |
352 | // ---------- |
353 | // |
354 | // Note |
355 | // ---- |
356 | // emitWord method behaves differently for ELF32 and ELF64, writing |
357 | // 4 bytes in the former and 8 in the latter. |
358 | |
359 | WriteBytes(ELF::ElfMagic); // e_ident[EI_MAG0] to e_ident[EI_MAG3] |
360 | |
361 | Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] |
362 | |
363 | // e_ident[EI_DATA] |
364 | Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); |
365 | |
366 | Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] |
367 | // e_ident[EI_OSABI] |
368 | Write8(TargetObjectWriter->getOSABI()); |
369 | Write8(0); // e_ident[EI_ABIVERSION] |
370 | |
371 | WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); |
372 | |
373 | Write16(ELF::ET_REL); // e_type |
374 | |
375 | Write16(TargetObjectWriter->getEMachine()); // e_machine = target |
376 | |
377 | Write32(ELF::EV_CURRENT); // e_version |
378 | WriteWord(0); // e_entry, no entry point in .o file |
379 | WriteWord(0); // e_phoff, no program header for .o |
380 | WriteWord(0); // e_shoff = sec hdr table off in bytes |
381 | |
382 | // e_flags = whatever the target wants |
383 | Write32(Asm.getELFHeaderEFlags()); |
384 | |
385 | // e_ehsize = ELF header size |
386 | Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); |
387 | |
388 | Write16(0); // e_phentsize = prog header entry size |
389 | Write16(0); // e_phnum = # prog header entries = 0 |
390 | |
391 | // e_shentsize = Section header entry size |
392 | Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); |
393 | |
394 | // e_shnum = # of section header ents |
395 | Write16(0); |
396 | |
397 | // e_shstrndx = Section # of '.shstrtab' |
398 | assert(ShstrtabIndex < ELF::SHN_LORESERVE)((ShstrtabIndex < ELF::SHN_LORESERVE) ? static_cast<void > (0) : __assert_fail ("ShstrtabIndex < ELF::SHN_LORESERVE" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 398, __PRETTY_FUNCTION__)); |
399 | Write16(ShstrtabIndex); |
400 | } |
401 | |
402 | uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym, |
403 | const MCAsmLayout &Layout) { |
404 | MCSymbolData &Data = Sym.getData(); |
405 | if (Data.isCommon() && Data.isExternal()) |
406 | return Data.getCommonAlignment(); |
407 | |
408 | uint64_t Res; |
409 | if (!Layout.getSymbolOffset(Sym, Res)) |
410 | return 0; |
411 | |
412 | if (Layout.getAssembler().isThumbFunc(&Sym)) |
413 | Res |= 1; |
414 | |
415 | return Res; |
416 | } |
417 | |
418 | void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, |
419 | const MCAsmLayout &Layout) { |
420 | // The presence of symbol versions causes undefined symbols and |
421 | // versions declared with @@@ to be renamed. |
422 | |
423 | for (const MCSymbol &Alias : Asm.symbols()) { |
424 | MCSymbolData &OriginalData = Alias.getData(); |
425 | |
426 | // Not an alias. |
427 | if (!Alias.isVariable()) |
428 | continue; |
429 | auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue()); |
430 | if (!Ref) |
431 | continue; |
432 | const MCSymbol &Symbol = Ref->getSymbol(); |
433 | MCSymbolData &SD = Asm.getSymbolData(Symbol); |
434 | |
435 | StringRef AliasName = Alias.getName(); |
436 | size_t Pos = AliasName.find('@'); |
437 | if (Pos == StringRef::npos) |
438 | continue; |
439 | |
440 | // Aliases defined with .symvar copy the binding from the symbol they alias. |
441 | // This is the first place we are able to copy this information. |
442 | OriginalData.setExternal(SD.isExternal()); |
443 | MCELF::SetBinding(OriginalData, MCELF::GetBinding(SD)); |
444 | |
445 | StringRef Rest = AliasName.substr(Pos); |
446 | if (!Symbol.isUndefined() && !Rest.startswith("@@@")) |
447 | continue; |
448 | |
449 | // FIXME: produce a better error message. |
450 | if (Symbol.isUndefined() && Rest.startswith("@@") && |
451 | !Rest.startswith("@@@")) |
452 | report_fatal_error("A @@ version cannot be undefined"); |
453 | |
454 | Renames.insert(std::make_pair(&Symbol, &Alias)); |
455 | } |
456 | } |
457 | |
458 | static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { |
459 | uint8_t Type = newType; |
460 | |
461 | // Propagation rules: |
462 | // IFUNC > FUNC > OBJECT > NOTYPE |
463 | // TLS_OBJECT > OBJECT > NOTYPE |
464 | // |
465 | // dont let the new type degrade the old type |
466 | switch (origType) { |
467 | default: |
468 | break; |
469 | case ELF::STT_GNU_IFUNC: |
470 | if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT || |
471 | Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS) |
472 | Type = ELF::STT_GNU_IFUNC; |
473 | break; |
474 | case ELF::STT_FUNC: |
475 | if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || |
476 | Type == ELF::STT_TLS) |
477 | Type = ELF::STT_FUNC; |
478 | break; |
479 | case ELF::STT_OBJECT: |
480 | if (Type == ELF::STT_NOTYPE) |
481 | Type = ELF::STT_OBJECT; |
482 | break; |
483 | case ELF::STT_TLS: |
484 | if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || |
485 | Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC) |
486 | Type = ELF::STT_TLS; |
487 | break; |
488 | } |
489 | |
490 | return Type; |
491 | } |
492 | |
493 | void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, |
494 | const MCAsmLayout &Layout) { |
495 | MCSymbolData &OrigData = MSD.Symbol->getData(); |
496 | assert((!OrigData.getFragment() ||(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &MSD.Symbol->getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &MSD.Symbol->getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 499, __PRETTY_FUNCTION__)) |
497 | (&OrigData.getFragment()->getParent()->getSection() ==(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &MSD.Symbol->getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &MSD.Symbol->getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 499, __PRETTY_FUNCTION__)) |
498 | &MSD.Symbol->getSection())) &&(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &MSD.Symbol->getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &MSD.Symbol->getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 499, __PRETTY_FUNCTION__)) |
499 | "The symbol's section doesn't match the fragment's symbol")(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &MSD.Symbol->getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &MSD.Symbol->getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 499, __PRETTY_FUNCTION__)); |
500 | const MCSymbol *Base = Layout.getBaseSymbol(*MSD.Symbol); |
501 | |
502 | // This has to be in sync with when computeSymbolTable uses SHN_ABS or |
503 | // SHN_COMMON. |
504 | bool IsReserved = !Base || OrigData.isCommon(); |
505 | |
506 | // Binding and Type share the same byte as upper and lower nibbles |
507 | uint8_t Binding = MCELF::GetBinding(OrigData); |
508 | uint8_t Type = MCELF::GetType(OrigData); |
509 | MCSymbolData *BaseSD = nullptr; |
510 | if (Base) { |
511 | BaseSD = &Layout.getAssembler().getSymbolData(*Base); |
512 | Type = mergeTypeForSet(Type, MCELF::GetType(*BaseSD)); |
513 | } |
514 | uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); |
515 | |
516 | // Other and Visibility share the same byte with Visibility using the lower |
517 | // 2 bits |
518 | uint8_t Visibility = MCELF::GetVisibility(OrigData); |
519 | uint8_t Other = MCELF::getOther(OrigData) << (ELF_STO_Shift - ELF_STV_Shift); |
520 | Other |= Visibility; |
521 | |
522 | uint64_t Value = SymbolValue(*MSD.Symbol, Layout); |
523 | uint64_t Size = 0; |
524 | |
525 | const MCExpr *ESize = OrigData.getSize(); |
526 | if (!ESize && Base) |
527 | ESize = BaseSD->getSize(); |
528 | |
529 | if (ESize) { |
530 | int64_t Res; |
531 | if (!ESize->evaluateKnownAbsolute(Res, Layout)) |
532 | report_fatal_error("Size expression must be absolute."); |
533 | Size = Res; |
534 | } |
535 | |
536 | // Write out the symbol table entry |
537 | Writer.writeSymbol(MSD.StringIndex, Info, Value, Size, Other, |
538 | MSD.SectionIndex, IsReserved); |
539 | } |
540 | |
541 | void ELFObjectWriter::writeSymbolTable(MCContext &Ctx, |
542 | const MCAsmLayout &Layout, |
543 | SectionOffsetsTy &SectionOffsets) { |
544 | unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; |
545 | |
546 | // Symbol table |
547 | MCSectionELF *SymtabSection = |
548 | Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, ""); |
549 | SymtabSection->setAlignment(is64Bit() ? 8 : 4); |
550 | SymbolTableIndex = addToSectionTable(SymtabSection); |
551 | |
552 | // The string table must be emitted first because we need the index |
553 | // into the string table for all the symbol names. |
554 | |
555 | SymbolTableWriter Writer(*this, is64Bit()); |
556 | |
557 | uint64_t Padding = |
558 | OffsetToAlignment(OS.tell(), SymtabSection->getAlignment()); |
559 | WriteZeros(Padding); |
560 | |
561 | uint64_t SecStart = OS.tell(); |
562 | |
563 | // The first entry is the undefined symbol entry. |
564 | Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); |
565 | |
566 | for (unsigned i = 0, e = FileSymbolData.size(); i != e; ++i) { |
567 | Writer.writeSymbol(FileSymbolData[i], ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, |
568 | ELF::STV_DEFAULT, ELF::SHN_ABS, true); |
569 | } |
570 | |
571 | // Write the symbol table entries. |
572 | LastLocalSymbolIndex = FileSymbolData.size() + LocalSymbolData.size() + 1; |
573 | |
574 | for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { |
575 | ELFSymbolData &MSD = LocalSymbolData[i]; |
576 | WriteSymbol(Writer, MSD, Layout); |
577 | } |
578 | |
579 | for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { |
580 | ELFSymbolData &MSD = ExternalSymbolData[i]; |
581 | MCSymbolData &Data = MSD.Symbol->getData(); |
582 | 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~svn237945/lib/MC/ELFObjectWriter.cpp" , 584, __PRETTY_FUNCTION__)) |
583 | (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~svn237945/lib/MC/ELFObjectWriter.cpp" , 584, __PRETTY_FUNCTION__)) |
584 | "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~svn237945/lib/MC/ELFObjectWriter.cpp" , 584, __PRETTY_FUNCTION__)); |
585 | WriteSymbol(Writer, MSD, Layout); |
586 | if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) |
587 | LastLocalSymbolIndex++; |
588 | } |
589 | |
590 | for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { |
591 | ELFSymbolData &MSD = UndefinedSymbolData[i]; |
592 | MCSymbolData &Data = MSD.Symbol->getData(); |
593 | WriteSymbol(Writer, MSD, Layout); |
594 | if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) |
595 | LastLocalSymbolIndex++; |
596 | } |
597 | |
598 | uint64_t SecEnd = OS.tell(); |
599 | SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd); |
600 | |
601 | ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes(); |
602 | if (ShndxIndexes.empty()) |
603 | return; |
604 | |
605 | SecStart = OS.tell(); |
606 | MCSectionELF *SymtabShndxSection = |
607 | Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, ""); |
608 | addToSectionTable(SymtabShndxSection); |
609 | SymtabShndxSection->setAlignment(4); |
610 | for (uint32_t Index : ShndxIndexes) |
611 | write(Index); |
612 | SecEnd = OS.tell(); |
613 | SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd); |
614 | } |
615 | |
616 | // It is always valid to create a relocation with a symbol. It is preferable |
617 | // to use a relocation with a section if that is possible. Using the section |
618 | // allows us to omit some local symbols from the symbol table. |
619 | bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, |
620 | const MCSymbolRefExpr *RefA, |
621 | const MCSymbol *Sym, uint64_t C, |
622 | unsigned Type) const { |
623 | MCSymbolData *SD = Sym ? &Sym->getData() : nullptr; |
624 | |
625 | // A PCRel relocation to an absolute value has no symbol (or section). We |
626 | // represent that with a relocation to a null section. |
627 | if (!RefA) |
628 | return false; |
629 | |
630 | MCSymbolRefExpr::VariantKind Kind = RefA->getKind(); |
631 | switch (Kind) { |
632 | default: |
633 | break; |
634 | // The .odp creation emits a relocation against the symbol ".TOC." which |
635 | // create a R_PPC64_TOC relocation. However the relocation symbol name |
636 | // in final object creation should be NULL, since the symbol does not |
637 | // really exist, it is just the reference to TOC base for the current |
638 | // object file. Since the symbol is undefined, returning false results |
639 | // in a relocation with a null section which is the desired result. |
640 | case MCSymbolRefExpr::VK_PPC_TOCBASE: |
641 | return false; |
642 | |
643 | // These VariantKind cause the relocation to refer to something other than |
644 | // the symbol itself, like a linker generated table. Since the address of |
645 | // symbol is not relevant, we cannot replace the symbol with the |
646 | // section and patch the difference in the addend. |
647 | case MCSymbolRefExpr::VK_GOT: |
648 | case MCSymbolRefExpr::VK_PLT: |
649 | case MCSymbolRefExpr::VK_GOTPCREL: |
650 | case MCSymbolRefExpr::VK_Mips_GOT: |
651 | case MCSymbolRefExpr::VK_PPC_GOT_LO: |
652 | case MCSymbolRefExpr::VK_PPC_GOT_HI: |
653 | case MCSymbolRefExpr::VK_PPC_GOT_HA: |
654 | return true; |
655 | } |
656 | |
657 | // An undefined symbol is not in any section, so the relocation has to point |
658 | // to the symbol itself. |
659 | assert(Sym && "Expected a symbol")((Sym && "Expected a symbol") ? static_cast<void> (0) : __assert_fail ("Sym && \"Expected a symbol\"", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 659, __PRETTY_FUNCTION__)); |
660 | if (Sym->isUndefined()) |
661 | return true; |
662 | |
663 | unsigned Binding = MCELF::GetBinding(*SD); |
664 | switch(Binding) { |
665 | default: |
666 | llvm_unreachable("Invalid Binding")::llvm::llvm_unreachable_internal("Invalid Binding", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 666); |
667 | case ELF::STB_LOCAL: |
668 | break; |
669 | case ELF::STB_WEAK: |
670 | // If the symbol is weak, it might be overridden by a symbol in another |
671 | // file. The relocation has to point to the symbol so that the linker |
672 | // can update it. |
673 | return true; |
674 | case ELF::STB_GLOBAL: |
675 | // Global ELF symbols can be preempted by the dynamic linker. The relocation |
676 | // has to point to the symbol for a reason analogous to the STB_WEAK case. |
677 | return true; |
678 | } |
679 | |
680 | // If a relocation points to a mergeable section, we have to be careful. |
681 | // If the offset is zero, a relocation with the section will encode the |
682 | // same information. With a non-zero offset, the situation is different. |
683 | // For example, a relocation can point 42 bytes past the end of a string. |
684 | // If we change such a relocation to use the section, the linker would think |
685 | // that it pointed to another string and subtracting 42 at runtime will |
686 | // produce the wrong value. |
687 | auto &Sec = cast<MCSectionELF>(Sym->getSection()); |
688 | unsigned Flags = Sec.getFlags(); |
689 | if (Flags & ELF::SHF_MERGE) { |
690 | if (C != 0) |
691 | return true; |
692 | |
693 | // It looks like gold has a bug (http://sourceware.org/PR16794) and can |
694 | // only handle section relocations to mergeable sections if using RELA. |
695 | if (!hasRelocationAddend()) |
696 | return true; |
697 | } |
698 | |
699 | // Most TLS relocations use a got, so they need the symbol. Even those that |
700 | // are just an offset (@tpoff), require a symbol in gold versions before |
701 | // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed |
702 | // http://sourceware.org/PR16773. |
703 | if (Flags & ELF::SHF_TLS) |
704 | return true; |
705 | |
706 | // If the symbol is a thumb function the final relocation must set the lowest |
707 | // bit. With a symbol that is done by just having the symbol have that bit |
708 | // set, so we would lose the bit if we relocated with the section. |
709 | // FIXME: We could use the section but add the bit to the relocation value. |
710 | if (Asm.isThumbFunc(Sym)) |
711 | return true; |
712 | |
713 | if (TargetObjectWriter->needsRelocateWithSymbol(*SD, Type)) |
714 | return true; |
715 | return false; |
716 | } |
717 | |
718 | static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { |
719 | const MCSymbol &Sym = Ref.getSymbol(); |
720 | |
721 | if (Ref.getKind() == MCSymbolRefExpr::VK_WEAKREF) |
722 | return &Sym; |
723 | |
724 | if (!Sym.isVariable()) |
725 | return nullptr; |
726 | |
727 | const MCExpr *Expr = Sym.getVariableValue(); |
728 | const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr); |
729 | if (!Inner) |
730 | return nullptr; |
731 | |
732 | if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) |
733 | return &Inner->getSymbol(); |
734 | return nullptr; |
735 | } |
736 | |
737 | // True if the assembler knows nothing about the final value of the symbol. |
738 | // This doesn't cover the comdat issues, since in those cases the assembler |
739 | // can at least know that all symbols in the section will move together. |
740 | static bool isWeak(const MCSymbolData &D) { |
741 | if (MCELF::GetType(D) == ELF::STT_GNU_IFUNC) |
742 | return true; |
743 | |
744 | switch (MCELF::GetBinding(D)) { |
745 | default: |
746 | llvm_unreachable("Unknown binding")::llvm::llvm_unreachable_internal("Unknown binding", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 746); |
747 | case ELF::STB_LOCAL: |
748 | return false; |
749 | case ELF::STB_GLOBAL: |
750 | return false; |
751 | case ELF::STB_WEAK: |
752 | case ELF::STB_GNU_UNIQUE: |
753 | return true; |
754 | } |
755 | } |
756 | |
757 | void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, |
758 | const MCAsmLayout &Layout, |
759 | const MCFragment *Fragment, |
760 | const MCFixup &Fixup, MCValue Target, |
761 | bool &IsPCRel, uint64_t &FixedValue) { |
762 | const MCSectionData *FixupSectionD = Fragment->getParent(); |
763 | const MCSectionELF &FixupSection = |
764 | cast<MCSectionELF>(FixupSectionD->getSection()); |
765 | uint64_t C = Target.getConstant(); |
766 | uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); |
767 | |
768 | if (const MCSymbolRefExpr *RefB = Target.getSymB()) { |
769 | 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~svn237945/lib/MC/ELFObjectWriter.cpp" , 770, __PRETTY_FUNCTION__)) |
770 | "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~svn237945/lib/MC/ELFObjectWriter.cpp" , 770, __PRETTY_FUNCTION__)); |
771 | |
772 | // Let A, B and C being the components of Target and R be the location of |
773 | // the fixup. If the fixup is not pcrel, we want to compute (A - B + C). |
774 | // If it is pcrel, we want to compute (A - B + C - R). |
775 | |
776 | // In general, ELF has no relocations for -B. It can only represent (A + C) |
777 | // or (A + C - R). If B = R + K and the relocation is not pcrel, we can |
778 | // replace B to implement it: (A - R - K + C) |
779 | if (IsPCRel) |
780 | Asm.getContext().reportFatalError( |
781 | Fixup.getLoc(), |
782 | "No relocation available to represent this relative expression"); |
783 | |
784 | const MCSymbol &SymB = RefB->getSymbol(); |
785 | |
786 | if (SymB.isUndefined()) |
787 | Asm.getContext().reportFatalError( |
788 | Fixup.getLoc(), |
789 | Twine("symbol '") + SymB.getName() + |
790 | "' can not be undefined in a subtraction expression"); |
791 | |
792 | 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~svn237945/lib/MC/ELFObjectWriter.cpp" , 792, __PRETTY_FUNCTION__)); |
793 | const MCSection &SecB = SymB.getSection(); |
794 | if (&SecB != &FixupSection) |
795 | Asm.getContext().reportFatalError( |
796 | Fixup.getLoc(), "Cannot represent a difference across sections"); |
797 | |
798 | if (::isWeak(SymB.getData())) |
799 | Asm.getContext().reportFatalError( |
800 | Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol"); |
801 | |
802 | uint64_t SymBOffset = Layout.getSymbolOffset(SymB); |
803 | uint64_t K = SymBOffset - FixupOffset; |
804 | IsPCRel = true; |
805 | C -= K; |
806 | } |
807 | |
808 | // We either rejected the fixup or folded B into C at this point. |
809 | const MCSymbolRefExpr *RefA = Target.getSymA(); |
810 | const MCSymbol *SymA = RefA ? &RefA->getSymbol() : nullptr; |
811 | |
812 | unsigned Type = GetRelocType(Target, Fixup, IsPCRel); |
813 | bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type); |
814 | if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) |
815 | C += Layout.getSymbolOffset(*SymA); |
816 | |
817 | uint64_t Addend = 0; |
818 | if (hasRelocationAddend()) { |
819 | Addend = C; |
820 | C = 0; |
821 | } |
822 | |
823 | FixedValue = C; |
824 | |
825 | // FIXME: What is this!?!? |
826 | MCSymbolRefExpr::VariantKind Modifier = |
827 | RefA ? RefA->getKind() : MCSymbolRefExpr::VK_None; |
828 | if (RelocNeedsGOT(Modifier)) |
829 | NeedsGOT = true; |
830 | |
831 | if (!RelocateWithSymbol) { |
832 | const MCSection *SecA = |
833 | (SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr; |
834 | auto *ELFSec = cast_or_null<MCSectionELF>(SecA); |
835 | MCSymbol *SectionSymbol = |
836 | ELFSec ? Asm.getContext().getOrCreateSectionSymbol(*ELFSec) |
837 | : nullptr; |
838 | ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend); |
839 | Relocations[&FixupSection].push_back(Rec); |
840 | return; |
841 | } |
842 | |
843 | if (SymA) { |
844 | if (const MCSymbol *R = Renames.lookup(SymA)) |
845 | SymA = R; |
846 | |
847 | if (const MCSymbol *WeakRef = getWeakRef(*RefA)) |
848 | WeakrefUsedInReloc.insert(WeakRef); |
849 | else |
850 | UsedInReloc.insert(SymA); |
851 | } |
852 | ELFRelocationEntry Rec(FixupOffset, SymA, Type, Addend); |
853 | Relocations[&FixupSection].push_back(Rec); |
854 | return; |
855 | } |
856 | |
857 | |
858 | uint64_t |
859 | ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, |
860 | const MCSymbol *S) { |
861 | const MCSymbolData &SD = Asm.getSymbolData(*S); |
862 | return SD.getIndex(); |
863 | } |
864 | |
865 | bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout, |
866 | const MCSymbol &Symbol, bool Used, |
867 | bool Renamed) { |
868 | const MCSymbolData &Data = Symbol.getData(); |
869 | if (Symbol.isVariable()) { |
870 | const MCExpr *Expr = Symbol.getVariableValue(); |
871 | if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) { |
872 | if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF) |
873 | return false; |
874 | } |
875 | } |
876 | |
877 | if (Used) |
878 | return true; |
879 | |
880 | if (Renamed) |
881 | return false; |
882 | |
883 | if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") |
884 | return true; |
885 | |
886 | if (Symbol.isVariable()) { |
887 | const MCSymbol *Base = Layout.getBaseSymbol(Symbol); |
888 | if (Base && Base->isUndefined()) |
889 | return false; |
890 | } |
891 | |
892 | bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; |
893 | if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) |
894 | return false; |
895 | |
896 | if (Symbol.isTemporary()) |
897 | return false; |
898 | |
899 | return true; |
900 | } |
901 | |
902 | bool ELFObjectWriter::isLocal(const MCSymbol &Symbol, bool isUsedInReloc) { |
903 | const MCSymbolData &Data = Symbol.getData(); |
904 | if (Data.isExternal()) |
905 | return false; |
906 | |
907 | if (Symbol.isDefined()) |
908 | return true; |
909 | |
910 | if (isUsedInReloc) |
911 | return false; |
912 | |
913 | return true; |
914 | } |
915 | |
916 | void ELFObjectWriter::computeSymbolTable( |
917 | MCAssembler &Asm, const MCAsmLayout &Layout, |
918 | const SectionIndexMapTy &SectionIndexMap, |
919 | const RevGroupMapTy &RevGroupMap) { |
920 | // FIXME: Is this the correct place to do this? |
921 | // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? |
922 | if (NeedsGOT) { |
923 | StringRef Name = "_GLOBAL_OFFSET_TABLE_"; |
924 | MCSymbol *Sym = Asm.getContext().getOrCreateSymbol(Name); |
925 | MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); |
926 | Data.setExternal(true); |
927 | MCELF::SetBinding(Data, ELF::STB_GLOBAL); |
928 | } |
929 | |
930 | // Add the data for the symbols. |
931 | for (const MCSymbol &Symbol : Asm.symbols()) { |
932 | MCSymbolData &SD = Symbol.getData(); |
933 | |
934 | bool Used = UsedInReloc.count(&Symbol); |
935 | bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); |
936 | bool isSignature = RevGroupMap.count(&Symbol); |
937 | |
938 | if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature, |
939 | Renames.count(&Symbol))) |
940 | continue; |
941 | |
942 | ELFSymbolData MSD; |
943 | MSD.Symbol = &Symbol; |
944 | const MCSymbol *BaseSymbol = Layout.getBaseSymbol(Symbol); |
945 | |
946 | // Undefined symbols are global, but this is the first place we |
947 | // are able to set it. |
948 | bool Local = isLocal(Symbol, Used); |
949 | if (!Local && MCELF::GetBinding(SD) == ELF::STB_LOCAL) { |
950 | assert(BaseSymbol)((BaseSymbol) ? static_cast<void> (0) : __assert_fail ( "BaseSymbol", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 950, __PRETTY_FUNCTION__)); |
951 | MCSymbolData &BaseData = Asm.getSymbolData(*BaseSymbol); |
952 | MCELF::SetBinding(SD, ELF::STB_GLOBAL); |
953 | MCELF::SetBinding(BaseData, ELF::STB_GLOBAL); |
954 | } |
955 | |
956 | if (!BaseSymbol) { |
957 | MSD.SectionIndex = ELF::SHN_ABS; |
958 | } else if (SD.isCommon()) { |
959 | assert(!Local)((!Local) ? static_cast<void> (0) : __assert_fail ("!Local" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 959, __PRETTY_FUNCTION__)); |
960 | MSD.SectionIndex = ELF::SHN_COMMON; |
961 | } else if (BaseSymbol->isUndefined()) { |
962 | if (isSignature && !Used) |
963 | MSD.SectionIndex = RevGroupMap.lookup(&Symbol); |
964 | else |
965 | MSD.SectionIndex = ELF::SHN_UNDEF; |
966 | if (!Used && WeakrefUsed) |
967 | MCELF::SetBinding(SD, ELF::STB_WEAK); |
968 | } else { |
969 | const MCSectionELF &Section = |
970 | static_cast<const MCSectionELF&>(BaseSymbol->getSection()); |
971 | MSD.SectionIndex = SectionIndexMap.lookup(&Section); |
972 | 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~svn237945/lib/MC/ELFObjectWriter.cpp" , 972, __PRETTY_FUNCTION__)); |
973 | } |
974 | |
975 | // The @@@ in symbol version is replaced with @ in undefined symbols and @@ |
976 | // in defined ones. |
977 | // |
978 | // FIXME: All name handling should be done before we get to the writer, |
979 | // including dealing with GNU-style version suffixes. Fixing this isn't |
980 | // trivial. |
981 | // |
982 | // We thus have to be careful to not perform the symbol version replacement |
983 | // blindly: |
984 | // |
985 | // The ELF format is used on Windows by the MCJIT engine. Thus, on |
986 | // Windows, the ELFObjectWriter can encounter symbols mangled using the MS |
987 | // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC |
988 | // C++ name mangling can legally have "@@@" as a sub-string. In that case, |
989 | // the EFLObjectWriter should not interpret the "@@@" sub-string as |
990 | // specifying GNU-style symbol versioning. The ELFObjectWriter therefore |
991 | // checks for the MSVC C++ name mangling prefix which is either "?", "@?", |
992 | // "__imp_?" or "__imp_@?". |
993 | // |
994 | // It would have been interesting to perform the MS mangling prefix check |
995 | // only when the target triple is of the form *-pc-windows-elf. But, it |
996 | // seems that this information is not easily accessible from the |
997 | // ELFObjectWriter. |
998 | StringRef Name = Symbol.getName(); |
999 | if (!Name.startswith("?") && !Name.startswith("@?") && |
1000 | !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) { |
1001 | // This symbol isn't following the MSVC C++ name mangling convention. We |
1002 | // can thus safely interpret the @@@ in symbol names as specifying symbol |
1003 | // versioning. |
1004 | SmallString<32> Buf; |
1005 | size_t Pos = Name.find("@@@"); |
1006 | if (Pos != StringRef::npos) { |
1007 | Buf += Name.substr(0, Pos); |
1008 | unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; |
1009 | Buf += Name.substr(Pos + Skip); |
1010 | Name = Buf; |
1011 | } |
1012 | } |
1013 | |
1014 | // Sections have their own string table |
1015 | if (MCELF::GetType(SD) != ELF::STT_SECTION) |
1016 | MSD.Name = StrTabBuilder.add(Name); |
1017 | |
1018 | if (MSD.SectionIndex == ELF::SHN_UNDEF) |
1019 | UndefinedSymbolData.push_back(MSD); |
1020 | else if (Local) |
1021 | LocalSymbolData.push_back(MSD); |
1022 | else |
1023 | ExternalSymbolData.push_back(MSD); |
1024 | } |
1025 | |
1026 | for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) |
1027 | StrTabBuilder.add(*i); |
1028 | |
1029 | StrTabBuilder.finalize(StringTableBuilder::ELF); |
1030 | |
1031 | for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) |
1032 | FileSymbolData.push_back(StrTabBuilder.getOffset(*i)); |
1033 | |
1034 | for (ELFSymbolData &MSD : LocalSymbolData) |
1035 | MSD.StringIndex = MCELF::GetType(MSD.Symbol->getData()) == ELF::STT_SECTION |
1036 | ? 0 |
1037 | : StrTabBuilder.getOffset(MSD.Name); |
1038 | for (ELFSymbolData &MSD : ExternalSymbolData) |
1039 | MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); |
1040 | for (ELFSymbolData& MSD : UndefinedSymbolData) |
1041 | MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); |
1042 | |
1043 | // Symbols are required to be in lexicographic order. |
1044 | array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); |
1045 | array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); |
1046 | array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); |
1047 | |
1048 | // Set the symbol indices. Local symbols must come before all other |
1049 | // symbols with non-local bindings. |
1050 | unsigned Index = FileSymbolData.size() + 1; |
1051 | for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) |
1052 | LocalSymbolData[i].Symbol->getData().setIndex(Index++); |
1053 | |
1054 | for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) |
1055 | ExternalSymbolData[i].Symbol->getData().setIndex(Index++); |
1056 | for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) |
1057 | UndefinedSymbolData[i].Symbol->getData().setIndex(Index++); |
1058 | } |
1059 | |
1060 | MCSectionELF * |
1061 | ELFObjectWriter::createRelocationSection(MCAssembler &Asm, |
1062 | const MCSectionELF &Sec) { |
1063 | if (Relocations[&Sec].empty()) |
1064 | return nullptr; |
1065 | |
1066 | MCContext &Ctx = Asm.getContext(); |
1067 | const StringRef SectionName = Sec.getSectionName(); |
1068 | std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; |
1069 | RelaSectionName += SectionName; |
1070 | |
1071 | unsigned EntrySize; |
1072 | if (hasRelocationAddend()) |
1073 | EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); |
1074 | else |
1075 | EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); |
1076 | |
1077 | unsigned Flags = 0; |
1078 | if (Sec.getFlags() & ELF::SHF_GROUP) |
1079 | Flags = ELF::SHF_GROUP; |
1080 | |
1081 | MCSectionELF *RelaSection = Ctx.createELFRelSection( |
1082 | RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL, |
1083 | Flags, EntrySize, Sec.getGroup(), &Sec); |
1084 | MCSectionData &RelSD = Asm.getOrCreateSectionData(*RelaSection); |
1085 | RelSD.setAlignment(is64Bit() ? 8 : 4); |
1086 | return RelaSection; |
1087 | } |
1088 | |
1089 | static SmallVector<char, 128> |
1090 | getUncompressedData(const MCAsmLayout &Layout, |
1091 | const MCSectionData::FragmentListType &Fragments) { |
1092 | SmallVector<char, 128> UncompressedData; |
1093 | for (const MCFragment &F : Fragments) { |
1094 | const SmallVectorImpl<char> *Contents; |
1095 | switch (F.getKind()) { |
1096 | case MCFragment::FT_Data: |
1097 | Contents = &cast<MCDataFragment>(F).getContents(); |
1098 | break; |
1099 | case MCFragment::FT_Dwarf: |
1100 | Contents = &cast<MCDwarfLineAddrFragment>(F).getContents(); |
1101 | break; |
1102 | case MCFragment::FT_DwarfFrame: |
1103 | Contents = &cast<MCDwarfCallFrameFragment>(F).getContents(); |
1104 | break; |
1105 | default: |
1106 | llvm_unreachable(::llvm::llvm_unreachable_internal("Not expecting any other fragment types in a debug_* section" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 1107) |
1107 | "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~svn237945/lib/MC/ELFObjectWriter.cpp" , 1107); |
1108 | } |
1109 | UncompressedData.append(Contents->begin(), Contents->end()); |
1110 | } |
1111 | return UncompressedData; |
1112 | } |
1113 | |
1114 | // Include the debug info compression header: |
1115 | // "ZLIB" followed by 8 bytes representing the uncompressed size of the section, |
1116 | // useful for consumers to preallocate a buffer to decompress into. |
1117 | static bool |
1118 | prependCompressionHeader(uint64_t Size, |
1119 | SmallVectorImpl<char> &CompressedContents) { |
1120 | const StringRef Magic = "ZLIB"; |
1121 | if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) |
1122 | return false; |
1123 | if (sys::IsLittleEndianHost) |
1124 | sys::swapByteOrder(Size); |
1125 | CompressedContents.insert(CompressedContents.begin(), |
1126 | Magic.size() + sizeof(Size), 0); |
1127 | std::copy(Magic.begin(), Magic.end(), CompressedContents.begin()); |
1128 | std::copy(reinterpret_cast<char *>(&Size), |
1129 | reinterpret_cast<char *>(&Size + 1), |
1130 | CompressedContents.begin() + Magic.size()); |
1131 | return true; |
1132 | } |
1133 | |
1134 | void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, |
1135 | const MCSectionData &SD, |
1136 | const MCAsmLayout &Layout) { |
1137 | MCSectionELF &Section = static_cast<MCSectionELF &>(SD.getSection()); |
1138 | StringRef SectionName = Section.getSectionName(); |
1139 | |
1140 | // Compressing debug_frame requires handling alignment fragments which is |
1141 | // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow |
1142 | // for writing to arbitrary buffers) for little benefit. |
1143 | if (!Asm.getContext().getAsmInfo()->compressDebugSections() || |
1144 | !SectionName.startswith(".debug_") || SectionName == ".debug_frame") { |
1145 | Asm.writeSectionData(&SD, Layout); |
1146 | return; |
1147 | } |
1148 | |
1149 | // Gather the uncompressed data from all the fragments. |
1150 | const MCSectionData::FragmentListType &Fragments = SD.getFragmentList(); |
1151 | SmallVector<char, 128> UncompressedData = |
1152 | getUncompressedData(Layout, Fragments); |
1153 | |
1154 | SmallVector<char, 128> CompressedContents; |
1155 | zlib::Status Success = zlib::compress( |
1156 | StringRef(UncompressedData.data(), UncompressedData.size()), |
1157 | CompressedContents); |
1158 | if (Success != zlib::StatusOK) { |
1159 | Asm.writeSectionData(&SD, Layout); |
1160 | return; |
1161 | } |
1162 | |
1163 | if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) { |
1164 | Asm.writeSectionData(&SD, Layout); |
1165 | return; |
1166 | } |
1167 | Asm.getContext().renameELFSection(&Section, |
1168 | (".z" + SectionName.drop_front(1)).str()); |
1169 | OS << CompressedContents; |
1170 | } |
1171 | |
1172 | void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, |
1173 | uint64_t Flags, uint64_t Address, |
1174 | uint64_t Offset, uint64_t Size, |
1175 | uint32_t Link, uint32_t Info, |
1176 | uint64_t Alignment, |
1177 | uint64_t EntrySize) { |
1178 | Write32(Name); // sh_name: index into string table |
1179 | Write32(Type); // sh_type |
1180 | WriteWord(Flags); // sh_flags |
1181 | WriteWord(Address); // sh_addr |
1182 | WriteWord(Offset); // sh_offset |
1183 | WriteWord(Size); // sh_size |
1184 | Write32(Link); // sh_link |
1185 | Write32(Info); // sh_info |
1186 | WriteWord(Alignment); // sh_addralign |
1187 | WriteWord(EntrySize); // sh_entsize |
1188 | } |
1189 | |
1190 | void ELFObjectWriter::writeRelocations(const MCAssembler &Asm, |
1191 | const MCSectionELF &Sec) { |
1192 | std::vector<ELFRelocationEntry> &Relocs = Relocations[&Sec]; |
1193 | |
1194 | // Sort the relocation entries. Most targets just sort by Offset, but some |
1195 | // (e.g., MIPS) have additional constraints. |
1196 | TargetObjectWriter->sortRelocs(Asm, Relocs); |
1197 | |
1198 | for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { |
1199 | const ELFRelocationEntry &Entry = Relocs[e - i - 1]; |
1200 | unsigned Index = |
1201 | Entry.Symbol ? getSymbolIndexInSymbolTable(Asm, Entry.Symbol) : 0; |
1202 | |
1203 | if (is64Bit()) { |
1204 | write(Entry.Offset); |
1205 | if (TargetObjectWriter->isN64()) { |
1206 | write(uint32_t(Index)); |
1207 | |
1208 | write(TargetObjectWriter->getRSsym(Entry.Type)); |
1209 | write(TargetObjectWriter->getRType3(Entry.Type)); |
1210 | write(TargetObjectWriter->getRType2(Entry.Type)); |
1211 | write(TargetObjectWriter->getRType(Entry.Type)); |
1212 | } else { |
1213 | struct ELF::Elf64_Rela ERE64; |
1214 | ERE64.setSymbolAndType(Index, Entry.Type); |
1215 | write(ERE64.r_info); |
1216 | } |
1217 | if (hasRelocationAddend()) |
1218 | write(Entry.Addend); |
1219 | } else { |
1220 | write(uint32_t(Entry.Offset)); |
1221 | |
1222 | struct ELF::Elf32_Rela ERE32; |
1223 | ERE32.setSymbolAndType(Index, Entry.Type); |
1224 | write(ERE32.r_info); |
1225 | |
1226 | if (hasRelocationAddend()) |
1227 | write(uint32_t(Entry.Addend)); |
1228 | } |
1229 | } |
1230 | } |
1231 | |
1232 | const MCSectionELF *ELFObjectWriter::createSectionHeaderStringTable() { |
1233 | const MCSectionELF *ShstrtabSection = SectionTable[ShstrtabIndex - 1]; |
1234 | ShStrTabBuilder.finalize(StringTableBuilder::ELF); |
1235 | OS << ShStrTabBuilder.data(); |
1236 | return ShstrtabSection; |
1237 | } |
1238 | |
1239 | const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) { |
1240 | MCSectionELF *StrtabSection = |
1241 | Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0); |
1242 | StringTableIndex = addToSectionTable(StrtabSection); |
1243 | OS << StrTabBuilder.data(); |
1244 | return StrtabSection; |
1245 | } |
1246 | |
1247 | void ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap, |
1248 | uint32_t GroupSymbolIndex, uint64_t Offset, |
1249 | uint64_t Size, const MCSectionELF &Section) { |
1250 | uint64_t sh_link = 0; |
1251 | uint64_t sh_info = 0; |
1252 | |
1253 | switch(Section.getType()) { |
1254 | default: |
1255 | // Nothing to do. |
1256 | break; |
1257 | |
1258 | case ELF::SHT_DYNAMIC: |
1259 | llvm_unreachable("SHT_DYNAMIC in a relocatable object")::llvm::llvm_unreachable_internal("SHT_DYNAMIC in a relocatable object" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 1259); |
1260 | |
1261 | case ELF::SHT_REL: |
1262 | case ELF::SHT_RELA: { |
1263 | sh_link = SymbolTableIndex; |
1264 | 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~svn237945/lib/MC/ELFObjectWriter.cpp" , 1264, __PRETTY_FUNCTION__)); |
1265 | const MCSectionELF *InfoSection = Section.getAssociatedSection(); |
1266 | sh_info = SectionIndexMap.lookup(InfoSection); |
1267 | break; |
1268 | } |
1269 | |
1270 | case ELF::SHT_SYMTAB: |
1271 | case ELF::SHT_DYNSYM: |
1272 | sh_link = StringTableIndex; |
1273 | sh_info = LastLocalSymbolIndex; |
1274 | break; |
1275 | |
1276 | case ELF::SHT_SYMTAB_SHNDX: |
1277 | sh_link = SymbolTableIndex; |
1278 | break; |
1279 | |
1280 | case ELF::SHT_GROUP: |
1281 | sh_link = SymbolTableIndex; |
1282 | sh_info = GroupSymbolIndex; |
1283 | break; |
1284 | } |
1285 | |
1286 | if (TargetObjectWriter->getEMachine() == ELF::EM_ARM && |
1287 | Section.getType() == ELF::SHT_ARM_EXIDX) |
1288 | sh_link = SectionIndexMap.lookup(Section.getAssociatedSection()); |
1289 | |
1290 | WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()), |
1291 | Section.getType(), Section.getFlags(), 0, Offset, Size, |
1292 | sh_link, sh_info, Section.getAlignment(), |
1293 | Section.getEntrySize()); |
1294 | } |
1295 | |
1296 | void ELFObjectWriter::writeSectionHeader( |
1297 | const MCAssembler &Asm, const MCAsmLayout &Layout, |
1298 | const SectionIndexMapTy &SectionIndexMap, |
1299 | const SectionOffsetsTy &SectionOffsets) { |
1300 | const unsigned NumSections = SectionTable.size(); |
1301 | |
1302 | // Null section first. |
1303 | uint64_t FirstSectionSize = |
1304 | (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0; |
1305 | WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0); |
1306 | |
1307 | for (MCSectionELF *Section : SectionTable) { |
1308 | uint32_t GroupSymbolIndex; |
1309 | unsigned Type = Section->getType(); |
1310 | if (Type != ELF::SHT_GROUP) |
1311 | GroupSymbolIndex = 0; |
1312 | else |
1313 | GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, Section->getGroup()); |
1314 | |
1315 | const std::pair<uint64_t, uint64_t> &Offsets = |
1316 | SectionOffsets.find(Section)->second; |
1317 | uint64_t Size; |
1318 | if (Type == ELF::SHT_NOBITS) { |
1319 | const MCSectionData &SD = Asm.getSectionData(*Section); |
1320 | Size = Layout.getSectionAddressSize(&SD); |
1321 | } else { |
1322 | Size = Offsets.second - Offsets.first; |
1323 | } |
1324 | |
1325 | writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size, |
1326 | *Section); |
1327 | } |
1328 | } |
1329 | |
1330 | void ELFObjectWriter::WriteObject(MCAssembler &Asm, |
1331 | const MCAsmLayout &Layout) { |
1332 | MCContext &Ctx = Asm.getContext(); |
1333 | MCSectionELF *ShstrtabSection = |
1334 | Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0); |
1335 | ShstrtabIndex = addToSectionTable(ShstrtabSection); |
1336 | |
1337 | RevGroupMapTy RevGroupMap; |
1338 | SectionIndexMapTy SectionIndexMap; |
1339 | |
1340 | std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers; |
1341 | |
1342 | // Write out the ELF header ... |
1343 | writeHeader(Asm); |
1344 | |
1345 | // ... then the sections ... |
1346 | SectionOffsetsTy SectionOffsets; |
1347 | bool ComputedSymtab = false; |
1348 | for (const MCSectionData &SD : Asm) { |
1349 | MCSectionELF &Section = static_cast<MCSectionELF &>(SD.getSection()); |
1350 | |
1351 | uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment()); |
1352 | WriteZeros(Padding); |
1353 | |
1354 | // Remember the offset into the file for this section. |
1355 | uint64_t SecStart = OS.tell(); |
1356 | |
1357 | const MCSymbol *SignatureSymbol = Section.getGroup(); |
1358 | unsigned Type = Section.getType(); |
1359 | if (Type == ELF::SHT_GROUP) { |
1360 | assert(SignatureSymbol)((SignatureSymbol) ? static_cast<void> (0) : __assert_fail ("SignatureSymbol", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 1360, __PRETTY_FUNCTION__)); |
1361 | write(uint32_t(ELF::GRP_COMDAT)); |
1362 | for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) { |
1363 | uint32_t SecIndex = SectionIndexMap.lookup(Member); |
1364 | write(SecIndex); |
1365 | } |
1366 | } else if (Type == ELF::SHT_REL || Type == ELF::SHT_RELA) { |
1367 | if (!ComputedSymtab) { |
1368 | // Compute symbol table information. |
1369 | computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap); |
1370 | ComputedSymtab = true; |
1371 | } |
1372 | writeRelocations(Asm, *Section.getAssociatedSection()); |
1373 | } else { |
1374 | writeSectionData(Asm, SD, Layout); |
1375 | } |
1376 | |
1377 | uint64_t SecEnd = OS.tell(); |
1378 | SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd); |
1379 | |
1380 | if (Type == ELF::SHT_GROUP || Type == ELF::SHT_REL || Type == ELF::SHT_RELA) |
1381 | continue; |
1382 | |
1383 | MCSectionELF *RelSection = createRelocationSection(Asm, Section); |
1384 | |
1385 | if (SignatureSymbol) { |
1386 | Asm.getOrCreateSymbolData(*SignatureSymbol); |
1387 | unsigned &GroupIdx = RevGroupMap[SignatureSymbol]; |
1388 | if (!GroupIdx) { |
1389 | MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol); |
1390 | GroupIdx = addToSectionTable(Group); |
1391 | MCSectionData *GroupD = &Asm.getOrCreateSectionData(*Group); |
1392 | GroupD->setAlignment(4); |
1393 | } |
1394 | GroupMembers[SignatureSymbol].push_back(&Section); |
1395 | if (RelSection) |
1396 | GroupMembers[SignatureSymbol].push_back(RelSection); |
1397 | } |
1398 | |
1399 | SectionIndexMap[&Section] = addToSectionTable(&Section); |
1400 | if (RelSection) |
1401 | SectionIndexMap[RelSection] = addToSectionTable(RelSection); |
1402 | } |
1403 | |
1404 | if (!ComputedSymtab) { |
1405 | // Compute symbol table information. |
1406 | computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap); |
1407 | ComputedSymtab = true; |
Value stored to 'ComputedSymtab' is never read | |
1408 | } |
1409 | |
1410 | writeSymbolTable(Ctx, Layout, SectionOffsets); |
1411 | |
1412 | { |
1413 | uint64_t SecStart = OS.tell(); |
1414 | const MCSectionELF *Sec = createStringTable(Ctx); |
1415 | uint64_t SecEnd = OS.tell(); |
1416 | SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd); |
1417 | } |
1418 | |
1419 | { |
1420 | uint64_t SecStart = OS.tell(); |
1421 | const MCSectionELF *Sec = createSectionHeaderStringTable(); |
1422 | uint64_t SecEnd = OS.tell(); |
1423 | SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd); |
1424 | } |
1425 | |
1426 | uint64_t NaturalAlignment = is64Bit() ? 8 : 4; |
1427 | uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment); |
1428 | WriteZeros(Padding); |
1429 | |
1430 | const unsigned SectionHeaderOffset = OS.tell(); |
1431 | |
1432 | // ... then the section header table ... |
1433 | writeSectionHeader(Asm, Layout, SectionIndexMap, SectionOffsets); |
1434 | |
1435 | uint16_t NumSections = (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) |
1436 | ? (uint16_t)ELF::SHN_UNDEF |
1437 | : SectionTable.size() + 1; |
1438 | if (sys::IsLittleEndianHost != IsLittleEndian) |
1439 | sys::swapByteOrder(NumSections); |
1440 | unsigned NumSectionsOffset; |
1441 | |
1442 | if (is64Bit()) { |
1443 | uint64_t Val = SectionHeaderOffset; |
1444 | if (sys::IsLittleEndianHost != IsLittleEndian) |
1445 | sys::swapByteOrder(Val); |
1446 | OS.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), |
1447 | offsetof(ELF::Elf64_Ehdr, e_shoff)__builtin_offsetof(ELF::Elf64_Ehdr, e_shoff)); |
1448 | NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum)__builtin_offsetof(ELF::Elf64_Ehdr, e_shnum); |
1449 | } else { |
1450 | uint32_t Val = SectionHeaderOffset; |
1451 | if (sys::IsLittleEndianHost != IsLittleEndian) |
1452 | sys::swapByteOrder(Val); |
1453 | OS.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), |
1454 | offsetof(ELF::Elf32_Ehdr, e_shoff)__builtin_offsetof(ELF::Elf32_Ehdr, e_shoff)); |
1455 | NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum)__builtin_offsetof(ELF::Elf32_Ehdr, e_shnum); |
1456 | } |
1457 | OS.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections), |
1458 | NumSectionsOffset); |
1459 | } |
1460 | |
1461 | bool ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( |
1462 | const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, |
1463 | bool InSet, bool IsPCRel) const { |
1464 | if (IsPCRel) { |
1465 | assert(!InSet)((!InSet) ? static_cast<void> (0) : __assert_fail ("!InSet" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn237945/lib/MC/ELFObjectWriter.cpp" , 1465, __PRETTY_FUNCTION__)); |
1466 | if (::isWeak(SymA.getData())) |
1467 | return false; |
1468 | } |
1469 | return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB, |
1470 | InSet, IsPCRel); |
1471 | } |
1472 | |
1473 | bool ELFObjectWriter::isWeak(const MCSymbol &Sym) const { |
1474 | const MCSymbolData &SD = Sym.getData(); |
1475 | if (::isWeak(SD)) |
1476 | return true; |
1477 | |
1478 | // It is invalid to replace a reference to a global in a comdat |
1479 | // with a reference to a local since out of comdat references |
1480 | // to a local are forbidden. |
1481 | // We could try to return false for more cases, like the reference |
1482 | // being in the same comdat or Sym being an alias to another global, |
1483 | // but it is not clear if it is worth the effort. |
1484 | if (MCELF::GetBinding(SD) != ELF::STB_GLOBAL) |
1485 | return false; |
1486 | |
1487 | if (!Sym.isInSection()) |
1488 | return false; |
1489 | |
1490 | const auto &Sec = cast<MCSectionELF>(Sym.getSection()); |
1491 | return Sec.getGroup(); |
1492 | } |
1493 | |
1494 | MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, |
1495 | raw_pwrite_stream &OS, |
1496 | bool IsLittleEndian) { |
1497 | return new ELFObjectWriter(MOTW, OS, IsLittleEndian); |
1498 | } |