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(
915 StrTabBuilder.getOffset(Section.getName()), Section.getType(),
916 Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
917 Section.getAlignmentForObjectFile(Size), 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")))
static const char * name
This file contains some templates that are useful if you are working with the STL at all.
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:551
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:167
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:516
void setAlignment(Align Value)
Definition MCSection.h:601
unsigned getOrdinal() const
Definition MCSection.h:622
Align getAlign() const
Definition MCSection.h:600
void setOrdinal(unsigned Value)
Definition MCSection.h:623
StringRef getName() const
Definition MCSection.h:586
MCSymbol * getBeginSymbol()
Definition MCSection.h:589
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