Files
clang-p2996/lld/wasm/Config.h
Nick Fitzgerald 6018930ef1 [lld][WebAssembly] Support for the custom-page-sizes WebAssembly proposal (#128942)
This commit adds support for WebAssembly's custom-page-sizes proposal to
`wasm-ld`. An overview of the proposal can be found
[here](https://github.com/WebAssembly/custom-page-sizes/blob/main/proposals/custom-page-sizes/Overview.md).
In a sentence, it allows customizing a Wasm memory's page size, enabling
Wasm to target environments with less than 64KiB of memory (the default
Wasm page size) available for Wasm memories.

This commit contains the following:

* Adds a `--page-size=N` CLI flag to `wasm-ld` for configuring the
linked Wasm binary's linear memory's page size.

* When the page size is configured to a non-default value, then the
final Wasm binary will use the encodings defined in the
custom-page-sizes proposal to declare the linear memory's page size.

* Defines a `__wasm_first_page_end` symbol, whose address points to the
first page in the Wasm linear memory, a.k.a. is the Wasm memory's page
size. This allows writing code that is compatible with any page size,
and doesn't require re-compiling its object code. At the same time,
because it just lowers to a constant rather than a memory access or
something, it enables link-time optimization.

* Adds tests for these new features.

r? @sbc100 

cc @sunfishcode
2025-03-04 09:39:30 -08:00

171 lines
5.0 KiB
C++

//===- Config.h -------------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLD_WASM_CONFIG_H
#define LLD_WASM_CONFIG_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/Support/CachePruning.h"
#include <optional>
namespace llvm {
enum class CodeGenOptLevel;
} // namespace llvm
namespace lld::wasm {
class InputFile;
class StubFile;
class ObjFile;
class SharedFile;
class BitcodeFile;
class InputTable;
class InputGlobal;
class InputFunction;
class Symbol;
// For --unresolved-symbols.
enum class UnresolvedPolicy { ReportError, Warn, Ignore, ImportDynamic };
// For --build-id.
enum class BuildIdKind { None, Fast, Sha1, Hexstring, Uuid };
// This struct contains the global configuration for the linker.
// Most fields are direct mapping from the command line options
// and such fields have the same name as the corresponding options.
// Most fields are initialized by the driver.
struct Config {
bool allowMultipleDefinition;
bool bsymbolic;
bool checkFeatures;
bool compressRelocations;
bool demangle;
bool disableVerify;
bool experimentalPic;
bool emitRelocs;
bool exportAll;
bool exportDynamic;
bool exportTable;
bool extendedConst;
bool growableTable;
bool gcSections;
llvm::StringSet<> keepSections;
std::optional<std::pair<llvm::StringRef, llvm::StringRef>> memoryImport;
std::optional<llvm::StringRef> memoryExport;
bool sharedMemory;
bool importTable;
bool importUndefined;
std::optional<bool> is64;
bool mergeDataSegments;
bool noinhibitExec;
bool pie;
bool printGcSections;
bool relocatable;
bool saveTemps;
bool shared;
bool shlibSigCheck;
bool stripAll;
bool stripDebug;
bool stackFirst;
// Because dyamanic linking under Wasm is still experimental we default to
// static linking
bool isStatic = true;
bool thinLTOEmitImportsFiles;
bool thinLTOEmitIndexFiles;
bool thinLTOIndexOnly;
bool trace;
uint64_t globalBase;
uint64_t initialHeap;
uint64_t initialMemory;
uint64_t maxMemory;
bool noGrowableMemory;
// The table offset at which to place function addresses. We reserve zero
// for the null function pointer. This gets set to 1 for executables and 0
// for shared libraries (since they always added to a dynamic offset at
// runtime).
uint64_t tableBase;
uint64_t zStackSize;
uint64_t pageSize;
unsigned ltoPartitions;
unsigned ltoo;
llvm::CodeGenOptLevel ltoCgo;
unsigned optimize;
bool ltoDebugPassManager;
UnresolvedPolicy unresolvedSymbols;
BuildIdKind buildId = BuildIdKind::None;
llvm::StringRef entry;
llvm::StringRef ltoObjPath;
llvm::StringRef mapFile;
llvm::StringRef outputFile;
llvm::StringRef soName;
llvm::StringRef thinLTOCacheDir;
llvm::StringRef thinLTOJobs;
llvm::StringRef thinLTOIndexOnlyArg;
std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
llvm::StringRef thinLTOPrefixReplaceOld;
llvm::StringRef thinLTOPrefixReplaceNew;
llvm::StringRef thinLTOPrefixReplaceNativeObject;
llvm::StringRef whyExtract;
llvm::StringSet<> allowUndefinedSymbols;
llvm::StringSet<> exportedSymbols;
std::vector<llvm::StringRef> requiredExports;
llvm::SmallVector<llvm::StringRef, 0> searchPaths;
llvm::SmallVector<llvm::StringRef, 0> rpath;
llvm::CachePruningPolicy thinLTOCachePolicy;
std::optional<std::vector<std::string>> features;
std::optional<std::vector<std::string>> extraFeatures;
llvm::SmallVector<uint8_t, 0> buildIdVector;
};
// The Ctx object hold all other (non-configuration) global state.
struct Ctx {
Config arg;
llvm::SmallVector<ObjFile *, 0> objectFiles;
llvm::SmallVector<StubFile *, 0> stubFiles;
llvm::SmallVector<SharedFile *, 0> sharedFiles;
llvm::SmallVector<BitcodeFile *, 0> bitcodeFiles;
llvm::SmallVector<BitcodeFile *, 0> lazyBitcodeFiles;
llvm::SmallVector<InputFunction *, 0> syntheticFunctions;
llvm::SmallVector<InputGlobal *, 0> syntheticGlobals;
llvm::SmallVector<InputTable *, 0> syntheticTables;
// True if we are creating position-independent code.
bool isPic = false;
// True if we have an MVP input that uses __indirect_function_table and which
// requires it to be allocated to table number 0.
bool legacyFunctionTable = false;
// Will be set to true if bss data segments should be emitted. In most cases
// this is not necessary.
bool emitBssSegments = false;
// A tuple of (reference, extractedFile, sym). Used by --why-extract=.
llvm::SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>,
0>
whyExtractRecords;
Ctx();
void reset();
};
extern Ctx ctx;
void errorOrWarn(const llvm::Twine &msg);
} // namespace lld::wasm
#endif