[lld][WebAssembly] Error on import/export of mutable global without mutable-globals feature

Also add the +mutable-globals features in clang when
building with `-fPIC` since the linker will generate mutable
globals imports and exports in that case.

Differential Revision: https://reviews.llvm.org/D87537
This commit is contained in:
Sam Clegg 2020-07-23 15:06:21 -07:00
parent d6fadc49e3
commit 04febd30a8
9 changed files with 77 additions and 9 deletions

View File

@ -243,6 +243,27 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
CC1Args.push_back("+sign-ext");
}
if (!DriverArgs.hasFlag(options::OPT_mmutable_globals,
options::OPT_mno_mutable_globals, false)) {
// -fPIC implies +mutable-globals because the PIC ABI used by the linker
// depends on importing and exporting mutable globals.
llvm::Reloc::Model RelocationModel;
unsigned PICLevel;
bool IsPIE;
std::tie(RelocationModel, PICLevel, IsPIE) =
ParsePICArgs(*this, DriverArgs);
if (RelocationModel == llvm::Reloc::PIC_) {
if (DriverArgs.hasFlag(options::OPT_mno_mutable_globals,
options::OPT_mmutable_globals, false)) {
getDriver().Diag(diag::err_drv_argument_not_allowed_with)
<< "-fPIC"
<< "-mno-mutable-globals";
}
CC1Args.push_back("-target-feature");
CC1Args.push_back("+mutable-globals");
}
}
if (DriverArgs.getLastArg(options::OPT_fwasm_exceptions)) {
// '-fwasm-exceptions' is not compatible with '-mno-exception-handling'
if (DriverArgs.hasFlag(options::OPT_mno_exception_handing,

View File

@ -119,3 +119,14 @@
// RUN: | FileCheck -check-prefix=CHECK-REACTOR %s
// CHECK-REACTOR: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// CHECK-REACTOR: wasm-ld{{.*}}" "crt1-reactor.o" "--entry" "_initialize" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// -fPIC implies +mutable-globals
// RUN: %clang %s -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=%s/no-sysroot-there -fPIC 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-PIC %s
// CHECK-PIC: clang{{.*}}" "-cc1" {{.*}} "-target-feature" "+mutable-globals"
// '-mno-mutable-globals' is not allowed with '-fPIC'
// RUN: %clang %s -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=%s/no-sysroot-there -fPIC -mno-mutable-globals %s 2>&1 \
// RUN: | FileCheck -check-prefix=PIC_NO_MUTABLE_GLOBALS %s
// PIC_NO_MUTABLE_GLOBALS: error: invalid argument '-fPIC' not allowed with '-mno-mutable-globals'

View File

@ -7,5 +7,5 @@ use_undef_global:
global.get used_undef_global
end_function
.globaltype unused_undef_global, i64
.globaltype used_undef_global, i64
.globaltype unused_undef_global, i64, immutable
.globaltype used_undef_global, i64, immutable

View File

@ -1,6 +1,6 @@
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -o %t.o < %s
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/ret32.s -o %t.ret32.o
# RUN: wasm-ld -pie --export-all --no-gc-sections --no-entry --emit-relocs -o %t.wasm %t.o %t.ret32.o
# RUN: wasm-ld -pie --export-all --no-check-features --no-gc-sections --no-entry --emit-relocs -o %t.wasm %t.o %t.ret32.o
# RUN: obj2yaml %t.wasm | FileCheck %s
load_hidden_data:

View File

@ -31,7 +31,7 @@ _start:
# CHECK-NEXT: Field: used_undef_global
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I64
# CHECK-NEXT: GlobalMutable: true
# CHECK-NEXT: GlobalMutable: false
# CHECK-NEXT: - Type:
# CHECK: - Type: CUSTOM
# CHECK-NEXT: Name: name
@ -62,12 +62,12 @@ _start:
# NO-GC-NEXT: Field: unused_undef_global
# NO-GC-NEXT: Kind: GLOBAL
# NO-GC-NEXT: GlobalType: I64
# NO-GC-NEXT: GlobalMutable: true
# NO-GC-NEXT: GlobalMutable: false
# NO-GC-NEXT: - Module: env
# NO-GC-NEXT: Field: used_undef_global
# NO-GC-NEXT: Kind: GLOBAL
# NO-GC-NEXT: GlobalType: I64
# NO-GC-NEXT: GlobalMutable: true
# NO-GC-NEXT: GlobalMutable: false
# NO-GC-NEXT: - Type:
# NO-GC: - Type: CUSTOM
# NO-GC-NEXT: Name: name

View File

@ -0,0 +1,13 @@
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
# RUN: not wasm-ld %t.o -o %t.wasm 2>&1 | FileCheck %s
.globl _start
_start:
.functype _start () -> ()
i32.const 1
global.set foo
end_function
.globaltype foo, i32
# CHECK: error: mutable global imported but 'mutable-globals' feature not present in inputs: `foo`. Use --no-check-features to suppress.

View File

@ -1,4 +1,4 @@
; RUN: llc -relocation-model=pic -filetype=obj %s -o %t.o
; RUN: llc -relocation-model=pic -mattr=+mutable-globals -filetype=obj %s -o %t.o
; RUN: wasm-ld --no-gc-sections --allow-undefined -pie -o %t.wasm %t.o
; RUN: obj2yaml %t.wasm | FileCheck %s

View File

@ -1,4 +1,4 @@
; RUN: llc -relocation-model=pic -filetype=obj %s -o %t.o
; RUN: llc -relocation-model=pic -mattr=+mutable-globals -filetype=obj %s -o %t.o
; RUN: wasm-ld -shared -o %t.wasm %t.o
; RUN: obj2yaml %t.wasm | FileCheck %s

View File

@ -461,6 +461,29 @@ void Writer::populateTargetFeatures() {
if (!config->checkFeatures)
return;
if (!config->relocatable && used.count("mutable-globals") == 0) {
for (Symbol *sym : symtab->getSymbols()) {
if (auto *global = dyn_cast<GlobalSymbol>(sym)) {
if (global->getGlobalType()->Mutable) {
if (!sym->isLive())
continue;
if (!sym->isUsedInRegularObj)
continue;
if (sym->isUndefined() && sym->isWeak() && !config->relocatable)
continue;
if (sym->isUndefined())
error(Twine("mutable global imported but 'mutable-globals' feature "
"not present in inputs: `") +
toString(*sym) + "`. Use --no-check-features to suppress.");
else if (sym->isExported())
error(Twine("mutable global exported but 'mutable-globals' feature "
"not present in inputs: `") +
toString(*sym) + "`. Use --no-check-features to suppress.");
}
}
}
}
if (config->sharedMemory) {
if (disallowed.count("shared-mem"))
error("--shared-memory is disallowed by " + disallowed["shared-mem"] +