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