Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lld/ELF/InputFiles.h
34869 views
1
//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
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
#ifndef LLD_ELF_INPUT_FILES_H
10
#define LLD_ELF_INPUT_FILES_H
11
12
#include "Config.h"
13
#include "Symbols.h"
14
#include "lld/Common/ErrorHandler.h"
15
#include "lld/Common/LLVM.h"
16
#include "lld/Common/Reproduce.h"
17
#include "llvm/ADT/DenseSet.h"
18
#include "llvm/BinaryFormat/Magic.h"
19
#include "llvm/Object/ELF.h"
20
#include "llvm/Support/MemoryBufferRef.h"
21
#include "llvm/Support/Threading.h"
22
23
namespace llvm {
24
struct DILineInfo;
25
class TarWriter;
26
namespace lto {
27
class InputFile;
28
}
29
} // namespace llvm
30
31
namespace lld {
32
class DWARFCache;
33
34
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
35
std::string toString(const elf::InputFile *f);
36
37
namespace elf {
38
39
class InputSection;
40
class Symbol;
41
42
// If --reproduce is specified, all input files are written to this tar archive.
43
extern std::unique_ptr<llvm::TarWriter> tar;
44
45
// Opens a given file.
46
std::optional<MemoryBufferRef> readFile(StringRef path);
47
48
// Add symbols in File to the symbol table.
49
void parseFile(InputFile *file);
50
void parseFiles(const std::vector<InputFile *> &files,
51
InputFile *armCmseImpLib);
52
53
// The root class of input files.
54
class InputFile {
55
protected:
56
std::unique_ptr<Symbol *[]> symbols;
57
uint32_t numSymbols = 0;
58
SmallVector<InputSectionBase *, 0> sections;
59
60
public:
61
enum Kind : uint8_t {
62
ObjKind,
63
SharedKind,
64
BitcodeKind,
65
BinaryKind,
66
InternalKind,
67
};
68
69
InputFile(Kind k, MemoryBufferRef m);
70
Kind kind() const { return fileKind; }
71
72
bool isElf() const {
73
Kind k = kind();
74
return k == ObjKind || k == SharedKind;
75
}
76
bool isInternal() const { return kind() == InternalKind; }
77
78
StringRef getName() const { return mb.getBufferIdentifier(); }
79
MemoryBufferRef mb;
80
81
// Returns sections. It is a runtime error to call this function
82
// on files that don't have the notion of sections.
83
ArrayRef<InputSectionBase *> getSections() const {
84
assert(fileKind == ObjKind || fileKind == BinaryKind);
85
return sections;
86
}
87
void cacheDecodedCrel(size_t i, InputSectionBase *s) { sections[i] = s; }
88
89
// Returns object file symbols. It is a runtime error to call this
90
// function on files of other types.
91
ArrayRef<Symbol *> getSymbols() const {
92
assert(fileKind == BinaryKind || fileKind == ObjKind ||
93
fileKind == BitcodeKind);
94
return {symbols.get(), numSymbols};
95
}
96
97
MutableArrayRef<Symbol *> getMutableSymbols() {
98
assert(fileKind == BinaryKind || fileKind == ObjKind ||
99
fileKind == BitcodeKind);
100
return {symbols.get(), numSymbols};
101
}
102
103
Symbol &getSymbol(uint32_t symbolIndex) const {
104
assert(fileKind == ObjKind);
105
if (symbolIndex >= numSymbols)
106
fatal(toString(this) + ": invalid symbol index");
107
return *this->symbols[symbolIndex];
108
}
109
110
template <typename RelT> Symbol &getRelocTargetSym(const RelT &rel) const {
111
uint32_t symIndex = rel.getSymbol(config->isMips64EL);
112
return getSymbol(symIndex);
113
}
114
115
// Get filename to use for linker script processing.
116
StringRef getNameForScript() const;
117
118
// Check if a non-common symbol should be extracted to override a common
119
// definition.
120
bool shouldExtractForCommon(StringRef name) const;
121
122
// .got2 in the current file. This is used by PPC32 -fPIC/-fPIE to compute
123
// offsets in PLT call stubs.
124
InputSection *ppc32Got2 = nullptr;
125
126
// Index of MIPS GOT built for this file.
127
uint32_t mipsGotIndex = -1;
128
129
// groupId is used for --warn-backrefs which is an optional error
130
// checking feature. All files within the same --{start,end}-group or
131
// --{start,end}-lib get the same group ID. Otherwise, each file gets a new
132
// group ID. For more info, see checkDependency() in SymbolTable.cpp.
133
uint32_t groupId;
134
static bool isInGroup;
135
static uint32_t nextGroupId;
136
137
// If this is an architecture-specific file, the following members
138
// have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.
139
uint16_t emachine = llvm::ELF::EM_NONE;
140
const Kind fileKind;
141
ELFKind ekind = ELFNoneKind;
142
uint8_t osabi = 0;
143
uint8_t abiVersion = 0;
144
145
// True if this is a relocatable object file/bitcode file in an ar archive
146
// or between --start-lib and --end-lib.
147
bool lazy = false;
148
149
// True if this is an argument for --just-symbols. Usually false.
150
bool justSymbols = false;
151
152
std::string getSrcMsg(const Symbol &sym, const InputSectionBase &sec,
153
uint64_t offset);
154
155
// On PPC64 we need to keep track of which files contain small code model
156
// relocations that access the .toc section. To minimize the chance of a
157
// relocation overflow, files that do contain said relocations should have
158
// their .toc sections sorted closer to the .got section than files that do
159
// not contain any small code model relocations. Thats because the toc-pointer
160
// is defined to point at .got + 0x8000 and the instructions used with small
161
// code model relocations support immediates in the range [-0x8000, 0x7FFC],
162
// making the addressable range relative to the toc pointer
163
// [.got, .got + 0xFFFC].
164
bool ppc64SmallCodeModelTocRelocs = false;
165
166
// True if the file has TLSGD/TLSLD GOT relocations without R_PPC64_TLSGD or
167
// R_PPC64_TLSLD. Disable TLS relaxation to avoid bad code generation.
168
bool ppc64DisableTLSRelax = false;
169
170
public:
171
// If not empty, this stores the name of the archive containing this file.
172
// We use this string for creating error messages.
173
SmallString<0> archiveName;
174
// Cache for toString(). Only toString() should use this member.
175
mutable SmallString<0> toStringCache;
176
177
private:
178
// Cache for getNameForScript().
179
mutable SmallString<0> nameForScriptCache;
180
};
181
182
class ELFFileBase : public InputFile {
183
public:
184
ELFFileBase(Kind k, ELFKind ekind, MemoryBufferRef m);
185
static bool classof(const InputFile *f) { return f->isElf(); }
186
187
void init();
188
template <typename ELFT> llvm::object::ELFFile<ELFT> getObj() const {
189
return check(llvm::object::ELFFile<ELFT>::create(mb.getBuffer()));
190
}
191
192
StringRef getStringTable() const { return stringTable; }
193
194
ArrayRef<Symbol *> getLocalSymbols() {
195
if (numSymbols == 0)
196
return {};
197
return llvm::ArrayRef(symbols.get() + 1, firstGlobal - 1);
198
}
199
ArrayRef<Symbol *> getGlobalSymbols() {
200
return llvm::ArrayRef(symbols.get() + firstGlobal,
201
numSymbols - firstGlobal);
202
}
203
MutableArrayRef<Symbol *> getMutableGlobalSymbols() {
204
return llvm::MutableArrayRef(symbols.get() + firstGlobal,
205
numSymbols - firstGlobal);
206
}
207
208
template <typename ELFT> typename ELFT::ShdrRange getELFShdrs() const {
209
return typename ELFT::ShdrRange(
210
reinterpret_cast<const typename ELFT::Shdr *>(elfShdrs), numELFShdrs);
211
}
212
template <typename ELFT> typename ELFT::SymRange getELFSyms() const {
213
return typename ELFT::SymRange(
214
reinterpret_cast<const typename ELFT::Sym *>(elfSyms), numELFSyms);
215
}
216
template <typename ELFT> typename ELFT::SymRange getGlobalELFSyms() const {
217
return getELFSyms<ELFT>().slice(firstGlobal);
218
}
219
220
protected:
221
// Initializes this class's member variables.
222
template <typename ELFT> void init(InputFile::Kind k);
223
224
StringRef stringTable;
225
const void *elfShdrs = nullptr;
226
const void *elfSyms = nullptr;
227
uint32_t numELFShdrs = 0;
228
uint32_t numELFSyms = 0;
229
uint32_t firstGlobal = 0;
230
231
public:
232
uint32_t andFeatures = 0;
233
bool hasCommonSyms = false;
234
ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
235
};
236
237
// .o file.
238
template <class ELFT> class ObjFile : public ELFFileBase {
239
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
240
241
public:
242
static bool classof(const InputFile *f) { return f->kind() == ObjKind; }
243
244
llvm::object::ELFFile<ELFT> getObj() const {
245
return this->ELFFileBase::getObj<ELFT>();
246
}
247
248
ObjFile(ELFKind ekind, MemoryBufferRef m, StringRef archiveName)
249
: ELFFileBase(ObjKind, ekind, m) {
250
this->archiveName = archiveName;
251
}
252
253
void parse(bool ignoreComdats = false);
254
void parseLazy();
255
256
StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> sections,
257
const Elf_Shdr &sec);
258
259
uint32_t getSectionIndex(const Elf_Sym &sym) const;
260
261
std::optional<llvm::DILineInfo> getDILineInfo(const InputSectionBase *,
262
uint64_t);
263
std::optional<std::pair<std::string, unsigned>>
264
getVariableLoc(StringRef name);
265
266
// Name of source file obtained from STT_FILE symbol value,
267
// or empty string if there is no such symbol in object file
268
// symbol table.
269
StringRef sourceFile;
270
271
// Pointer to this input file's .llvm_addrsig section, if it has one.
272
const Elf_Shdr *addrsigSec = nullptr;
273
274
// SHT_LLVM_CALL_GRAPH_PROFILE section index.
275
uint32_t cgProfileSectionIndex = 0;
276
277
// MIPS GP0 value defined by this file. This value represents the gp value
278
// used to create the relocatable object and required to support
279
// R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
280
uint32_t mipsGp0 = 0;
281
282
// True if the file defines functions compiled with
283
// -fsplit-stack. Usually false.
284
bool splitStack = false;
285
286
// True if the file defines functions compiled with -fsplit-stack,
287
// but had one or more functions with the no_split_stack attribute.
288
bool someNoSplitStack = false;
289
290
// Get cached DWARF information.
291
DWARFCache *getDwarf();
292
293
void initSectionsAndLocalSyms(bool ignoreComdats);
294
void postParse();
295
void importCmseSymbols();
296
297
private:
298
void initializeSections(bool ignoreComdats,
299
const llvm::object::ELFFile<ELFT> &obj);
300
void initializeSymbols(const llvm::object::ELFFile<ELFT> &obj);
301
void initializeJustSymbols();
302
303
InputSectionBase *getRelocTarget(uint32_t idx, uint32_t info);
304
InputSectionBase *createInputSection(uint32_t idx, const Elf_Shdr &sec,
305
StringRef name);
306
307
bool shouldMerge(const Elf_Shdr &sec, StringRef name);
308
309
// Each ELF symbol contains a section index which the symbol belongs to.
310
// However, because the number of bits dedicated for that is limited, a
311
// symbol can directly point to a section only when the section index is
312
// equal to or smaller than 65280.
313
//
314
// If an object file contains more than 65280 sections, the file must
315
// contain .symtab_shndx section. The section contains an array of
316
// 32-bit integers whose size is the same as the number of symbols.
317
// Nth symbol's section index is in the Nth entry of .symtab_shndx.
318
//
319
// The following variable contains the contents of .symtab_shndx.
320
// If the section does not exist (which is common), the array is empty.
321
ArrayRef<Elf_Word> shndxTable;
322
323
// Debugging information to retrieve source file and line for error
324
// reporting. Linker may find reasonable number of errors in a
325
// single object file, so we cache debugging information in order to
326
// parse it only once for each object file we link.
327
std::unique_ptr<DWARFCache> dwarf;
328
llvm::once_flag initDwarf;
329
};
330
331
class BitcodeFile : public InputFile {
332
public:
333
BitcodeFile(MemoryBufferRef m, StringRef archiveName,
334
uint64_t offsetInArchive, bool lazy);
335
static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
336
void parse();
337
void parseLazy();
338
void postParse();
339
std::unique_ptr<llvm::lto::InputFile> obj;
340
std::vector<bool> keptComdats;
341
};
342
343
// .so file.
344
class SharedFile : public ELFFileBase {
345
public:
346
SharedFile(MemoryBufferRef m, StringRef defaultSoName);
347
348
// This is actually a vector of Elf_Verdef pointers.
349
SmallVector<const void *, 0> verdefs;
350
351
// If the output file needs Elf_Verneed data structures for this file, this is
352
// a vector of Elf_Vernaux version identifiers that map onto the entries in
353
// Verdefs, otherwise it is empty.
354
SmallVector<uint32_t, 0> vernauxs;
355
356
static unsigned vernauxNum;
357
358
SmallVector<StringRef, 0> dtNeeded;
359
StringRef soName;
360
361
static bool classof(const InputFile *f) { return f->kind() == SharedKind; }
362
363
template <typename ELFT> void parse();
364
365
// Used for --as-needed
366
bool isNeeded;
367
368
// Non-weak undefined symbols which are not yet resolved when the SO is
369
// parsed. Only filled for `--no-allow-shlib-undefined`.
370
SmallVector<Symbol *, 0> requiredSymbols;
371
372
private:
373
template <typename ELFT>
374
std::vector<uint32_t> parseVerneed(const llvm::object::ELFFile<ELFT> &obj,
375
const typename ELFT::Shdr *sec);
376
};
377
378
class BinaryFile : public InputFile {
379
public:
380
explicit BinaryFile(MemoryBufferRef m) : InputFile(BinaryKind, m) {}
381
static bool classof(const InputFile *f) { return f->kind() == BinaryKind; }
382
void parse();
383
};
384
385
InputFile *createInternalFile(StringRef name);
386
ELFFileBase *createObjFile(MemoryBufferRef mb, StringRef archiveName = "",
387
bool lazy = false);
388
389
std::string replaceThinLTOSuffix(StringRef path);
390
391
} // namespace elf
392
} // namespace lld
393
394
#endif
395
396