2017-11-17 18:14:09 +00:00
|
|
|
//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
|
|
|
|
//
|
2019-01-19 08:50:56 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2017-11-17 18:14:09 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLD_WASM_INPUT_FILES_H
|
|
|
|
#define LLD_WASM_INPUT_FILES_H
|
|
|
|
|
2018-02-20 21:53:18 +00:00
|
|
|
#include "Symbols.h"
|
2017-11-17 18:14:09 +00:00
|
|
|
#include "lld/Common/LLVM.h"
|
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
|
|
#include "llvm/ADT/DenseSet.h"
|
2018-05-30 18:07:52 +00:00
|
|
|
#include "llvm/LTO/LTO.h"
|
2017-11-17 18:14:09 +00:00
|
|
|
#include "llvm/Object/Wasm.h"
|
|
|
|
#include "llvm/Support/MemoryBuffer.h"
|
2023-02-07 12:21:51 +00:00
|
|
|
#include "llvm/TargetParser/Triple.h"
|
2023-01-02 18:29:04 -08:00
|
|
|
#include <optional>
|
2017-11-17 18:14:09 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2019-05-21 11:52:14 +00:00
|
|
|
namespace llvm {
|
|
|
|
class TarWriter;
|
|
|
|
}
|
|
|
|
|
2017-11-17 18:14:09 +00:00
|
|
|
namespace lld {
|
|
|
|
namespace wasm {
|
|
|
|
|
2018-01-12 22:25:17 +00:00
|
|
|
class InputChunk;
|
2018-01-09 23:56:44 +00:00
|
|
|
class InputFunction;
|
2017-11-17 18:14:09 +00:00
|
|
|
class InputSegment;
|
2018-02-23 05:08:53 +00:00
|
|
|
class InputGlobal;
|
2021-06-15 01:49:43 -07:00
|
|
|
class InputTag;
|
2021-01-05 12:08:58 +01:00
|
|
|
class InputTable;
|
2018-04-10 16:12:49 +00:00
|
|
|
class InputSection;
|
2017-11-17 18:14:09 +00:00
|
|
|
|
2019-05-21 11:52:14 +00:00
|
|
|
// If --reproduce option is given, all input files are written
|
|
|
|
// to this tar archive.
|
|
|
|
extern std::unique_ptr<llvm::TarWriter> tar;
|
|
|
|
|
2017-11-17 18:14:09 +00:00
|
|
|
class InputFile {
|
|
|
|
public:
|
|
|
|
enum Kind {
|
|
|
|
ObjectKind,
|
2019-03-13 21:29:20 +00:00
|
|
|
SharedKind,
|
2018-05-30 18:07:52 +00:00
|
|
|
BitcodeKind,
|
2022-12-06 16:49:13 -08:00
|
|
|
StubKind,
|
2017-11-17 18:14:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
virtual ~InputFile() {}
|
|
|
|
|
|
|
|
// Returns the filename.
|
|
|
|
StringRef getName() const { return mb.getBufferIdentifier(); }
|
|
|
|
|
|
|
|
Kind kind() const { return fileKind; }
|
|
|
|
|
|
|
|
// An archive file name if this file is created from an archive.
|
2019-09-18 21:51:03 +00:00
|
|
|
std::string archiveName;
|
2017-11-17 18:14:09 +00:00
|
|
|
|
2018-05-30 18:07:52 +00:00
|
|
|
ArrayRef<Symbol *> getSymbols() const { return symbols; }
|
|
|
|
|
2019-05-24 14:14:25 +00:00
|
|
|
MutableArrayRef<Symbol *> getMutableSymbols() { return symbols; }
|
|
|
|
|
2020-09-30 20:00:04 -07:00
|
|
|
// An InputFile is considered live if any of the symbols defined by it
|
|
|
|
// are live.
|
|
|
|
void markLive() { live = true; }
|
|
|
|
bool isLive() const { return live; }
|
|
|
|
|
2024-01-22 10:04:26 -08:00
|
|
|
// True if this is a relocatable object file/bitcode file in an ar archive
|
|
|
|
// or between --start-lib and --end-lib.
|
2024-01-19 16:20:29 -08:00
|
|
|
bool lazy = false;
|
|
|
|
|
2017-11-17 18:14:09 +00:00
|
|
|
protected:
|
2020-09-30 20:00:04 -07:00
|
|
|
InputFile(Kind k, MemoryBufferRef m)
|
|
|
|
: mb(m), fileKind(k), live(!config->gcSections) {}
|
2020-10-26 14:38:09 -07:00
|
|
|
|
|
|
|
void checkArch(llvm::Triple::ArchType arch) const;
|
|
|
|
|
2017-11-17 18:14:09 +00:00
|
|
|
MemoryBufferRef mb;
|
|
|
|
|
2018-05-30 18:07:52 +00:00
|
|
|
// List of all symbols referenced or defined by this file.
|
|
|
|
std::vector<Symbol *> symbols;
|
|
|
|
|
2017-11-17 18:14:09 +00:00
|
|
|
private:
|
|
|
|
const Kind fileKind;
|
2020-09-30 20:00:04 -07:00
|
|
|
bool live;
|
2017-11-17 18:14:09 +00:00
|
|
|
};
|
|
|
|
|
2024-07-12 13:26:52 -07:00
|
|
|
class WasmFileBase : public InputFile {
|
|
|
|
public:
|
|
|
|
explicit WasmFileBase(Kind k, MemoryBufferRef m);
|
|
|
|
|
|
|
|
// Returns the underlying wasm file.
|
|
|
|
const WasmObjectFile *getWasmObj() const { return wasmObj.get(); }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
std::unique_ptr<WasmObjectFile> wasmObj;
|
|
|
|
};
|
|
|
|
|
2017-11-17 18:14:09 +00:00
|
|
|
// .o file (wasm object file)
|
2024-07-12 13:26:52 -07:00
|
|
|
class ObjFile : public WasmFileBase {
|
2017-11-17 18:14:09 +00:00
|
|
|
public:
|
2024-01-19 16:20:29 -08:00
|
|
|
ObjFile(MemoryBufferRef m, StringRef archiveName, bool lazy = false);
|
2017-11-17 18:14:09 +00:00
|
|
|
static bool classof(const InputFile *f) { return f->kind() == ObjectKind; }
|
|
|
|
|
2019-06-05 17:50:45 +00:00
|
|
|
void parse(bool ignoreComdats = false);
|
2024-01-19 16:20:29 -08:00
|
|
|
void parseLazy();
|
2017-11-17 18:14:09 +00:00
|
|
|
|
2018-01-10 19:22:42 +00:00
|
|
|
uint32_t calcNewIndex(const WasmRelocation &reloc) const;
|
2021-03-08 11:23:33 -08:00
|
|
|
uint64_t calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,
|
|
|
|
const InputChunk *chunk) const;
|
2022-02-23 22:23:05 -08:00
|
|
|
int64_t calcNewAddend(const WasmRelocation &reloc) const;
|
2019-04-04 18:40:51 +00:00
|
|
|
Symbol *getSymbol(const WasmRelocation &reloc) const {
|
|
|
|
return symbols[reloc.Index];
|
|
|
|
};
|
2017-11-17 18:14:09 +00:00
|
|
|
|
|
|
|
const WasmSection *codeSection = nullptr;
|
2018-01-10 01:13:34 +00:00
|
|
|
const WasmSection *dataSection = nullptr;
|
2017-11-17 18:14:09 +00:00
|
|
|
|
2018-03-12 19:54:26 +00:00
|
|
|
// Maps input type indices to output type indices
|
2017-11-17 18:14:09 +00:00
|
|
|
std::vector<uint32_t> typeMap;
|
2018-01-31 23:48:14 +00:00
|
|
|
std::vector<bool> typeIsUsed;
|
2018-03-12 19:54:26 +00:00
|
|
|
// Maps function indices to table indices
|
|
|
|
std::vector<uint32_t> tableEntries;
|
2020-05-28 18:39:27 -07:00
|
|
|
std::vector<uint32_t> tableEntriesRel;
|
2019-05-15 16:03:28 +00:00
|
|
|
std::vector<bool> keptComdats;
|
2021-05-14 16:25:04 -07:00
|
|
|
std::vector<InputChunk *> segments;
|
2018-01-09 23:56:44 +00:00
|
|
|
std::vector<InputFunction *> functions;
|
2018-02-23 05:08:53 +00:00
|
|
|
std::vector<InputGlobal *> globals;
|
2021-06-15 01:49:43 -07:00
|
|
|
std::vector<InputTag *> tags;
|
2021-01-05 12:08:58 +01:00
|
|
|
std::vector<InputTable *> tables;
|
2021-05-12 16:48:34 -07:00
|
|
|
std::vector<InputChunk *> customSections;
|
|
|
|
llvm::DenseMap<uint32_t, InputChunk *> customSectionsByIndex;
|
2019-07-11 05:40:30 +00:00
|
|
|
|
2018-02-23 05:08:53 +00:00
|
|
|
Symbol *getSymbol(uint32_t index) const { return symbols[index]; }
|
|
|
|
FunctionSymbol *getFunctionSymbol(uint32_t index) const;
|
|
|
|
DataSymbol *getDataSymbol(uint32_t index) const;
|
|
|
|
GlobalSymbol *getGlobalSymbol(uint32_t index) const;
|
2018-05-04 23:14:42 +00:00
|
|
|
SectionSymbol *getSectionSymbol(uint32_t index) const;
|
2021-06-15 01:49:43 -07:00
|
|
|
TagSymbol *getTagSymbol(uint32_t index) const;
|
2021-01-05 12:08:58 +01:00
|
|
|
TableSymbol *getTableSymbol(uint32_t index) const;
|
2018-01-31 01:45:47 +00:00
|
|
|
|
2017-11-17 18:14:09 +00:00
|
|
|
private:
|
2018-02-28 00:50:54 +00:00
|
|
|
Symbol *createDefined(const WasmSymbol &sym);
|
2019-05-24 22:45:08 +00:00
|
|
|
Symbol *createUndefined(const WasmSymbol &sym, bool isCalledDirectly);
|
2018-02-23 05:08:53 +00:00
|
|
|
|
2021-10-04 16:47:59 -07:00
|
|
|
bool isExcludedByComdat(const InputChunk *chunk) const;
|
2021-02-12 20:01:41 +01:00
|
|
|
void addLegacyIndirectFunctionTableIfNeeded(uint32_t tableSymbolCount);
|
2017-11-17 18:14:09 +00:00
|
|
|
};
|
|
|
|
|
2019-03-13 21:29:20 +00:00
|
|
|
// .so file.
|
2024-07-12 13:26:52 -07:00
|
|
|
class SharedFile : public WasmFileBase {
|
2019-03-13 21:29:20 +00:00
|
|
|
public:
|
2024-07-12 13:26:52 -07:00
|
|
|
explicit SharedFile(MemoryBufferRef m) : WasmFileBase(SharedKind, m) {}
|
|
|
|
|
|
|
|
void parse();
|
|
|
|
|
2019-03-13 21:29:20 +00:00
|
|
|
static bool classof(const InputFile *f) { return f->kind() == SharedKind; }
|
|
|
|
};
|
|
|
|
|
|
|
|
// .bc file
|
2018-05-30 18:07:52 +00:00
|
|
|
class BitcodeFile : public InputFile {
|
|
|
|
public:
|
2021-10-28 08:15:20 -07:00
|
|
|
BitcodeFile(MemoryBufferRef m, StringRef archiveName,
|
2024-01-19 16:20:29 -08:00
|
|
|
uint64_t offsetInArchive, bool lazy);
|
2018-05-30 18:07:52 +00:00
|
|
|
static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
|
|
|
|
|
2023-09-18 14:11:49 -07:00
|
|
|
void parse(StringRef symName);
|
2024-01-19 16:20:29 -08:00
|
|
|
void parseLazy();
|
2018-05-30 18:07:52 +00:00
|
|
|
std::unique_ptr<llvm::lto::InputFile> obj;
|
2019-12-19 17:30:24 -08:00
|
|
|
|
|
|
|
// Set to true once LTO is complete in order prevent further bitcode objects
|
|
|
|
// being added.
|
|
|
|
static bool doneLTO;
|
2018-05-30 18:07:52 +00:00
|
|
|
};
|
|
|
|
|
2023-05-10 19:53:47 +02:00
|
|
|
// Stub library (See docs/WebAssembly.rst)
|
2022-12-06 16:49:13 -08:00
|
|
|
class StubFile : public InputFile {
|
|
|
|
public:
|
|
|
|
explicit StubFile(MemoryBufferRef m) : InputFile(StubKind, m) {}
|
|
|
|
|
|
|
|
static bool classof(const InputFile *f) { return f->kind() == StubKind; }
|
|
|
|
|
|
|
|
void parse();
|
|
|
|
|
|
|
|
llvm::DenseMap<StringRef, std::vector<StringRef>> symbolDependencies;
|
|
|
|
};
|
|
|
|
|
2018-07-23 23:51:19 +00:00
|
|
|
// Will report a fatal() error if the input buffer is not a valid bitcode
|
2019-01-17 02:29:41 +00:00
|
|
|
// or wasm object file.
|
2021-10-28 08:15:20 -07:00
|
|
|
InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName = "",
|
2024-01-19 16:20:29 -08:00
|
|
|
uint64_t offsetInArchive = 0, bool lazy = false);
|
2018-07-23 23:51:19 +00:00
|
|
|
|
2017-11-17 18:14:09 +00:00
|
|
|
// Opens a given file.
|
2023-01-02 18:29:04 -08:00
|
|
|
std::optional<MemoryBufferRef> readFile(StringRef path);
|
2017-11-17 18:14:09 +00:00
|
|
|
|
|
|
|
} // namespace wasm
|
|
|
|
|
2017-12-05 16:50:46 +00:00
|
|
|
std::string toString(const wasm::InputFile *file);
|
2017-11-17 18:14:09 +00:00
|
|
|
|
|
|
|
} // namespace lld
|
|
|
|
|
|
|
|
#endif
|