blob: 4a5748147274073d360f66662fa8b0cabd15acfa [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"
Rafael Espindolaf2f41a92015-08-28 02:40:04 +000014#include "Symbols.h"
15
Michael J. Spencer84487f12015-07-24 21:03:07 +000016#include "lld/Core/LLVM.h"
17#include "llvm/Object/ELF.h"
18
19namespace lld {
20namespace elf2 {
21class SymbolBody;
Michael J. Spencer84487f12015-07-24 21:03:07 +000022
23// The root class of input files.
24class InputFile {
25public:
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000026 enum Kind { Object32LEKind, Object32BEKind, Object64LEKind, Object64BEKind };
Michael J. Spencer84487f12015-07-24 21:03:07 +000027 Kind kind() const { return FileKind; }
28 virtual ~InputFile() {}
29
30 // Returns symbols defined by this file.
31 virtual ArrayRef<SymbolBody *> getSymbols() = 0;
32
33 // Reads a file (constructors don't do that).
34 virtual void parse() = 0;
35
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000036 StringRef getName() const { return MB.getBufferIdentifier(); }
37
Michael J. Spencer84487f12015-07-24 21:03:07 +000038protected:
39 explicit InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
40 MemoryBufferRef MB;
41
42private:
43 const Kind FileKind;
44};
45
46// .o file.
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000047class ObjectFileBase : public InputFile {
48public:
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000049 explicit ObjectFileBase(Kind K, MemoryBufferRef M) : InputFile(K, M) {}
50 static bool classof(const InputFile *F) {
51 Kind K = F->kind();
52 return K >= Object32LEKind && K <= Object64BEKind;
53 }
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000054
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000055 ArrayRef<SymbolBody *> getSymbols() override { return SymbolBodies; }
56
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000057 virtual bool isCompatibleWith(const ObjectFileBase &Other) const = 0;
58
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000059protected:
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000060 // List of all symbols referenced or defined by this file.
61 std::vector<SymbolBody *> SymbolBodies;
62
63 llvm::BumpPtrAllocator Alloc;
64};
65
66template <class ELFT> class ObjectFile : public ObjectFileBase {
Michael J. Spencer84487f12015-07-24 21:03:07 +000067 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
68 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
69 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
Rafael Espindola20348222015-08-24 21:43:25 +000070 typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word;
Michael J. Spencer84487f12015-07-24 21:03:07 +000071
72public:
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000073 bool isCompatibleWith(const ObjectFileBase &Other) const override;
74
75 static Kind getKind() {
76 if (!ELFT::Is64Bits) {
77 if (ELFT::TargetEndianness == llvm::support::little)
78 return Object32LEKind;
79 return Object32BEKind;
80 }
81 if (ELFT::TargetEndianness == llvm::support::little)
82 return Object64LEKind;
83 return Object64BEKind;
84 }
85
86 static bool classof(const InputFile *F) { return F->kind() == getKind(); }
87
88 explicit ObjectFile(MemoryBufferRef M) : ObjectFileBase(getKind(), M) {}
Michael J. Spencer84487f12015-07-24 21:03:07 +000089 void parse() override;
Michael J. Spencer84487f12015-07-24 21:03:07 +000090
91 // Returns the underying ELF file.
Rafael Espindola3c9cb4b2015-08-05 12:03:34 +000092 llvm::object::ELFFile<ELFT> *getObj() const { return ELFObj.get(); }
Michael J. Spencer84487f12015-07-24 21:03:07 +000093
Rafael Espindolae7a00e32015-08-05 13:55:34 +000094 ArrayRef<SectionChunk<ELFT> *> getChunks() { return Chunks; }
95
Michael J. Spencer67bc8d62015-08-27 23:15:56 +000096 SymbolBody *getSymbolBody(uint32_t SymbolIndex) {
97 uint32_t FirstNonLocal = Symtab->sh_info;
98 if (SymbolIndex < FirstNonLocal)
99 return nullptr;
100 return SymbolBodies[SymbolIndex - FirstNonLocal]->getReplacement();
101 }
102
Michael J. Spencer84487f12015-07-24 21:03:07 +0000103private:
104 void initializeChunks();
105 void initializeSymbols();
106
107 SymbolBody *createSymbolBody(StringRef StringTable, const Elf_Sym *Sym);
108
109 std::unique_ptr<llvm::object::ELFFile<ELFT>> ELFObj;
Rafael Espindolae7a00e32015-08-05 13:55:34 +0000110
111 // List of all chunks defined by this file.
112 std::vector<SectionChunk<ELFT> *> Chunks;
Rafael Espindolad8340da2015-08-10 15:12:17 +0000113
114 const Elf_Shdr *Symtab = nullptr;
Rafael Espindola20348222015-08-24 21:43:25 +0000115 ArrayRef<Elf_Word> SymtabSHNDX;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000116};
117
118} // namespace elf2
119} // namespace lld
120
121#endif