mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-28 08:02:08 +00:00
[WebAssembly] Add --export-all flag
This causes all symbols to be exported in the final wasm binary even if they were not compiled with default visibility. This feature is useful for the emscripten toolchain that has a corresponding EXPORT_ALL feature which allows the JS code to interact with all C function. Differential Revision: https://reviews.llvm.org/D47806 llvm-svn: 334157
This commit is contained in:
parent
7a88f19099
commit
177b458c8a
45
lld/test/wasm/export-all.ll
Normal file
45
lld/test/wasm/export-all.ll
Normal file
@ -0,0 +1,45 @@
|
||||
; RUN: llc -O0 -filetype=obj %s -o %t.o
|
||||
|
||||
; RUN: wasm-ld -o %t.wasm %t.o
|
||||
; RUN: obj2yaml %t.wasm | FileCheck %s
|
||||
|
||||
; RUN: wasm-ld --export-all -o %t.wasm %t.o
|
||||
; RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=EXPORT
|
||||
|
||||
; RUN: wasm-ld --export-all --no-gc-sections -o %t.wasm %t.o
|
||||
; RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=NOGC
|
||||
|
||||
; Verify the --export-all flag exports hidden symbols
|
||||
|
||||
target triple = "wasm32-unknown-unknown"
|
||||
|
||||
define hidden void @bar() local_unnamed_addr {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
define hidden void @foo() local_unnamed_addr {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
define hidden void @_start() local_unnamed_addr {
|
||||
entry:
|
||||
call void @foo()
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: - Type: EXPORT
|
||||
; CHECK: - Name: _start
|
||||
; CHECK-NOT: - Name: bar
|
||||
; CHECK-NOT: - Name: foo
|
||||
|
||||
; EXPORT: - Type: EXPORT
|
||||
; EXPORT: - Name: _start
|
||||
; EXPORT-NOT: - Name: bar
|
||||
; EXPORT: - Name: foo
|
||||
|
||||
; NOGC: - Type: EXPORT
|
||||
; NOGC: - Name: _start
|
||||
; NOGC: - Name: bar
|
||||
; NOGC: - Name: foo
|
@ -23,6 +23,7 @@ struct Configuration {
|
||||
bool CompressRelocTargets;
|
||||
bool Demangle;
|
||||
bool DisableVerify;
|
||||
bool ExportAll;
|
||||
bool ExportTable;
|
||||
bool GcSections;
|
||||
bool ImportMemory;
|
||||
|
@ -319,6 +319,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);
|
||||
Config->DisableVerify = Args.hasArg(OPT_disable_verify);
|
||||
Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start");
|
||||
Config->ExportAll = Args.hasArg(OPT_export_all);
|
||||
Config->ExportTable = Args.hasArg(OPT_export_table);
|
||||
errorHandler().FatalWarnings =
|
||||
Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
|
||||
@ -389,10 +390,6 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
|
||||
Symbol *EntrySym = nullptr;
|
||||
if (!Config->Relocatable) {
|
||||
// Can't export the SP right now because it's mutable, and mutable
|
||||
// globals aren't yet supported in the official binary format.
|
||||
// TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN if/when the
|
||||
// "mutable global" proposal is accepted.
|
||||
llvm::wasm::WasmGlobal Global;
|
||||
Global.Type = {WASM_TYPE_I32, true};
|
||||
Global.InitExpr.Value.Int32 = 0;
|
||||
@ -407,6 +404,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
WasmSym::CallCtors = Symtab->addSyntheticFunction(
|
||||
"__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN,
|
||||
make<SyntheticFunction>(NullSignature, "__wasm_call_ctors"));
|
||||
// TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN when the mutable global
|
||||
// spec proposal is implemented in all major browsers.
|
||||
// See: https://github.com/WebAssembly/mutable-global
|
||||
WasmSym::StackPointer = Symtab->addSyntheticGlobal(
|
||||
"__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer);
|
||||
WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base", 0);
|
||||
|
@ -105,6 +105,9 @@ def allow_undefined_file_s: Separate<["-"], "allow-undefined-file">,
|
||||
defm export: Eq<"export">,
|
||||
HelpText<"Force a symbol to be exported">;
|
||||
|
||||
def export_all: F<"export-all">,
|
||||
HelpText<"Export all symbols (normally combined with --no-gc-sections)">;
|
||||
|
||||
def export_table: F<"export-table">,
|
||||
HelpText<"Export function table to the environment">;
|
||||
|
||||
|
@ -742,7 +742,9 @@ void Writer::calculateExports() {
|
||||
for (Symbol *Sym : Symtab->getSymbols()) {
|
||||
if (!Sym->isDefined())
|
||||
continue;
|
||||
if (Sym->isHidden() || Sym->isLocal())
|
||||
if (Sym->isHidden() && !Config->ExportAll)
|
||||
continue;
|
||||
if (Sym->isLocal())
|
||||
continue;
|
||||
if (!Sym->isLive())
|
||||
continue;
|
||||
@ -752,6 +754,14 @@ void Writer::calculateExports() {
|
||||
if (auto *F = dyn_cast<DefinedFunction>(Sym)) {
|
||||
Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()};
|
||||
} else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
|
||||
// TODO(sbc): Remove this check once to mutable global proposal is
|
||||
// implement in all major browsers.
|
||||
// See: https://github.com/WebAssembly/mutable-global
|
||||
if (G->getGlobalType()->Mutable) {
|
||||
// Only the __stack_pointer should ever be create as mutable.
|
||||
assert(G == WasmSym::StackPointer);
|
||||
continue;
|
||||
}
|
||||
Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
|
||||
} else {
|
||||
auto *D = cast<DefinedData>(Sym);
|
||||
|
Loading…
Reference in New Issue
Block a user