Skip to content

Commit

Permalink
[lld][WebAssembly] Don't allow --global-base to be specified in -sh…
Browse files Browse the repository at this point in the history
…are/-pie or --relocatable modes

Add some checks around this combination of flags

Also, honor `--global-base` when specified in `--stack-first` mode
rather than ignoring it.  But error out if the specified base preseeds
the end of the stack.

Differential Revision: https://reviews.llvm.org/D136117
  • Loading branch information
sbc100 committed Oct 19, 2022
1 parent 0f374ca commit 6912ed7
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
10 changes: 10 additions & 0 deletions lld/test/wasm/global-base.test
@@ -1,5 +1,15 @@
RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/start.s -o %t.o

# Check for error on `--global-base` with `-shared` and `-pie`
RUN: not wasm-ld --global-base=2048 --experimental-pic -shared -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=SHARED-ERROR
RUN: not wasm-ld --global-base=2048 --experimental-pic -pie -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=SHARED-ERROR
SHARED-ERROR: error: --global-base may not be used with -shared/-pie

# Check for error on `--global-base` which is lower than that end of the stack
# when `--stack-first` is used.
RUN: not wasm-ld --global-base=2048 --stack-first -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=STACK-ERROR
STACK-ERROR: error: --global-base cannot be less than stack size when --stack-first is used

RUN: wasm-ld --export=__global_base --export=__data_end --allow-undefined -o %t.wasm %t.o
RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=CHECK-1024
CHECK-1024: - Type: GLOBAL
Expand Down
8 changes: 7 additions & 1 deletion lld/wasm/Driver.cpp
Expand Up @@ -428,7 +428,7 @@ static void readConfigs(opt::InputArgList &args) {
LLVM_DEBUG(errorHandler().verbose = true);

config->initialMemory = args::getInteger(args, OPT_initial_memory, 0);
config->globalBase = args::getInteger(args, OPT_global_base, 1024);
config->globalBase = args::getInteger(args, OPT_global_base, 0);
config->maxMemory = args::getInteger(args, OPT_max_memory, 0);
config->zStackSize =
args::getZOptionValue(args, OPT_z, "stack-size", WasmPageSize);
Expand Down Expand Up @@ -551,6 +551,8 @@ static void checkOptions(opt::InputArgList &args) {
error("-r and -pie may not be used together");
if (config->sharedMemory)
error("-r and --shared-memory may not be used together");
if (config->globalBase)
error("-r and --global-base may not by used together");
}

// To begin to prepare for Module Linking-style shared libraries, start
Expand Down Expand Up @@ -578,6 +580,10 @@ static void checkOptions(opt::InputArgList &args) {
if (config->bsymbolic && !config->shared) {
warn("-Bsymbolic is only meaningful when combined with -shared");
}

if (config->globalBase && config->isPic) {
error("--global-base may not be used with -shared/-pie");
}
}

// Force Sym to be entered in the output. Used for -u or equivalent.
Expand Down
23 changes: 17 additions & 6 deletions lld/wasm/Writer.cpp
Expand Up @@ -226,9 +226,9 @@ static void setGlobalPtr(DefinedGlobal *g, uint64_t memoryPtr) {
// to each of the input data sections as well as the explicit stack region.
// The default memory layout is as follows, from low to high.
//
// - initialized data (starting at Config->globalBase)
// - initialized data (starting at config->globalBase)
// - BSS data (not currently implemented in llvm)
// - explicit stack (Config->ZStackSize)
// - explicit stack (config->ZStackSize)
// - heap start / unallocated
//
// The --stack-first option means that stack is placed before any static data.
Expand Down Expand Up @@ -257,11 +257,25 @@ void Writer::layoutMemory() {

if (config->stackFirst) {
placeStack();
if (config->globalBase) {
if (config->globalBase < memoryPtr) {
error("--global-base cannot be less than stack size when --stack-first is used");
return;
}
memoryPtr = config->globalBase;
}
} else {
if (!config->globalBase && !config->relocatable && !config->isPic) {
// The default offset for static/global data, for when --global-base is
// not specified on the command line. The precise value of 1024 is
// somewhat arbitrary, and pre-dates wasm-ld (Its the value that
// emscripten used prior to wasm-ld).
config->globalBase = 1024;
}
memoryPtr = config->globalBase;
log("mem: global base = " + Twine(config->globalBase));
}

log("mem: global base = " + Twine(memoryPtr));
if (WasmSym::globalBase)
WasmSym::globalBase->setVA(memoryPtr);

Expand Down Expand Up @@ -1523,9 +1537,6 @@ void Writer::createSyntheticSectionsPostLayout() {
}

void Writer::run() {
if (config->relocatable || config->isPic)
config->globalBase = 0;

// For PIC code the table base is assigned dynamically by the loader.
// For non-PIC, we start at 1 so that accessing table index 0 always traps.
if (!config->isPic) {
Expand Down

0 comments on commit 6912ed7

Please sign in to comment.