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