aboutsummaryrefslogtreecommitdiff
path: root/ELF/InputFiles.h
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/InputFiles.h')
-rw-r--r--ELF/InputFiles.h105
1 files changed, 51 insertions, 54 deletions
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 006218b45d9e..427f2fdea53e 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -11,12 +11,10 @@
#define LLD_ELF_INPUT_FILES_H
#include "Config.h"
-#include "Error.h"
-#include "InputSection.h"
-#include "Symbols.h"
+#include "lld/Common/ErrorHandler.h"
-#include "lld/Core/LLVM.h"
-#include "lld/Core/Reproduce.h"
+#include "lld/Common/LLVM.h"
+#include "lld/Common/Reproduce.h"
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
@@ -40,9 +38,10 @@ class InputFile;
namespace lld {
namespace elf {
class InputFile;
+class InputSectionBase;
}
-// Returns "(internal)", "foo.a(bar.o)" or "baz.o".
+// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
std::string toString(const elf::InputFile *F);
namespace elf {
@@ -50,7 +49,7 @@ namespace elf {
using llvm::object::Archive;
class Lazy;
-class SymbolBody;
+class Symbol;
// If -reproduce option is given, all input files are written
// to this tar archive.
@@ -63,9 +62,9 @@ llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
class InputFile {
public:
enum Kind {
- ObjectKind,
+ ObjKind,
SharedKind,
- LazyObjectKind,
+ LazyObjKind,
ArchiveKind,
BitcodeKind,
BinaryKind,
@@ -79,10 +78,18 @@ public:
// Returns sections. It is a runtime error to call this function
// on files that don't have the notion of sections.
ArrayRef<InputSectionBase *> getSections() const {
- assert(FileKind == ObjectKind || FileKind == BinaryKind);
+ assert(FileKind == ObjKind || FileKind == BinaryKind);
return Sections;
}
+ // Returns object file symbols. It is a runtime error to call this
+ // function on files of other types.
+ ArrayRef<Symbol *> getSymbols() {
+ assert(FileKind == ObjKind || FileKind == BitcodeKind ||
+ FileKind == ArchiveKind);
+ return Symbols;
+ }
+
// Filename of .a which contained this file. If this file was
// not in an archive file, it is the empty string. We use this
// string for creating error messages.
@@ -100,6 +107,7 @@ public:
protected:
InputFile(Kind K, MemoryBufferRef M);
std::vector<InputSectionBase *> Sections;
+ std::vector<Symbol *> Symbols;
private:
const Kind FileKind;
@@ -115,21 +123,22 @@ public:
ELFFileBase(Kind K, MemoryBufferRef M);
static bool classof(const InputFile *F) {
Kind K = F->kind();
- return K == ObjectKind || K == SharedKind;
+ return K == ObjKind || K == SharedKind;
}
llvm::object::ELFFile<ELFT> getObj() const {
- return llvm::object::ELFFile<ELFT>(MB.getBuffer());
+ return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
}
StringRef getStringTable() const { return StringTable; }
uint32_t getSectionIndex(const Elf_Sym &Sym) const;
- Elf_Sym_Range getGlobalSymbols();
+ Elf_Sym_Range getGlobalELFSyms();
+ Elf_Sym_Range getELFSyms() const { return ELFSyms; }
protected:
- ArrayRef<Elf_Sym> Symbols;
+ ArrayRef<Elf_Sym> ELFSyms;
uint32_t FirstNonLocal = 0;
ArrayRef<Elf_Word> SymtabSHNDX;
StringRef StringTable;
@@ -137,7 +146,7 @@ protected:
};
// .o file.
-template <class ELFT> class ObjectFile : public ELFFileBase<ELFT> {
+template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
typedef ELFFileBase<ELFT> Base;
typedef typename ELFT::Rel Elf_Rel;
typedef typename ELFT::Rela Elf_Rela;
@@ -150,34 +159,29 @@ template <class ELFT> class ObjectFile : public ELFFileBase<ELFT> {
ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec);
public:
- static bool classof(const InputFile *F) {
- return F->kind() == Base::ObjectKind;
- }
+ static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
- ArrayRef<SymbolBody *> getSymbols();
- ArrayRef<SymbolBody *> getLocalSymbols();
+ ArrayRef<Symbol *> getLocalSymbols();
- ObjectFile(MemoryBufferRef M, StringRef ArchiveName);
+ ObjFile(MemoryBufferRef M, StringRef ArchiveName);
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
- InputSectionBase *getSection(const Elf_Sym &Sym) const;
-
- SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
- if (SymbolIndex >= SymbolBodies.size())
+ Symbol &getSymbol(uint32_t SymbolIndex) const {
+ if (SymbolIndex >= this->Symbols.size())
fatal(toString(this) + ": invalid symbol index");
- return *SymbolBodies[SymbolIndex];
+ return *this->Symbols[SymbolIndex];
}
- template <typename RelT>
- SymbolBody &getRelocTargetSym(const RelT &Rel) const {
+ template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
- return getSymbolBody(SymIndex);
+ return getSymbol(SymIndex);
}
// Returns source line information for a given offset.
// If no information is available, returns "".
std::string getLineInfo(InputSectionBase *S, uint64_t Offset);
llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t);
+ llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef Name);
// MIPS GP0 value defined by this file. This value represents the gp value
// used to create the relocatable object and required to support
@@ -193,16 +197,13 @@ private:
void
initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
void initializeSymbols();
- void initializeDwarfLine();
+ void initializeDwarf();
InputSectionBase *getRelocTarget(const Elf_Shdr &Sec);
InputSectionBase *createInputSection(const Elf_Shdr &Sec);
StringRef getSectionName(const Elf_Shdr &Sec);
bool shouldMerge(const Elf_Shdr &Sec);
- SymbolBody *createSymbolBody(const Elf_Sym *Sym);
-
- // List of all symbols referenced or defined by this file.
- std::vector<SymbolBody *> SymbolBodies;
+ Symbol *createSymbol(const Elf_Sym *Sym);
// .shstrtab contents.
StringRef SectionStringTable;
@@ -212,34 +213,33 @@ private:
// single object file, so we cache debugging information in order to
// parse it only once for each object file we link.
std::unique_ptr<llvm::DWARFDebugLine> DwarfLine;
+ llvm::DenseMap<StringRef, std::pair<unsigned, unsigned>> VariableLoc;
llvm::once_flag InitDwarfLine;
};
-// LazyObjectFile is analogous to ArchiveFile in the sense that
+// LazyObjFile is analogous to ArchiveFile in the sense that
// the file contains lazy symbols. The difference is that
-// LazyObjectFile wraps a single file instead of multiple files.
+// LazyObjFile wraps a single file instead of multiple files.
//
// This class is used for --start-lib and --end-lib options which
// instruct the linker to link object files between them with the
// archive file semantics.
-class LazyObjectFile : public InputFile {
+class LazyObjFile : public InputFile {
public:
- LazyObjectFile(MemoryBufferRef M, StringRef ArchiveName,
- uint64_t OffsetInArchive)
- : InputFile(LazyObjectKind, M), OffsetInArchive(OffsetInArchive) {
+ LazyObjFile(MemoryBufferRef M, StringRef ArchiveName,
+ uint64_t OffsetInArchive)
+ : InputFile(LazyObjKind, M), OffsetInArchive(OffsetInArchive) {
this->ArchiveName = ArchiveName;
}
- static bool classof(const InputFile *F) {
- return F->kind() == LazyObjectKind;
- }
+ static bool classof(const InputFile *F) { return F->kind() == LazyObjKind; }
template <class ELFT> void parse();
MemoryBufferRef getBuffer();
InputFile *fetch();
private:
- std::vector<StringRef> getSymbols();
+ std::vector<StringRef> getSymbolNames();
template <class ELFT> std::vector<StringRef> getElfSymbols();
std::vector<StringRef> getBitcodeSymbols();
@@ -253,7 +253,6 @@ public:
explicit ArchiveFile(std::unique_ptr<Archive> &&File);
static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
template <class ELFT> void parse();
- ArrayRef<Symbol *> getSymbols() { return Symbols; }
// Returns a memory buffer for a given symbol and the offset in the archive
// for the member. An empty memory buffer and an offset of zero
@@ -264,7 +263,6 @@ public:
private:
std::unique_ptr<Archive> File;
llvm::DenseSet<uint64_t> Seen;
- std::vector<Symbol *> Symbols;
};
class BitcodeFile : public InputFile {
@@ -274,11 +272,7 @@ public:
static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
template <class ELFT>
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
- ArrayRef<Symbol *> getSymbols() { return Symbols; }
std::unique_ptr<llvm::lto::InputFile> Obj;
-
-private:
- std::vector<Symbol *> Symbols;
};
// .so file.
@@ -296,9 +290,9 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
const Elf_Shdr *VerdefSec = nullptr;
public:
+ std::vector<const Elf_Verdef *> Verdefs;
std::string SoName;
- const Elf_Shdr *getSection(const Elf_Sym &Sym) const;
llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
static bool classof(const InputFile *F) {
@@ -324,9 +318,7 @@ public:
std::map<const Elf_Verdef *, NeededVer> VerdefMap;
// Used for --as-needed
- bool AsNeeded = false;
- bool IsUsed = false;
- bool isNeeded() const { return !AsNeeded || IsUsed; }
+ bool IsNeeded;
};
class BinaryFile : public InputFile {
@@ -340,6 +332,11 @@ InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
uint64_t OffsetInArchive = 0);
InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName);
+extern std::vector<BinaryFile *> BinaryFiles;
+extern std::vector<BitcodeFile *> BitcodeFiles;
+extern std::vector<InputFile *> ObjectFiles;
+extern std::vector<InputFile *> SharedFiles;
+
} // namespace elf
} // namespace lld