annotate lld/ELF/InputFiles.h @ 201:a96fbbdf2d0f

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 04 Jun 2021 21:07:06 +0900
parents 0572611fdcc8
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===- InputFiles.h ---------------------------------------------*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #ifndef LLD_ELF_INPUT_FILES_H
anatofuz
parents:
diff changeset
10 #define LLD_ELF_INPUT_FILES_H
anatofuz
parents:
diff changeset
11
anatofuz
parents:
diff changeset
12 #include "Config.h"
anatofuz
parents:
diff changeset
13 #include "lld/Common/ErrorHandler.h"
anatofuz
parents:
diff changeset
14 #include "lld/Common/LLVM.h"
anatofuz
parents:
diff changeset
15 #include "lld/Common/Reproduce.h"
anatofuz
parents:
diff changeset
16 #include "llvm/ADT/CachedHashString.h"
anatofuz
parents:
diff changeset
17 #include "llvm/ADT/DenseSet.h"
anatofuz
parents:
diff changeset
18 #include "llvm/ADT/STLExtras.h"
anatofuz
parents:
diff changeset
19 #include "llvm/IR/Comdat.h"
anatofuz
parents:
diff changeset
20 #include "llvm/Object/Archive.h"
anatofuz
parents:
diff changeset
21 #include "llvm/Object/ELF.h"
anatofuz
parents:
diff changeset
22 #include "llvm/Object/IRObjectFile.h"
anatofuz
parents:
diff changeset
23 #include "llvm/Support/Threading.h"
anatofuz
parents:
diff changeset
24 #include <map>
anatofuz
parents:
diff changeset
25
anatofuz
parents:
diff changeset
26 namespace llvm {
anatofuz
parents:
diff changeset
27 struct DILineInfo;
anatofuz
parents:
diff changeset
28 class TarWriter;
anatofuz
parents:
diff changeset
29 namespace lto {
anatofuz
parents:
diff changeset
30 class InputFile;
anatofuz
parents:
diff changeset
31 }
anatofuz
parents:
diff changeset
32 } // namespace llvm
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 namespace lld {
anatofuz
parents:
diff changeset
35 class DWARFCache;
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 // Returns "<internal>", "foo.a(bar.o)" or "baz.o".
anatofuz
parents:
diff changeset
38 std::string toString(const elf::InputFile *f);
anatofuz
parents:
diff changeset
39
anatofuz
parents:
diff changeset
40 namespace elf {
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 using llvm::object::Archive;
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 class Symbol;
anatofuz
parents:
diff changeset
45
anatofuz
parents:
diff changeset
46 // If -reproduce option is given, all input files are written
anatofuz
parents:
diff changeset
47 // to this tar archive.
anatofuz
parents:
diff changeset
48 extern std::unique_ptr<llvm::TarWriter> tar;
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50 // Opens a given file.
anatofuz
parents:
diff changeset
51 llvm::Optional<MemoryBufferRef> readFile(StringRef path);
anatofuz
parents:
diff changeset
52
anatofuz
parents:
diff changeset
53 // Add symbols in File to the symbol table.
anatofuz
parents:
diff changeset
54 void parseFile(InputFile *file);
anatofuz
parents:
diff changeset
55
anatofuz
parents:
diff changeset
56 // The root class of input files.
anatofuz
parents:
diff changeset
57 class InputFile {
anatofuz
parents:
diff changeset
58 public:
anatofuz
parents:
diff changeset
59 enum Kind {
anatofuz
parents:
diff changeset
60 ObjKind,
anatofuz
parents:
diff changeset
61 SharedKind,
anatofuz
parents:
diff changeset
62 LazyObjKind,
anatofuz
parents:
diff changeset
63 ArchiveKind,
anatofuz
parents:
diff changeset
64 BitcodeKind,
anatofuz
parents:
diff changeset
65 BinaryKind,
anatofuz
parents:
diff changeset
66 };
anatofuz
parents:
diff changeset
67
anatofuz
parents:
diff changeset
68 Kind kind() const { return fileKind; }
anatofuz
parents:
diff changeset
69
anatofuz
parents:
diff changeset
70 bool isElf() const {
anatofuz
parents:
diff changeset
71 Kind k = kind();
anatofuz
parents:
diff changeset
72 return k == ObjKind || k == SharedKind;
anatofuz
parents:
diff changeset
73 }
anatofuz
parents:
diff changeset
74
anatofuz
parents:
diff changeset
75 StringRef getName() const { return mb.getBufferIdentifier(); }
anatofuz
parents:
diff changeset
76 MemoryBufferRef mb;
anatofuz
parents:
diff changeset
77
anatofuz
parents:
diff changeset
78 // Returns sections. It is a runtime error to call this function
anatofuz
parents:
diff changeset
79 // on files that don't have the notion of sections.
anatofuz
parents:
diff changeset
80 ArrayRef<InputSectionBase *> getSections() const {
anatofuz
parents:
diff changeset
81 assert(fileKind == ObjKind || fileKind == BinaryKind);
anatofuz
parents:
diff changeset
82 return sections;
anatofuz
parents:
diff changeset
83 }
anatofuz
parents:
diff changeset
84
anatofuz
parents:
diff changeset
85 // Returns object file symbols. It is a runtime error to call this
anatofuz
parents:
diff changeset
86 // function on files of other types.
anatofuz
parents:
diff changeset
87 ArrayRef<Symbol *> getSymbols() { return getMutableSymbols(); }
anatofuz
parents:
diff changeset
88
anatofuz
parents:
diff changeset
89 MutableArrayRef<Symbol *> getMutableSymbols() {
anatofuz
parents:
diff changeset
90 assert(fileKind == BinaryKind || fileKind == ObjKind ||
anatofuz
parents:
diff changeset
91 fileKind == BitcodeKind);
anatofuz
parents:
diff changeset
92 return symbols;
anatofuz
parents:
diff changeset
93 }
anatofuz
parents:
diff changeset
94
anatofuz
parents:
diff changeset
95 // Filename of .a which contained this file. If this file was
anatofuz
parents:
diff changeset
96 // not in an archive file, it is the empty string. We use this
anatofuz
parents:
diff changeset
97 // string for creating error messages.
anatofuz
parents:
diff changeset
98 std::string archiveName;
anatofuz
parents:
diff changeset
99
anatofuz
parents:
diff changeset
100 // If this is an architecture-specific file, the following members
anatofuz
parents:
diff changeset
101 // have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.
anatofuz
parents:
diff changeset
102 ELFKind ekind = ELFNoneKind;
anatofuz
parents:
diff changeset
103 uint16_t emachine = llvm::ELF::EM_NONE;
anatofuz
parents:
diff changeset
104 uint8_t osabi = 0;
anatofuz
parents:
diff changeset
105 uint8_t abiVersion = 0;
anatofuz
parents:
diff changeset
106
anatofuz
parents:
diff changeset
107 // Cache for toString(). Only toString() should use this member.
anatofuz
parents:
diff changeset
108 mutable std::string toStringCache;
anatofuz
parents:
diff changeset
109
anatofuz
parents:
diff changeset
110 std::string getSrcMsg(const Symbol &sym, InputSectionBase &sec,
anatofuz
parents:
diff changeset
111 uint64_t offset);
anatofuz
parents:
diff changeset
112
anatofuz
parents:
diff changeset
113 // True if this is an argument for --just-symbols. Usually false.
anatofuz
parents:
diff changeset
114 bool justSymbols = false;
anatofuz
parents:
diff changeset
115
anatofuz
parents:
diff changeset
116 // outSecOff of .got2 in the current file. This is used by PPC32 -fPIC/-fPIE
anatofuz
parents:
diff changeset
117 // to compute offsets in PLT call stubs.
anatofuz
parents:
diff changeset
118 uint32_t ppc32Got2OutSecOff = 0;
anatofuz
parents:
diff changeset
119
anatofuz
parents:
diff changeset
120 // On PPC64 we need to keep track of which files contain small code model
anatofuz
parents:
diff changeset
121 // relocations that access the .toc section. To minimize the chance of a
anatofuz
parents:
diff changeset
122 // relocation overflow, files that do contain said relocations should have
anatofuz
parents:
diff changeset
123 // their .toc sections sorted closer to the .got section than files that do
anatofuz
parents:
diff changeset
124 // not contain any small code model relocations. Thats because the toc-pointer
anatofuz
parents:
diff changeset
125 // is defined to point at .got + 0x8000 and the instructions used with small
anatofuz
parents:
diff changeset
126 // code model relocations support immediates in the range [-0x8000, 0x7FFC],
anatofuz
parents:
diff changeset
127 // making the addressable range relative to the toc pointer
anatofuz
parents:
diff changeset
128 // [.got, .got + 0xFFFC].
anatofuz
parents:
diff changeset
129 bool ppc64SmallCodeModelTocRelocs = false;
anatofuz
parents:
diff changeset
130
anatofuz
parents:
diff changeset
131 // groupId is used for --warn-backrefs which is an optional error
anatofuz
parents:
diff changeset
132 // checking feature. All files within the same --{start,end}-group or
anatofuz
parents:
diff changeset
133 // --{start,end}-lib get the same group ID. Otherwise, each file gets a new
anatofuz
parents:
diff changeset
134 // group ID. For more info, see checkDependency() in SymbolTable.cpp.
anatofuz
parents:
diff changeset
135 uint32_t groupId;
anatofuz
parents:
diff changeset
136 static bool isInGroup;
anatofuz
parents:
diff changeset
137 static uint32_t nextGroupId;
anatofuz
parents:
diff changeset
138
anatofuz
parents:
diff changeset
139 // Index of MIPS GOT built for this file.
anatofuz
parents:
diff changeset
140 llvm::Optional<size_t> mipsGotIndex;
anatofuz
parents:
diff changeset
141
anatofuz
parents:
diff changeset
142 std::vector<Symbol *> symbols;
anatofuz
parents:
diff changeset
143
anatofuz
parents:
diff changeset
144 protected:
anatofuz
parents:
diff changeset
145 InputFile(Kind k, MemoryBufferRef m);
anatofuz
parents:
diff changeset
146 std::vector<InputSectionBase *> sections;
anatofuz
parents:
diff changeset
147
anatofuz
parents:
diff changeset
148 private:
anatofuz
parents:
diff changeset
149 const Kind fileKind;
anatofuz
parents:
diff changeset
150 };
anatofuz
parents:
diff changeset
151
anatofuz
parents:
diff changeset
152 class ELFFileBase : public InputFile {
anatofuz
parents:
diff changeset
153 public:
anatofuz
parents:
diff changeset
154 ELFFileBase(Kind k, MemoryBufferRef m);
anatofuz
parents:
diff changeset
155 static bool classof(const InputFile *f) { return f->isElf(); }
anatofuz
parents:
diff changeset
156
anatofuz
parents:
diff changeset
157 template <typename ELFT> llvm::object::ELFFile<ELFT> getObj() const {
anatofuz
parents:
diff changeset
158 return check(llvm::object::ELFFile<ELFT>::create(mb.getBuffer()));
anatofuz
parents:
diff changeset
159 }
anatofuz
parents:
diff changeset
160
anatofuz
parents:
diff changeset
161 StringRef getStringTable() const { return stringTable; }
anatofuz
parents:
diff changeset
162
anatofuz
parents:
diff changeset
163 template <typename ELFT> typename ELFT::SymRange getELFSyms() const {
anatofuz
parents:
diff changeset
164 return typename ELFT::SymRange(
anatofuz
parents:
diff changeset
165 reinterpret_cast<const typename ELFT::Sym *>(elfSyms), numELFSyms);
anatofuz
parents:
diff changeset
166 }
anatofuz
parents:
diff changeset
167 template <typename ELFT> typename ELFT::SymRange getGlobalELFSyms() const {
anatofuz
parents:
diff changeset
168 return getELFSyms<ELFT>().slice(firstGlobal);
anatofuz
parents:
diff changeset
169 }
anatofuz
parents:
diff changeset
170
anatofuz
parents:
diff changeset
171 protected:
anatofuz
parents:
diff changeset
172 // Initializes this class's member variables.
anatofuz
parents:
diff changeset
173 template <typename ELFT> void init();
anatofuz
parents:
diff changeset
174
anatofuz
parents:
diff changeset
175 const void *elfSyms = nullptr;
anatofuz
parents:
diff changeset
176 size_t numELFSyms = 0;
anatofuz
parents:
diff changeset
177 uint32_t firstGlobal = 0;
anatofuz
parents:
diff changeset
178 StringRef stringTable;
anatofuz
parents:
diff changeset
179 };
anatofuz
parents:
diff changeset
180
anatofuz
parents:
diff changeset
181 // .o file.
anatofuz
parents:
diff changeset
182 template <class ELFT> class ObjFile : public ELFFileBase {
anatofuz
parents:
diff changeset
183 using Elf_Rel = typename ELFT::Rel;
anatofuz
parents:
diff changeset
184 using Elf_Rela = typename ELFT::Rela;
anatofuz
parents:
diff changeset
185 using Elf_Sym = typename ELFT::Sym;
anatofuz
parents:
diff changeset
186 using Elf_Shdr = typename ELFT::Shdr;
anatofuz
parents:
diff changeset
187 using Elf_Word = typename ELFT::Word;
anatofuz
parents:
diff changeset
188 using Elf_CGProfile = typename ELFT::CGProfile;
anatofuz
parents:
diff changeset
189
anatofuz
parents:
diff changeset
190 public:
anatofuz
parents:
diff changeset
191 static bool classof(const InputFile *f) { return f->kind() == ObjKind; }
anatofuz
parents:
diff changeset
192
anatofuz
parents:
diff changeset
193 llvm::object::ELFFile<ELFT> getObj() const {
anatofuz
parents:
diff changeset
194 return this->ELFFileBase::getObj<ELFT>();
anatofuz
parents:
diff changeset
195 }
anatofuz
parents:
diff changeset
196
anatofuz
parents:
diff changeset
197 ArrayRef<Symbol *> getLocalSymbols();
anatofuz
parents:
diff changeset
198 ArrayRef<Symbol *> getGlobalSymbols();
anatofuz
parents:
diff changeset
199
anatofuz
parents:
diff changeset
200 ObjFile(MemoryBufferRef m, StringRef archiveName) : ELFFileBase(ObjKind, m) {
anatofuz
parents:
diff changeset
201 this->archiveName = std::string(archiveName);
anatofuz
parents:
diff changeset
202 }
anatofuz
parents:
diff changeset
203
anatofuz
parents:
diff changeset
204 void parse(bool ignoreComdats = false);
anatofuz
parents:
diff changeset
205
anatofuz
parents:
diff changeset
206 StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> sections,
anatofuz
parents:
diff changeset
207 const Elf_Shdr &sec);
anatofuz
parents:
diff changeset
208
anatofuz
parents:
diff changeset
209 Symbol &getSymbol(uint32_t symbolIndex) const {
anatofuz
parents:
diff changeset
210 if (symbolIndex >= this->symbols.size())
anatofuz
parents:
diff changeset
211 fatal(toString(this) + ": invalid symbol index");
anatofuz
parents:
diff changeset
212 return *this->symbols[symbolIndex];
anatofuz
parents:
diff changeset
213 }
anatofuz
parents:
diff changeset
214
anatofuz
parents:
diff changeset
215 uint32_t getSectionIndex(const Elf_Sym &sym) const;
anatofuz
parents:
diff changeset
216
anatofuz
parents:
diff changeset
217 template <typename RelT> Symbol &getRelocTargetSym(const RelT &rel) const {
anatofuz
parents:
diff changeset
218 uint32_t symIndex = rel.getSymbol(config->isMips64EL);
anatofuz
parents:
diff changeset
219 return getSymbol(symIndex);
anatofuz
parents:
diff changeset
220 }
anatofuz
parents:
diff changeset
221
anatofuz
parents:
diff changeset
222 llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t);
anatofuz
parents:
diff changeset
223 llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef name);
anatofuz
parents:
diff changeset
224
anatofuz
parents:
diff changeset
225 // MIPS GP0 value defined by this file. This value represents the gp value
anatofuz
parents:
diff changeset
226 // used to create the relocatable object and required to support
anatofuz
parents:
diff changeset
227 // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
anatofuz
parents:
diff changeset
228 uint32_t mipsGp0 = 0;
anatofuz
parents:
diff changeset
229
anatofuz
parents:
diff changeset
230 uint32_t andFeatures = 0;
anatofuz
parents:
diff changeset
231
anatofuz
parents:
diff changeset
232 // Name of source file obtained from STT_FILE symbol value,
anatofuz
parents:
diff changeset
233 // or empty string if there is no such symbol in object file
anatofuz
parents:
diff changeset
234 // symbol table.
anatofuz
parents:
diff changeset
235 StringRef sourceFile;
anatofuz
parents:
diff changeset
236
anatofuz
parents:
diff changeset
237 // True if the file defines functions compiled with
anatofuz
parents:
diff changeset
238 // -fsplit-stack. Usually false.
anatofuz
parents:
diff changeset
239 bool splitStack = false;
anatofuz
parents:
diff changeset
240
anatofuz
parents:
diff changeset
241 // True if the file defines functions compiled with -fsplit-stack,
anatofuz
parents:
diff changeset
242 // but had one or more functions with the no_split_stack attribute.
anatofuz
parents:
diff changeset
243 bool someNoSplitStack = false;
anatofuz
parents:
diff changeset
244
anatofuz
parents:
diff changeset
245 // Pointer to this input file's .llvm_addrsig section, if it has one.
anatofuz
parents:
diff changeset
246 const Elf_Shdr *addrsigSec = nullptr;
anatofuz
parents:
diff changeset
247
anatofuz
parents:
diff changeset
248 // SHT_LLVM_CALL_GRAPH_PROFILE table
anatofuz
parents:
diff changeset
249 ArrayRef<Elf_CGProfile> cgProfile;
anatofuz
parents:
diff changeset
250
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
251 // Get cached DWARF information.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
252 DWARFCache *getDwarf();
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
253
150
anatofuz
parents:
diff changeset
254 private:
anatofuz
parents:
diff changeset
255 void initializeSections(bool ignoreComdats);
anatofuz
parents:
diff changeset
256 void initializeSymbols();
anatofuz
parents:
diff changeset
257 void initializeJustSymbols();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
258
150
anatofuz
parents:
diff changeset
259 InputSectionBase *getRelocTarget(const Elf_Shdr &sec);
anatofuz
parents:
diff changeset
260 InputSectionBase *createInputSection(const Elf_Shdr &sec);
anatofuz
parents:
diff changeset
261 StringRef getSectionName(const Elf_Shdr &sec);
anatofuz
parents:
diff changeset
262
anatofuz
parents:
diff changeset
263 bool shouldMerge(const Elf_Shdr &sec, StringRef name);
anatofuz
parents:
diff changeset
264
anatofuz
parents:
diff changeset
265 // Each ELF symbol contains a section index which the symbol belongs to.
anatofuz
parents:
diff changeset
266 // However, because the number of bits dedicated for that is limited, a
anatofuz
parents:
diff changeset
267 // symbol can directly point to a section only when the section index is
anatofuz
parents:
diff changeset
268 // equal to or smaller than 65280.
anatofuz
parents:
diff changeset
269 //
anatofuz
parents:
diff changeset
270 // If an object file contains more than 65280 sections, the file must
anatofuz
parents:
diff changeset
271 // contain .symtab_shndx section. The section contains an array of
anatofuz
parents:
diff changeset
272 // 32-bit integers whose size is the same as the number of symbols.
anatofuz
parents:
diff changeset
273 // Nth symbol's section index is in the Nth entry of .symtab_shndx.
anatofuz
parents:
diff changeset
274 //
anatofuz
parents:
diff changeset
275 // The following variable contains the contents of .symtab_shndx.
anatofuz
parents:
diff changeset
276 // If the section does not exist (which is common), the array is empty.
anatofuz
parents:
diff changeset
277 ArrayRef<Elf_Word> shndxTable;
anatofuz
parents:
diff changeset
278
anatofuz
parents:
diff changeset
279 // .shstrtab contents.
anatofuz
parents:
diff changeset
280 StringRef sectionStringTable;
anatofuz
parents:
diff changeset
281
anatofuz
parents:
diff changeset
282 // Debugging information to retrieve source file and line for error
anatofuz
parents:
diff changeset
283 // reporting. Linker may find reasonable number of errors in a
anatofuz
parents:
diff changeset
284 // single object file, so we cache debugging information in order to
anatofuz
parents:
diff changeset
285 // parse it only once for each object file we link.
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
286 std::unique_ptr<DWARFCache> dwarf;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
287 llvm::once_flag initDwarf;
150
anatofuz
parents:
diff changeset
288 };
anatofuz
parents:
diff changeset
289
anatofuz
parents:
diff changeset
290 // LazyObjFile is analogous to ArchiveFile in the sense that
anatofuz
parents:
diff changeset
291 // the file contains lazy symbols. The difference is that
anatofuz
parents:
diff changeset
292 // LazyObjFile wraps a single file instead of multiple files.
anatofuz
parents:
diff changeset
293 //
anatofuz
parents:
diff changeset
294 // This class is used for --start-lib and --end-lib options which
anatofuz
parents:
diff changeset
295 // instruct the linker to link object files between them with the
anatofuz
parents:
diff changeset
296 // archive file semantics.
anatofuz
parents:
diff changeset
297 class LazyObjFile : public InputFile {
anatofuz
parents:
diff changeset
298 public:
anatofuz
parents:
diff changeset
299 LazyObjFile(MemoryBufferRef m, StringRef archiveName,
anatofuz
parents:
diff changeset
300 uint64_t offsetInArchive)
anatofuz
parents:
diff changeset
301 : InputFile(LazyObjKind, m), offsetInArchive(offsetInArchive) {
anatofuz
parents:
diff changeset
302 this->archiveName = std::string(archiveName);
anatofuz
parents:
diff changeset
303 }
anatofuz
parents:
diff changeset
304
anatofuz
parents:
diff changeset
305 static bool classof(const InputFile *f) { return f->kind() == LazyObjKind; }
anatofuz
parents:
diff changeset
306
anatofuz
parents:
diff changeset
307 template <class ELFT> void parse();
anatofuz
parents:
diff changeset
308 void fetch();
anatofuz
parents:
diff changeset
309
anatofuz
parents:
diff changeset
310 private:
anatofuz
parents:
diff changeset
311 uint64_t offsetInArchive;
anatofuz
parents:
diff changeset
312 };
anatofuz
parents:
diff changeset
313
anatofuz
parents:
diff changeset
314 // An ArchiveFile object represents a .a file.
anatofuz
parents:
diff changeset
315 class ArchiveFile : public InputFile {
anatofuz
parents:
diff changeset
316 public:
anatofuz
parents:
diff changeset
317 explicit ArchiveFile(std::unique_ptr<Archive> &&file);
anatofuz
parents:
diff changeset
318 static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; }
anatofuz
parents:
diff changeset
319 void parse();
anatofuz
parents:
diff changeset
320
anatofuz
parents:
diff changeset
321 // Pulls out an object file that contains a definition for Sym and
anatofuz
parents:
diff changeset
322 // returns it. If the same file was instantiated before, this
anatofuz
parents:
diff changeset
323 // function does nothing (so we don't instantiate the same file
anatofuz
parents:
diff changeset
324 // more than once.)
anatofuz
parents:
diff changeset
325 void fetch(const Archive::Symbol &sym);
anatofuz
parents:
diff changeset
326
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
327 size_t getMemberCount() const;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
328 size_t getFetchedMemberCount() const { return seen.size(); }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
329
150
anatofuz
parents:
diff changeset
330 private:
anatofuz
parents:
diff changeset
331 std::unique_ptr<Archive> file;
anatofuz
parents:
diff changeset
332 llvm::DenseSet<uint64_t> seen;
anatofuz
parents:
diff changeset
333 };
anatofuz
parents:
diff changeset
334
anatofuz
parents:
diff changeset
335 class BitcodeFile : public InputFile {
anatofuz
parents:
diff changeset
336 public:
anatofuz
parents:
diff changeset
337 BitcodeFile(MemoryBufferRef m, StringRef archiveName,
anatofuz
parents:
diff changeset
338 uint64_t offsetInArchive);
anatofuz
parents:
diff changeset
339 static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
anatofuz
parents:
diff changeset
340 template <class ELFT> void parse();
anatofuz
parents:
diff changeset
341 std::unique_ptr<llvm::lto::InputFile> obj;
anatofuz
parents:
diff changeset
342 };
anatofuz
parents:
diff changeset
343
anatofuz
parents:
diff changeset
344 // .so file.
anatofuz
parents:
diff changeset
345 class SharedFile : public ELFFileBase {
anatofuz
parents:
diff changeset
346 public:
anatofuz
parents:
diff changeset
347 SharedFile(MemoryBufferRef m, StringRef defaultSoName)
anatofuz
parents:
diff changeset
348 : ELFFileBase(SharedKind, m), soName(std::string(defaultSoName)),
anatofuz
parents:
diff changeset
349 isNeeded(!config->asNeeded) {}
anatofuz
parents:
diff changeset
350
anatofuz
parents:
diff changeset
351 // This is actually a vector of Elf_Verdef pointers.
anatofuz
parents:
diff changeset
352 std::vector<const void *> verdefs;
anatofuz
parents:
diff changeset
353
anatofuz
parents:
diff changeset
354 // If the output file needs Elf_Verneed data structures for this file, this is
anatofuz
parents:
diff changeset
355 // a vector of Elf_Vernaux version identifiers that map onto the entries in
anatofuz
parents:
diff changeset
356 // Verdefs, otherwise it is empty.
anatofuz
parents:
diff changeset
357 std::vector<unsigned> vernauxs;
anatofuz
parents:
diff changeset
358
anatofuz
parents:
diff changeset
359 static unsigned vernauxNum;
anatofuz
parents:
diff changeset
360
anatofuz
parents:
diff changeset
361 std::vector<StringRef> dtNeeded;
anatofuz
parents:
diff changeset
362 std::string soName;
anatofuz
parents:
diff changeset
363
anatofuz
parents:
diff changeset
364 static bool classof(const InputFile *f) { return f->kind() == SharedKind; }
anatofuz
parents:
diff changeset
365
anatofuz
parents:
diff changeset
366 template <typename ELFT> void parse();
anatofuz
parents:
diff changeset
367
anatofuz
parents:
diff changeset
368 // Used for --no-allow-shlib-undefined.
anatofuz
parents:
diff changeset
369 bool allNeededIsKnown;
anatofuz
parents:
diff changeset
370
anatofuz
parents:
diff changeset
371 // Used for --as-needed
anatofuz
parents:
diff changeset
372 bool isNeeded;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
373
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
374 private:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
375 template <typename ELFT>
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
376 std::vector<uint32_t> parseVerneed(const llvm::object::ELFFile<ELFT> &obj,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
377 const typename ELFT::Shdr *sec);
150
anatofuz
parents:
diff changeset
378 };
anatofuz
parents:
diff changeset
379
anatofuz
parents:
diff changeset
380 class BinaryFile : public InputFile {
anatofuz
parents:
diff changeset
381 public:
anatofuz
parents:
diff changeset
382 explicit BinaryFile(MemoryBufferRef m) : InputFile(BinaryKind, m) {}
anatofuz
parents:
diff changeset
383 static bool classof(const InputFile *f) { return f->kind() == BinaryKind; }
anatofuz
parents:
diff changeset
384 void parse();
anatofuz
parents:
diff changeset
385 };
anatofuz
parents:
diff changeset
386
anatofuz
parents:
diff changeset
387 InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName = "",
anatofuz
parents:
diff changeset
388 uint64_t offsetInArchive = 0);
anatofuz
parents:
diff changeset
389
anatofuz
parents:
diff changeset
390 inline bool isBitcode(MemoryBufferRef mb) {
anatofuz
parents:
diff changeset
391 return identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode;
anatofuz
parents:
diff changeset
392 }
anatofuz
parents:
diff changeset
393
anatofuz
parents:
diff changeset
394 std::string replaceThinLTOSuffix(StringRef path);
anatofuz
parents:
diff changeset
395
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
396 extern std::vector<ArchiveFile *> archiveFiles;
150
anatofuz
parents:
diff changeset
397 extern std::vector<BinaryFile *> binaryFiles;
anatofuz
parents:
diff changeset
398 extern std::vector<BitcodeFile *> bitcodeFiles;
anatofuz
parents:
diff changeset
399 extern std::vector<LazyObjFile *> lazyObjFiles;
anatofuz
parents:
diff changeset
400 extern std::vector<InputFile *> objectFiles;
anatofuz
parents:
diff changeset
401 extern std::vector<SharedFile *> sharedFiles;
anatofuz
parents:
diff changeset
402
anatofuz
parents:
diff changeset
403 } // namespace elf
anatofuz
parents:
diff changeset
404 } // namespace lld
anatofuz
parents:
diff changeset
405
anatofuz
parents:
diff changeset
406 #endif