swiftwasm / swift

WebAssembly support for the Swift programming language
https://swiftwasm.org
1.32k stars 28 forks source link

Metadata doesn't work on runtime #20

Closed kateinoigakukun closed 4 years ago

kateinoigakukun commented 4 years ago

As far as I investigated, it fails to deference absolute pointer.

Absolute Pointer?

In apple/swift, they use relative pointer which has an offset between its own address and pointee. But linker support is necessary to calculate the offset and wasm-ld doesn't have the subtraction relocation type yet.

To avoid relative pointer, @zhuowei changed to replace the offset with absolute pointer instead and it works well.

But there are some issues in this way.

Issues

What we need to do

There are some ways to solve these issues.

  1. Implement subtraction relocation type in wasm-ld.

If wasm-ld supports the relocation type, we need nothing to do except reverting absolute pointer patch.

I'm contacting llvm people now for this topic. https://github.com/WebAssembly/tool-conventions/issues/132

  1. Support absolute pointer in correct way

I'm implementing AbsolutePointer type and make it more robust to support 64bit environment.

MaxDesiatov commented 4 years ago

@kateinoigakukun do you think this could be the reason for current crashes of hello.wasm examples?

% ./target/release/wasmtime ~/Downloads/macos-hello.wasm/hello.wasm 
Error: failed to process main module `/Users/maxd/Downloads/macos-hello.wasm/hello.wasm`

Caused by:
    0: Instantiation failed during setup
    1: Trap occurred while invoking start function: wasm trap: out of bounds memory access, source location: @3d0f52

% ./target/release/wasmtime ~/Downloads/linux-hello.wasm/hello.wasm 
Error: failed to process main module `/Users/maxd/Downloads/linux-hello.wasm/hello.wasm`

Caused by:
    0: Instantiation failed during setup
    1: Trap occurred while invoking start function: wasm trap: out of bounds memory access, source location: @3d035f
kateinoigakukun commented 4 years ago

Yes! Debugging is very hard 😅

syrusakbary commented 4 years ago

Have you tried it with wasmer? We can help a bit to debug what's going on :)

kateinoigakukun commented 4 years ago

@syrusakbary Thanks, I tried wasmer but I couldn't get any debug information from that.

$ wasmer run linux-hello.wasm/hello.wasm
Error: wasm trap occured: memory out-of-bounds access

Is there any way to debug like lldb and see the stack on wasmer?

kateinoigakukun commented 4 years ago

A quick update on my progress.

I'm working on supporting 64bit absolute pointer for metadata on x86_64 first because debugging on wasm is very hard. Here is my hacky branch to replace relative pointer with absolute one. https://github.com/apple/swift/compare/master...kateinoigakukun:katei/replace/absolute-pointer

I found there are many logics based on 4byte relative pointer and the metadata structures are broken for 8 byte alignment.

For example, { i32, i32 } in relative-pointer era can be { i32, i64 }. This structure are packed in 12 byte in LLVM IR but when the runtime library read them as C++ structure, they are aligned as { i32, /* 4 byte padding */, i64 } and the size get to be 16 byte.

karwa commented 4 years ago

FWIW, I'm seeing a different error with a bit more information than Max gets. But it's definitely metadata-related:

karl@Karls-MBP sdkroot % wasmtime -d hello.wasm 
Assertion failed: protocolsSize % sizeof(ProtocolRecord) == 0 && "protocols section not a multiple of ProtocolRecord" (/Volumes/Code/swift/swift/stdlib/public/runtime/MetadataLookup.cpp: addImageProtocolsBlockCallbackUnsafe: 893)
Error: failed to process main module `/Volumes/Code/swift/swift/utils/webassembly/sdkroot/hello.wasm`

Caused by:
    0: Instantiation failed during setup
    1: Trap occurred while invoking start function: wasm trap: unreachable, source location: @41b2b7
kateinoigakukun commented 4 years ago

Now, my two PR https://github.com/swiftwasm/swift/pull/21 https://github.com/swiftwasm/swift/pull/6 are merged and print("Hello") works now!

Our next goal is to support wasm64 💪

MaxDesiatov commented 4 years ago

@kateinoigakukun interesting, do you know of any browsers that provide wasm64 support? AFAIK there are no stable versions with wasm64 from any major vendor, even LLVM itself currently doesn't support wasm64.

MaxDesiatov commented 4 years ago

Now, my two PR #21 #6 are merged and print("Hello") works now!

Great work by the way, this is fantastic 👏 Looking forward to getting the SDK compiled and trying it out. Now we can also slowly start enabling the test suite and looking into Foundation, Dispatch and SwiftPM support 🙌

kateinoigakukun commented 4 years ago

Oh, I didn't know that LLVM doesn't support wasm64 😢 Thanks!

MaxDesiatov commented 4 years ago

I'm not sure that wasm64 part is even specced, just looking at how it's still referred to as a "future feature":

The WebAssembly MVP will support the wasm32 mode of WebAssembly, with linear memory sizes up to 4 GiB using 32-bit linear memory indices. To support larger sizes, the wasm64 mode of WebAssembly will be added in the future, supporting much greater linear memory sizes using 64-bit linear memory indices. wasm32 and wasm64 are both just modes of WebAssembly, to be selected by a flag in a module header, and don't imply any semantics differences outside of how linear memory is handled. Platforms will also have APIs for querying which of wasm32 and wasm64 are supported.

I'm not aware of such APIs for querying this existing in any available runtime.