It was already using just code that is common to all object files.
llvm-svn: 243985
error("no input files.");
// Create a symbol table.
- SymbolTable<object::ELF64LE> Symtab;
+ SymbolTable Symtab;
// Parse all input files and put all symbols to the symbol table.
// The symbol table will take care of name resolution.
};
// .o file.
-template <class ELFT> class ObjectFile : public InputFile {
+class ObjectFileBase : public InputFile {
+public:
+ explicit ObjectFileBase(MemoryBufferRef M) : InputFile(ObjectKind, M) {}
+ static bool classof(const InputFile *F) { return F->kind() == ObjectKind; }
+
+ ArrayRef<Chunk *> getChunks() { return Chunks; }
+ ArrayRef<SymbolBody *> getSymbols() override { return SymbolBodies; }
+
+protected:
+ // List of all chunks defined by this file. This includes both section
+ // chunks and non-section chunks for common symbols.
+ std::vector<Chunk *> Chunks;
+
+ // List of all symbols referenced or defined by this file.
+ std::vector<SymbolBody *> SymbolBodies;
+
+ llvm::BumpPtrAllocator Alloc;
+};
+
+template <class ELFT> class ObjectFile : public ObjectFileBase {
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
public:
- explicit ObjectFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {}
- static bool classof(const InputFile *F) { return F->kind() == ObjectKind; }
+ explicit ObjectFile(MemoryBufferRef M) : ObjectFileBase(M) {}
void parse() override;
- ArrayRef<Chunk *> getChunks() { return Chunks; }
- ArrayRef<SymbolBody *> getSymbols() override { return SymbolBodies; }
// Returns the underying ELF file.
llvm::object::ELFFile<ELFT> *getObj() { return ELFObj.get(); }
SymbolBody *createSymbolBody(StringRef StringTable, const Elf_Sym *Sym);
std::unique_ptr<llvm::object::ELFFile<ELFT>> ELFObj;
- llvm::BumpPtrAllocator Alloc;
-
- // List of all chunks defined by this file. This includes both section
- // chunks and non-section chunks for common symbols.
- std::vector<Chunk *> Chunks;
-
- // List of all symbols referenced or defined by this file.
- std::vector<SymbolBody *> SymbolBodies;
};
} // namespace elf2
using namespace lld;
using namespace lld::elf2;
-template <class ELFT> SymbolTable<ELFT>::SymbolTable() {
- resolve(new (Alloc) Undefined("_start"));
-}
+SymbolTable::SymbolTable() { resolve(new (Alloc) Undefined("_start")); }
-template <class ELFT>
-void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) {
+void SymbolTable::addFile(std::unique_ptr<InputFile> File) {
File->parse();
InputFile *FileP = File.release();
- auto *P = cast<ObjectFile<ELFT>>(FileP);
+ auto *P = cast<ObjectFileBase>(FileP);
addObject(P);
}
-template <class ELFT>
-void SymbolTable<ELFT>::addObject(ObjectFile<ELFT> *File) {
+void SymbolTable::addObject(ObjectFileBase *File) {
ObjectFiles.emplace_back(File);
for (SymbolBody *Body : File->getSymbols())
if (Body->isExternal())
resolve(Body);
}
-template <class ELFT> void SymbolTable<ELFT>::reportRemainingUndefines() {
+void SymbolTable::reportRemainingUndefines() {
for (auto &I : Symtab) {
Symbol *Sym = I.second;
if (auto *Undef = dyn_cast<Undefined>(Sym->Body))
// This function resolves conflicts if there's an existing symbol with
// the same name. Decisions are made based on symbol type.
-template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) {
+void SymbolTable::resolve(SymbolBody *New) {
// Find an existing Symbol or create and insert a new one.
StringRef Name = New->getName();
Symbol *&Sym = Symtab[Name];
if (comp == 0)
error(Twine("duplicate symbol: ") + Name);
}
-
-namespace lld {
-namespace elf2 {
-template class SymbolTable<object::ELF32LE>;
-template class SymbolTable<object::ELF32BE>;
-template class SymbolTable<object::ELF64LE>;
-template class SymbolTable<object::ELF64BE>;
-}
-}
// an undefined symbol. Or, if there's a conflict between a lazy and a
// undefined, it'll read an archive member to read a real definition
// to replace the lazy symbol. The logic is implemented in resolve().
-template <class ELFT> class SymbolTable {
+class SymbolTable {
public:
SymbolTable();
void reportRemainingUndefines();
// The writer needs to infer the machine type from the object files.
- std::vector<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles;
+ std::vector<std::unique_ptr<ObjectFileBase>> ObjectFiles;
private:
- void addObject(ObjectFile<ELFT> *File);
+ void addObject(ObjectFileBase *File);
void resolve(SymbolBody *Body);
static const int PageSize = 4096;
-template <class ELFT> Writer<ELFT>::Writer(SymbolTable<ELFT> *T) : Symtab(T) {}
+template <class ELFT>
+Writer<ELFT>::Writer(SymbolTable *Symtab)
+ : Symtab(Symtab) {}
template <class ELFT> Writer<ELFT>::~Writer() {}
// The main function of the writer.
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::createSections() {
SmallDenseMap<StringRef, OutputSection *> Map;
- for (std::unique_ptr<ObjectFile<ELFT>> &File : Symtab->ObjectFiles) {
+ for (std::unique_ptr<ObjectFileBase> &File : Symtab->ObjectFiles) {
for (Chunk *C : File->getChunks()) {
OutputSection *&Sec = Map[C->getSectionName()];
if (!Sec) {
public:
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
- explicit Writer(SymbolTable<ELFT> *T);
+ explicit Writer(SymbolTable *Symtab);
~Writer();
void write(StringRef Path);
void writeHeader();
void writeSections();
- SymbolTable<ELFT> *Symtab;
+ SymbolTable *Symtab;
std::unique_ptr<llvm::FileOutputBuffer> Buffer;
llvm::SpecificBumpPtrAllocator<OutputSection> CAlloc;
std::vector<OutputSection *> OutputSections;