LLVM 23.0.0git
ELFObjectWriter.cpp
Go to the documentation of this file.
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"
17#include "llvm/ADT/Statistic.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/Twine.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"
28#include "llvm/MC/MCExpr.h"
29#include "llvm/MC/MCFixup.h"
31#include "llvm/MC/MCSection.h"
33#include "llvm/MC/MCSymbol.h"
34#include "llvm/MC/MCSymbolELF.h"
36#include "llvm/MC/MCValue.h"
41#include "llvm/Support/Endian.h"
44#include "llvm/Support/LEB128.h"
45#include "llvm/Support/SMLoc.h"
48#include <cassert>
49#include <cstddef>
50#include <cstdint>
51#include <memory>
52#include <string>
53#include <utility>
54#include <vector>
55
56using namespace llvm;
57
58#define DEBUG_TYPE "elf-object-writer"
59
60namespace {
61namespace stats {
62
63STATISTIC(ELFHeaderBytes, "Total size of ELF headers");
64STATISTIC(SectionHeaderBytes, "Total size of section headers table");
65STATISTIC(AllocTextBytes, "Total size of SHF_ALLOC text sections");
66STATISTIC(AllocROBytes, "Total size of SHF_ALLOC readonly sections");
67STATISTIC(AllocRWBytes, "Total size of SHF_ALLOC read-write sections");
68STATISTIC(StrtabBytes, "Total size of SHT_STRTAB sections");
69STATISTIC(SymtabBytes, "Total size of SHT_SYMTAB sections");
70STATISTIC(RelocationBytes, "Total size of relocation sections");
71STATISTIC(DynsymBytes, "Total size of SHT_DYNSYM sections");
73 DebugBytes,
74 "Total size of debug info sections (not including those written to .dwo)");
75STATISTIC(UnwindBytes, "Total size of unwind sections");
76STATISTIC(OtherBytes, "Total size of uncategorized sections");
77STATISTIC(DwoBytes, "Total size of sections written to .dwo file");
78
79} // namespace stats
80
81struct ELFWriter;
82
83bool isDwoSection(const MCSectionELF &Sec) {
84 return Sec.getName().ends_with(".dwo");
85}
86
87class 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
101public:
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
107 ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
108};
109
110struct 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
160public:
161 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
168 MCContext &getContext() const { return Asm.getContext(); }
169
170 void writeWord(uint64_t Word) {
171 if (is64Bit())
172 W.write<uint64_t>(Word);
173 else
174 W.write<uint32_t>(Word);
175 }
176
177 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
217uint64_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
224unsigned ELFWriter::addToSectionTable(MCSectionELF *Sec) {
225 SectionTable.push_back(Sec);
226 StrTabBuilder.add(Sec->getName());
227 return SectionTable.size();
228}
229
230void SymbolTableWriter::createSymtabShndx() {
231 if (!ShndxIndexes.empty())
232 return;
233
234 ShndxIndexes.resize(NumWritten);
235}
236
237template <typename T> void SymbolTableWriter::write(T Value) {
238 EWriter.write(Value);
239}
240
241SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)
242 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
243
244void 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
280bool ELFWriter::is64Bit() const {
281 return OWriter.TargetObjectWriter->is64Bit();
282}
283
284// Emit the ELF header.
285void 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
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
346uint64_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
360static 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;
372 if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
375 break;
376 case ELF::STT_FUNC:
380 break;
381 case ELF::STT_OBJECT:
382 if (Type == ELF::STT_NOTYPE)
384 break;
385 case ELF::STT_TLS:
389 break;
390 }
391
392 return Type;
393}
394
395static 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) !=
403 return false;
404 Symbol = &static_cast<const MCSymbolELF &>(Value->getSymbol());
405 }
406 return true;
407}
408
409void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
410 ELFSymbolData &MSD) {
411 auto &Symbol = static_cast<const MCSymbolELF &>(*MSD.Symbol);
412 auto *Base = static_cast<const MCSymbolELF *>(Asm.getBaseSymbol(Symbol));
413
414 // This has to be in sync with when computeSymbolTable uses SHN_ABS or
415 // SHN_COMMON.
416 bool IsReserved = !Base || Symbol.isCommon();
417
418 // Binding and Type share the same byte as upper and lower nibbles
419 uint8_t Binding = Symbol.getBinding();
420 uint8_t Type = Symbol.getType();
421 if (isIFunc(&Symbol))
423 if (Base) {
424 Type = mergeTypeForSet(Type, Base->getType());
425 }
426 uint8_t Info = (Binding << 4) | Type;
427
428 // Other and Visibility share the same byte with Visibility using the lower
429 // 2 bits
430 uint8_t Visibility = Symbol.getVisibility();
431 uint8_t Other = Symbol.getOther() | Visibility;
432
433 uint64_t Value = symbolValue(*MSD.Symbol);
434 uint64_t Size = 0;
435
436 const MCExpr *ESize = MSD.Symbol->getSize();
437 if (!ESize && Base) {
438 // For expressions like .set y, x+1, if y's size is unset, inherit from x.
439 ESize = Base->getSize();
440
441 // For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,
442 // z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give
443 // us 2. Follow the MCSymbolRefExpr assignment chain, which covers most
444 // needs. MCBinaryExpr is not handled.
445 const MCSymbolELF *Sym = &Symbol;
446 while (Sym->isVariable()) {
447 if (auto *Expr = dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue())) {
448 Sym = static_cast<const MCSymbolELF *>(&Expr->getSymbol());
449 if (!Sym->getSize())
450 continue;
451 ESize = Sym->getSize();
452 }
453 break;
454 }
455 }
456
457 if (ESize) {
458 int64_t Res;
459 if (!ESize->evaluateKnownAbsolute(Res, Asm))
460 report_fatal_error("Size expression must be absolute.");
461 Size = Res;
462 }
463
464 // Write out the symbol table entry
465 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
466 IsReserved);
467}
468
469bool ELFWriter::isInSymtab(const MCSymbolELF &Symbol) {
470 if (Symbol.isUsedInReloc() || Symbol.isSignature())
471 return true;
472
473 if (OWriter.Renames.count(&Symbol))
474 return false;
475
476 if (Symbol.isVariable()) {
477 const MCExpr *Expr = Symbol.getVariableValue();
478 // Target Expressions that are always inlined do not appear in the symtab
479 if (const auto *T = dyn_cast<MCTargetExpr>(Expr))
480 if (T->inlineAssignedExpr())
481 return false;
482 // The .weakref alias does not appear in the symtab.
483 if (Symbol.isWeakref())
484 return false;
485
486 if (Symbol.isUndefined()) {
487 // FIXME: this is here just to diagnose the case of a var = commmon_sym.
488 Asm.getBaseSymbol(Symbol);
489 return false;
490 }
491 }
492
493 if (Symbol.isTemporary())
494 return false;
495
496 return Symbol.getType() != ELF::STT_SECTION;
497}
498
499void ELFWriter::computeSymbolTable(const RevGroupMapTy &RevGroupMap) {
500 MCContext &Ctx = Asm.getContext();
501 SymbolTableWriter Writer(*this, is64Bit());
502
503 // Symbol table
504 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
505 MCSectionELF *SymtabSection =
506 Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize);
507 SymtabSection->setAlignment(is64Bit() ? Align(8) : Align(4));
508 SymbolTableIndex = addToSectionTable(SymtabSection);
509
510 uint64_t SecStart = align(SymtabSection->getAlign());
511
512 // The first entry is the undefined symbol entry.
513 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
514
515 std::vector<ELFSymbolData> LocalSymbolData;
516 std::vector<ELFSymbolData> ExternalSymbolData;
518 OWriter.getFileNames();
519 for (const std::pair<std::string, size_t> &F : FileNames)
520 StrTabBuilder.add(F.first);
521
522 // Add the data for the symbols.
523 bool HasLargeSectionIndex = false;
524 for (auto It : llvm::enumerate(Asm.symbols())) {
525 auto &Symbol = static_cast<const MCSymbolELF &>(It.value());
526 if (!isInSymtab(Symbol))
527 continue;
528
529 if (Symbol.isTemporary() && Symbol.isUndefined()) {
530 Ctx.reportError(SMLoc(), "Undefined temporary symbol " + Symbol.getName());
531 continue;
532 }
533
534 ELFSymbolData MSD;
535 MSD.Symbol = static_cast<const MCSymbolELF *>(&Symbol);
536 MSD.Order = It.index();
537
538 bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
539 assert(Local || !Symbol.isTemporary());
540
541 if (Symbol.isAbsolute()) {
542 MSD.SectionIndex = ELF::SHN_ABS;
543 } else if (Symbol.isCommon()) {
544 auto Shndx = Symbol.getIndex();
545 if (!Shndx) {
546 assert(!Local);
547 Shndx = ELF::SHN_COMMON;
548 }
549 MSD.SectionIndex = Shndx;
550 } else if (Symbol.isUndefined()) {
551 if (Symbol.isSignature() && !Symbol.isUsedInReloc()) {
552 MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
553 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
554 HasLargeSectionIndex = true;
555 } else {
556 MSD.SectionIndex = ELF::SHN_UNDEF;
557 }
558 } else {
559 const MCSectionELF &Section =
560 static_cast<const MCSectionELF &>(Symbol.getSection());
561 assert(Section.isRegistered());
562 if (Mode == NonDwoOnly && isDwoSection(Section))
563 continue;
564 MSD.SectionIndex = Section.getOrdinal();
565 assert(MSD.SectionIndex && "Invalid section index!");
566 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
567 HasLargeSectionIndex = true;
568 }
569
570 // Temporary symbols generated for certain assembler features (.eh_frame,
571 // .debug_line) of an empty name may be referenced by relocations due to
572 // linker relaxation. Rename them to ".L0 " to match the gas fake label name
573 // and allow ld/objcopy --discard-locals to discard such symbols.
574 StringRef Name = Symbol.getName();
575 if (Name.empty())
576 Name = ".L0 ";
577
578 // Sections have their own string table
579 if (Symbol.getType() != ELF::STT_SECTION) {
580 MSD.Name = Name;
581 StrTabBuilder.add(Name);
582 }
583
584 if (Local)
585 LocalSymbolData.push_back(MSD);
586 else
587 ExternalSymbolData.push_back(MSD);
588 }
589
590 // This holds the .symtab_shndx section index.
591 unsigned SymtabShndxSectionIndex = 0;
592
593 if (HasLargeSectionIndex) {
594 MCSectionELF *SymtabShndxSection =
595 Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4);
596 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
597 SymtabShndxSection->setAlignment(Align(4));
598 }
599
600 StrTabBuilder.finalize();
601
602 // Make the first STT_FILE precede previous local symbols.
603 unsigned Index = 1;
604 auto FileNameIt = FileNames.begin();
605 if (!FileNames.empty())
606 FileNames[0].second = 0;
607
608 for (ELFSymbolData &MSD : LocalSymbolData) {
609 // Emit STT_FILE symbols before their associated local symbols.
610 for (; FileNameIt != FileNames.end() && FileNameIt->second <= MSD.Order;
611 ++FileNameIt) {
612 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
614 ELF::SHN_ABS, true);
615 ++Index;
616 }
617
618 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
619 ? 0
620 : StrTabBuilder.getOffset(MSD.Name);
621 MSD.Symbol->setIndex(Index++);
622 writeSymbol(Writer, StringIndex, MSD);
623 }
624 for (; FileNameIt != FileNames.end(); ++FileNameIt) {
625 Writer.writeSymbol(StrTabBuilder.getOffset(FileNameIt->first),
627 ELF::SHN_ABS, true);
628 ++Index;
629 }
630
631 // Write the symbol table entries.
632 LastLocalSymbolIndex = Index;
633
634 for (ELFSymbolData &MSD : ExternalSymbolData) {
635 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
636 MSD.Symbol->setIndex(Index++);
637 writeSymbol(Writer, StringIndex, MSD);
638 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
639 }
640
641 uint64_t SecEnd = W.OS.tell();
642 SymtabSection->setOffsets(SecStart, SecEnd);
643
644 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
645 if (ShndxIndexes.empty()) {
646 assert(SymtabShndxSectionIndex == 0);
647 return;
648 }
649 assert(SymtabShndxSectionIndex != 0);
650
651 SecStart = W.OS.tell();
652 MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1];
653 for (uint32_t Index : ShndxIndexes)
654 write(Index);
655 SecEnd = W.OS.tell();
656 SymtabShndxSection->setOffsets(SecStart, SecEnd);
657}
658
659void ELFWriter::writeAddrsigSection() {
660 for (const MCSymbol *Sym : OWriter.getAddrsigSyms())
661 if (Sym->getIndex() != 0)
662 encodeULEB128(Sym->getIndex(), W.OS);
663}
664
665MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
666 const MCSectionELF &Sec) {
667 if (OWriter.Relocations[&Sec].empty())
668 return nullptr;
669
670 unsigned Flags = ELF::SHF_INFO_LINK;
671 if (Sec.getFlags() & ELF::SHF_GROUP)
673
674 const StringRef SectionName = Sec.getName();
675 const MCTargetOptions *TO = Ctx.getTargetOptions();
676 if (TO->Crel) {
677 MCSectionELF *RelaSection =
678 Ctx.createELFRelSection(".crel" + SectionName, ELF::SHT_CREL, Flags,
679 /*EntrySize=*/1, Sec.getGroup(), &Sec);
680 return RelaSection;
681 }
682
683 const bool Rela = OWriter.usesRela(TO, Sec);
684 unsigned EntrySize;
685 if (Rela)
686 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
687 else
688 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
689
690 MCSectionELF *RelaSection =
691 Ctx.createELFRelSection(((Rela ? ".rela" : ".rel") + SectionName),
692 Rela ? ELF::SHT_RELA : ELF::SHT_REL, Flags,
693 EntrySize, Sec.getGroup(), &Sec);
694 RelaSection->setAlignment(is64Bit() ? Align(8) : Align(4));
695 return RelaSection;
696}
697
698// Include the debug info compression header.
699bool ELFWriter::maybeWriteCompression(
700 uint32_t ChType, uint64_t Size,
701 SmallVectorImpl<uint8_t> &CompressedContents, Align Alignment) {
702 uint64_t HdrSize =
703 is64Bit() ? sizeof(ELF::Elf64_Chdr) : sizeof(ELF::Elf32_Chdr);
704 if (Size <= HdrSize + CompressedContents.size())
705 return false;
706 // Platform specific header is followed by compressed data.
707 if (is64Bit()) {
708 // Write Elf64_Chdr header.
709 write(static_cast<ELF::Elf64_Word>(ChType));
710 write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
711 write(static_cast<ELF::Elf64_Xword>(Size));
712 write(static_cast<ELF::Elf64_Xword>(Alignment.value()));
713 } else {
714 // Write Elf32_Chdr header otherwise.
715 write(static_cast<ELF::Elf32_Word>(ChType));
716 write(static_cast<ELF::Elf32_Word>(Size));
717 write(static_cast<ELF::Elf32_Word>(Alignment.value()));
718 }
719 return true;
720}
721
722void ELFWriter::writeSectionData(MCSection &Sec) {
723 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
724 StringRef SectionName = Section.getName();
725 auto &Ctx = Asm.getContext();
726 const DebugCompressionType CompressionType =
728 if (CompressionType == DebugCompressionType::None ||
729 !SectionName.starts_with(".debug_")) {
730 Asm.writeSectionData(W.OS, &Section);
731 return;
732 }
733
734 SmallVector<char, 128> UncompressedData;
735 raw_svector_ostream VecOS(UncompressedData);
736 Asm.writeSectionData(VecOS, &Section);
737 ArrayRef<uint8_t> Uncompressed =
738 ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
739 UncompressedData.size());
740
741 SmallVector<uint8_t, 128> Compressed;
742 uint32_t ChType;
743 switch (CompressionType) {
744 case DebugCompressionType::None:
745 llvm_unreachable("has been handled");
746 case DebugCompressionType::Zlib:
747 ChType = ELF::ELFCOMPRESS_ZLIB;
748 break;
749 case DebugCompressionType::Zstd:
750 ChType = ELF::ELFCOMPRESS_ZSTD;
751 break;
752 }
753 compression::compress(compression::Params(CompressionType), Uncompressed,
754 Compressed);
755 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
756 Sec.getAlign())) {
757 W.OS << UncompressedData;
758 return;
759 }
760
761 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
762 // Alignment field should reflect the requirements of
763 // the compressed section header.
764 Section.setAlignment(is64Bit() ? Align(8) : Align(4));
765 W.OS << toStringRef(Compressed);
766}
767
768void ELFWriter::writeSectionHeaderEntry(uint32_t Name, uint32_t Type,
769 uint64_t Flags, uint64_t Address,
770 uint64_t Offset, uint64_t Size,
771 uint32_t Link, uint32_t Info,
772 MaybeAlign Alignment,
773 uint64_t EntrySize) {
774 W.write<uint32_t>(Name); // sh_name: index into string table
775 W.write<uint32_t>(Type); // sh_type
776 writeWord(Flags); // sh_flags
777 writeWord(Address); // sh_addr
778 writeWord(Offset); // sh_offset
779 writeWord(Size); // sh_size
780 W.write<uint32_t>(Link); // sh_link
781 W.write<uint32_t>(Info); // sh_info
782 writeWord(Alignment ? Alignment->value() : 0); // sh_addralign
783 writeWord(EntrySize); // sh_entsize
784}
785
786template <bool Is64>
788 using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
789 ELF::encodeCrel<Is64>(OS, Relocs, [&](const ELFRelocationEntry &R) {
790 uint32_t SymIdx = R.Symbol ? R.Symbol->getIndex() : 0;
791 return ELF::Elf_Crel<Is64>{static_cast<uint>(R.Offset), SymIdx, R.Type,
792 std::make_signed_t<uint>(R.Addend)};
793 });
794}
795
796void ELFWriter::writeRelocations(const MCSectionELF &Sec) {
797 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
798 const MCTargetOptions *TO = getContext().getTargetOptions();
799 const bool Rela = OWriter.usesRela(TO, Sec);
800
801 // Sort the relocation entries. MIPS needs this.
802 OWriter.TargetObjectWriter->sortRelocs(Relocs);
803
804 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
805 for (const ELFRelocationEntry &Entry : Relocs) {
806 uint32_t SymIdx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
807 if (is64Bit()) {
808 write(Entry.Offset);
809 write(uint32_t(SymIdx));
810 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
811 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
812 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
813 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
814 if (Rela)
815 write(Entry.Addend);
816 } else {
817 write(uint32_t(Entry.Offset));
818 ELF::Elf32_Rela ERE32;
819 ERE32.setSymbolAndType(SymIdx, Entry.Type);
820 write(ERE32.r_info);
821 if (Rela)
822 write(uint32_t(Entry.Addend));
823 if (uint32_t RType =
824 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
825 write(uint32_t(Entry.Offset));
826 ERE32.setSymbolAndType(0, RType);
827 write(ERE32.r_info);
828 write(uint32_t(0));
829 }
830 if (uint32_t RType =
831 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
832 write(uint32_t(Entry.Offset));
833 ERE32.setSymbolAndType(0, RType);
834 write(ERE32.r_info);
835 write(uint32_t(0));
836 }
837 }
838 }
839 } else if (TO && TO->Crel) {
840 if (is64Bit())
841 encodeCrel<true>(Relocs, W.OS);
842 else
843 encodeCrel<false>(Relocs, W.OS);
844 } else {
845 for (const ELFRelocationEntry &Entry : Relocs) {
846 uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
847 if (is64Bit()) {
848 write(Entry.Offset);
849 ELF::Elf64_Rela ERE;
850 ERE.setSymbolAndType(Symidx, Entry.Type);
851 write(ERE.r_info);
852 if (Rela)
853 write(Entry.Addend);
854 } else {
855 write(uint32_t(Entry.Offset));
856 ELF::Elf32_Rela ERE;
857 ERE.setSymbolAndType(Symidx, Entry.Type);
858 write(ERE.r_info);
859 if (Rela)
860 write(uint32_t(Entry.Addend));
861 }
862 }
863 }
864}
865
866void ELFWriter::writeSectionHeader(uint32_t GroupSymbolIndex, uint64_t Offset,
867 uint64_t Size, const MCSectionELF &Section) {
868 uint64_t sh_link = 0;
869 uint64_t sh_info = 0;
870
871 switch(Section.getType()) {
872 default:
873 // Nothing to do.
874 break;
875
876 case ELF::SHT_DYNAMIC:
877 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
878
879 case ELF::SHT_REL:
880 case ELF::SHT_RELA:
881 case ELF::SHT_CREL: {
882 sh_link = SymbolTableIndex;
883 assert(sh_link && ".symtab not found");
884 const MCSection *InfoSection = Section.getLinkedToSection();
885 sh_info = InfoSection->getOrdinal();
886 break;
887 }
888
889 case ELF::SHT_SYMTAB:
890 sh_link = StringTableIndex;
891 sh_info = LastLocalSymbolIndex;
892 break;
893
897 sh_link = SymbolTableIndex;
898 break;
899
900 case ELF::SHT_GROUP:
901 sh_link = SymbolTableIndex;
902 sh_info = GroupSymbolIndex;
903 break;
904 }
905
906 if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
907 // If the value in the associated metadata is not a definition, Sym will be
908 // undefined. Represent this with sh_link=0.
909 const MCSymbol *Sym = Section.getLinkedToSymbol();
910 if (Sym && Sym->isInSection())
911 sh_link = Sym->getSection().getOrdinal();
912 }
913
914 writeSectionHeaderEntry(StrTabBuilder.getOffset(Section.getName()),
915 Section.getType(), Section.getFlags(), 0, Offset,
916 Size, sh_link, sh_info, Section.getAlign(),
917 Section.getEntrySize());
918}
919
920void ELFWriter::writeSectionHeaders() {
921 uint64_t Start = W.OS.tell();
922 const unsigned NumSections = SectionTable.size();
923
924 // Null section first.
925 uint64_t FirstSectionSize =
926 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
927 writeSectionHeaderEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt,
928 0);
929
930 for (const MCSectionELF *Section : SectionTable) {
931 uint32_t GroupSymbolIndex;
932 unsigned Type = Section->getType();
933 if (Type != ELF::SHT_GROUP)
934 GroupSymbolIndex = 0;
935 else
936 GroupSymbolIndex = Section->getGroup()->getIndex();
937
938 std::pair<uint64_t, uint64_t> Offsets = Section->getOffsets();
939 uint64_t Size;
940 if (Type == ELF::SHT_NOBITS)
941 Size = Asm.getSectionAddressSize(*Section);
942 else
943 Size = Offsets.second - Offsets.first;
944
945 auto SectionHasFlag = [&](uint64_t Flag) -> bool {
946 return Section->getFlags() & Flag;
947 };
948
949 if (Mode == DwoOnly) {
950 stats::DwoBytes += Size;
951 } else if (Section->getName().starts_with(".debug")) {
952 stats::DebugBytes += Size;
953 } else if (Section->getName().starts_with(".eh_frame")) {
954 stats::UnwindBytes += Size;
955 } else if (SectionHasFlag(ELF::SHF_ALLOC)) {
956 if (SectionHasFlag(ELF::SHF_EXECINSTR)) {
957 stats::AllocTextBytes += Size;
958 } else if (SectionHasFlag(ELF::SHF_WRITE)) {
959 stats::AllocRWBytes += Size;
960 } else {
961 stats::AllocROBytes += Size;
962 }
963 } else {
964 switch (Section->getType()) {
965 case ELF::SHT_STRTAB:
966 stats::StrtabBytes += Size;
967 break;
968 case ELF::SHT_SYMTAB:
969 stats::SymtabBytes += Size;
970 break;
971 case ELF::SHT_DYNSYM:
972 stats::DynsymBytes += Size;
973 break;
974 case ELF::SHT_REL:
975 case ELF::SHT_RELA:
976 case ELF::SHT_CREL:
977 stats::RelocationBytes += Size;
978 break;
979 default:
980 stats::OtherBytes += Size;
981 break;
982 }
983 }
984
985 writeSectionHeader(GroupSymbolIndex, Offsets.first, Size, *Section);
986 }
987
988 stats::SectionHeaderBytes += W.OS.tell() - Start;
989}
990
991uint64_t ELFWriter::writeObject() {
992 uint64_t StartOffset = W.OS.tell();
993
994 MCContext &Ctx = getContext();
995 MCSectionELF *StrtabSection =
996 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
997 StringTableIndex = addToSectionTable(StrtabSection);
998
999 RevGroupMapTy RevGroupMap;
1000
1001 // Write out the ELF header ...
1002 writeHeader();
1003
1004 stats::ELFHeaderBytes += W.OS.tell() - StartOffset;
1005
1006 // ... then the sections ...
1008 // Map from group section index to group
1009 SmallVector<unsigned, 0> GroupMap;
1010 SmallVector<MCSectionELF *> Relocations;
1011 for (MCSection &Sec : Asm) {
1012 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
1013 if (Mode == NonDwoOnly && isDwoSection(Section))
1014 continue;
1015 if (Mode == DwoOnly && !isDwoSection(Section))
1016 continue;
1017
1018 // Remember the offset into the file for this section.
1019 const uint64_t SecStart = align(Section.getAlign());
1020
1021 const MCSymbolELF *SignatureSymbol = Section.getGroup();
1022 writeSectionData(Section);
1023
1024 uint64_t SecEnd = W.OS.tell();
1025 Section.setOffsets(SecStart, SecEnd);
1026
1027 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
1028
1029 unsigned *GroupIdxEntry = nullptr;
1030 if (SignatureSymbol) {
1031 GroupIdxEntry = &RevGroupMap[SignatureSymbol];
1032 if (!*GroupIdxEntry) {
1033 MCSectionELF *Group =
1034 Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
1035 *GroupIdxEntry = addToSectionTable(Group);
1036 Group->setAlignment(Align(4));
1037
1038 GroupMap.resize(*GroupIdxEntry + 1);
1039 GroupMap[*GroupIdxEntry] = Groups.size();
1040 Groups.emplace_back(Group, SmallVector<unsigned>{});
1041 }
1042 }
1043
1044 Section.setOrdinal(addToSectionTable(&Section));
1045 if (RelSection) {
1046 RelSection->setOrdinal(addToSectionTable(RelSection));
1047 Relocations.push_back(RelSection);
1048 }
1049
1050 if (GroupIdxEntry) {
1051 auto &Members = Groups[GroupMap[*GroupIdxEntry]];
1052 Members.second.push_back(Section.getOrdinal());
1053 if (RelSection)
1054 Members.second.push_back(RelSection->getOrdinal());
1055 }
1056 }
1057
1058 for (auto &[Group, Members] : Groups) {
1059 // Remember the offset into the file for this section.
1060 const uint64_t SecStart = align(Group->getAlign());
1061
1062 write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));
1063 W.write<unsigned>(Members);
1064
1065 uint64_t SecEnd = W.OS.tell();
1066 Group->setOffsets(SecStart, SecEnd);
1067 }
1068
1069 if (Mode == DwoOnly) {
1070 // dwo files don't have symbol tables or relocations, but they do have
1071 // string tables.
1072 StrTabBuilder.finalize();
1073 } else {
1074 MCSectionELF *AddrsigSection;
1075 if (OWriter.getEmitAddrsigSection()) {
1076 AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,
1078 addToSectionTable(AddrsigSection);
1079 }
1080
1081 // Compute symbol table information.
1082 computeSymbolTable(RevGroupMap);
1083
1084 for (MCSectionELF *RelSection : Relocations) {
1085 // Remember the offset into the file for this section.
1086 const uint64_t SecStart = align(RelSection->getAlign());
1087
1088 writeRelocations(
1089 static_cast<const MCSectionELF &>(*RelSection->getLinkedToSection()));
1090
1091 uint64_t SecEnd = W.OS.tell();
1092 RelSection->setOffsets(SecStart, SecEnd);
1093 }
1094
1095 if (OWriter.getEmitAddrsigSection()) {
1096 uint64_t SecStart = W.OS.tell();
1097 writeAddrsigSection();
1098 uint64_t SecEnd = W.OS.tell();
1099 AddrsigSection->setOffsets(SecStart, SecEnd);
1100 }
1101 }
1102
1103 {
1104 uint64_t SecStart = W.OS.tell();
1105 StrTabBuilder.write(W.OS);
1106 StrtabSection->setOffsets(SecStart, W.OS.tell());
1107 }
1108
1109 const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
1110
1111 // ... then the section header table ...
1112 writeSectionHeaders();
1113
1114 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1115 (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1116 : SectionTable.size() + 1,
1117 W.Endian);
1118 unsigned NumSectionsOffset;
1119
1120 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
1121 if (is64Bit()) {
1122 uint64_t Val =
1123 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1124 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1125 offsetof(ELF::Elf64_Ehdr, e_shoff));
1126 NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
1127 } else {
1128 uint32_t Val =
1129 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1130 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1131 offsetof(ELF::Elf32_Ehdr, e_shoff));
1132 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
1133 }
1134 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1135 NumSectionsOffset);
1136
1137 return W.OS.tell() - StartOffset;
1138}
1139
1140ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1142 : TargetObjectWriter(std::move(MOTW)), OS(OS),
1144ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1147 : TargetObjectWriter(std::move(MOTW)), OS(OS), DwoOS(&DwoOS),
1149
1151 ELFHeaderEFlags = 0;
1152 SeenGnuAbi = false;
1153 OverrideABIVersion.reset();
1154 Relocations.clear();
1155 Renames.clear();
1156 Weakrefs.clear();
1157 Symvers.clear();
1158 SeenGnuAbi = false;
1160}
1161
1166
1168 return TargetObjectWriter->hasRelocationAddend();
1169}
1170
1172 // The presence of symbol versions causes undefined symbols and
1173 // versions declared with @@@ to be renamed.
1174 for (const Symver &S : Symvers) {
1175 StringRef AliasName = S.Name;
1176 auto &Symbol = static_cast<const MCSymbolELF &>(*S.Sym);
1177 size_t Pos = AliasName.find('@');
1178 assert(Pos != StringRef::npos);
1179
1180 StringRef Prefix = AliasName.substr(0, Pos);
1181 StringRef Rest = AliasName.substr(Pos);
1182 StringRef Tail = Rest;
1183 if (Rest.starts_with("@@@"))
1184 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1185
1186 auto *Alias = static_cast<MCSymbolELF *>(
1187 Asm->getContext().getOrCreateSymbol(Prefix + Tail));
1188 Asm->registerSymbol(*Alias);
1189 const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm->getContext());
1190 Alias->setVariableValue(Value);
1191
1192 // Aliases defined with .symvar copy the binding from the symbol they alias.
1193 // This is the first place we are able to copy this information.
1194 Alias->setBinding(Symbol.getBinding());
1195 Alias->setVisibility(Symbol.getVisibility());
1196 Alias->setOther(Symbol.getOther());
1197
1198 if (!Symbol.isUndefined() && S.KeepOriginalSym)
1199 continue;
1200
1201 if (Symbol.isUndefined() && Rest.starts_with("@@") &&
1202 !Rest.starts_with("@@@")) {
1203 Asm->getContext().reportError(S.Loc, "default version symbol " +
1204 AliasName + " must be defined");
1205 continue;
1206 }
1207
1208 if (auto It = Renames.find(&Symbol);
1209 It != Renames.end() && It->second != Alias) {
1210 Asm->getContext().reportError(S.Loc, Twine("multiple versions for ") +
1211 Symbol.getName());
1212 continue;
1213 }
1214
1215 Renames.insert(std::make_pair(&Symbol, Alias));
1216 }
1217
1218 for (const MCSymbol *&Sym : AddrsigSyms) {
1219 if (const MCSymbol *R =
1220 Renames.lookup(static_cast<const MCSymbolELF *>(Sym)))
1221 Sym = R;
1222 if (Sym->isInSection() && Sym->getName().starts_with(".L"))
1223 Sym = Sym->getSection().getBeginSymbol();
1224 Sym->setUsedInReloc();
1225 }
1226
1227 // For each `.weakref alias, target`, if the variable `alias` is registered
1228 // (typically through MCObjectStreamer::visitUsedSymbol), register `target`.
1229 // If `target` was unregistered before (not directly referenced or defined),
1230 // make it weak.
1231 for (const MCSymbol *Alias : Weakrefs) {
1232 if (!Alias->isRegistered())
1233 continue;
1234 auto *Expr = Alias->getVariableValue();
1235 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1236 auto &Sym = static_cast<const MCSymbolELF &>(Inner->getSymbol());
1237 if (Asm->registerSymbol(Sym))
1238 Sym.setBinding(ELF::STB_WEAK);
1239 }
1240 }
1241}
1242
1243// It is always valid to create a relocation with a symbol. It is preferable
1244// to use a relocation with a section if that is possible. Using the section
1245// allows us to omit some local symbols from the symbol table.
1247 const MCSymbolELF *Sym, uint64_t C,
1248 unsigned Type) const {
1249 // Keep symbol type for a local ifunc because it may result in an IRELATIVE
1250 // reloc that the dynamic loader will use to resolve the address at startup
1251 // time.
1252 if (Sym->getType() == ELF::STT_GNU_IFUNC)
1253 return false;
1254
1255 // If a relocation points to a mergeable section, we have to be careful.
1256 // If the offset is zero, a relocation with the section will encode the
1257 // same information. With a non-zero offset, the situation is different.
1258 // For example, a relocation can point 42 bytes past the end of a string.
1259 // If we change such a relocation to use the section, the linker would think
1260 // that it pointed to another string and subtracting 42 at runtime will
1261 // produce the wrong value.
1262 if (Sym->isInSection()) {
1263 auto &Sec = static_cast<const MCSectionELF &>(Sym->getSection());
1264 unsigned Flags = Sec.getFlags();
1265 if (Flags & ELF::SHF_MERGE) {
1266 if (C != 0)
1267 return false;
1268
1269 // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)
1270 // (http://sourceware.org/PR16794).
1271 if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&
1272 Type == ELF::R_386_GOTOFF)
1273 return false;
1274
1275 // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so
1276 // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an
1277 // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in
1278 // range of a MergeInputSection. We could introduce a new RelExpr member
1279 // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)
1280 // but the complexity is unnecessary given that GNU as keeps the original
1281 // symbol for this case as well.
1282 if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&
1284 return false;
1285 }
1286
1287 // Most TLS relocations use a got, so they need the symbol. Even those that
1288 // are just an offset (@tpoff), require a symbol in gold versions before
1289 // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
1290 // http://sourceware.org/PR16773.
1291 if (Flags & ELF::SHF_TLS)
1292 return false;
1293 }
1294
1295 return !TargetObjectWriter->needsRelocateWithSymbol(Val, Type);
1296}
1297
1299 const MCSectionELF *To) {
1300 if (isDwoSection(*From)) {
1301 getContext().reportError(Loc, "A dwo section may not contain relocations");
1302 return false;
1303 }
1304 if (To && isDwoSection(*To)) {
1306 "A relocation may not refer to a dwo section");
1307 return false;
1308 }
1309 return true;
1310}
1311
1313 const MCFixup &Fixup, MCValue Target,
1314 uint64_t &FixedValue) {
1315 auto &Section = static_cast<const MCSectionELF &>(*F.getParent());
1316 MCContext &Ctx = getContext();
1317
1318 auto *SymA = static_cast<const MCSymbolELF *>(Target.getAddSym());
1319 const MCSectionELF *SecA =
1320 (SymA && SymA->isInSection())
1321 ? static_cast<const MCSectionELF *>(&SymA->getSection())
1322 : nullptr;
1323 if (DwoOS && !checkRelocation(Fixup.getLoc(), &Section, SecA))
1324 return;
1325
1326 bool IsPCRel = Fixup.isPCRel();
1327 uint64_t FixupOffset = Asm->getFragmentOffset(F) + Fixup.getOffset();
1328 uint64_t Addend = Target.getConstant();
1329 if (auto *RefB = Target.getSubSym()) {
1330 auto &SymB = static_cast<const MCSymbolELF &>(*RefB);
1331 if (SymB.isUndefined()) {
1332 Ctx.reportError(Fixup.getLoc(),
1333 Twine("symbol '") + SymB.getName() +
1334 "' can not be undefined in a subtraction expression");
1335 return;
1336 }
1337
1338 assert(!SymB.isAbsolute() && "Should have been folded");
1339 const MCSection &SecB = SymB.getSection();
1340 if (&SecB != &Section) {
1341 Ctx.reportError(Fixup.getLoc(),
1342 "Cannot represent a difference across sections");
1343 return;
1344 }
1345
1346 assert(!IsPCRel && "should have been folded");
1347 IsPCRel = true;
1348 Addend += FixupOffset - Asm->getSymbolOffset(SymB);
1349 }
1350
1351 unsigned Type;
1352 if (mc::isRelocRelocation(Fixup.getKind()))
1354 else
1355 Type = TargetObjectWriter->getRelocType(Fixup, Target, IsPCRel);
1356
1357 // Convert SymA to an STT_SECTION symbol if it's defined, local, and meets
1358 // specific conditions, unless it's a .reloc directive, which disables
1359 // STT_SECTION adjustment.
1360 const MCTargetOptions *TO = Ctx.getTargetOptions();
1361 bool UseSectionSym = SymA && SymA->getBinding() == ELF::STB_LOCAL &&
1362 !SymA->isUndefined() &&
1363 !mc::isRelocRelocation(Fixup.getKind());
1364 if (UseSectionSym) {
1365 auto RSS = TO ? TO->RelocSectionSym : RelocSectionSymType::All;
1366 UseSectionSym = RSS == RelocSectionSymType::All ||
1368 SymA->getName().starts_with(
1369 Ctx.getAsmInfo()->getInternalSymbolPrefix()));
1370 }
1371 if (UseSectionSym && useSectionSymbol(Target, SymA, Addend, Type)) {
1372 Addend += Asm->getSymbolOffset(*SymA);
1373 SymA = static_cast<const MCSymbolELF *>(SecA->getBeginSymbol());
1374 } else if (const MCSymbolELF *R = Renames.lookup(SymA)) {
1375 SymA = R;
1376 }
1377 if (SymA)
1378 SymA->setUsedInReloc();
1379
1380 FixedValue = usesRela(TO, Section) ? 0 : Addend;
1381 Relocations[&Section].emplace_back(FixupOffset, SymA, Type, Addend);
1382}
1383
1385 const MCSectionELF &Sec) const {
1386 return (hasRelocationAddend() &&
1388 TO->Crel;
1389}
1390
1392 const MCSymbol &SA, const MCFragment &FB, bool InSet, bool IsPCRel) const {
1393 auto &SymA = static_cast<const MCSymbolELF &>(SA);
1394 if (IsPCRel) {
1395 assert(!InSet);
1396 if (SymA.getBinding() != ELF::STB_LOCAL ||
1397 SymA.getType() == ELF::STT_GNU_IFUNC)
1398 return false;
1399 }
1400 return &SymA.getSection() == FB.getParent();
1401}
1402
1404 uint64_t Size =
1405 ELFWriter(*Asm, *this, OS, IsLittleEndian,
1406 DwoOS ? ELFWriter::NonDwoOnly : ELFWriter::AllSections)
1407 .writeObject();
1408 if (DwoOS)
1409 Size += ELFWriter(*Asm, *this, *DwoOS, IsLittleEndian, ELFWriter::DwoOnly)
1410 .writeObject();
1411 return Size;
1412}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
DXIL Resource Implicit Binding
This file defines the DenseMap class.
static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType)
static void encodeCrel(ArrayRef< ELFRelocationEntry > Relocs, raw_ostream &OS)
static bool isIFunc(const MCSymbolELF *Symbol)
#define offsetof(TYPE, MEMBER)
lazy value info
#define F(x, y, z)
Definition MD5.cpp:54
#define T
PowerPC TLS Dynamic Call Fixup
if(PassOpts->AAPipeline)
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file contains some templates that are useful if you are working with the STL at all.
static const char * name
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
DEMANGLE_NAMESPACE_BEGIN bool starts_with(std::string_view self, char C) noexcept
static bool isInSymtab(const MCSymbolWasm &Sym)
static bool isDwoSection(const MCSection &Sec)
static bool is64Bit(const char *name)
static const X86InstrFMA3Group Groups[]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
std::unique_ptr< MCELFObjectTargetWriter > TargetObjectWriter
ELFObjectWriter(std::unique_ptr< MCELFObjectTargetWriter > MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
void setAssembler(MCAssembler *Asm) override
SmallVector< const MCSymbolELF *, 0 > Weakrefs
bool checkRelocation(SMLoc Loc, const MCSectionELF *From, const MCSectionELF *To)
unsigned getELFHeaderEFlags() const
void reset() override
lifetime management
std::optional< uint8_t > OverrideABIVersion
uint64_t writeObject() override
Write the object file and returns the number of bytes written.
DenseMap< const MCSectionELF *, std::vector< ELFRelocationEntry > > Relocations
void executePostLayoutBinding() override
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
bool isSymbolRefDifferenceFullyResolvedImpl(const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override
SmallVector< Symver, 0 > Symvers
raw_pwrite_stream & OS
void recordRelocation(const MCFragment &F, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) override
Record a relocation entry.
raw_pwrite_stream * DwoOS
bool usesRela(const MCTargetOptions *TO, const MCSectionELF &Sec) const
bool useSectionSymbol(const MCValue &Val, const MCSymbolELF *Sym, uint64_t C, unsigned Type) const
DenseMap< const MCSymbolELF *, const MCSymbolELF * > Renames
Context object for machine code objects.
Definition MCContext.h:83
LLVM_ABI const MCTargetOptions * getTargetOptions() const
LLVM_ABI MCSectionELF * createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, const MCSectionELF *RelInfoSection)
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition MCContext.h:550
LLVM_ABI void reportError(SMLoc L, const Twine &Msg)
LLVM_ABI MCSectionELF * createELFGroupSection(const MCSymbolELF *Group, bool IsComdat)
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
LLVM_ABI bool evaluateKnownAbsolute(int64_t &Res, const MCAssembler &Asm) const
Aggressive variant of evaluateAsRelocatable when relocations are unavailable (e.g.
Definition MCExpr.cpp:250
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition MCFixup.h:61
MCSection * getParent() const
Definition MCSection.h:181
MutableArrayRef< std::pair< std::string, size_t > > getFileNames()
virtual void setAssembler(MCAssembler *A)
std::vector< const MCSymbol * > & getAddrsigSyms()
virtual void reset()
lifetime management
std::vector< const MCSymbol * > AddrsigSyms
MCContext & getContext() const
This represents a section on linux, lots of unix variants and some bare metal systems.
const MCSection * getLinkedToSection() const
unsigned getFlags() const
void setOffsets(uint64_t Start, uint64_t End)
const MCSymbolELF * getGroup() const
unsigned getType() const
bool isComdat() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:569
void setAlignment(Align Value)
Definition MCSection.h:654
unsigned getOrdinal() const
Definition MCSection.h:662
Align getAlign() const
Definition MCSection.h:653
void setOrdinal(unsigned Value)
Definition MCSection.h:663
StringRef getName() const
Definition MCSection.h:639
MCSymbol * getBeginSymbol()
Definition MCSection.h:642
unsigned getType() const
const MCExpr * getSize() const
Definition MCSymbolELF.h:26
Represent a reference to a symbol from inside an expression.
Definition MCExpr.h:190
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
Definition MCSymbol.h:237
bool isCommon() const
Is this a 'common' symbol.
Definition MCSymbol.h:343
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition MCSymbol.h:267
MaybeAlign getCommonAlignment() const
Return the alignment of a 'common' symbol.
Definition MCSymbol.h:322
void setUsedInReloc() const
Definition MCSymbol.h:198
uint32_t getIndex() const
Get the (implementation defined) index.
Definition MCSymbol.h:280
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition MCSymbol.h:251
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
Definition MCSymbol.h:270
RelocSectionSymType RelocSectionSym
DebugCompressionType CompressDebugSections
Represents a location in source code.
Definition SMLoc.h:22
void resize(size_type N)
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
static constexpr size_t npos
Definition StringRef.h:57
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:591
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition StringRef.h:290
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition StringRef.h:270
LLVM_ABI size_t getOffset(CachedHashStringRef S) const
Get the offest of a string in the string table.
LLVM_ABI size_t add(CachedHashStringRef S, uint8_t Priority=0)
Add a string to the builder.
LLVM_ABI void write(raw_ostream &OS) const
LLVM_ABI void finalize()
Analyze the strings and build the final table.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
An abstract base class for streams implementations that also support a pwrite operation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const char SectionName[]
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ Entry
Definition COFF.h:862
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition CallingConv.h:76
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ EV_CURRENT
Definition ELF.h:130
uint64_t Elf64_Xword
Definition ELF.h:43
void encodeCrel(raw_ostream &OS, RelocsTy Relocs, F ToCrel)
Definition MCELFExtras.h:25
@ SHN_XINDEX
Definition ELF.h:1141
@ SHN_ABS
Definition ELF.h:1139
@ SHN_COMMON
Definition ELF.h:1140
@ SHN_UNDEF
Definition ELF.h:1133
@ SHN_LORESERVE
Definition ELF.h:1134
@ SHF_MERGE
Definition ELF.h:1255
@ SHF_INFO_LINK
Definition ELF.h:1261
@ SHF_EXCLUDE
Definition ELF.h:1283
@ SHF_ALLOC
Definition ELF.h:1249
@ SHF_LINK_ORDER
Definition ELF.h:1264
@ SHF_GROUP
Definition ELF.h:1271
@ SHF_COMPRESSED
Definition ELF.h:1277
@ SHF_WRITE
Definition ELF.h:1246
@ SHF_TLS
Definition ELF.h:1274
@ SHF_EXECINSTR
Definition ELF.h:1252
@ EI_PAD
Definition ELF.h:60
@ EI_NIDENT
Definition ELF.h:61
@ EM_386
Definition ELF.h:141
@ EM_MIPS
Definition ELF.h:146
uint32_t Elf32_Word
Definition ELF.h:35
static const char ElfMagic[]
Definition ELF.h:47
@ SHT_STRTAB
Definition ELF.h:1150
@ SHT_GROUP
Definition ELF.h:1162
@ SHT_REL
Definition ELF.h:1156
@ SHT_LLVM_CALL_GRAPH_PROFILE
Definition ELF.h:1185
@ SHT_NOBITS
Definition ELF.h:1155
@ SHT_SYMTAB
Definition ELF.h:1149
@ SHT_CREL
Definition ELF.h:1169
@ SHT_DYNAMIC
Definition ELF.h:1153
@ SHT_SYMTAB_SHNDX
Definition ELF.h:1163
@ SHT_LLVM_ADDRSIG
Definition ELF.h:1177
@ SHT_RELA
Definition ELF.h:1151
@ SHT_DYNSYM
Definition ELF.h:1158
@ ELFOSABI_GNU
Definition ELF.h:349
@ ELFOSABI_NONE
Definition ELF.h:346
@ STB_LOCAL
Definition ELF.h:1405
@ STB_WEAK
Definition ELF.h:1407
@ ELFCOMPRESS_ZSTD
Definition ELF.h:2048
@ ELFCOMPRESS_ZLIB
Definition ELF.h:2047
@ ELFDATA2MSB
Definition ELF.h:341
@ ELFDATA2LSB
Definition ELF.h:340
@ STT_FUNC
Definition ELF.h:1419
@ STT_NOTYPE
Definition ELF.h:1417
@ STT_SECTION
Definition ELF.h:1420
@ STT_FILE
Definition ELF.h:1421
@ STT_GNU_IFUNC
Definition ELF.h:1424
@ STT_OBJECT
Definition ELF.h:1418
@ STT_TLS
Definition ELF.h:1423
@ ELFCLASS64
Definition ELF.h:334
@ ELFCLASS32
Definition ELF.h:333
@ ET_REL
Definition ELF.h:119
uint32_t Elf64_Word
Definition ELF.h:41
@ SYMENTRY_SIZE32
Definition ELF.h:1399
@ SYMENTRY_SIZE64
Definition ELF.h:1400
@ GRP_COMDAT
Definition ELF.h:1352
@ STV_DEFAULT
Definition ELF.h:1435
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Offsets
Offsets in bytes from the start of the input buffer.
LLVM_ABI void compress(Params P, ArrayRef< uint8_t > Input, SmallVectorImpl< uint8_t > &Output)
support::ulittle32_t Word
Definition IRSymtab.h:53
bool isRelocRelocation(MCFixupKind FixupKind)
Definition MCFixup.h:135
Context & getContext() const
Definition BasicBlock.h:99
value_type byte_swap(value_type value, endianness endian)
Definition Endian.h:44
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
@ Other
Any other memory.
Definition ModRef.h:68
@ FirstLiteralRelocationKind
Definition MCFixup.h:29
DebugCompressionType
Definition Compression.h:28
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue)
Definition DWP.cpp:677
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition LEB128.h:79
endianness
Definition bit.h:71
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
Elf32_Word r_info
Definition ELF.h:1471
void setSymbolAndType(Elf32_Word s, unsigned char t)
Definition ELF.h:1480
void setSymbolAndType(Elf64_Word s, Elf64_Word t)
Definition ELF.h:1516
Elf64_Xword r_info
Definition ELF.h:1507