LLVM 22.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 && 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 : DebugCompressionType::None;
729 if (CompressionType == DebugCompressionType::None ||
730 !SectionName.starts_with(".debug_")) {
731 Asm.writeSectionData(W.OS, &Section);
732 return;
733 }
734
735 SmallVector<char, 128> UncompressedData;
736 raw_svector_ostream VecOS(UncompressedData);
737 Asm.writeSectionData(VecOS, &Section);
738 ArrayRef<uint8_t> Uncompressed =
739 ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
740 UncompressedData.size());
741
742 SmallVector<uint8_t, 128> Compressed;
743 uint32_t ChType;
744 switch (CompressionType) {
745 case DebugCompressionType::None:
746 llvm_unreachable("has been handled");
747 case DebugCompressionType::Zlib:
748 ChType = ELF::ELFCOMPRESS_ZLIB;
749 break;
750 case DebugCompressionType::Zstd:
751 ChType = ELF::ELFCOMPRESS_ZSTD;
752 break;
753 }
754 compression::compress(compression::Params(CompressionType), Uncompressed,
755 Compressed);
756 if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
757 Sec.getAlign())) {
758 W.OS << UncompressedData;
759 return;
760 }
761
762 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
763 // Alignment field should reflect the requirements of
764 // the compressed section header.
765 Section.setAlignment(is64Bit() ? Align(8) : Align(4));
766 W.OS << toStringRef(Compressed);
767}
768
769void ELFWriter::writeSectionHeaderEntry(uint32_t Name, uint32_t Type,
770 uint64_t Flags, uint64_t Address,
771 uint64_t Offset, uint64_t Size,
772 uint32_t Link, uint32_t Info,
773 MaybeAlign Alignment,
774 uint64_t EntrySize) {
775 W.write<uint32_t>(Name); // sh_name: index into string table
776 W.write<uint32_t>(Type); // sh_type
777 writeWord(Flags); // sh_flags
778 writeWord(Address); // sh_addr
779 writeWord(Offset); // sh_offset
780 writeWord(Size); // sh_size
781 W.write<uint32_t>(Link); // sh_link
782 W.write<uint32_t>(Info); // sh_info
783 writeWord(Alignment ? Alignment->value() : 0); // sh_addralign
784 writeWord(EntrySize); // sh_entsize
785}
786
787template <bool Is64>
789 using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
790 ELF::encodeCrel<Is64>(OS, Relocs, [&](const ELFRelocationEntry &R) {
791 uint32_t SymIdx = R.Symbol ? R.Symbol->getIndex() : 0;
792 return ELF::Elf_Crel<Is64>{static_cast<uint>(R.Offset), SymIdx, R.Type,
793 std::make_signed_t<uint>(R.Addend)};
794 });
795}
796
797void ELFWriter::writeRelocations(const MCSectionELF &Sec) {
798 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
799 const MCTargetOptions *TO = getContext().getTargetOptions();
800 const bool Rela = OWriter.usesRela(TO, Sec);
801
802 // Sort the relocation entries. MIPS needs this.
803 OWriter.TargetObjectWriter->sortRelocs(Relocs);
804
805 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
806 for (const ELFRelocationEntry &Entry : Relocs) {
807 uint32_t SymIdx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
808 if (is64Bit()) {
809 write(Entry.Offset);
810 write(uint32_t(SymIdx));
811 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
812 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
813 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
814 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
815 if (Rela)
816 write(Entry.Addend);
817 } else {
818 write(uint32_t(Entry.Offset));
819 ELF::Elf32_Rela ERE32;
820 ERE32.setSymbolAndType(SymIdx, Entry.Type);
821 write(ERE32.r_info);
822 if (Rela)
823 write(uint32_t(Entry.Addend));
824 if (uint32_t RType =
825 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
826 write(uint32_t(Entry.Offset));
827 ERE32.setSymbolAndType(0, RType);
828 write(ERE32.r_info);
829 write(uint32_t(0));
830 }
831 if (uint32_t RType =
832 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
833 write(uint32_t(Entry.Offset));
834 ERE32.setSymbolAndType(0, RType);
835 write(ERE32.r_info);
836 write(uint32_t(0));
837 }
838 }
839 }
840 } else if (TO && TO->Crel) {
841 if (is64Bit())
842 encodeCrel<true>(Relocs, W.OS);
843 else
844 encodeCrel<false>(Relocs, W.OS);
845 } else {
846 for (const ELFRelocationEntry &Entry : Relocs) {
847 uint32_t Symidx = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
848 if (is64Bit()) {
849 write(Entry.Offset);
850 ELF::Elf64_Rela ERE;
851 ERE.setSymbolAndType(Symidx, Entry.Type);
852 write(ERE.r_info);
853 if (Rela)
854 write(Entry.Addend);
855 } else {
856 write(uint32_t(Entry.Offset));
857 ELF::Elf32_Rela ERE;
858 ERE.setSymbolAndType(Symidx, Entry.Type);
859 write(ERE.r_info);
860 if (Rela)
861 write(uint32_t(Entry.Addend));
862 }
863 }
864 }
865}
866
867void ELFWriter::writeSectionHeader(uint32_t GroupSymbolIndex, uint64_t Offset,
868 uint64_t Size, const MCSectionELF &Section) {
869 uint64_t sh_link = 0;
870 uint64_t sh_info = 0;
871
872 switch(Section.getType()) {
873 default:
874 // Nothing to do.
875 break;
876
877 case ELF::SHT_DYNAMIC:
878 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
879
880 case ELF::SHT_REL:
881 case ELF::SHT_RELA:
882 case ELF::SHT_CREL: {
883 sh_link = SymbolTableIndex;
884 assert(sh_link && ".symtab not found");
885 const MCSection *InfoSection = Section.getLinkedToSection();
886 sh_info = InfoSection->getOrdinal();
887 break;
888 }
889
890 case ELF::SHT_SYMTAB:
891 sh_link = StringTableIndex;
892 sh_info = LastLocalSymbolIndex;
893 break;
894
898 sh_link = SymbolTableIndex;
899 break;
900
901 case ELF::SHT_GROUP:
902 sh_link = SymbolTableIndex;
903 sh_info = GroupSymbolIndex;
904 break;
905 }
906
907 if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
908 // If the value in the associated metadata is not a definition, Sym will be
909 // undefined. Represent this with sh_link=0.
910 const MCSymbol *Sym = Section.getLinkedToSymbol();
911 if (Sym && Sym->isInSection())
912 sh_link = Sym->getSection().getOrdinal();
913 }
914
915 writeSectionHeaderEntry(StrTabBuilder.getOffset(Section.getName()),
916 Section.getType(), Section.getFlags(), 0, Offset,
917 Size, sh_link, sh_info, Section.getAlign(),
918 Section.getEntrySize());
919}
920
921void ELFWriter::writeSectionHeaders() {
922 uint64_t Start = W.OS.tell();
923 const unsigned NumSections = SectionTable.size();
924
925 // Null section first.
926 uint64_t FirstSectionSize =
927 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
928 writeSectionHeaderEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt,
929 0);
930
931 for (const MCSectionELF *Section : SectionTable) {
932 uint32_t GroupSymbolIndex;
933 unsigned Type = Section->getType();
934 if (Type != ELF::SHT_GROUP)
935 GroupSymbolIndex = 0;
936 else
937 GroupSymbolIndex = Section->getGroup()->getIndex();
938
939 std::pair<uint64_t, uint64_t> Offsets = Section->getOffsets();
940 uint64_t Size;
941 if (Type == ELF::SHT_NOBITS)
942 Size = Asm.getSectionAddressSize(*Section);
943 else
944 Size = Offsets.second - Offsets.first;
945
946 auto SectionHasFlag = [&](uint64_t Flag) -> bool {
947 return Section->getFlags() & Flag;
948 };
949
950 if (Mode == DwoOnly) {
951 stats::DwoBytes += Size;
952 } else if (Section->getName().starts_with(".debug")) {
953 stats::DebugBytes += Size;
954 } else if (Section->getName().starts_with(".eh_frame")) {
955 stats::UnwindBytes += Size;
956 } else if (SectionHasFlag(ELF::SHF_ALLOC)) {
957 if (SectionHasFlag(ELF::SHF_EXECINSTR)) {
958 stats::AllocTextBytes += Size;
959 } else if (SectionHasFlag(ELF::SHF_WRITE)) {
960 stats::AllocRWBytes += Size;
961 } else {
962 stats::AllocROBytes += Size;
963 }
964 } else {
965 switch (Section->getType()) {
966 case ELF::SHT_STRTAB:
967 stats::StrtabBytes += Size;
968 break;
969 case ELF::SHT_SYMTAB:
970 stats::SymtabBytes += Size;
971 break;
972 case ELF::SHT_DYNSYM:
973 stats::DynsymBytes += Size;
974 break;
975 case ELF::SHT_REL:
976 case ELF::SHT_RELA:
977 case ELF::SHT_CREL:
978 stats::RelocationBytes += Size;
979 break;
980 default:
981 stats::OtherBytes += Size;
982 break;
983 }
984 }
985
986 writeSectionHeader(GroupSymbolIndex, Offsets.first, Size, *Section);
987 }
988
989 stats::SectionHeaderBytes += W.OS.tell() - Start;
990}
991
992uint64_t ELFWriter::writeObject() {
993 uint64_t StartOffset = W.OS.tell();
994
995 MCContext &Ctx = getContext();
996 MCSectionELF *StrtabSection =
997 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
998 StringTableIndex = addToSectionTable(StrtabSection);
999
1000 RevGroupMapTy RevGroupMap;
1001
1002 // Write out the ELF header ...
1003 writeHeader();
1004
1005 stats::ELFHeaderBytes += W.OS.tell() - StartOffset;
1006
1007 // ... then the sections ...
1009 // Map from group section index to group
1010 SmallVector<unsigned, 0> GroupMap;
1011 SmallVector<MCSectionELF *> Relocations;
1012 for (MCSection &Sec : Asm) {
1013 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
1014 if (Mode == NonDwoOnly && isDwoSection(Section))
1015 continue;
1016 if (Mode == DwoOnly && !isDwoSection(Section))
1017 continue;
1018
1019 // Remember the offset into the file for this section.
1020 const uint64_t SecStart = align(Section.getAlign());
1021
1022 const MCSymbolELF *SignatureSymbol = Section.getGroup();
1023 writeSectionData(Section);
1024
1025 uint64_t SecEnd = W.OS.tell();
1026 Section.setOffsets(SecStart, SecEnd);
1027
1028 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
1029
1030 unsigned *GroupIdxEntry = nullptr;
1031 if (SignatureSymbol) {
1032 GroupIdxEntry = &RevGroupMap[SignatureSymbol];
1033 if (!*GroupIdxEntry) {
1034 MCSectionELF *Group =
1035 Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
1036 *GroupIdxEntry = addToSectionTable(Group);
1037 Group->setAlignment(Align(4));
1038
1039 GroupMap.resize(*GroupIdxEntry + 1);
1040 GroupMap[*GroupIdxEntry] = Groups.size();
1041 Groups.emplace_back(Group, SmallVector<unsigned>{});
1042 }
1043 }
1044
1045 Section.setOrdinal(addToSectionTable(&Section));
1046 if (RelSection) {
1047 RelSection->setOrdinal(addToSectionTable(RelSection));
1048 Relocations.push_back(RelSection);
1049 }
1050
1051 if (GroupIdxEntry) {
1052 auto &Members = Groups[GroupMap[*GroupIdxEntry]];
1053 Members.second.push_back(Section.getOrdinal());
1054 if (RelSection)
1055 Members.second.push_back(RelSection->getOrdinal());
1056 }
1057 }
1058
1059 for (auto &[Group, Members] : Groups) {
1060 // Remember the offset into the file for this section.
1061 const uint64_t SecStart = align(Group->getAlign());
1062
1063 write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));
1064 W.write<unsigned>(Members);
1065
1066 uint64_t SecEnd = W.OS.tell();
1067 Group->setOffsets(SecStart, SecEnd);
1068 }
1069
1070 if (Mode == DwoOnly) {
1071 // dwo files don't have symbol tables or relocations, but they do have
1072 // string tables.
1073 StrTabBuilder.finalize();
1074 } else {
1075 MCSectionELF *AddrsigSection;
1076 if (OWriter.getEmitAddrsigSection()) {
1077 AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,
1079 addToSectionTable(AddrsigSection);
1080 }
1081
1082 // Compute symbol table information.
1083 computeSymbolTable(RevGroupMap);
1084
1085 for (MCSectionELF *RelSection : Relocations) {
1086 // Remember the offset into the file for this section.
1087 const uint64_t SecStart = align(RelSection->getAlign());
1088
1089 writeRelocations(
1090 static_cast<const MCSectionELF &>(*RelSection->getLinkedToSection()));
1091
1092 uint64_t SecEnd = W.OS.tell();
1093 RelSection->setOffsets(SecStart, SecEnd);
1094 }
1095
1096 if (OWriter.getEmitAddrsigSection()) {
1097 uint64_t SecStart = W.OS.tell();
1098 writeAddrsigSection();
1099 uint64_t SecEnd = W.OS.tell();
1100 AddrsigSection->setOffsets(SecStart, SecEnd);
1101 }
1102 }
1103
1104 {
1105 uint64_t SecStart = W.OS.tell();
1106 StrTabBuilder.write(W.OS);
1107 StrtabSection->setOffsets(SecStart, W.OS.tell());
1108 }
1109
1110 const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
1111
1112 // ... then the section header table ...
1113 writeSectionHeaders();
1114
1115 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1116 (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1117 : SectionTable.size() + 1,
1118 W.Endian);
1119 unsigned NumSectionsOffset;
1120
1121 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
1122 if (is64Bit()) {
1123 uint64_t Val =
1124 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1125 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1126 offsetof(ELF::Elf64_Ehdr, e_shoff));
1127 NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
1128 } else {
1129 uint32_t Val =
1130 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1131 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1132 offsetof(ELF::Elf32_Ehdr, e_shoff));
1133 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
1134 }
1135 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1136 NumSectionsOffset);
1137
1138 return W.OS.tell() - StartOffset;
1139}
1140
1141ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1143 : TargetObjectWriter(std::move(MOTW)), OS(OS),
1145ELFObjectWriter::ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1148 : TargetObjectWriter(std::move(MOTW)), OS(OS), DwoOS(&DwoOS),
1150
1152 ELFHeaderEFlags = 0;
1153 SeenGnuAbi = false;
1154 OverrideABIVersion.reset();
1155 Relocations.clear();
1156 Renames.clear();
1157 Weakrefs.clear();
1158 Symvers.clear();
1159 SeenGnuAbi = false;
1161}
1162
1167
1169 return TargetObjectWriter->hasRelocationAddend();
1170}
1171
1173 // The presence of symbol versions causes undefined symbols and
1174 // versions declared with @@@ to be renamed.
1175 for (const Symver &S : Symvers) {
1176 StringRef AliasName = S.Name;
1177 auto &Symbol = static_cast<const MCSymbolELF &>(*S.Sym);
1178 size_t Pos = AliasName.find('@');
1179 assert(Pos != StringRef::npos);
1180
1181 StringRef Prefix = AliasName.substr(0, Pos);
1182 StringRef Rest = AliasName.substr(Pos);
1183 StringRef Tail = Rest;
1184 if (Rest.starts_with("@@@"))
1185 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1186
1187 auto *Alias = static_cast<MCSymbolELF *>(
1188 Asm->getContext().getOrCreateSymbol(Prefix + Tail));
1189 Asm->registerSymbol(*Alias);
1190 const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm->getContext());
1191 Alias->setVariableValue(Value);
1192
1193 // Aliases defined with .symvar copy the binding from the symbol they alias.
1194 // This is the first place we are able to copy this information.
1195 Alias->setBinding(Symbol.getBinding());
1196 Alias->setVisibility(Symbol.getVisibility());
1197 Alias->setOther(Symbol.getOther());
1198
1199 if (!Symbol.isUndefined() && S.KeepOriginalSym)
1200 continue;
1201
1202 if (Symbol.isUndefined() && Rest.starts_with("@@") &&
1203 !Rest.starts_with("@@@")) {
1204 Asm->getContext().reportError(S.Loc, "default version symbol " +
1205 AliasName + " must be defined");
1206 continue;
1207 }
1208
1209 if (auto It = Renames.find(&Symbol);
1210 It != Renames.end() && It->second != Alias) {
1211 Asm->getContext().reportError(S.Loc, Twine("multiple versions for ") +
1212 Symbol.getName());
1213 continue;
1214 }
1215
1216 Renames.insert(std::make_pair(&Symbol, Alias));
1217 }
1218
1219 for (const MCSymbol *&Sym : AddrsigSyms) {
1220 if (const MCSymbol *R =
1221 Renames.lookup(static_cast<const MCSymbolELF *>(Sym)))
1222 Sym = R;
1223 if (Sym->isInSection() && Sym->getName().starts_with(".L"))
1224 Sym = Sym->getSection().getBeginSymbol();
1225 Sym->setUsedInReloc();
1226 }
1227
1228 // For each `.weakref alias, target`, if the variable `alias` is registered
1229 // (typically through MCObjectStreamer::visitUsedSymbol), register `target`.
1230 // If `target` was unregistered before (not directly referenced or defined),
1231 // make it weak.
1232 for (const MCSymbol *Alias : Weakrefs) {
1233 if (!Alias->isRegistered())
1234 continue;
1235 auto *Expr = Alias->getVariableValue();
1236 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1237 auto &Sym = static_cast<const MCSymbolELF &>(Inner->getSymbol());
1238 if (Asm->registerSymbol(Sym))
1239 Sym.setBinding(ELF::STB_WEAK);
1240 }
1241 }
1242}
1243
1244// It is always valid to create a relocation with a symbol. It is preferable
1245// to use a relocation with a section if that is possible. Using the section
1246// allows us to omit some local symbols from the symbol table.
1248 const MCSymbolELF *Sym, uint64_t C,
1249 unsigned Type) const {
1250 // Keep symbol type for a local ifunc because it may result in an IRELATIVE
1251 // reloc that the dynamic loader will use to resolve the address at startup
1252 // time.
1253 if (Sym->getType() == ELF::STT_GNU_IFUNC)
1254 return false;
1255
1256 // If a relocation points to a mergeable section, we have to be careful.
1257 // If the offset is zero, a relocation with the section will encode the
1258 // same information. With a non-zero offset, the situation is different.
1259 // For example, a relocation can point 42 bytes past the end of a string.
1260 // If we change such a relocation to use the section, the linker would think
1261 // that it pointed to another string and subtracting 42 at runtime will
1262 // produce the wrong value.
1263 if (Sym->isInSection()) {
1264 auto &Sec = static_cast<const MCSectionELF &>(Sym->getSection());
1265 unsigned Flags = Sec.getFlags();
1266 if (Flags & ELF::SHF_MERGE) {
1267 if (C != 0)
1268 return false;
1269
1270 // gold<2.34 incorrectly ignored the addend for R_386_GOTOFF (9)
1271 // (http://sourceware.org/PR16794).
1272 if (TargetObjectWriter->getEMachine() == ELF::EM_386 &&
1273 Type == ELF::R_386_GOTOFF)
1274 return false;
1275
1276 // ld.lld handles R_MIPS_HI16/R_MIPS_LO16 separately, not as a whole, so
1277 // it doesn't know that an R_MIPS_HI16 with implicit addend 1 and an
1278 // R_MIPS_LO16 with implicit addend -32768 represents 32768, which is in
1279 // range of a MergeInputSection. We could introduce a new RelExpr member
1280 // (like R_RISCV_PC_INDIRECT for R_RISCV_PCREL_HI20 / R_RISCV_PCREL_LO12)
1281 // but the complexity is unnecessary given that GNU as keeps the original
1282 // symbol for this case as well.
1283 if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS &&
1285 return false;
1286 }
1287
1288 // Most TLS relocations use a got, so they need the symbol. Even those that
1289 // are just an offset (@tpoff), require a symbol in gold versions before
1290 // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
1291 // http://sourceware.org/PR16773.
1292 if (Flags & ELF::SHF_TLS)
1293 return false;
1294 }
1295
1296 return !TargetObjectWriter->needsRelocateWithSymbol(Val, Type);
1297}
1298
1300 const MCSectionELF *To) {
1301 if (isDwoSection(*From)) {
1302 getContext().reportError(Loc, "A dwo section may not contain relocations");
1303 return false;
1304 }
1305 if (To && isDwoSection(*To)) {
1307 "A relocation may not refer to a dwo section");
1308 return false;
1309 }
1310 return true;
1311}
1312
1314 const MCFixup &Fixup, MCValue Target,
1315 uint64_t &FixedValue) {
1316 auto &Section = static_cast<const MCSectionELF &>(*F.getParent());
1317 MCContext &Ctx = getContext();
1318
1319 auto *SymA = static_cast<const MCSymbolELF *>(Target.getAddSym());
1320 const MCSectionELF *SecA =
1321 (SymA && SymA->isInSection())
1322 ? static_cast<const MCSectionELF *>(&SymA->getSection())
1323 : nullptr;
1324 if (DwoOS && !checkRelocation(Fixup.getLoc(), &Section, SecA))
1325 return;
1326
1327 bool IsPCRel = Fixup.isPCRel();
1328 uint64_t FixupOffset = Asm->getFragmentOffset(F) + Fixup.getOffset();
1329 uint64_t Addend = Target.getConstant();
1330 if (auto *RefB = Target.getSubSym()) {
1331 auto &SymB = static_cast<const MCSymbolELF &>(*RefB);
1332 if (SymB.isUndefined()) {
1333 Ctx.reportError(Fixup.getLoc(),
1334 Twine("symbol '") + SymB.getName() +
1335 "' can not be undefined in a subtraction expression");
1336 return;
1337 }
1338
1339 assert(!SymB.isAbsolute() && "Should have been folded");
1340 const MCSection &SecB = SymB.getSection();
1341 if (&SecB != &Section) {
1342 Ctx.reportError(Fixup.getLoc(),
1343 "Cannot represent a difference across sections");
1344 return;
1345 }
1346
1347 assert(!IsPCRel && "should have been folded");
1348 IsPCRel = true;
1349 Addend += FixupOffset - Asm->getSymbolOffset(SymB);
1350 }
1351
1352 unsigned Type;
1353 if (mc::isRelocRelocation(Fixup.getKind()))
1355 else
1356 Type = TargetObjectWriter->getRelocType(Fixup, Target, IsPCRel);
1357
1358 // Convert SymA to an STT_SECTION symbol if it's defined, local, and meets
1359 // specific conditions, unless it's a .reloc directive, which disables
1360 // STT_SECTION adjustment.
1361 bool UseSectionSym = SymA && SymA->getBinding() == ELF::STB_LOCAL &&
1362 !SymA->isUndefined() &&
1363 !mc::isRelocRelocation(Fixup.getKind());
1364 if (UseSectionSym && useSectionSymbol(Target, SymA, Addend, Type)) {
1365 Addend += Asm->getSymbolOffset(*SymA);
1366 SymA = static_cast<const MCSymbolELF *>(SecA->getBeginSymbol());
1367 } else if (const MCSymbolELF *R = Renames.lookup(SymA)) {
1368 SymA = R;
1369 }
1370 if (SymA)
1371 SymA->setUsedInReloc();
1372
1373 FixedValue = usesRela(Ctx.getTargetOptions(), Section) ? 0 : Addend;
1374 Relocations[&Section].emplace_back(FixupOffset, SymA, Type, Addend);
1375}
1376
1378 const MCSectionELF &Sec) const {
1379 return (hasRelocationAddend() &&
1381 (TO && TO->Crel);
1382}
1383
1385 const MCSymbol &SA, const MCFragment &FB, bool InSet, bool IsPCRel) const {
1386 auto &SymA = static_cast<const MCSymbolELF &>(SA);
1387 if (IsPCRel) {
1388 assert(!InSet);
1389 if (SymA.getBinding() != ELF::STB_LOCAL ||
1390 SymA.getType() == ELF::STT_GNU_IFUNC)
1391 return false;
1392 }
1393 return &SymA.getSection() == FB.getParent();
1394}
1395
1397 uint64_t Size =
1398 ELFWriter(*Asm, *this, OS, IsLittleEndian,
1399 DwoOS ? ELFWriter::NonDwoOnly : ELFWriter::AllSections)
1400 .writeObject();
1401 if (DwoOS)
1402 Size += ELFWriter(*Asm, *this, *DwoOS, IsLittleEndian, ELFWriter::DwoOnly)
1403 .writeObject();
1404 return Size;
1405}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define offsetof(TYPE, MEMBER)
Analysis containing CSE Info
Definition CSEInfo.cpp:27
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)
lazy value info
#define F(x, y, z)
Definition MD5.cpp:55
#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:167
This file contains some functions that are useful when dealing with strings.
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:41
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:142
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 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:549
LLVM_ABI void reportError(SMLoc L, const Twine &Msg)
const MCTargetOptions * getTargetOptions() const
Definition MCContext.h:420
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:158
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:496
void setAlignment(Align Value)
Definition MCSection.h:580
unsigned getOrdinal() const
Definition MCSection.h:588
Align getAlign() const
Definition MCSection.h:579
void setOrdinal(unsigned Value)
Definition MCSection.h:589
StringRef getName() const
Definition MCSection.h:565
MCSymbol * getBeginSymbol()
Definition MCSection.h:568
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:344
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:323
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
DebugCompressionType CompressDebugSections
Represents a location in source code.
Definition SMLoc.h:23
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
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:581
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:269
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition StringRef.h:301
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition StringRef.h:281
static constexpr size_t npos
Definition StringRef.h:57
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:45
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
@ SYMENTRY_SIZE32
Definition ELF.h:1390
@ SYMENTRY_SIZE64
Definition ELF.h:1391
@ GRP_COMDAT
Definition ELF.h:1343
@ 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
@ SHT_STRTAB
Definition ELF.h:1142
@ SHT_GROUP
Definition ELF.h:1154
@ SHT_REL
Definition ELF.h:1148
@ SHT_LLVM_CALL_GRAPH_PROFILE
Definition ELF.h:1177
@ SHT_NOBITS
Definition ELF.h:1147
@ SHT_SYMTAB
Definition ELF.h:1141
@ SHT_CREL
Definition ELF.h:1161
@ SHT_DYNAMIC
Definition ELF.h:1145
@ SHT_SYMTAB_SHNDX
Definition ELF.h:1155
@ SHT_LLVM_ADDRSIG
Definition ELF.h:1169
@ SHT_RELA
Definition ELF.h:1143
@ SHT_DYNSYM
Definition ELF.h:1150
static const char ElfMagic[]
Definition ELF.h:47
@ SHF_MERGE
Definition ELF.h:1246
@ SHF_INFO_LINK
Definition ELF.h:1252
@ SHF_EXCLUDE
Definition ELF.h:1274
@ SHF_ALLOC
Definition ELF.h:1240
@ SHF_LINK_ORDER
Definition ELF.h:1255
@ SHF_GROUP
Definition ELF.h:1262
@ SHF_COMPRESSED
Definition ELF.h:1268
@ SHF_WRITE
Definition ELF.h:1237
@ SHF_TLS
Definition ELF.h:1265
@ SHF_EXECINSTR
Definition ELF.h:1243
@ ELFOSABI_GNU
Definition ELF.h:349
@ ELFOSABI_NONE
Definition ELF.h:346
@ STT_FUNC
Definition ELF.h:1410
@ STT_NOTYPE
Definition ELF.h:1408
@ STT_SECTION
Definition ELF.h:1411
@ STT_FILE
Definition ELF.h:1412
@ STT_GNU_IFUNC
Definition ELF.h:1415
@ STT_OBJECT
Definition ELF.h:1409
@ STT_TLS
Definition ELF.h:1414
@ ELFDATA2MSB
Definition ELF.h:341
@ ELFDATA2LSB
Definition ELF.h:340
@ STV_DEFAULT
Definition ELF.h:1426
@ ELFCLASS64
Definition ELF.h:334
@ ELFCLASS32
Definition ELF.h:333
@ ET_REL
Definition ELF.h:119
uint32_t Elf64_Word
Definition ELF.h:41
@ STB_LOCAL
Definition ELF.h:1396
@ STB_WEAK
Definition ELF.h:1398
@ ELFCOMPRESS_ZSTD
Definition ELF.h:2038
@ ELFCOMPRESS_ZLIB
Definition ELF.h:2037
@ SHN_XINDEX
Definition ELF.h:1133
@ SHN_ABS
Definition ELF.h:1131
@ SHN_COMMON
Definition ELF.h:1132
@ SHN_UNDEF
Definition ELF.h:1125
@ SHN_LORESERVE
Definition ELF.h:1126
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:477
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:1685
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:2474
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
Definition DWP.cpp:622
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
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
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:155
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:1869
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:81
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:851
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:85
Elf32_Word r_info
Definition ELF.h:1462
void setSymbolAndType(Elf32_Word s, unsigned char t)
Definition ELF.h:1471
void setSymbolAndType(Elf64_Word s, Elf64_Word t)
Definition ELF.h:1507
Elf64_Xword r_info
Definition ELF.h:1498