blob: dc1c65bd1c1e307bb04c3efda589bb0ad9c821e8 [file] [log] [blame]
Rafael Espindolabeee25e2015-08-14 14:12:54 +00001//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
Michael J. Spencer84487f12015-07-24 21:03:07 +00002//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_INPUT_FILES_H
11#define LLD_ELF_INPUT_FILES_H
12
Rafael Espindolae7a00e32015-08-05 13:55:34 +000013#include "Chunks.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000014#include "lld/Core/LLVM.h"
15#include "llvm/Object/ELF.h"
16
17namespace lld {
18namespace elf2 {
19class SymbolBody;
Michael J. Spencer84487f12015-07-24 21:03:07 +000020
21// The root class of input files.
22class InputFile {
23public:
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000024 enum Kind { Object32LEKind, Object32BEKind, Object64LEKind, Object64BEKind };
Michael J. Spencer84487f12015-07-24 21:03:07 +000025 Kind kind() const { return FileKind; }
26 virtual ~InputFile() {}
27
28 // Returns symbols defined by this file.
29 virtual ArrayRef<SymbolBody *> getSymbols() = 0;
30
31 // Reads a file (constructors don't do that).
32 virtual void parse() = 0;
33
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000034 StringRef getName() const { return MB.getBufferIdentifier(); }
35
Michael J. Spencer84487f12015-07-24 21:03:07 +000036protected:
37 explicit InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
38 MemoryBufferRef MB;
39
40private:
41 const Kind FileKind;
42};
43
44// .o file.
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000045class ObjectFileBase : public InputFile {
46public:
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000047 explicit ObjectFileBase(Kind K, MemoryBufferRef M) : InputFile(K, M) {}
48 static bool classof(const InputFile *F) {
49 Kind K = F->kind();
50 return K >= Object32LEKind && K <= Object64BEKind;
51 }
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000052
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000053 ArrayRef<SymbolBody *> getSymbols() override { return SymbolBodies; }
54
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000055 virtual bool isCompatibleWith(const ObjectFileBase &Other) const = 0;
56
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000057protected:
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000058 // List of all symbols referenced or defined by this file.
59 std::vector<SymbolBody *> SymbolBodies;
60
61 llvm::BumpPtrAllocator Alloc;
62};
63
64template <class ELFT> class ObjectFile : public ObjectFileBase {
Michael J. Spencer84487f12015-07-24 21:03:07 +000065 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
66 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
67 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
Rafael Espindola20348222015-08-24 21:43:25 +000068 typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word;
Michael J. Spencer84487f12015-07-24 21:03:07 +000069
70public:
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000071 bool isCompatibleWith(const ObjectFileBase &Other) const override;
72
73 static Kind getKind() {
74 if (!ELFT::Is64Bits) {
75 if (ELFT::TargetEndianness == llvm::support::little)
76 return Object32LEKind;
77 return Object32BEKind;
78 }
79 if (ELFT::TargetEndianness == llvm::support::little)
80 return Object64LEKind;
81 return Object64BEKind;
82 }
83
84 static bool classof(const InputFile *F) { return F->kind() == getKind(); }
85
86 explicit ObjectFile(MemoryBufferRef M) : ObjectFileBase(getKind(), M) {}
Michael J. Spencer84487f12015-07-24 21:03:07 +000087 void parse() override;
Michael J. Spencer84487f12015-07-24 21:03:07 +000088
89 // Returns the underying ELF file.
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000090 llvm::object::ELFFile<ELFT> *getObj() const { return ELFObj.get(); }
Michael J. Spencer84487f12015-07-24 21:03:07 +000091
Rafael Espindolae7a00e32015-08-05 13:55:34 +000092 ArrayRef<SectionChunk<ELFT> *> getChunks() { return Chunks; }
93
Michael J. Spencer67bc8d62015-08-27 23:15:56 +000094 SymbolBody *getSymbolBody(uint32_t SymbolIndex) {
95 uint32_t FirstNonLocal = Symtab->sh_info;
96 if (SymbolIndex < FirstNonLocal)
97 return nullptr;
98 return SymbolBodies[SymbolIndex - FirstNonLocal]->getReplacement();
99 }
100
Michael J. Spencer84487f12015-07-24 21:03:07 +0000101private:
102 void initializeChunks();
103 void initializeSymbols();
104
105 SymbolBody *createSymbolBody(StringRef StringTable, const Elf_Sym *Sym);
106
107 std::unique_ptr<llvm::object::ELFFile<ELFT>> ELFObj;
Rafael Espindolae7a00e32015-08-05 13:55:34 +0000108
109 // List of all chunks defined by this file.
110 std::vector<SectionChunk<ELFT> *> Chunks;
Rafael Espindolad8340da2015-08-10 15:12:17 +0000111
112 const Elf_Shdr *Symtab = nullptr;
Rafael Espindola20348222015-08-24 21:43:25 +0000113 ArrayRef<Elf_Word> SymtabSHNDX;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000114};
115
116} // namespace elf2
117} // namespace lld
118
119#endif