Bug Summary

File:lib/MC/ELFObjectWriter.cpp
Location:line 1407, column 5
Description:Value stored to 'ComputedSymtab' is never read

Annotated Source Code

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>
38using namespace llvm;
39
40#undef DEBUG_TYPE"reloc-info"
41#define DEBUG_TYPE"reloc-info" "reloc-info"
42
43namespace {
44
45typedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy;
46
47class ELFObjectWriter;
48
49class 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
63public:
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
72class 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
262unsigned ELFObjectWriter::addToSectionTable(MCSectionELF *Sec) {
263 SectionTable.push_back(Sec);
264 ShStrTabBuilder.add(Sec->getSectionName());
265 return SectionTable.size();
266}
267
268void SymbolTableWriter::createSymtabShndx() {
269 if (!ShndxIndexes.empty())
270 return;
271
272 ShndxIndexes.resize(NumWritten);
273}
274
275template <typename T> void SymbolTableWriter::write(T Value) {
276 EWriter.write(Value);
277}
278
279SymbolTableWriter::SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit)
280 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
281
282void 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
318bool 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
325bool 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
346ELFObjectWriter::~ELFObjectWriter()
347{}
348
349// Emit the ELF header.
350void 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
402uint64_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
418void 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
458static 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
493void 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
541void 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.
619bool 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
718static 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.
740static 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
757void 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
858uint64_t
859ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
860 const MCSymbol *S) {
861 const MCSymbolData &SD = Asm.getSymbolData(*S);
862 return SD.getIndex();
863}
864
865bool 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
902bool 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
916void 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
1060MCSectionELF *
1061ELFObjectWriter::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
1089static SmallVector<char, 128>
1090getUncompressedData(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.
1117static bool
1118prependCompressionHeader(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
1134void 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
1172void 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
1190void 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
1232const MCSectionELF *ELFObjectWriter::createSectionHeaderStringTable() {
1233 const MCSectionELF *ShstrtabSection = SectionTable[ShstrtabIndex - 1];
1234 ShStrTabBuilder.finalize(StringTableBuilder::ELF);
1235 OS << ShStrTabBuilder.data();
1236 return ShstrtabSection;
1237}
1238
1239const 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
1247void 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
1296void 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
1330void 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
1461bool 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
1473bool 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
1494MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1495 raw_pwrite_stream &OS,
1496 bool IsLittleEndian) {
1497 return new ELFObjectWriter(MOTW, OS, IsLittleEndian);
1498}