1 //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements ELF object file writer information.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/DenseMap.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/ADT/iterator.h"
20 #include "llvm/BinaryFormat/ELF.h"
21 #include "llvm/MC/MCAsmBackend.h"
22 #include "llvm/MC/MCAsmInfo.h"
23 #include "llvm/MC/MCAsmLayout.h"
24 #include "llvm/MC/MCAssembler.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCELFObjectWriter.h"
27 #include "llvm/MC/MCExpr.h"
28 #include "llvm/MC/MCFixup.h"
29 #include "llvm/MC/MCFixupKindInfo.h"
30 #include "llvm/MC/MCFragment.h"
31 #include "llvm/MC/MCObjectWriter.h"
32 #include "llvm/MC/MCSection.h"
33 #include "llvm/MC/MCSectionELF.h"
34 #include "llvm/MC/MCSymbol.h"
35 #include "llvm/MC/MCSymbolELF.h"
36 #include "llvm/MC/MCTargetOptions.h"
37 #include "llvm/MC/MCValue.h"
38 #include "llvm/MC/StringTableBuilder.h"
39 #include "llvm/Support/Alignment.h"
40 #include "llvm/Support/Casting.h"
41 #include "llvm/Support/Compression.h"
42 #include "llvm/Support/Endian.h"
43 #include "llvm/Support/EndianStream.h"
44 #include "llvm/Support/Error.h"
45 #include "llvm/Support/ErrorHandling.h"
46 #include "llvm/Support/Host.h"
47 #include "llvm/Support/LEB128.h"
48 #include "llvm/Support/MathExtras.h"
49 #include "llvm/Support/SMLoc.h"
50 #include "llvm/Support/raw_ostream.h"
51 #include <algorithm>
52 #include <cassert>
53 #include <cstddef>
54 #include <cstdint>
55 #include <map>
56 #include <memory>
57 #include <string>
58 #include <utility>
59 #include <vector>
60
61 using namespace llvm;
62
63 #undef DEBUG_TYPE
64 #define DEBUG_TYPE "reloc-info"
65
66 namespace {
67
68 using SectionIndexMapTy = DenseMap<const MCSectionELF *, uint32_t>;
69
70 class ELFObjectWriter;
71 struct ELFWriter;
72
isDwoSection(const MCSectionELF & Sec)73 bool isDwoSection(const MCSectionELF &Sec) {
74 return Sec.getName().endswith(".dwo");
75 }
76
77 class SymbolTableWriter {
78 ELFWriter &EWriter;
79 bool Is64Bit;
80
81 // indexes we are going to write to .symtab_shndx.
82 std::vector<uint32_t> ShndxIndexes;
83
84 // The numbel of symbols written so far.
85 unsigned NumWritten;
86
87 void createSymtabShndx();
88
89 template <typename T> void write(T Value);
90
91 public:
92 SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);
93
94 void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
95 uint8_t other, uint32_t shndx, bool Reserved);
96
getShndxIndexes() const97 ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
98 };
99
100 struct ELFWriter {
101 ELFObjectWriter &OWriter;
102 support::endian::Writer W;
103
104 enum DwoMode {
105 AllSections,
106 NonDwoOnly,
107 DwoOnly,
108 } Mode;
109
110 static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
111 static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
112 bool Used, bool Renamed);
113
114 /// Helper struct for containing some precomputed information on symbols.
115 struct ELFSymbolData {
116 const MCSymbolELF *Symbol;
117 StringRef Name;
118 uint32_t SectionIndex;
119 uint32_t Order;
120 };
121
122 /// @}
123 /// @name Symbol Table Data
124 /// @{
125
126 StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
127
128 /// @}
129
130 // This holds the symbol table index of the last local symbol.
131 unsigned LastLocalSymbolIndex;
132 // This holds the .strtab section index.
133 unsigned StringTableIndex;
134 // This holds the .symtab section index.
135 unsigned SymbolTableIndex;
136
137 // Sections in the order they are to be output in the section table.
138 std::vector<const MCSectionELF *> SectionTable;
139 unsigned addToSectionTable(const MCSectionELF *Sec);
140
141 // TargetObjectWriter wrappers.
142 bool is64Bit() const;
143 bool usesRela(const MCSectionELF &Sec) const;
144
145 uint64_t align(Align Alignment);
146
147 bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
148 SmallVectorImpl<uint8_t> &CompressedContents,
149 Align Alignment);
150
151 public:
ELFWriter__anonb5a8eaba0111::ELFWriter152 ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
153 bool IsLittleEndian, DwoMode Mode)
154 : OWriter(OWriter),
155 W(OS, IsLittleEndian ? support::little : support::big), Mode(Mode) {}
156
WriteWord__anonb5a8eaba0111::ELFWriter157 void WriteWord(uint64_t Word) {
158 if (is64Bit())
159 W.write<uint64_t>(Word);
160 else
161 W.write<uint32_t>(Word);
162 }
163
write__anonb5a8eaba0111::ELFWriter164 template <typename T> void write(T Val) {
165 W.write(Val);
166 }
167
168 void writeHeader(const MCAssembler &Asm);
169
170 void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
171 ELFSymbolData &MSD, const MCAsmLayout &Layout);
172
173 // Start and end offset of each section
174 using SectionOffsetsTy =
175 std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
176
177 // Map from a signature symbol to the group section index
178 using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;
179
180 /// Compute the symbol table data
181 ///
182 /// \param Asm - The assembler.
183 /// \param SectionIndexMap - Maps a section to its index.
184 /// \param RevGroupMap - Maps a signature symbol to the group section.
185 void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
186 const SectionIndexMapTy &SectionIndexMap,
187 const RevGroupMapTy &RevGroupMap,
188 SectionOffsetsTy &SectionOffsets);
189
190 void writeAddrsigSection();
191
192 MCSectionELF *createRelocationSection(MCContext &Ctx,
193 const MCSectionELF &Sec);
194
195 void createMemtagRelocs(MCAssembler &Asm);
196
197 void writeSectionHeader(const MCAsmLayout &Layout,
198 const SectionIndexMapTy &SectionIndexMap,
199 const SectionOffsetsTy &SectionOffsets);
200
201 void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
202 const MCAsmLayout &Layout);
203
204 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
205 uint64_t Address, uint64_t Offset, uint64_t Size,
206 uint32_t Link, uint32_t Info, MaybeAlign Alignment,
207 uint64_t EntrySize);
208
209 void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
210
211 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout);
212 void writeSection(const SectionIndexMapTy &SectionIndexMap,
213 uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
214 const MCSectionELF &Section);
215 };
216
217 class ELFObjectWriter : public MCObjectWriter {
218 /// The target specific ELF writer instance.
219 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
220
221 DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> Relocations;
222
223 DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
224
225 bool SeenGnuAbi = false;
226
227 bool hasRelocationAddend() const;
228
229 bool shouldRelocateWithSymbol(const MCAssembler &Asm,
230 const MCSymbolRefExpr *RefA,
231 const MCSymbolELF *Sym, uint64_t C,
232 unsigned Type) const;
233
234 public:
ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)235 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
236 : TargetObjectWriter(std::move(MOTW)) {}
237
reset()238 void reset() override {
239 SeenGnuAbi = false;
240 Relocations.clear();
241 Renames.clear();
242 MCObjectWriter::reset();
243 }
244
245 bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
246 const MCSymbol &SymA,
247 const MCFragment &FB, bool InSet,
248 bool IsPCRel) const override;
249
checkRelocation(MCContext & Ctx,SMLoc Loc,const MCSectionELF * From,const MCSectionELF * To)250 virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
251 const MCSectionELF *From,
252 const MCSectionELF *To) {
253 return true;
254 }
255
256 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
257 const MCFragment *Fragment, const MCFixup &Fixup,
258 MCValue Target, uint64_t &FixedValue) override;
259
260 void executePostLayoutBinding(MCAssembler &Asm,
261 const MCAsmLayout &Layout) override;
262
markGnuAbi()263 void markGnuAbi() override { SeenGnuAbi = true; }
seenGnuAbi() const264 bool seenGnuAbi() const { return SeenGnuAbi; }
265
266 friend struct ELFWriter;
267 };
268
269 class ELFSingleObjectWriter : public ELFObjectWriter {
270 raw_pwrite_stream &OS;
271 bool IsLittleEndian;
272
273 public:
ELFSingleObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,raw_pwrite_stream & OS,bool IsLittleEndian)274 ELFSingleObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
275 raw_pwrite_stream &OS, bool IsLittleEndian)
276 : ELFObjectWriter(std::move(MOTW)), OS(OS),
277 IsLittleEndian(IsLittleEndian) {}
278
writeObject(MCAssembler & Asm,const MCAsmLayout & Layout)279 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
280 return ELFWriter(*this, OS, IsLittleEndian, ELFWriter::AllSections)
281 .writeObject(Asm, Layout);
282 }
283
284 friend struct ELFWriter;
285 };
286
287 class ELFDwoObjectWriter : public ELFObjectWriter {
288 raw_pwrite_stream &OS, &DwoOS;
289 bool IsLittleEndian;
290
291 public:
ELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,raw_pwrite_stream & OS,raw_pwrite_stream & DwoOS,bool IsLittleEndian)292 ELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
293 raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
294 bool IsLittleEndian)
295 : ELFObjectWriter(std::move(MOTW)), OS(OS), DwoOS(DwoOS),
296 IsLittleEndian(IsLittleEndian) {}
297
checkRelocation(MCContext & Ctx,SMLoc Loc,const MCSectionELF * From,const MCSectionELF * To)298 bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From,
299 const MCSectionELF *To) override {
300 if (isDwoSection(*From)) {
301 Ctx.reportError(Loc, "A dwo section may not contain relocations");
302 return false;
303 }
304 if (To && isDwoSection(*To)) {
305 Ctx.reportError(Loc, "A relocation may not refer to a dwo section");
306 return false;
307 }
308 return true;
309 }
310
writeObject(MCAssembler & Asm,const MCAsmLayout & Layout)311 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
312 uint64_t Size = ELFWriter(*this, OS, IsLittleEndian, ELFWriter::NonDwoOnly)
313 .writeObject(Asm, Layout);
314 Size += ELFWriter(*this, DwoOS, IsLittleEndian, ELFWriter::DwoOnly)
315 .writeObject(Asm, Layout);
316 return Size;
317 }
318 };
319
320 } // end anonymous namespace
321
align(Align Alignment)322 uint64_t ELFWriter::align(Align Alignment) {
323 uint64_t Offset = W.OS.tell();
324 uint64_t NewOffset = alignTo(Offset, Alignment);
325 W.OS.write_zeros(NewOffset - Offset);
326 return NewOffset;
327 }
328
addToSectionTable(const MCSectionELF * Sec)329 unsigned ELFWriter::addToSectionTable(const MCSectionELF *Sec) {
330 SectionTable.push_back(Sec);
331 StrTabBuilder.add(Sec->getName());
332 return SectionTable.size();
333 }
334
createSymtabShndx()335 void SymbolTableWriter::createSymtabShndx() {
336 if (!ShndxIndexes.empty())
337 return;
338
339 ShndxIndexes.resize(NumWritten);
340 }
341
write(T Value)342 template <typename T> void SymbolTableWriter::write(T Value) {
343 EWriter.write(Value);
344 }
345
SymbolTableWriter(ELFWriter & EWriter,bool Is64Bit)346 SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)
347 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
348
writeSymbol(uint32_t name,uint8_t info,uint64_t value,uint64_t size,uint8_t other,uint32_t shndx,bool Reserved)349 void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
350 uint64_t size, uint8_t other,
351 uint32_t shndx, bool Reserved) {
352 bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;
353
354 if (LargeIndex)
355 createSymtabShndx();
356
357 if (!ShndxIndexes.empty()) {
358 if (LargeIndex)
359 ShndxIndexes.push_back(shndx);
360 else
361 ShndxIndexes.push_back(0);
362 }
363
364 uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
365
366 if (Is64Bit) {
367 write(name); // st_name
368 write(info); // st_info
369 write(other); // st_other
370 write(Index); // st_shndx
371 write(value); // st_value
372 write(size); // st_size
373 } else {
374 write(name); // st_name
375 write(uint32_t(value)); // st_value
376 write(uint32_t(size)); // st_size
377 write(info); // st_info
378 write(other); // st_other
379 write(Index); // st_shndx
380 }
381
382 ++NumWritten;
383 }
384
is64Bit() const385 bool ELFWriter::is64Bit() const {
386 return OWriter.TargetObjectWriter->is64Bit();
387 }
388
usesRela(const MCSectionELF & Sec) const389 bool ELFWriter::usesRela(const MCSectionELF &Sec) const {
390 return OWriter.hasRelocationAddend() &&
391 Sec.getType() != ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
392 }
393
394 // Emit the ELF header.
writeHeader(const MCAssembler & Asm)395 void ELFWriter::writeHeader(const MCAssembler &Asm) {
396 // ELF Header
397 // ----------
398 //
399 // Note
400 // ----
401 // emitWord method behaves differently for ELF32 and ELF64, writing
402 // 4 bytes in the former and 8 in the latter.
403
404 W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
405
406 W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
407
408 // e_ident[EI_DATA]
409 W.OS << char(W.Endian == support::little ? ELF::ELFDATA2LSB
410 : ELF::ELFDATA2MSB);
411
412 W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
413 // e_ident[EI_OSABI]
414 uint8_t OSABI = OWriter.TargetObjectWriter->getOSABI();
415 W.OS << char(OSABI == ELF::ELFOSABI_NONE && OWriter.seenGnuAbi()
416 ? int(ELF::ELFOSABI_GNU)
417 : OSABI);
418 // e_ident[EI_ABIVERSION]
419 W.OS << char(OWriter.TargetObjectWriter->getABIVersion());
420
421 W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
422
423 W.write<uint16_t>(ELF::ET_REL); // e_type
424
425 W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target
426
427 W.write<uint32_t>(ELF::EV_CURRENT); // e_version
428 WriteWord(0); // e_entry, no entry point in .o file
429 WriteWord(0); // e_phoff, no program header for .o
430 WriteWord(0); // e_shoff = sec hdr table off in bytes
431
432 // e_flags = whatever the target wants
433 W.write<uint32_t>(Asm.getELFHeaderEFlags());
434
435 // e_ehsize = ELF header size
436 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)
437 : sizeof(ELF::Elf32_Ehdr));
438
439 W.write<uint16_t>(0); // e_phentsize = prog header entry size
440 W.write<uint16_t>(0); // e_phnum = # prog header entries = 0
441
442 // e_shentsize = Section header entry size
443 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)
444 : sizeof(ELF::Elf32_Shdr));
445
446 // e_shnum = # of section header ents
447 W.write<uint16_t>(0);
448
449 // e_shstrndx = Section # of '.strtab'
450 assert(StringTableIndex < ELF::SHN_LORESERVE);
451 W.write<uint16_t>(StringTableIndex);
452 }
453
SymbolValue(const MCSymbol & Sym,const MCAsmLayout & Layout)454 uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
455 const MCAsmLayout &Layout) {
456 if (Sym.isCommon())
457 return Sym.getCommonAlignment()->value();
458
459 uint64_t Res;
460 if (!Layout.getSymbolOffset(Sym, Res))
461 return 0;
462
463 if (Layout.getAssembler().isThumbFunc(&Sym))
464 Res |= 1;
465
466 return Res;
467 }
468
mergeTypeForSet(uint8_t origType,uint8_t newType)469 static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
470 uint8_t Type = newType;
471
472 // Propagation rules:
473 // IFUNC > FUNC > OBJECT > NOTYPE
474 // TLS_OBJECT > OBJECT > NOTYPE
475 //
476 // dont let the new type degrade the old type
477 switch (origType) {
478 default:
479 break;
480 case ELF::STT_GNU_IFUNC:
481 if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
482 Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)
483 Type = ELF::STT_GNU_IFUNC;
484 break;
485 case ELF::STT_FUNC:
486 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
487 Type == ELF::STT_TLS)
488 Type = ELF::STT_FUNC;
489 break;
490 case ELF::STT_OBJECT:
491 if (Type == ELF::STT_NOTYPE)
492 Type = ELF::STT_OBJECT;
493 break;
494 case ELF::STT_TLS:
495 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
496 Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)
497 Type = ELF::STT_TLS;
498 break;
499 }
500
501 return Type;
502 }
503
isIFunc(const MCSymbolELF * Symbol)504 static bool isIFunc(const MCSymbolELF *Symbol) {
505 while (Symbol->getType() != ELF::STT_GNU_IFUNC) {
506 const MCSymbolRefExpr *Value;
507 if (!Symbol->isVariable() ||
508 !(Value = dyn_cast<MCSymbolRefExpr>(Symbol->getVariableValue())) ||
509 Value->getKind() != MCSymbolRefExpr::VK_None ||
510 mergeTypeForSet(Symbol->getType(), ELF::STT_GNU_IFUNC) != ELF::STT_GNU_IFUNC)
511 return false;
512 Symbol = &cast<MCSymbolELF>(Value->getSymbol());
513 }
514 return true;
515 }
516
writeSymbol(SymbolTableWriter & Writer,uint32_t StringIndex,ELFSymbolData & MSD,const MCAsmLayout & Layout)517 void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
518 ELFSymbolData &MSD, const MCAsmLayout &Layout) {
519 const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
520 const MCSymbolELF *Base =
521 cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
522
523 // This has to be in sync with when computeSymbolTable uses SHN_ABS or
524 // SHN_COMMON.
525 bool IsReserved = !Base || Symbol.isCommon();
526
527 // Binding and Type share the same byte as upper and lower nibbles
528 uint8_t Binding = Symbol.getBinding();
529 uint8_t Type = Symbol.getType();
530 if (isIFunc(&Symbol))
531 Type = ELF::STT_GNU_IFUNC;
532 if (Base) {
533 Type = mergeTypeForSet(Type, Base->getType());
534 }
535 uint8_t Info = (Binding << 4) | Type;
536
537 // Other and Visibility share the same byte with Visibility using the lower
538 // 2 bits
539 uint8_t Visibility = Symbol.getVisibility();
540 uint8_t Other = Symbol.getOther() | Visibility;
541
542 uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
543 uint64_t Size = 0;
544
545 const MCExpr *ESize = MSD.Symbol->getSize();
546 if (!ESize && Base) {
547 // For expressions like .set y, x+1, if y's size is unset, inherit from x.
548 ESize = Base->getSize();
549
550 // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,
551 // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give
552 // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most
553 // needs. MCBinaryExpr is not handled.
554 const MCSymbolELF *Sym = &Symbol;
555 while (Sym->isVariable()) {
556 if (auto *Expr =
557 dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) {
558 Sym = cast<MCSymbolELF>(&Expr->getSymbol());
559 if (!Sym->getSize())
560 continue;
561 ESize = Sym->getSize();
562 }
563 break;
564 }
565 }
566
567 if (ESize) {
568 int64_t Res;
569 if (!ESize->evaluateKnownAbsolute(Res, Layout))
570 report_fatal_error("Size expression must be absolute.");
571 Size = Res;
572 }
573
574 // Write out the symbol table entry
575 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
576 IsReserved);
577 }
578
isInSymtab(const MCAsmLayout & Layout,const MCSymbolELF & Symbol,bool Used,bool Renamed)579 bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
580 bool Used, bool Renamed) {
581 if (Symbol.isVariable()) {
582 const MCExpr *Expr = Symbol.getVariableValue();
583 // Target Expressions that are always inlined do not appear in the symtab
584 if (const auto *T = dyn_cast<MCTargetExpr>(Expr))
585 if (T->inlineAssignedExpr())
586 return false;
587 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
588 if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
589 return false;
590 }
591 }
592
593 if (Used)
594 return true;
595
596 if (Renamed)
597 return false;
598
599 if (Symbol.isVariable() && Symbol.isUndefined()) {
600 // FIXME: this is here just to diagnose the case of a var = commmon_sym.
601 Layout.getBaseSymbol(Symbol);
602 return false;
603 }
604
605 if (Symbol.isTemporary())
606 return false;
607
608 if (Symbol.getType() == ELF::STT_SECTION)
609 return false;
610
611 return true;
612 }
613
createMemtagRelocs(MCAssembler & Asm)614 void ELFWriter::createMemtagRelocs(MCAssembler &Asm) {
615 MCSectionELF *MemtagRelocs = nullptr;
616 for (const MCSymbol &Sym : Asm.symbols()) {
617 const auto &SymE = cast<MCSymbolELF>(Sym);
618 if (!SymE.isMemtag())
619 continue;
620 if (MemtagRelocs == nullptr) {
621 MemtagRelocs = OWriter.TargetObjectWriter->getMemtagRelocsSection(Asm.getContext());
622 if (MemtagRelocs == nullptr)
623 report_fatal_error("Tagged globals are not available on this architecture.");
624 Asm.registerSection(*MemtagRelocs);
625 }
626 ELFRelocationEntry Rec(0, &SymE, ELF::R_AARCH64_NONE, 0, nullptr, 0);
627 OWriter.Relocations[MemtagRelocs].push_back(Rec);
628 }
629 }
630
computeSymbolTable(MCAssembler & Asm,const MCAsmLayout & Layout,const SectionIndexMapTy & SectionIndexMap,const RevGroupMapTy & RevGroupMap,SectionOffsetsTy & SectionOffsets)631 void ELFWriter::computeSymbolTable(
632 MCAssembler &Asm, const MCAsmLayout &Layout,
633 const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap,
634 SectionOffsetsTy &SectionOffsets) {
635 MCContext &Ctx = Asm.getContext();
636 SymbolTableWriter Writer(*this, is64Bit());
637
638 // Symbol table
639 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
640 MCSectionELF *SymtabSection =
641 Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize);
642 SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
643 SymbolTableIndex = addToSectionTable(SymtabSection);
644
645 uint64_t SecStart = align(SymtabSection->getAlign());
646
647 // The first entry is the undefined symbol entry.
648 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
649
650 std::vector<ELFSymbolData> LocalSymbolData;
651 std::vector<ELFSymbolData> ExternalSymbolData;
652 MutableArrayRef<std::pair<std::string, size_t>> FileNames =
653 Asm.getFileNames();
654 for (const std::pair<std::string, size_t> &F : FileNames)
655 StrTabBuilder.add(F.first);
656
657 // Add the data for the symbols.
658 bool HasLargeSectionIndex = false;
659 for (auto It : llvm::enumerate(Asm.symbols())) {
660 const auto &Symbol = cast<MCSymbolELF>(It.value());
661 bool Used = Symbol.isUsedInReloc();
662 bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
663 bool isSignature = Symbol.isSignature();
664
665 if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
666 OWriter.Renames.count(&Symbol)))
667 continue;
668
669 if (Symbol.isTemporary() && Symbol.isUndefined()) {
670 Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName());
671 continue;
672 }
673
674 ELFSymbolData MSD;
675 MSD.Symbol = cast<MCSymbolELF>(&Symbol);
676 MSD.Order = It.index();
677
678 bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
679 assert(Local || !Symbol.isTemporary());
680
681 if (Symbol.isAbsolute()) {
682 MSD.SectionIndex = ELF::SHN_ABS;
683 } else if (Symbol.isCommon()) {
684 if (Symbol.isTargetCommon()) {
685 MSD.SectionIndex = Symbol.getIndex();
686 } else {
687 assert(!Local);
688 MSD.SectionIndex = ELF::SHN_COMMON;
689 }
690 } else if (Symbol.isUndefined()) {
691 if (isSignature && !Used) {
692 MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
693 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
694 HasLargeSectionIndex = true;
695 } else {
696 MSD.SectionIndex = ELF::SHN_UNDEF;
697 }
698 } else {
699 const MCSectionELF &Section =
700 static_cast<const MCSectionELF &>(Symbol.getSection());
701
702 // We may end up with a situation when section symbol is technically
703 // defined, but should not be. That happens because we explicitly
704 // pre-create few .debug_* sections to have accessors.
705 // And if these sections were not really defined in the code, but were
706 // referenced, we simply error out.
707 if (!Section.isRegistered()) {
708 assert(static_cast<const MCSymbolELF &>(Symbol).getType() ==
709 ELF::STT_SECTION);
710 Ctx.reportError(SMLoc(),
711 "Undefined section reference: " + Symbol.getName());
712 continue;
713 }
714
715 if (Mode == NonDwoOnly && isDwoSection(Section))
716 continue;
717 MSD.SectionIndex = SectionIndexMap.lookup(&Section);
718 assert(MSD.SectionIndex && "Invalid section index!");
719 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
720 HasLargeSectionIndex = true;
721 }
722
723 StringRef Name = Symbol.getName();
724
725 // Sections have their own string table
726 if (Symbol.getType() != ELF::STT_SECTION) {
727 MSD.Name = Name;
728 StrTabBuilder.add(Name);
729 }
730
731 if (Local)
732 LocalSymbolData.push_back(MSD);
733 else
734 ExternalSymbolData.push_back(MSD);
735 }
736
737 // This holds the .symtab_shndx section index.
738 unsigned SymtabShndxSectionIndex = 0;
739
740 if (HasLargeSectionIndex) {
741 MCSectionELF *SymtabShndxSection =
742 Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);
743 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
744 SymtabShndxSection->setAlignment(Align(4));
745 }
746
747 StrTabBuilder.finalize();
748
749 // Make the first STT_FILE precede previous local symbols.
750 unsigned Index = 1;
751 auto FileNameIt = FileNames.begin();
752 if (!FileNames.empty())
753 FileNames[0].second = 0;
754
755 for (ELFSymbolData &MSD : LocalSymbolData) {
756 // Emit STT_FILE symbols before their associated local symbols.
757 for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
758 ++FileNameIt) {
759 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
760 ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
761 ELF::SHN_ABS, true);
762 ++Index;
763 }
764
765 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
766 ? 0
767 : StrTabBuilder.getOffset(MSD.Name);
768 MSD.Symbol->setIndex(Index++);
769 writeSymbol(Writer, StringIndex, MSD, Layout);
770 }
771 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
772 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
773 ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
774 ELF::SHN_ABS, true);
775 ++Index;
776 }
777
778 // Write the symbol table entries.
779 LastLocalSymbolIndex = Index;
780
781 for (ELFSymbolData &MSD : ExternalSymbolData) {
782 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
783 MSD.Symbol->setIndex(Index++);
784 writeSymbol(Writer, StringIndex, MSD, Layout);
785 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
786 }
787
788 uint64_t SecEnd = W.OS.tell();
789 SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
790
791 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
792 if (ShndxIndexes.empty()) {
793 assert(SymtabShndxSectionIndex == 0);
794 return;
795 }
796 assert(SymtabShndxSectionIndex != 0);
797
798 SecStart = W.OS.tell();
799 const MCSectionELF *SymtabShndxSection =
800 SectionTable[SymtabShndxSectionIndex - 1];
801 for (uint32_t Index : ShndxIndexes)
802 write(Index);
803 SecEnd = W.OS.tell();
804 SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
805 }
806
writeAddrsigSection()807 void ELFWriter::writeAddrsigSection() {
808 for (const MCSymbol *Sym : OWriter.AddrsigSyms)
809 if (Sym->getIndex() != 0)
810 encodeULEB128(Sym->getIndex(), W.OS);
811 }
812
createRelocationSection(MCContext & Ctx,const MCSectionELF & Sec)813 MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
814 const MCSectionELF &Sec) {
815 if (OWriter.Relocations[&Sec].empty())
816 return nullptr;
817
818 const StringRef SectionName = Sec.getName();
819 bool Rela = usesRela(Sec);
820 std::string RelaSectionName = Rela ? ".rela" : ".rel";
821 RelaSectionName += SectionName;
822
823 unsigned EntrySize;
824 if (Rela)
825 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
826 else
827 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
828
829 unsigned Flags = ELF::SHF_INFO_LINK;
830 if (Sec.getFlags() & ELF::SHF_GROUP)
831 Flags = ELF::SHF_GROUP;
832
833 MCSectionELF *RelaSection = Ctx.createELFRelSection(
834 RelaSectionName, Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags, EntrySize,
835 Sec.getGroup(), &Sec);
836 RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));
837 return RelaSection;
838 }
839
840 // Include the debug info compression header.
maybeWriteCompression(uint32_t ChType,uint64_t Size,SmallVectorImpl<uint8_t> & CompressedContents,Align Alignment)841 bool ELFWriter::maybeWriteCompression(
842 uint32_t ChType, uint64_t Size,
843 SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {
844 uint64_t HdrSize =
845 is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr);
846 if (Size <= HdrSize + CompressedContents.size())
847 return false;
848 // Platform specific header is followed by compressed data.
849 if (is64Bit()) {
850 // Write Elf64_Chdr header.
851 write(static_cast<ELF::Elf64_Word>(ChType));
852 write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
853 write(static_cast<ELF::Elf64_Xword>(Size));
854 write(static_cast<ELF::Elf64_Xword>(Alignment.value()));
855 } else {
856 // Write Elf32_Chdr header otherwise.
857 write(static_cast<ELF::Elf32_Word>(ChType));
858 write(static_cast<ELF::Elf32_Word>(Size));
859 write(static_cast<ELF::Elf32_Word>(Alignment.value()));
860 }
861 return true;
862 }
863
writeSectionData(const MCAssembler & Asm,MCSection & Sec,const MCAsmLayout & Layout)864 void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
865 const MCAsmLayout &Layout) {
866 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
867 StringRef SectionName = Section.getName();
868
869 auto &MC = Asm.getContext();
870 const auto &MAI = MC.getAsmInfo();
871
872 const DebugCompressionType CompressionType = MAI->compressDebugSections();
873 if (CompressionType == DebugCompressionType::None ||
874 !SectionName.startswith(".debug_")) {
875 Asm.writeSectionData(W.OS, &Section, Layout);
876 return;
877 }
878
879 SmallVector<char, 128> UncompressedData;
880 raw_svector_ostream VecOS(UncompressedData);
881 Asm.writeSectionData(VecOS, &Section, Layout);
882 ArrayRef<uint8_t> Uncompressed =
883 ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
884 UncompressedData.size());
885
886 SmallVector<uint8_t, 128> Compressed;
887 uint32_t ChType;
888 switch (CompressionType) {
889 case DebugCompressionType::None:
890 llvm_unreachable("has been handled");
891 case DebugCompressionType::Zlib:
892 ChType = ELF::ELFCOMPRESS_ZLIB;
893 break;
894 case DebugCompressionType::Zstd:
895 ChType = ELF::ELFCOMPRESS_ZSTD;
896 break;
897 }
898 compression::compress(compression::Params(CompressionType), Uncompressed,
899 Compressed);
900 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
901 Sec.getAlign())) {
902 W.OS << UncompressedData;
903 return;
904 }
905
906 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
907 // Alignment field should reflect the requirements of
908 // the compressed section header.
909 Section.setAlignment(is64Bit() ? Align(8) : Align(4));
910 W.OS << toStringRef(Compressed);
911 }
912
WriteSecHdrEntry(uint32_t Name,uint32_t Type,uint64_t Flags,uint64_t Address,uint64_t Offset,uint64_t Size,uint32_t Link,uint32_t Info,MaybeAlign Alignment,uint64_t EntrySize)913 void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
914 uint64_t Address, uint64_t Offset,
915 uint64_t Size, uint32_t Link, uint32_t Info,
916 MaybeAlign Alignment, uint64_t EntrySize) {
917 W.write<uint32_t>(Name); // sh_name: index into string table
918 W.write<uint32_t>(Type); // sh_type
919 WriteWord(Flags); // sh_flags
920 WriteWord(Address); // sh_addr
921 WriteWord(Offset); // sh_offset
922 WriteWord(Size); // sh_size
923 W.write<uint32_t>(Link); // sh_link
924 W.write<uint32_t>(Info); // sh_info
925 WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign
926 WriteWord(EntrySize); // sh_entsize
927 }
928
writeRelocations(const MCAssembler & Asm,const MCSectionELF & Sec)929 void ELFWriter::writeRelocations(const MCAssembler &Asm,
930 const MCSectionELF &Sec) {
931 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
932
933 // We record relocations by pushing to the end of a vector. Reverse the vector
934 // to get the relocations in the order they were created.
935 // In most cases that is not important, but it can be for special sections
936 // (.eh_frame) or specific relocations (TLS optimizations on SystemZ).
937 std::reverse(Relocs.begin(), Relocs.end());
938
939 // Sort the relocation entries. MIPS needs this.
940 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
941
942 const bool Rela = usesRela(Sec);
943 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
944 const ELFRelocationEntry &Entry = Relocs[e - i - 1];
945 unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
946
947 if (is64Bit()) {
948 write(Entry.Offset);
949 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
950 write(uint32_t(Index));
951
952 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
953 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
954 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
955 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
956 } else {
957 struct ELF::Elf64_Rela ERE64;
958 ERE64.setSymbolAndType(Index, Entry.Type);
959 write(ERE64.r_info);
960 }
961 if (Rela)
962 write(Entry.Addend);
963 } else {
964 write(uint32_t(Entry.Offset));
965
966 struct ELF::Elf32_Rela ERE32;
967 ERE32.setSymbolAndType(Index, Entry.Type);
968 write(ERE32.r_info);
969
970 if (Rela)
971 write(uint32_t(Entry.Addend));
972
973 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
974 if (uint32_t RType =
975 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
976 write(uint32_t(Entry.Offset));
977
978 ERE32.setSymbolAndType(0, RType);
979 write(ERE32.r_info);
980 write(uint32_t(0));
981 }
982 if (uint32_t RType =
983 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
984 write(uint32_t(Entry.Offset));
985
986 ERE32.setSymbolAndType(0, RType);
987 write(ERE32.r_info);
988 write(uint32_t(0));
989 }
990 }
991 }
992 }
993 }
994
writeSection(const SectionIndexMapTy & SectionIndexMap,uint32_t GroupSymbolIndex,uint64_t Offset,uint64_t Size,const MCSectionELF & Section)995 void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
996 uint32_t GroupSymbolIndex, uint64_t Offset,
997 uint64_t Size, const MCSectionELF &Section) {
998 uint64_t sh_link = 0;
999 uint64_t sh_info = 0;
1000
1001 switch(Section.getType()) {
1002 default:
1003 // Nothing to do.
1004 break;
1005
1006 case ELF::SHT_DYNAMIC:
1007 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
1008
1009 case ELF::SHT_REL:
1010 case ELF::SHT_RELA: {
1011 sh_link = SymbolTableIndex;
1012 assert(sh_link && ".symtab not found");
1013 const MCSection *InfoSection = Section.getLinkedToSection();
1014 sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection));
1015 break;
1016 }
1017
1018 case ELF::SHT_SYMTAB:
1019 sh_link = StringTableIndex;
1020 sh_info = LastLocalSymbolIndex;
1021 break;
1022
1023 case ELF::SHT_SYMTAB_SHNDX:
1024 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
1025 case ELF::SHT_LLVM_ADDRSIG:
1026 sh_link = SymbolTableIndex;
1027 break;
1028
1029 case ELF::SHT_GROUP:
1030 sh_link = SymbolTableIndex;
1031 sh_info = GroupSymbolIndex;
1032 break;
1033 }
1034
1035 if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
1036 // If the value in the associated metadata is not a definition, Sym will be
1037 // undefined. Represent this with sh_link=0.
1038 const MCSymbol *Sym = Section.getLinkedToSymbol();
1039 if (Sym && Sym->isInSection()) {
1040 const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
1041 sh_link = SectionIndexMap.lookup(Sec);
1042 }
1043 }
1044
1045 WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
1046 Section.getType(), Section.getFlags(), 0, Offset, Size,
1047 sh_link, sh_info, Section.getAlign(),
1048 Section.getEntrySize());
1049 }
1050
writeSectionHeader(const MCAsmLayout & Layout,const SectionIndexMapTy & SectionIndexMap,const SectionOffsetsTy & SectionOffsets)1051 void ELFWriter::writeSectionHeader(
1052 const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
1053 const SectionOffsetsTy &SectionOffsets) {
1054 const unsigned NumSections = SectionTable.size();
1055
1056 // Null section first.
1057 uint64_t FirstSectionSize =
1058 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
1059 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0);
1060
1061 for (const MCSectionELF *Section : SectionTable) {
1062 uint32_t GroupSymbolIndex;
1063 unsigned Type = Section->getType();
1064 if (Type != ELF::SHT_GROUP)
1065 GroupSymbolIndex = 0;
1066 else
1067 GroupSymbolIndex = Section->getGroup()->getIndex();
1068
1069 const std::pair<uint64_t, uint64_t> &Offsets =
1070 SectionOffsets.find(Section)->second;
1071 uint64_t Size;
1072 if (Type == ELF::SHT_NOBITS)
1073 Size = Layout.getSectionAddressSize(Section);
1074 else
1075 Size = Offsets.second - Offsets.first;
1076
1077 writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
1078 *Section);
1079 }
1080 }
1081
writeObject(MCAssembler & Asm,const MCAsmLayout & Layout)1082 uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
1083 uint64_t StartOffset = W.OS.tell();
1084
1085 MCContext &Ctx = Asm.getContext();
1086 MCSectionELF *StrtabSection =
1087 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
1088 StringTableIndex = addToSectionTable(StrtabSection);
1089
1090 createMemtagRelocs(Asm);
1091
1092 RevGroupMapTy RevGroupMap;
1093 SectionIndexMapTy SectionIndexMap;
1094
1095 std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
1096
1097 // Write out the ELF header ...
1098 writeHeader(Asm);
1099
1100 // ... then the sections ...
1101 SectionOffsetsTy SectionOffsets;
1102 std::vector<MCSectionELF *> Groups;
1103 std::vector<MCSectionELF *> Relocations;
1104 for (MCSection &Sec : Asm) {
1105 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
1106 if (Mode == NonDwoOnly && isDwoSection(Section))
1107 continue;
1108 if (Mode == DwoOnly && !isDwoSection(Section))
1109 continue;
1110
1111 // Remember the offset into the file for this section.
1112 const uint64_t SecStart = align(Section.getAlign());
1113
1114 const MCSymbolELF *SignatureSymbol = Section.getGroup();
1115 writeSectionData(Asm, Section, Layout);
1116
1117 uint64_t SecEnd = W.OS.tell();
1118 SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
1119
1120 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
1121
1122 if (SignatureSymbol) {
1123 unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1124 if (!GroupIdx) {
1125 MCSectionELF *Group =
1126 Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
1127 GroupIdx = addToSectionTable(Group);
1128 Group->setAlignment(Align(4));
1129 Groups.push_back(Group);
1130 }
1131 std::vector<const MCSectionELF *> &Members =
1132 GroupMembers[SignatureSymbol];
1133 Members.push_back(&Section);
1134 if (RelSection)
1135 Members.push_back(RelSection);
1136 }
1137
1138 SectionIndexMap[&Section] = addToSectionTable(&Section);
1139 if (RelSection) {
1140 SectionIndexMap[RelSection] = addToSectionTable(RelSection);
1141 Relocations.push_back(RelSection);
1142 }
1143
1144 OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);
1145 }
1146
1147 for (MCSectionELF *Group : Groups) {
1148 // Remember the offset into the file for this section.
1149 const uint64_t SecStart = align(Group->getAlign());
1150
1151 const MCSymbol *SignatureSymbol = Group->getGroup();
1152 assert(SignatureSymbol);
1153 write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));
1154 for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1155 uint32_t SecIndex = SectionIndexMap.lookup(Member);
1156 write(SecIndex);
1157 }
1158
1159 uint64_t SecEnd = W.OS.tell();
1160 SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
1161 }
1162
1163 if (Mode == DwoOnly) {
1164 // dwo files don't have symbol tables or relocations, but they do have
1165 // string tables.
1166 StrTabBuilder.finalize();
1167 } else {
1168 MCSectionELF *AddrsigSection;
1169 if (OWriter.EmitAddrsigSection) {
1170 AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,
1171 ELF::SHF_EXCLUDE);
1172 addToSectionTable(AddrsigSection);
1173 }
1174
1175 // Compute symbol table information.
1176 computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
1177 SectionOffsets);
1178
1179 for (MCSectionELF *RelSection : Relocations) {
1180 // Remember the offset into the file for this section.
1181 const uint64_t SecStart = align(RelSection->getAlign());
1182
1183 writeRelocations(Asm,
1184 cast<MCSectionELF>(*RelSection->getLinkedToSection()));
1185
1186 uint64_t SecEnd = W.OS.tell();
1187 SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
1188 }
1189
1190 if (OWriter.EmitAddrsigSection) {
1191 uint64_t SecStart = W.OS.tell();
1192 writeAddrsigSection();
1193 uint64_t SecEnd = W.OS.tell();
1194 SectionOffsets[AddrsigSection] = std::make_pair(SecStart, SecEnd);
1195 }
1196 }
1197
1198 {
1199 uint64_t SecStart = W.OS.tell();
1200 StrTabBuilder.write(W.OS);
1201 SectionOffsets[StrtabSection] = std::make_pair(SecStart, W.OS.tell());
1202 }
1203
1204 const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
1205
1206 // ... then the section header table ...
1207 writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
1208
1209 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1210 (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1211 : SectionTable.size() + 1,
1212 W.Endian);
1213 unsigned NumSectionsOffset;
1214
1215 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
1216 if (is64Bit()) {
1217 uint64_t Val =
1218 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1219 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1220 offsetof(ELF::Elf64_Ehdr, e_shoff));
1221 NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
1222 } else {
1223 uint32_t Val =
1224 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1225 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1226 offsetof(ELF::Elf32_Ehdr, e_shoff));
1227 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
1228 }
1229 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1230 NumSectionsOffset);
1231
1232 return W.OS.tell() - StartOffset;
1233 }
1234
hasRelocationAddend() const1235 bool ELFObjectWriter::hasRelocationAddend() const {
1236 return TargetObjectWriter->hasRelocationAddend();
1237 }
1238
executePostLayoutBinding(MCAssembler & Asm,const MCAsmLayout & Layout)1239 void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
1240 const MCAsmLayout &Layout) {
1241 // The presence of symbol versions causes undefined symbols and
1242 // versions declared with @@@ to be renamed.
1243 for (const MCAssembler::Symver &S : Asm.Symvers) {
1244 StringRef AliasName = S.Name;
1245 const auto &Symbol = cast<MCSymbolELF>(*S.Sym);
1246 size_t Pos = AliasName.find('@');
1247 assert(Pos != StringRef::npos);
1248
1249 StringRef Prefix = AliasName.substr(0, Pos);
1250 StringRef Rest = AliasName.substr(Pos);
1251 StringRef Tail = Rest;
1252 if (Rest.startswith("@@@"))
1253 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1254
1255 auto *Alias =
1256 cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
1257 Asm.registerSymbol(*Alias);
1258 const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
1259 Alias->setVariableValue(Value);
1260
1261 // Aliases defined with .symvar copy the binding from the symbol they alias.
1262 // This is the first place we are able to copy this information.
1263 Alias->setBinding(Symbol.getBinding());
1264 Alias->setVisibility(Symbol.getVisibility());
1265 Alias->setOther(Symbol.getOther());
1266
1267 if (!Symbol.isUndefined() && S.KeepOriginalSym)
1268 continue;
1269
1270 if (Symbol.isUndefined() && Rest.startswith("@@") &&
1271 !Rest.startswith("@@@")) {
1272 Asm.getContext().reportError(S.Loc, "default version symbol " +
1273 AliasName + " must be defined");
1274 continue;
1275 }
1276
1277 if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
1278 Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
1279 Symbol.getName());
1280 continue;
1281 }
1282
1283 Renames.insert(std::make_pair(&Symbol, Alias));
1284 }
1285
1286 for (const MCSymbol *&Sym : AddrsigSyms) {
1287 if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym)))
1288 Sym = R;
1289 if (Sym->isInSection() && Sym->getName().startswith(".L"))
1290 Sym = Sym->getSection().getBeginSymbol();
1291 Sym->setUsedInReloc();
1292 }
1293 }
1294
1295 // It is always valid to create a relocation with a symbol. It is preferable
1296 // to use a relocation with a section if that is possible. Using the section
1297 // allows us to omit some local symbols from the symbol table.
shouldRelocateWithSymbol(const MCAssembler & Asm,const MCSymbolRefExpr * RefA,const MCSymbolELF * Sym,uint64_t C,unsigned Type) const1298 bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
1299 const MCSymbolRefExpr *RefA,
1300 const MCSymbolELF *Sym,
1301 uint64_t C,
1302 unsigned Type) const {
1303 // A PCRel relocation to an absolute value has no symbol (or section). We
1304 // represent that with a relocation to a null section.
1305 if (!RefA)
1306 return false;
1307
1308 MCSymbolRefExpr::VariantKind Kind = RefA->getKind();
1309 switch (Kind) {
1310 default:
1311 break;
1312 // The .odp creation emits a relocation against the symbol ".TOC." which
1313 // create a R_PPC64_TOC relocation. However the relocation symbol name
1314 // in final object creation should be NULL, since the symbol does not
1315 // really exist, it is just the reference to TOC base for the current
1316 // object file. Since the symbol is undefined, returning false results
1317 // in a relocation with a null section which is the desired result.
1318 case MCSymbolRefExpr::VK_PPC_TOCBASE:
1319 return false;
1320
1321 // These VariantKind cause the relocation to refer to something other than
1322 // the symbol itself, like a linker generated table. Since the address of
1323 // symbol is not relevant, we cannot replace the symbol with the
1324 // section and patch the difference in the addend.
1325 case MCSymbolRefExpr::VK_GOT:
1326 case MCSymbolRefExpr::VK_PLT:
1327 case MCSymbolRefExpr::VK_GOTPCREL:
1328 case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:
1329 case MCSymbolRefExpr::VK_PPC_GOT_LO:
1330 case MCSymbolRefExpr::VK_PPC_GOT_HI:
1331 case MCSymbolRefExpr::VK_PPC_GOT_HA:
1332 return true;
1333 }
1334
1335 // An undefined symbol is not in any section, so the relocation has to point
1336 // to the symbol itself.
1337 assert(Sym && "Expected a symbol");
1338 if (Sym->isUndefined())
1339 return true;
1340
1341 // For memory-tagged symbols, ensure that the relocation uses the symbol. For
1342 // tagged symbols, we emit an empty relocation (R_AARCH64_NONE) in a special
1343 // section (SHT_AARCH64_MEMTAG_GLOBALS_STATIC) to indicate to the linker that
1344 // this global needs to be tagged. In addition, the linker needs to know
1345 // whether to emit a special addend when relocating `end` symbols, and this
1346 // can only be determined by the attributes of the symbol itself.
1347 if (Sym->isMemtag())
1348 return true;
1349
1350 unsigned Binding = Sym->getBinding();
1351 switch(Binding) {
1352 default:
1353 llvm_unreachable("Invalid Binding");
1354 case ELF::STB_LOCAL:
1355 break;
1356 case ELF::STB_WEAK:
1357 // If the symbol is weak, it might be overridden by a symbol in another
1358 // file. The relocation has to point to the symbol so that the linker
1359 // can update it.
1360 return true;
1361 case ELF::STB_GLOBAL:
1362 case ELF::STB_GNU_UNIQUE:
1363 // Global ELF symbols can be preempted by the dynamic linker. The relocation
1364 // has to point to the symbol for a reason analogous to the STB_WEAK case.
1365 return true;
1366 }
1367
1368 // Keep symbol type for a local ifunc because it may result in an IRELATIVE
1369 // reloc that the dynamic loader will use to resolve the address at startup
1370 // time.
1371 if (Sym->getType() == ELF::STT_GNU_IFUNC)
1372 return true;
1373
1374 // If a relocation points to a mergeable section, we have to be careful.
1375 // If the offset is zero, a relocation with the section will encode the
1376 // same information. With a non-zero offset, the situation is different.
1377 // For example, a relocation can point 42 bytes past the end of a string.
1378 // If we change such a relocation to use the section, the linker would think
1379 // that it pointed to another string and subtracting 42 at runtime will
1380 // produce the wrong value.
1381 if (Sym->isInSection()) {
1382 auto &Sec = cast<MCSectionELF>(Sym->getSection());
1383 unsigned Flags = Sec.getFlags();
1384 if (Flags & ELF::SHF_MERGE) {
1385 if (C != 0)
1386 return true;
1387
1388 // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)
1389 // (http://sourceware.org/PR16794).
1390 if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&
1391 Type == ELF::R_386_GOTOFF)
1392 return true;
1393
1394 // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so
1395 // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an
1396 // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in
1397 // range of a MergeInputSection. We could introduce a new RelExpr member
1398 // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)
1399 // but the complexity is unnecessary given that GNU as keeps the original
1400 // symbol for this case as well.
1401 if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&
1402 !hasRelocationAddend())
1403 return true;
1404 }
1405
1406 // Most TLS relocations use a got, so they need the symbol. Even those that
1407 // are just an offset (@tpoff), require a symbol in gold versions before
1408 // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
1409 // http://sourceware.org/PR16773.
1410 if (Flags & ELF::SHF_TLS)
1411 return true;
1412 }
1413
1414 // If the symbol is a thumb function the final relocation must set the lowest
1415 // bit. With a symbol that is done by just having the symbol have that bit
1416 // set, so we would lose the bit if we relocated with the section.
1417 // FIXME: We could use the section but add the bit to the relocation value.
1418 if (Asm.isThumbFunc(Sym))
1419 return true;
1420
1421 if (TargetObjectWriter->needsRelocateWithSymbol(*Sym, Type))
1422 return true;
1423 return false;
1424 }
1425
recordRelocation(MCAssembler & Asm,const MCAsmLayout & Layout,const MCFragment * Fragment,const MCFixup & Fixup,MCValue Target,uint64_t & FixedValue)1426 void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
1427 const MCAsmLayout &Layout,
1428 const MCFragment *Fragment,
1429 const MCFixup &Fixup, MCValue Target,
1430 uint64_t &FixedValue) {
1431 MCAsmBackend &Backend = Asm.getBackend();
1432 bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
1433 MCFixupKindInfo::FKF_IsPCRel;
1434 const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
1435 uint64_t C = Target.getConstant();
1436 uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
1437 MCContext &Ctx = Asm.getContext();
1438
1439 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1440 const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
1441 if (SymB.isUndefined()) {
1442 Ctx.reportError(Fixup.getLoc(),
1443 Twine("symbol '") + SymB.getName() +
1444 "' can not be undefined in a subtraction expression");
1445 return;
1446 }
1447
1448 assert(!SymB.isAbsolute() && "Should have been folded");
1449 const MCSection &SecB = SymB.getSection();
1450 if (&SecB != &FixupSection) {
1451 Ctx.reportError(Fixup.getLoc(),
1452 "Cannot represent a difference across sections");
1453 return;
1454 }
1455
1456 assert(!IsPCRel && "should have been folded");
1457 IsPCRel = true;
1458 C += FixupOffset - Layout.getSymbolOffset(SymB);
1459 }
1460
1461 // We either rejected the fixup or folded B into C at this point.
1462 const MCSymbolRefExpr *RefA = Target.getSymA();
1463 const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
1464
1465 bool ViaWeakRef = false;
1466 if (SymA && SymA->isVariable()) {
1467 const MCExpr *Expr = SymA->getVariableValue();
1468 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1469 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
1470 SymA = cast<MCSymbolELF>(&Inner->getSymbol());
1471 ViaWeakRef = true;
1472 }
1473 }
1474 }
1475
1476 const MCSectionELF *SecA = (SymA && SymA->isInSection())
1477 ? cast<MCSectionELF>(&SymA->getSection())
1478 : nullptr;
1479 if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA))
1480 return;
1481
1482 unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
1483 const auto *Parent = cast<MCSectionELF>(Fragment->getParent());
1484 // Emiting relocation with sybmol for CG Profile to help with --cg-profile.
1485 bool RelocateWithSymbol =
1486 shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type) ||
1487 (Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE);
1488 uint64_t Addend = 0;
1489
1490 FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()
1491 ? C + Layout.getSymbolOffset(*SymA)
1492 : C;
1493 if (hasRelocationAddend()) {
1494 Addend = FixedValue;
1495 FixedValue = 0;
1496 }
1497
1498 if (!RelocateWithSymbol) {
1499 const auto *SectionSymbol =
1500 SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;
1501 if (SectionSymbol)
1502 SectionSymbol->setUsedInReloc();
1503 ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA, C);
1504 Relocations[&FixupSection].push_back(Rec);
1505 return;
1506 }
1507
1508 const MCSymbolELF *RenamedSymA = SymA;
1509 if (SymA) {
1510 if (const MCSymbolELF *R = Renames.lookup(SymA))
1511 RenamedSymA = R;
1512
1513 if (ViaWeakRef)
1514 RenamedSymA->setIsWeakrefUsedInReloc();
1515 else
1516 RenamedSymA->setUsedInReloc();
1517 }
1518 ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C);
1519 Relocations[&FixupSection].push_back(Rec);
1520 }
1521
isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler & Asm,const MCSymbol & SA,const MCFragment & FB,bool InSet,bool IsPCRel) const1522 bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
1523 const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
1524 bool InSet, bool IsPCRel) const {
1525 const auto &SymA = cast<MCSymbolELF>(SA);
1526 if (IsPCRel) {
1527 assert(!InSet);
1528 if (SymA.getBinding() != ELF::STB_LOCAL ||
1529 SymA.getType() == ELF::STT_GNU_IFUNC)
1530 return false;
1531 }
1532 return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
1533 InSet, IsPCRel);
1534 }
1535
1536 std::unique_ptr<MCObjectWriter>
createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,raw_pwrite_stream & OS,bool IsLittleEndian)1537 llvm::createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1538 raw_pwrite_stream &OS, bool IsLittleEndian) {
1539 return std::make_unique<ELFSingleObjectWriter>(std::move(MOTW), OS,
1540 IsLittleEndian);
1541 }
1542
1543 std::unique_ptr<MCObjectWriter>
createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,raw_pwrite_stream & OS,raw_pwrite_stream & DwoOS,bool IsLittleEndian)1544 llvm::createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1545 raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
1546 bool IsLittleEndian) {
1547 return std::make_unique<ELFDwoObjectWriter>(std::move(MOTW), OS, DwoOS,
1548 IsLittleEndian);
1549 }
1550