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