diff --git a/lld/test/wasm/global-base.test b/lld/test/wasm/global-base.test --- a/lld/test/wasm/global-base.test +++ b/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 diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -428,7 +428,7 @@ 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); @@ -551,6 +551,8 @@ 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 @@ -578,6 +580,10 @@ 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. diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -226,9 +226,9 @@ // 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. @@ -257,11 +257,21 @@ 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) { + 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); @@ -1513,9 +1523,6 @@ } 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) {