[WebAssembly] Add support for shared tags (#188367)
Mostly following the structure of other Shared* constructs Fixes: #188120
This commit is contained in:
parent
942e1082ac
commit
e3e4b8481d
@ -1,4 +1,4 @@
|
||||
.globl _bar,_dynamic
|
||||
.globl _bar,_dynamic,_foo_tag
|
||||
|
||||
.section .data,"",@
|
||||
_bar:
|
||||
@ -6,3 +6,6 @@ _bar:
|
||||
|
||||
_dynamic:
|
||||
.size _dynamic,4
|
||||
|
||||
.tagtype _foo_tag i32
|
||||
_foo_tag:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -o %t.o %s
|
||||
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -mattr=+exception-handling -o %t.o %s
|
||||
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten %p/Inputs/ret32.s -o %t.ret32.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten %p/Inputs/libsearch-dyn.s -o %t.dyn.o
|
||||
# RUN: wasm-ld --experimental-pic -shared %t.ret32.o %t.dyn.o -o %t.lib.so
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
# Same again for wasm64
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-emscripten -o %t.o %s
|
||||
# RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-emscripten -mattr=+exception-handling -o %t.o %s
|
||||
# RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-emscripten %p/Inputs/ret32.s -o %t.ret32.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-emscripten %p/Inputs/libsearch-dyn.s -o %t.dyn.o
|
||||
# RUN: wasm-ld --experimental-pic -mwasm64 -shared %t.ret32.o %t.dyn.o -o %t.lib.so
|
||||
@ -18,8 +18,9 @@
|
||||
|
||||
# ERROR: error: {{.*}}: undefined symbol: ret32
|
||||
# ERROR: error: {{.*}}: undefined symbol: _bar
|
||||
# ERROR: error: {{.*}}: undefined symbol: _foo_tag
|
||||
.functype ret32 (f32) -> (i32)
|
||||
|
||||
.tagtype _foo_tag i32
|
||||
.globl _start
|
||||
_start:
|
||||
.functype _start () -> ()
|
||||
@ -28,6 +29,8 @@ _start:
|
||||
drop
|
||||
i32.const _bar@GOT
|
||||
drop
|
||||
i32.const 0
|
||||
throw _foo_tag
|
||||
end_function
|
||||
|
||||
# CHECK: Sections:
|
||||
@ -39,3 +42,7 @@ _start:
|
||||
# CHECK-NEXT: TableAlignment: 0
|
||||
# CHECK-NEXT: Needed:
|
||||
# CHECK-NEXT: - {{.*}}.lib.so
|
||||
#
|
||||
# CHECK: Field: _foo_tag
|
||||
# CHECK-NEXT: Kind: TAG
|
||||
# CHECK-NEXT: SigIndex: 1
|
||||
|
||||
@ -453,6 +453,9 @@ void SharedFile::parse() {
|
||||
case WASM_SYMBOL_TYPE_DATA:
|
||||
s = symtab->addSharedData(name, flags, this);
|
||||
break;
|
||||
case WASM_SYMBOL_TYPE_TAG:
|
||||
s = symtab->addSharedTag(name, flags, this, wasmSym.Signature);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -352,6 +352,44 @@ static void reportFunctionSignatureMismatch(StringRef symName,
|
||||
isError);
|
||||
}
|
||||
|
||||
Symbol *SymbolTable::addSharedTag(StringRef name, uint32_t flags,
|
||||
InputFile *file, const WasmSignature *sig) {
|
||||
LLVM_DEBUG(dbgs() << "addSharedTag: " << name << " [" << toString(*sig)
|
||||
<< "]\n");
|
||||
Symbol *s;
|
||||
bool wasInserted;
|
||||
std::tie(s, wasInserted) = insert(name, file);
|
||||
|
||||
auto replaceSym = [&](Symbol *sym) {
|
||||
replaceSymbol<SharedTagSymbol>(sym, name, flags, file, sig);
|
||||
};
|
||||
|
||||
// same as addSharedFunction, but this is in its own function
|
||||
if (wasInserted || s->isLazy()) {
|
||||
replaceSym(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
auto *existingTag = dyn_cast<TagSymbol>(s);
|
||||
if (!existingTag) {
|
||||
reportTypeError(s, file, WASM_SYMBOL_TYPE_TAG);
|
||||
return s;
|
||||
}
|
||||
|
||||
if (s->isDefined()) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// undefined existing sym
|
||||
const WasmSignature *oldSig = existingTag->signature;
|
||||
if (oldSig && sig && *oldSig != *sig)
|
||||
error("Tag signature mismatch: " + name + "\n>>> defined as " +
|
||||
toString(*oldSig) + " in " + toString(existingTag->getFile()) +
|
||||
"\n>>> defined as " + toString(*sig) + " in " + toString(file));
|
||||
replaceSym(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
Symbol *SymbolTable::addSharedFunction(StringRef name, uint32_t flags,
|
||||
InputFile *file,
|
||||
const WasmSignature *sig) {
|
||||
|
||||
@ -53,6 +53,8 @@ public:
|
||||
Symbol *addSharedFunction(StringRef name, uint32_t flags, InputFile *file,
|
||||
const WasmSignature *sig);
|
||||
Symbol *addSharedData(StringRef name, uint32_t flags, InputFile *file);
|
||||
Symbol *addSharedTag(StringRef name, uint32_t flags, InputFile *file,
|
||||
const WasmSignature *sig);
|
||||
Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file,
|
||||
InputFunction *function);
|
||||
Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file,
|
||||
|
||||
@ -72,6 +72,8 @@ std::string toString(wasm::Symbol::Kind kind) {
|
||||
return "SharedFunctionKind";
|
||||
case wasm::Symbol::SharedDataKind:
|
||||
return "SharedDataKind";
|
||||
case wasm::Symbol::SharedTagKind:
|
||||
return "SharedTagSymbol";
|
||||
}
|
||||
llvm_unreachable("invalid symbol kind");
|
||||
}
|
||||
|
||||
@ -62,6 +62,7 @@ public:
|
||||
LazyKind,
|
||||
SharedFunctionKind,
|
||||
SharedDataKind,
|
||||
SharedTagKind,
|
||||
};
|
||||
|
||||
Kind kind() const { return symbolKind; }
|
||||
@ -77,7 +78,8 @@ public:
|
||||
|
||||
bool isLazy() const { return symbolKind == LazyKind; }
|
||||
bool isShared() const {
|
||||
return symbolKind == SharedFunctionKind || symbolKind == SharedDataKind;
|
||||
return symbolKind == SharedFunctionKind || symbolKind == SharedDataKind ||
|
||||
symbolKind == SharedTagKind;
|
||||
}
|
||||
|
||||
bool isLocal() const;
|
||||
@ -461,7 +463,8 @@ public:
|
||||
class TagSymbol : public Symbol {
|
||||
public:
|
||||
static bool classof(const Symbol *s) {
|
||||
return s->kind() == DefinedTagKind || s->kind() == UndefinedTagKind;
|
||||
return s->kind() == DefinedTagKind || s->kind() == UndefinedTagKind ||
|
||||
s->kind() == SharedTagKind;
|
||||
}
|
||||
|
||||
// Get/set the tag index
|
||||
@ -501,6 +504,15 @@ public:
|
||||
static bool classof(const Symbol *s) { return s->kind() == UndefinedTagKind; }
|
||||
};
|
||||
|
||||
class SharedTagSymbol : public TagSymbol {
|
||||
public:
|
||||
SharedTagSymbol(StringRef name, uint32_t flags, InputFile *f,
|
||||
const WasmSignature *sig)
|
||||
: TagSymbol(name, SharedTagKind, flags, f, sig) {}
|
||||
|
||||
static bool classof(const Symbol *s) { return s->kind() == SharedTagKind; }
|
||||
};
|
||||
|
||||
class SharedFunctionSymbol : public FunctionSymbol {
|
||||
public:
|
||||
SharedFunctionSymbol(StringRef name, uint32_t flags, InputFile *file,
|
||||
@ -553,6 +565,7 @@ union SymbolUnion {
|
||||
alignas(UndefinedTable) char j[sizeof(UndefinedTable)];
|
||||
alignas(SectionSymbol) char k[sizeof(SectionSymbol)];
|
||||
alignas(SharedFunctionSymbol) char l[sizeof(SharedFunctionSymbol)];
|
||||
alignas(SharedTagSymbol) char m[sizeof(SharedTagSymbol)];
|
||||
};
|
||||
|
||||
// It is important to keep the size of SymbolUnion small for performance and
|
||||
|
||||
@ -1547,6 +1547,10 @@ Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
|
||||
object_error::parse_failed);
|
||||
Info.Kind = wasm::WASM_SYMBOL_TYPE_TAG;
|
||||
Info.ElementIndex = Ex.Index;
|
||||
if (isDefinedTagIndex(Ex.Index)) {
|
||||
unsigned TagIndex = Ex.Index - NumImportedTags;
|
||||
Signature = &Signatures[Tags[TagIndex].SigIndex];
|
||||
}
|
||||
break;
|
||||
case wasm::WASM_EXTERNAL_MEMORY:
|
||||
break;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user