diff --git a/lld/test/wasm/mutable-global-exports.s b/lld/test/wasm/mutable-global-exports.s --- a/lld/test/wasm/mutable-global-exports.s +++ b/lld/test/wasm/mutable-global-exports.s @@ -3,18 +3,17 @@ # Should fail without mutable globals feature enabled. # RUN: not wasm-ld --export-all %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-ERR %s # RUN: not wasm-ld --export=foo_global %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-ERR %s -# -# RUN: wasm-ld --features=mutable-globals --export=foo_global %t.o -o %t.wasm + +# RUN: wasm-ld --extra-features=mutable-globals --export=foo_global %t.o -o %t.wasm # RUN: obj2yaml %t.wasm | FileCheck %s # Explcitly check that __stack_pointer can be exported -# RUN: wasm-ld --features=mutable-globals --export=__stack_pointer %t.o -o %t.wasm +# RUN: wasm-ld --extra-features=mutable-globals --export=__stack_pointer %t.o -o %t.wasm # RUN: obj2yaml %t.wasm | FileCheck -check-prefix=CHECK-SP %s -# RUN: wasm-ld --features=mutable-globals --export-all %t.o -o %t.wasm +# RUN: wasm-ld --extra-features=mutable-globals --export-all %t.o -o %t.wasm # RUN: obj2yaml %t.wasm | FileCheck -check-prefix=CHECK-ALL %s - .globl _start .globl foo_global @@ -25,6 +24,14 @@ .functype _start () -> () end_function +# Add a target feature and ensure that it is preserved when --extra-features is +# used above. +.section .custom_section.target_features,"",@ + .int8 1 + .int8 43 + .int8 7 + .ascii "atomics" + # CHECK-ERR: mutable global exported but 'mutable-globals' feature not present in inputs: `foo_global`. Use --no-check-features to suppress # CHECK: - Type: EXPORT @@ -86,3 +93,12 @@ # CHECK-ALL-NEXT: Kind: GLOBAL # CHECK-ALL-NEXT: Index: 7 # CHECK-ALL-NEXT: - Type: CODE + +# CHECK-ALL: Name: target_features +# CHECK-ALL-NEXT: Features: +# CHECK-ALL-NEXT: - Prefix: USED +# CHECK-ALL-NEXT: Name: atomics +# CHECK-ALL-NEXT: - Prefix: USED +# CHECK-ALL-NEXT: Name: mutable-globals +# CHECK-ALL-NEXT: ... + diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -77,6 +77,7 @@ llvm::SmallVector searchPaths; llvm::CachePruningPolicy thinLTOCachePolicy; llvm::Optional> features; + llvm::Optional> extraFeatures; // The following config options do not directly correspond to any // particular command line options. diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -469,6 +469,13 @@ config->features->push_back(std::string(s)); } + if (auto *arg = args.getLastArg(OPT_extra_features)) { + config->extraFeatures = + llvm::Optional>(std::vector()); + for (StringRef s : arg->getValues()) + config->extraFeatures->push_back(std::string(s)); + } + // Legacy --allow-undefined flag which is equivalent to // --unresolve-symbols=ignore + --import-undefined if (args.hasArg(OPT_allow_undefined)) { diff --git a/lld/wasm/Options.td b/lld/wasm/Options.td --- a/lld/wasm/Options.td +++ b/lld/wasm/Options.td @@ -220,6 +220,9 @@ def features: CommaJoined<["--", "-"], "features=">, HelpText<"Comma-separated used features, inferred from input objects by default.">; +def extra_features: CommaJoined<["--", "-"], "extra-features=">, + HelpText<"Comma-separated list of features to add to the default set of features inferred from input objects.">; + // Aliases def: JoinedOrSeparate<["-"], "e">, Alias; def: J<"entry=">, Alias; diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -445,6 +445,11 @@ allowed.insert("mutable-globals"); } + if (config->extraFeatures.has_value()) { + auto &extraFeatures = config->extraFeatures.value(); + allowed.insert(extraFeatures.begin(), extraFeatures.end()); + } + // Only infer used features if user did not specify features bool inferFeatures = !config->features.has_value();