207 lines · c
1//===- InputFiles.h ---------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLD_WASM_INPUT_FILES_H10#define LLD_WASM_INPUT_FILES_H11 12#include "Symbols.h"13#include "lld/Common/LLVM.h"14#include "llvm/ADT/DenseMap.h"15#include "llvm/ADT/DenseSet.h"16#include "llvm/LTO/LTO.h"17#include "llvm/Object/Wasm.h"18#include "llvm/Support/MemoryBuffer.h"19#include "llvm/TargetParser/Triple.h"20#include <optional>21#include <vector>22 23namespace llvm {24class TarWriter;25}26 27namespace lld {28namespace wasm {29 30class InputChunk;31class InputFunction;32class InputSegment;33class InputGlobal;34class InputTag;35class InputTable;36class InputSection;37 38// If --reproduce option is given, all input files are written39// to this tar archive.40extern std::unique_ptr<llvm::TarWriter> tar;41 42class InputFile {43public:44 enum Kind {45 ObjectKind,46 SharedKind,47 BitcodeKind,48 StubKind,49 };50 51 virtual ~InputFile() {}52 53 // Returns the filename.54 StringRef getName() const { return mb.getBufferIdentifier(); }55 56 Kind kind() const { return fileKind; }57 58 // An archive file name if this file is created from an archive.59 std::string archiveName;60 61 ArrayRef<Symbol *> getSymbols() const { return symbols; }62 63 MutableArrayRef<Symbol *> getMutableSymbols() { return symbols; }64 65 // An InputFile is considered live if any of the symbols defined by it66 // are live.67 void markLive() { live = true; }68 bool isLive() const { return live; }69 70 // True if this is a relocatable object file/bitcode file in an ar archive71 // or between --start-lib and --end-lib.72 bool lazy = false;73 74protected:75 InputFile(Kind k, MemoryBufferRef m)76 : mb(m), fileKind(k), live(!ctx.arg.gcSections) {}77 78 void checkArch(llvm::Triple::ArchType arch) const;79 80 MemoryBufferRef mb;81 82 // List of all symbols referenced or defined by this file.83 std::vector<Symbol *> symbols;84 85private:86 const Kind fileKind;87 bool live;88};89 90class WasmFileBase : public InputFile {91public:92 explicit WasmFileBase(Kind k, MemoryBufferRef m);93 94 // Returns the underlying wasm file.95 const WasmObjectFile *getWasmObj() const { return wasmObj.get(); }96 97protected:98 std::unique_ptr<WasmObjectFile> wasmObj;99};100 101// .o file (wasm object file)102class ObjFile : public WasmFileBase {103public:104 ObjFile(MemoryBufferRef m, StringRef archiveName, bool lazy = false);105 static bool classof(const InputFile *f) { return f->kind() == ObjectKind; }106 107 void parse(bool ignoreComdats = false);108 void parseLazy();109 110 uint32_t calcNewIndex(const WasmRelocation &reloc) const;111 uint64_t calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,112 const InputChunk *chunk) const;113 int64_t calcNewAddend(const WasmRelocation &reloc) const;114 Symbol *getSymbol(const WasmRelocation &reloc) const {115 return symbols[reloc.Index];116 };117 118 const WasmSection *codeSection = nullptr;119 const WasmSection *dataSection = nullptr;120 121 // Maps input type indices to output type indices122 std::vector<uint32_t> typeMap;123 std::vector<bool> typeIsUsed;124 // Maps function indices to table indices125 std::vector<uint32_t> tableEntries;126 std::vector<uint32_t> tableEntriesRel;127 std::vector<bool> keptComdats;128 std::vector<InputChunk *> segments;129 std::vector<InputFunction *> functions;130 std::vector<InputGlobal *> globals;131 std::vector<InputTag *> tags;132 std::vector<InputTable *> tables;133 std::vector<InputChunk *> customSections;134 llvm::DenseMap<uint32_t, InputChunk *> customSectionsByIndex;135 136 Symbol *getSymbol(uint32_t index) const { return symbols[index]; }137 FunctionSymbol *getFunctionSymbol(uint32_t index) const;138 DataSymbol *getDataSymbol(uint32_t index) const;139 GlobalSymbol *getGlobalSymbol(uint32_t index) const;140 SectionSymbol *getSectionSymbol(uint32_t index) const;141 TagSymbol *getTagSymbol(uint32_t index) const;142 TableSymbol *getTableSymbol(uint32_t index) const;143 144private:145 Symbol *createDefined(const WasmSymbol &sym);146 Symbol *createUndefined(const WasmSymbol &sym, bool isCalledDirectly);147 148 bool isExcludedByComdat(const InputChunk *chunk) const;149 void addLegacyIndirectFunctionTableIfNeeded(uint32_t tableSymbolCount);150};151 152// .so file.153class SharedFile : public WasmFileBase {154public:155 explicit SharedFile(MemoryBufferRef m) : WasmFileBase(SharedKind, m) {}156 157 void parse();158 159 static bool classof(const InputFile *f) { return f->kind() == SharedKind; }160};161 162// .bc file163class BitcodeFile : public InputFile {164public:165 BitcodeFile(MemoryBufferRef m, StringRef archiveName,166 uint64_t offsetInArchive, bool lazy);167 static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }168 169 void parse(StringRef symName);170 void parseLazy();171 std::unique_ptr<llvm::lto::InputFile> obj;172 173 // Set to true once LTO is complete in order prevent further bitcode objects174 // being added.175 static bool doneLTO;176};177 178// Stub library (See docs/WebAssembly.rst)179class StubFile : public InputFile {180public:181 explicit StubFile(MemoryBufferRef m) : InputFile(StubKind, m) {}182 183 static bool classof(const InputFile *f) { return f->kind() == StubKind; }184 185 void parse();186 187 llvm::DenseMap<StringRef, std::vector<StringRef>> symbolDependencies;188};189 190// Will report a fatal() error if the input buffer is not a valid bitcode191// or wasm object file.192InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName = "",193 uint64_t offsetInArchive = 0, bool lazy = false);194 195// Opens a given file.196std::optional<MemoryBufferRef> readFile(StringRef path);197 198std::string replaceThinLTOSuffix(StringRef path);199 200} // namespace wasm201 202std::string toString(const wasm::InputFile *file);203 204} // namespace lld205 206#endif207