diff options
author | Alon Zakai <azakai@google.com> | 2020-10-23 16:01:40 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-23 16:01:40 -0700 |
commit | 2dc156d1d3af7f3eb40bdce7c20aa84c98d50c15 (patch) | |
tree | 3a25edf7a1acc183ad57918ecd0c7a9ebe36199c /src/tools/wasm2c-wrapper.h | |
parent | 0daa41c4af29f7a2695e8356e610cf88dea10d7f (diff) | |
download | binaryen-2dc156d1d3af7f3eb40bdce7c20aa84c98d50c15.tar.gz binaryen-2dc156d1d3af7f3eb40bdce7c20aa84c98d50c15.tar.bz2 binaryen-2dc156d1d3af7f3eb40bdce7c20aa84c98d50c15.zip |
Fuzzer: Fix wasm2c name mangling (#3228)
This is necessary for cases where the input has an export name that
needs mangling, like a name with - (common in the spec test suite).
Diffstat (limited to 'src/tools/wasm2c-wrapper.h')
-rw-r--r-- | src/tools/wasm2c-wrapper.h | 83 |
1 files changed, 56 insertions, 27 deletions
diff --git a/src/tools/wasm2c-wrapper.h b/src/tools/wasm2c-wrapper.h index 6ea473d7a..8fa317a18 100644 --- a/src/tools/wasm2c-wrapper.h +++ b/src/tools/wasm2c-wrapper.h @@ -25,6 +25,58 @@ namespace wasm { +// Mangle a name in (hopefully) exactly the same way wasm2c does. +static std::string wasm2cMangle(Name name, Signature sig) { + const char escapePrefix = 'Z'; + std::string mangled = "Z_"; + const char* original = name.str; + unsigned char c; + while ((c = *original++)) { + if ((isalnum(c) && c != escapePrefix) || c == '_') { + // This character is ok to emit as it is. + mangled += c; + } else { + // This must be escaped, as prefix + hex character code. + mangled += escapePrefix; + std::stringstream ss; + ss << std::hex << std::uppercase << unsigned(c); + mangled += ss.str(); + } + } + + // Emit the result and params. + mangled += "Z_"; + + auto wasm2cSignature = [](Type type) { + TODO_SINGLE_COMPOUND(type); + switch (type.getBasic()) { + case Type::none: + return 'v'; + case Type::i32: + return 'i'; + case Type::i64: + return 'j'; + case Type::f32: + return 'f'; + case Type::f64: + return 'd'; + default: + Fatal() << "unhandled wasm2c wrapper signature type: " << type; + } + }; + + mangled += wasm2cSignature(sig.results); + if (sig.params.isTuple()) { + for (const auto& param : sig.params) { + mangled += wasm2cSignature(param); + } + } else { + mangled += wasm2cSignature(sig.params); + } + + return mangled; +} + static std::string generateWasm2CWrapper(Module& wasm) { // First, emit implementations of the wasm's imports so that the wasm2c code // can call them. The names use wasm2c's name mangling. @@ -142,35 +194,12 @@ int main(int argc, char** argv) { } } - // Emit the callee's name with wasm2c name mangling. - ret += std::string("(*Z_") + exp->name.str + "Z_"; + // Call the export. + ret += "(*"; - auto wasm2cSignature = [](Type type) { - TODO_SINGLE_COMPOUND(type); - switch (type.getBasic()) { - case Type::none: - return 'v'; - case Type::i32: - return 'i'; - case Type::i64: - return 'j'; - case Type::f32: - return 'f'; - case Type::f64: - return 'd'; - default: - Fatal() << "unhandled wasm2c wrapper signature type: " << type; - } - }; + // Emit the callee's name with wasm2c name mangling. + ret += wasm2cMangle(exp->name, func->sig); - ret += wasm2cSignature(result); - if (func->sig.params.isTuple()) { - for (const auto& param : func->sig.params) { - ret += wasm2cSignature(param); - } - } else { - ret += wasm2cSignature(func->sig.params); - } ret += ")("; // Emit the parameters (all 0s, like the other wrappers). |