1 //===- InputFiles.h ---------------------------------------------*- C++ -*-===// 2 // 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_WASM_INPUT_FILES_H 11 #define LLD_WASM_INPUT_FILES_H 12 13 #include "Symbols.h" 14 #include "lld/Common/LLVM.h" 15 #include "llvm/ADT/DenseMap.h" 16 #include "llvm/ADT/DenseSet.h" 17 #include "llvm/LTO/LTO.h" 18 #include "llvm/Object/Archive.h" 19 #include "llvm/Object/Wasm.h" 20 #include "llvm/Support/MemoryBuffer.h" 21 #include <vector> 22 23 namespace lld { 24 namespace wasm { 25 26 class InputChunk; 27 class InputFunction; 28 class InputSegment; 29 class InputGlobal; 30 class InputEvent; 31 class InputSection; 32 33 class InputFile { 34 public: 35 enum Kind { 36 ObjectKind, 37 ArchiveKind, 38 BitcodeKind, 39 }; 40 41 virtual ~InputFile() {} 42 43 // Returns the filename. 44 StringRef getName() const { return MB.getBufferIdentifier(); } 45 46 // Reads a file (the constructor doesn't do that). 47 virtual void parse() = 0; 48 49 Kind kind() const { return FileKind; } 50 51 // An archive file name if this file is created from an archive. 52 StringRef ArchiveName; 53 54 ArrayRef<Symbol *> getSymbols() const { return Symbols; } 55 56 protected: 57 InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} 58 MemoryBufferRef MB; 59 60 // List of all symbols referenced or defined by this file. 61 std::vector<Symbol *> Symbols; 62 63 private: 64 const Kind FileKind; 65 }; 66 67 // .a file (ar archive) 68 class ArchiveFile : public InputFile { 69 public: 70 explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {} 71 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } 72 73 void addMember(const llvm::object::Archive::Symbol *Sym); 74 75 void parse() override; 76 77 private: 78 std::unique_ptr<llvm::object::Archive> File; 79 llvm::DenseSet<uint64_t> Seen; 80 }; 81 82 // .o file (wasm object file) 83 class ObjFile : public InputFile { 84 public: 85 explicit ObjFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {} 86 static bool classof(const InputFile *F) { return F->kind() == ObjectKind; } 87 88 void parse() override; 89 90 // Returns the underlying wasm file. 91 const WasmObjectFile *getWasmObj() const { return WasmObj.get(); } 92 93 void dumpInfo() const; 94 95 uint32_t calcNewIndex(const WasmRelocation &Reloc) const; 96 uint32_t calcNewValue(const WasmRelocation &Reloc) const; 97 uint32_t calcNewAddend(const WasmRelocation &Reloc) const; 98 uint32_t calcExpectedValue(const WasmRelocation &Reloc) const; 99 100 const WasmSection *CodeSection = nullptr; 101 const WasmSection *DataSection = nullptr; 102 103 // Maps input type indices to output type indices 104 std::vector<uint32_t> TypeMap; 105 std::vector<bool> TypeIsUsed; 106 // Maps function indices to table indices 107 std::vector<uint32_t> TableEntries; 108 std::vector<bool> UsedComdats; 109 std::vector<InputSegment *> Segments; 110 std::vector<InputFunction *> Functions; 111 std::vector<InputGlobal *> Globals; 112 std::vector<InputEvent *> Events; 113 std::vector<InputSection *> CustomSections; 114 llvm::DenseMap<uint32_t, InputSection *> CustomSectionsByIndex; 115 116 Symbol *getSymbol(uint32_t Index) const { return Symbols[Index]; } 117 FunctionSymbol *getFunctionSymbol(uint32_t Index) const; 118 DataSymbol *getDataSymbol(uint32_t Index) const; 119 GlobalSymbol *getGlobalSymbol(uint32_t Index) const; 120 SectionSymbol *getSectionSymbol(uint32_t Index) const; 121 EventSymbol *getEventSymbol(uint32_t Index) const; 122 123 private: 124 Symbol *createDefined(const WasmSymbol &Sym); 125 Symbol *createUndefined(const WasmSymbol &Sym); 126 127 bool isExcludedByComdat(InputChunk *Chunk) const; 128 129 std::unique_ptr<WasmObjectFile> WasmObj; 130 }; 131 132 class BitcodeFile : public InputFile { 133 public: 134 explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {} 135 static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } 136 137 void parse() override; 138 std::unique_ptr<llvm::lto::InputFile> Obj; 139 }; 140 141 // Will report a fatal() error if the input buffer is not a valid bitcode 142 // or was object file. 143 InputFile *createObjectFile(MemoryBufferRef MB); 144 145 // Opens a given file. 146 llvm::Optional<MemoryBufferRef> readFile(StringRef Path); 147 148 } // namespace wasm 149 150 std::string toString(const wasm::InputFile *File); 151 152 } // namespace lld 153 154 #endif 155