diff options
Diffstat (limited to 'test/wasm')
38 files changed, 2762 insertions, 0 deletions
diff --git a/test/wasm/Inputs/archive1.ll b/test/wasm/Inputs/archive1.ll new file mode 100644 index 000000000000..c942fa2c1b55 --- /dev/null +++ b/test/wasm/Inputs/archive1.ll @@ -0,0 +1,7 @@ +declare i32 @bar() local_unnamed_addr #1 + +define i32 @foo() local_unnamed_addr #0 { +entry: + %call = tail call i32 @bar() #2 + ret i32 %call +} diff --git a/test/wasm/Inputs/archive2.ll b/test/wasm/Inputs/archive2.ll new file mode 100644 index 000000000000..35534dc9e076 --- /dev/null +++ b/test/wasm/Inputs/archive2.ll @@ -0,0 +1,7 @@ +declare i32 @foo() local_unnamed_addr #1 + +define i32 @bar() local_unnamed_addr #0 { +entry: + %call = tail call i32 @foo() #2 + ret i32 %call +} diff --git a/test/wasm/Inputs/call-indirect.ll b/test/wasm/Inputs/call-indirect.ll new file mode 100644 index 000000000000..388ea60c3a07 --- /dev/null +++ b/test/wasm/Inputs/call-indirect.ll @@ -0,0 +1,17 @@ +@indirect_bar = internal local_unnamed_addr global i32 ()* @bar, align 4 +@indirect_foo = internal local_unnamed_addr global i32 ()* @foo, align 4 + +declare i32 @foo() local_unnamed_addr + +define i32 @bar() { +entry: + ret i32 1 +} + +define void @call_bar_indirect() local_unnamed_addr #1 { +entry: + %0 = load i32 ()*, i32 ()** @indirect_bar, align 4 + %1 = load i32 ()*, i32 ()** @indirect_foo, align 4 + %call = tail call i32 %0() #2 + ret void +} diff --git a/test/wasm/Inputs/hello.ll b/test/wasm/Inputs/hello.ll new file mode 100644 index 000000000000..93df0f559809 --- /dev/null +++ b/test/wasm/Inputs/hello.ll @@ -0,0 +1,15 @@ +; Wasm module generated from the following C code: +; void puts(const char*); +; void hello() { puts("hello\n"); } + +@hello_str = unnamed_addr constant [7 x i8] c"hello\0A\00", align 1 + +; Function Attrs: nounwind +define hidden void @hello() local_unnamed_addr #0 { +entry: + tail call void @puts(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @hello_str, i32 0, i32 0)) + ret void +} + +; Function Attrs: nounwind +declare void @puts(i8* nocapture readonly) local_unnamed_addr #1 diff --git a/test/wasm/Inputs/hidden.ll b/test/wasm/Inputs/hidden.ll new file mode 100644 index 000000000000..25890e9f03f2 --- /dev/null +++ b/test/wasm/Inputs/hidden.ll @@ -0,0 +1,11 @@ +; Function Attrs: norecurse nounwind readnone +define hidden i32 @archiveHidden() #0 { +entry: + ret i32 0 +} + +; Function Attrs: norecurse nounwind readnone +define i32 @archiveDefault() #1 { +entry: + ret i32 0 +} diff --git a/test/wasm/Inputs/many-funcs.ll b/test/wasm/Inputs/many-funcs.ll new file mode 100644 index 000000000000..b8daab23638d --- /dev/null +++ b/test/wasm/Inputs/many-funcs.ll @@ -0,0 +1,776 @@ +@g0 = global i32 1, align 4 +@foo = global i32 1, align 4 + +define i32 @f1() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f2() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f3() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f4() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f5() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f6() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f7() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f8() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f9() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f10() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f11() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f12() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f13() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f14() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f15() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f16() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f17() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f18() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f19() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f20() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f21() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f22() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f23() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f24() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f25() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f26() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f27() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f28() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f29() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f30() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f31() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f32() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f33() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f34() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f35() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f36() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f37() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f38() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f39() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f40() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f41() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f42() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f43() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f44() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f45() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f46() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f47() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f48() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f49() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f50() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f51() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f52() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f53() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f54() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f55() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f56() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f57() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f58() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f59() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f60() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f61() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f62() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f63() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f64() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f65() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f66() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f67() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f68() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f69() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f70() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f71() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f72() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f73() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f74() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f75() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f76() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f77() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f78() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f79() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f80() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f81() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f82() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f83() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f84() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f85() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f86() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f87() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f88() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f89() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f90() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f91() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f92() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f93() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f94() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f95() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f96() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f97() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f98() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f99() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f100() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f101() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f102() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f103() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f104() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f105() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f106() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f107() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f108() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f109() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f110() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f111() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f112() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f113() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f114() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f115() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f116() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f117() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f118() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f119() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f120() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f121() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f122() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f123() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f124() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f125() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f126() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f127() { +entry: + %0 = load i32, i32* @foo, align 4 + ret i32 %0 +} + +define i32 @f128() { +entry: + %0 = load i32, i32* @g0, align 4 + ret i32 %0 +} + +define i32 @f129() { +entry: + %0 = load i32, i32* @g0, align 4 + ret i32 %0 +} diff --git a/test/wasm/Inputs/ret32.ll b/test/wasm/Inputs/ret32.ll new file mode 100644 index 000000000000..a4565288f08b --- /dev/null +++ b/test/wasm/Inputs/ret32.ll @@ -0,0 +1,6 @@ +; Function Attrs: norecurse nounwind readnone +define i32 @ret32(float %arg) #0 { +entry: + ret i32 0 + ; ptrtoint (i32 (float)* @ret32 to i32) +} diff --git a/test/wasm/Inputs/ret64.ll b/test/wasm/Inputs/ret64.ll new file mode 100644 index 000000000000..6a9de0dace1d --- /dev/null +++ b/test/wasm/Inputs/ret64.ll @@ -0,0 +1,4 @@ +define i64 @ret64(double %arg) local_unnamed_addr #0 { +entry: + ret i64 1 +} diff --git a/test/wasm/Inputs/weak-alias.ll b/test/wasm/Inputs/weak-alias.ll new file mode 100644 index 000000000000..079e68e3ce7a --- /dev/null +++ b/test/wasm/Inputs/weak-alias.ll @@ -0,0 +1,13 @@ +; Function Attrs: norecurse nounwind readnone +define i32 @foo() #0 { +entry: + ret i32 0 +} + +@bar = weak alias i32 (), i32 ()* @foo + +define i32 @call_bar() #0 { +entry: + %call = call i32 @bar() + ret i32 %call +} diff --git a/test/wasm/Inputs/weak-symbol1.ll b/test/wasm/Inputs/weak-symbol1.ll new file mode 100644 index 000000000000..2d561716f825 --- /dev/null +++ b/test/wasm/Inputs/weak-symbol1.ll @@ -0,0 +1,9 @@ +define weak i32 @weakFn() #0 { +entry: + ret i32 1 +} + +define i32 @exportWeak1() { +entry: + ret i32 ptrtoint (i32 ()* @weakFn to i32) +} diff --git a/test/wasm/Inputs/weak-symbol2.ll b/test/wasm/Inputs/weak-symbol2.ll new file mode 100644 index 000000000000..f43ea96673b9 --- /dev/null +++ b/test/wasm/Inputs/weak-symbol2.ll @@ -0,0 +1,9 @@ +define weak i32 @weakFn() #0 { +entry: + ret i32 2 +} + +define i32 @exportWeak2() { +entry: + ret i32 ptrtoint (i32 ()* @weakFn to i32) +} diff --git a/test/wasm/archive.ll b/test/wasm/archive.ll new file mode 100644 index 000000000000..18f35330d1e9 --- /dev/null +++ b/test/wasm/archive.ll @@ -0,0 +1,31 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %S/Inputs/archive1.ll -o %t.a1.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %S/Inputs/archive2.ll -o %t.a2.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %S/Inputs/hello.ll -o %t.a3.o +; RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o %t.a3.o +; RUN: lld -flavor wasm %t.a %t.o -o %t.wasm +; RUN: llvm-nm -a %t.wasm | FileCheck %s + +declare i32 @foo() local_unnamed_addr #1 + +define i32 @_start() local_unnamed_addr #0 { +entry: + %call = tail call i32 @foo() #2 + ret i32 %call +} + +; Verify that multually dependant object files in an archive is handled +; correctly. + +; CHECK: 00000002 T _start +; CHECK-NEXT: 00000002 T _start +; CHECK-NEXT: 00000000 T bar +; CHECK-NEXT: 00000000 T bar +; CHECK-NEXT: 00000001 T foo +; CHECK-NEXT: 00000001 T foo + +; Verify that symbols from unused objects don't appear in the symbol table +; CHECK-NOT: hello + +; Specifying the same archive twice is allowed. +; RUN: lld -flavor wasm %t.a %t.a %t.o -o %t.wasm diff --git a/test/wasm/call-indirect.ll b/test/wasm/call-indirect.ll new file mode 100644 index 000000000000..14845eb50f83 --- /dev/null +++ b/test/wasm/call-indirect.ll @@ -0,0 +1,112 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/call-indirect.ll -o %t2.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm -o %t.wasm %t2.o %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +; bitcode generated from the following C code: +; int foo(void) { return 1; } +; int (*indirect_func)(void) = &foo; +; void _start(void) { indirect_func(); } + +@indirect_func = local_unnamed_addr global i32 ()* @foo, align 4 + +; Function Attrs: norecurse nounwind readnone +define i32 @foo() #0 { +entry: + ret i32 2 +} + +; Function Attrs: nounwind +define i32 @_start() local_unnamed_addr #1 { +entry: + %0 = load i32 ()*, i32 ()** @indirect_func, align 4 + %call = tail call i32 %0() #2 + ret i32 0 +} + +; CHECK: !WASM +; CHECK-NEXT: FileHeader: +; CHECK-NEXT: Version: 0x00000001 +; CHECK-NEXT: Sections: +; CHECK-NEXT: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: ReturnType: NORESULT +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 0 ] +; CHECK-NEXT: - Type: TABLE +; CHECK-NEXT: Tables: +; CHECK-NEXT: - ElemType: ANYFUNC +; CHECK-NEXT: Limits: +; CHECK-NEXT: Flags: [ HAS_MAX ] +; CHECK-NEXT: Initial: 0x00000003 +; CHECK-NEXT: Maximum: 0x00000003 +; CHECK-NEXT: - Type: MEMORY +; CHECK-NEXT: Memories: +; CHECK-NEXT: - Initial: 0x00000002 +; CHECK-NEXT: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: true +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 66576 +; CHECK-NEXT: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 3 +; CHECK-NEXT: - Name: foo +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: bar +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: call_bar_indirect +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Type: ELEM +; CHECK-NEXT: Segments: +; CHECK-NEXT: - Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1 +; CHECK-NEXT: Functions: [ 0, 2 ] +; CHECK-NEXT: - Type: CODE +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41010B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 410028028088808000118080808000001A0B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41020B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 410028028888808000118080808000001A41000B +; CHECK-NEXT: - Type: DATA +; CHECK-NEXT: Segments: +; CHECK-NEXT: - SectionOffset: 7 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1024 +; CHECK-NEXT: Content: '010000000200000002000000' +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 12 +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: bar +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: call_bar_indirect +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Name: foo +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Name: _start diff --git a/test/wasm/conflict.test b/test/wasm/conflict.test new file mode 100644 index 000000000000..a0a2eb4e3b3a --- /dev/null +++ b/test/wasm/conflict.test @@ -0,0 +1,6 @@ +# RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o +# RUN: not lld -flavor wasm -o %t.wasm %t.ret32.o %t.ret32.o 2>&1 | FileCheck %s + +# CHECK: duplicate symbol: ret32 +# CHECK-NEXT: >>> defined in {{.*}}conflict.test.tmp.ret32.o +# CHECK-NEXT: >>> defined in {{.*}}conflict.test.tmp.ret32.o diff --git a/test/wasm/data-layout.ll b/test/wasm/data-layout.ll new file mode 100644 index 000000000000..0b2c61da5547 --- /dev/null +++ b/test/wasm/data-layout.ll @@ -0,0 +1,61 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/hello.ll -o %t.hello.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm --emit-relocs --allow-undefined --no-entry -o %t.wasm %t.o %t.hello.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +@foo = hidden global i32 1, align 4 +@aligned_bar = hidden global i32 3, align 16 + +@hello_str = external global i8* +@external_ref = global i8** @hello_str, align 8 + +; CHECK: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: true +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 66608 +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1024 +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1040 +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1048 +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1052 + +; CHECK: - Type: DATA +; CHECK-NEXT: Relocations: +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 +; CHECK-NEXT: Index: 4 +; CHECK-NEXT: Offset: 0x0000001F +; CHECK-NEXT: Segments: +; CHECK-NEXT: - SectionOffset: 7 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1024 +; CHECK-NEXT: Content: 0100000000000000000000000000000003000000000000001C040000 +; CHECK-NEXT: - SectionOffset: 41 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1052 +; CHECK-NEXT: Content: 68656C6C6F0A00 + +; CHECK: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 35 diff --git a/test/wasm/entry.ll b/test/wasm/entry.ll new file mode 100644 index 000000000000..e51c7055b80e --- /dev/null +++ b/test/wasm/entry.ll @@ -0,0 +1,19 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm -e entry -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s +; RUN: lld -flavor wasm --entry=entry -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +define void @entry() local_unnamed_addr #0 { +entry: + ret void +} + +; CHECK: - Type: EXPORT +; CHECK: Exports: +; CHECK: - Name: memory +; CHECK: Kind: MEMORY +; CHECK: Index: 0 +; CHECK: - Name: entry +; CHECK: Kind: FUNCTION +; CHECK: Index: 0 diff --git a/test/wasm/function-imports-first.ll b/test/wasm/function-imports-first.ll new file mode 100644 index 000000000000..085345ad7ffc --- /dev/null +++ b/test/wasm/function-imports-first.ll @@ -0,0 +1,42 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm -o %t.wasm %t.o %t.ret32.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +; Function Attrs: nounwind +define hidden void @_start() local_unnamed_addr #0 { +entry: + %call = tail call i32 @ret32(float 0.000000e+00) #2 + ret void +} + +declare i32 @ret32(float) local_unnamed_addr #1 + +; CHECK: - Type: TYPE +; CHECK: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: NORESULT +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - F32 +; CHECK: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0, 1 ] +; CHECK: - Type: CODE +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 43000000001081808080001A0B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41000B +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 0 +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: _start +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: ret32 +; CHECK-NEXT: ... diff --git a/test/wasm/function-imports.ll b/test/wasm/function-imports.ll new file mode 100644 index 000000000000..e0988ff95f96 --- /dev/null +++ b/test/wasm/function-imports.ll @@ -0,0 +1,37 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm -o %t.wasm %t.ret32.o %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +; Function Attrs: nounwind +define hidden void @_start() local_unnamed_addr #0 { +entry: + %call = tail call i32 @ret32(float 0.000000e+00) #2 + ret void +} + +declare i32 @ret32(float) local_unnamed_addr #1 + +; CHECK: Sections: +; CHECK: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - F32 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: ReturnType: NORESULT +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0, 1 ] +; CHECK: - Type: CODE +; CHECK-NEXT: Functions: +; CHECK: - Locals: +; CHECK: - Locals: +; CHECK: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: ret32 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: _start +; CHECK-NEXT: ... diff --git a/test/wasm/function-index.test b/test/wasm/function-index.test new file mode 100644 index 000000000000..03bd879b5176 --- /dev/null +++ b/test/wasm/function-index.test @@ -0,0 +1,18 @@ +# RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o +# RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/ret64.ll -o %t.ret64.o +# RUN: lld -flavor wasm -r -o %t.wasm %t.ret32.o %t.ret64.o +# RUN: obj2yaml %t.wasm | FileCheck %s + +CHECK: Sections: +CHECK: - Type: TYPE +CHECK: Signatures: +CHECK: - Index: 0 +CHECK: ReturnType: I32 +CHECK: ParamTypes: +CHECK: - F32 +CHECK: - Index: 1 +CHECK: ReturnType: I64 +CHECK: ParamTypes: +CHECK: - F64 +CHECK: - Type: FUNCTION +CHECK: FunctionTypes: [ 0, 1 ] diff --git a/test/wasm/import-memory.test b/test/wasm/import-memory.test new file mode 100644 index 000000000000..af0ff910449c --- /dev/null +++ b/test/wasm/import-memory.test @@ -0,0 +1,13 @@ +# RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o +# RUN: lld -flavor wasm -entry ret32 --import-memory -o %t.wasm %t.ret32.o +# RUN: obj2yaml %t.wasm | FileCheck %s + +# Verify the --import-memory flag creates a memory import + +# CHECK: - Type: IMPORT +# CHECK-NEXT: Imports: +# CHECK-NEXT: - Module: env +# CHECK-NEXT: Field: memory +# CHECK-NEXT: Kind: MEMORY +# CHECK-NEXT: Memory: +# CHECK-NEXT: Initial: 0x00000002 diff --git a/test/wasm/invalid-stack-size.test b/test/wasm/invalid-stack-size.test new file mode 100644 index 000000000000..6597c548499a --- /dev/null +++ b/test/wasm/invalid-stack-size.test @@ -0,0 +1,9 @@ +; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj %s -o %t.o +; RUN: not lld -flavor wasm -o %t.wasm -z stack-size=1 %t.o 2>&1 | FileCheck %s + +define i32 @_start() local_unnamed_addr #1 { +entry: + ret i32 0 +} + +; CHECK: error: stack size must be 16-byte aligned diff --git a/test/wasm/lit.local.cfg b/test/wasm/lit.local.cfg new file mode 100644 index 000000000000..bc76e57c8e87 --- /dev/null +++ b/test/wasm/lit.local.cfg @@ -0,0 +1,4 @@ +if 'wasm' not in config.available_features: + config.unsupported = True + +config.suffixes = ['.test', '.yaml', '.ll'] diff --git a/test/wasm/load-undefined.ll b/test/wasm/load-undefined.ll new file mode 100644 index 000000000000..f979c9acb517 --- /dev/null +++ b/test/wasm/load-undefined.ll @@ -0,0 +1,38 @@ +; Verify that the -u / --undefined option is able to pull in symbols from +; an archive, and doesn't error when uses to pull in a symbol already loaded. +; +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/ret64.ll -o %t.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/ret32.ll -o %t2.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t3.o +; RUN: llvm-ar rcs %t2.a %t2.o +; RUN: lld -flavor wasm %t3.o %t2.a %t.o -o %t.wasm -u ret32 --undefined ret64 +; RUN: obj2yaml %t.wasm | FileCheck %s + +define i32 @_start() local_unnamed_addr { +entry: + ret i32 1 +} + +; CHECK: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: ret32 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: ret64 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Type: + + +; Verify that referencing a symbol that doesn't exist won't work +; RUN: not lld -flavor wasm %t3.o -o %t.wasm -u symboldoesnotexist 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED1 %s +; CHECK-UNDEFINED1: error: undefined symbol: symboldoesnotexist + +; RUN: not lld -flavor wasm %t3.o -o %t.wasm --undefined symboldoesnotexist --allow-undefined 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED2 %s +; CHECK-UNDEFINED2: function forced with --undefined not found: symboldoesnotexist diff --git a/test/wasm/local-symbols.ll b/test/wasm/local-symbols.ll new file mode 100644 index 000000000000..3e6722b124ec --- /dev/null +++ b/test/wasm/local-symbols.ll @@ -0,0 +1,78 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +@foo = default global i32 1, align 4 +@bar = internal default global i32 3, align 4 + +define internal i32 @baz() local_unnamed_addr { +entry: + ret i32 2 +} + +define i32 @_start() local_unnamed_addr { +entry: + ret i32 1 +} + +; CHECK: --- !WASM +; CHECK-NEXT: FileHeader: +; CHECK-NEXT: Version: 0x00000001 +; CHECK-NEXT: Sections: +; CHECK-NEXT: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0, 0 ] +; CHECK-NEXT: - Type: TABLE +; CHECK-NEXT: Tables: +; CHECK-NEXT: - ElemType: ANYFUNC +; CHECK-NEXT: Limits: +; CHECK-NEXT: Flags: [ HAS_MAX ] +; CHECK-NEXT: Initial: 0x00000001 +; CHECK-NEXT: Maximum: 0x00000001 +; CHECK-NEXT: - Type: MEMORY +; CHECK-NEXT: Memories: +; CHECK-NEXT: - Initial: 0x00000002 +; CHECK-NEXT: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: true +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 66576 +; CHECK-NEXT: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Type: CODE +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41020B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41010B +; CHECK-NEXT: - Type: DATA +; CHECK-NEXT: Segments: +; CHECK-NEXT: - SectionOffset: 7 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1024 +; CHECK-NEXT: Content: '0100000003000000' +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 8 +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: baz +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: _start +; CHECK-NEXT: ... diff --git a/test/wasm/many-functions.ll b/test/wasm/many-functions.ll new file mode 100644 index 000000000000..77326d739a8b --- /dev/null +++ b/test/wasm/many-functions.ll @@ -0,0 +1,695 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/many-funcs.ll -o %t.many.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm -r -o %t.wasm %t.many.o %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +; Test that relocations within the CODE section correctly handle +; linking object with different header sizes. many-funcs.ll has +; 128 function and so the final output requires a 2-byte LEB in +; the CODE section header to store the function count. + +define i32 @func() { +entry: + %call = tail call i32 @func() + ret i32 %call +} + +; CHECK: - Type: CODE +; CHECK-NEXT: Relocations: +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000008 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000014 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000020 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000002C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000038 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000044 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000050 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000005C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000068 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000074 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000080 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000008C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000098 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000000A4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000000B0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000000BC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000000C8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000000D4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000000E0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000000EC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000000F8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000104 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000110 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000011C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000128 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000134 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000140 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000014C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000158 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000164 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000170 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000017C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000188 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000194 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000001A0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000001AC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000001B8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000001C4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000001D0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000001DC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000001E8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000001F4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000200 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000020C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000218 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000224 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000230 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000023C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000248 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000254 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000260 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000026C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000278 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000284 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000290 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000029C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000002A8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000002B4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000002C0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000002CC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000002D8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000002E4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000002F0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000002FC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000308 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000314 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000320 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000032C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000338 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000344 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000350 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000035C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000368 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000374 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000380 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000038C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000398 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000003A4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000003B0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000003BC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000003C8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000003D4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000003E0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000003EC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000003F8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000404 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000410 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000041C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000428 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000434 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000440 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000044C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000458 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000464 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000470 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000047C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000488 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000494 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000004A0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000004AC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000004B8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000004C4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000004D0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000004DC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000004E8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000004F4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000500 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000050C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000518 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000524 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000530 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000053C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000548 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000554 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000560 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000056C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000578 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000584 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000590 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000059C +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000005A8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000005B4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000005C0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000005CC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000005D8 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000005E4 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x000005F0 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Offset: 0x000005FC +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Offset: 0x00000608 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB +; CHECK-NEXT: Index: 129 +; CHECK-NEXT: Offset: 0x00000611 +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280284808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280280808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4100280280808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 1081818080000B +; CHECK-NEXT: - Type: DATA +; CHECK-NEXT: Segments: +; CHECK-NEXT: - SectionOffset: 6 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 0 +; CHECK-NEXT: Content: '01000000' +; CHECK-NEXT: - SectionOffset: 15 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 4 +; CHECK-NEXT: Content: '01000000' +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 8 +; CHECK-NEXT: SegmentInfo: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: .data.g0 +; CHECK-NEXT: Alignment: 4 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: .data.foo +; CHECK-NEXT: Alignment: 4 +; CHECK-NEXT: Flags: [ ] diff --git a/test/wasm/relocatable.ll b/test/wasm/relocatable.ll new file mode 100644 index 000000000000..cb86aa20cab2 --- /dev/null +++ b/test/wasm/relocatable.ll @@ -0,0 +1,194 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/hello.ll -o %t.hello.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm -r -o %t.wasm %t.hello.o %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +; Function Attrs: nounwind +define hidden i32 @my_func() local_unnamed_addr { +entry: + %call = tail call i32 @foo_import() + ret i32 1 +} + +declare i32 @foo_import() local_unnamed_addr +@data_import = external global i64 + +@func_addr1 = hidden global i32()* @my_func, align 4 +@func_addr2 = hidden global i32()* @foo_import, align 4 +@data_addr1 = hidden global i64* @data_import, align 8 + +; CHECK: --- !WASM +; CHECK-NEXT: FileHeader: +; CHECK-NEXT: Version: 0x00000001 +; CHECK-NEXT: Sections: +; CHECK-NEXT: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: NORESULT +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: ReturnType: NORESULT +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - I32 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: IMPORT +; CHECK-NEXT: Imports: +; CHECK-NEXT: - Module: env +; CHECK-NEXT: Field: puts +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SigIndex: 1 +; CHECK-NEXT: - Module: env +; CHECK-NEXT: Field: foo_import +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SigIndex: 2 +; CHECK-NEXT: - Module: env +; CHECK-NEXT: Field: data_import +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: GlobalType: I32 +; CHECK-NEXT: GlobalMutable: false +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0, 2 ] +; CHECK-NEXT: - Type: TABLE +; CHECK-NEXT: Tables: +; CHECK-NEXT: - ElemType: ANYFUNC +; CHECK-NEXT: Limits: +; CHECK-NEXT: Flags: [ HAS_MAX ] +; CHECK-NEXT: Initial: 0x00000002 +; CHECK-NEXT: Maximum: 0x00000002 +; CHECK-NEXT: - Type: MEMORY +; CHECK-NEXT: Memories: +; CHECK-NEXT: - Initial: 0x00000001 +; CHECK-NEXT: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 0 +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 8 +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 12 +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: false +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 16 +; CHECK-NEXT: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: hello +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: my_func +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 3 +; CHECK-NEXT: - Name: hello_str +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: func_addr1 +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: func_addr2 +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 3 +; CHECK-NEXT: - Name: data_addr1 +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 4 +; CHECK-NEXT: - Type: ELEM +; CHECK-NEXT: Segments: +; CHECK-NEXT: - Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 0 +; CHECK-NEXT: Functions: [ 3, 1 ] +; CHECK-NEXT: - Type: CODE +; CHECK-NEXT: Relocations: +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Offset: 0x00000004 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000000A +; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Offset: 0x00000013 +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4180808080001080808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 1081808080001A41010B +; CHECK-NEXT: - Type: DATA +; CHECK-NEXT: Relocations: +; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000012 +; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Offset: 0x0000001B +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000024 +; CHECK-NEXT: Segments: +; CHECK-NEXT: - SectionOffset: 6 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 0 +; CHECK-NEXT: Content: 68656C6C6F0A00 +; CHECK-NEXT: - SectionOffset: 18 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 8 +; CHECK-NEXT: Content: '00000000' +; CHECK-NEXT: - SectionOffset: 27 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 12 +; CHECK-NEXT: Content: '01000000' +; CHECK-NEXT: - SectionOffset: 36 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 16 +; CHECK-NEXT: Content: FFFFFFFF +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 20 +; CHECK-NEXT: SegmentInfo: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: .rodata.hello_str +; CHECK-NEXT: Alignment: 1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: .data.func_addr1 +; CHECK-NEXT: Alignment: 4 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Name: .data.func_addr2 +; CHECK-NEXT: Alignment: 4 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Name: .data.data_addr1 +; CHECK-NEXT: Alignment: 8 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: puts +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: foo_import +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Name: hello +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Name: my_func +; CHECK-NEXT: ... diff --git a/test/wasm/signature-mismatch.ll b/test/wasm/signature-mismatch.ll new file mode 100644 index 000000000000..88f70fea5123 --- /dev/null +++ b/test/wasm/signature-mismatch.ll @@ -0,0 +1,16 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.main.o +; RUN: not lld -flavor wasm --check-signatures -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s + +; Function Attrs: nounwind +define hidden void @_start() local_unnamed_addr #0 { +entry: + %call = tail call i32 @ret32(i32 1, i64 2, i32 3) #2 + ret void +} + +declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1 + +; CHECK: error: function signature mismatch: ret32 +; CHECK-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o +; CHECK-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o diff --git a/test/wasm/stack-pointer.ll b/test/wasm/stack-pointer.ll new file mode 100644 index 000000000000..738f0dce8e81 --- /dev/null +++ b/test/wasm/stack-pointer.ll @@ -0,0 +1,64 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm --emit-relocs -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +; Function Attrs: nounwind +define hidden i32 @_start() local_unnamed_addr { +entry: + %retval = alloca i32, align 4 + ret i32 0 +} + +; CHECK: --- !WASM +; CHECK-NEXT: FileHeader: +; CHECK-NEXT: Version: 0x00000001 +; CHECK-NEXT: Sections: +; CHECK-NEXT: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0 ] +; CHECK-NEXT: - Type: TABLE +; CHECK-NEXT: Tables: +; CHECK-NEXT: - ElemType: ANYFUNC +; CHECK-NEXT: Limits: +; CHECK-NEXT: Flags: [ HAS_MAX ] +; CHECK-NEXT: Initial: 0x00000001 +; CHECK-NEXT: Maximum: 0x00000001 +; CHECK-NEXT: - Type: MEMORY +; CHECK-NEXT: Memories: +; CHECK-NEXT: - Initial: 0x00000002 +; CHECK-NEXT: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: true +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Type: CODE +; CHECK-NEXT: Relocations: +; CHECK-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x00000004 +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 23808080800041106B1A41000B +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 0 +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: _start +; CHECK-NEXT: ... diff --git a/test/wasm/strip-debug.test b/test/wasm/strip-debug.test new file mode 100644 index 000000000000..57667a9f4406 --- /dev/null +++ b/test/wasm/strip-debug.test @@ -0,0 +1,6 @@ +RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o +RUN: lld -flavor wasm --strip-debug --entry=ret32 -o %t.wasm %t.ret32.o +RUN: obj2yaml %t.wasm | FileCheck %s + +# Check that there is no name section +CHECK-NOT: Name: name diff --git a/test/wasm/symbol-type-mismatch.ll b/test/wasm/symbol-type-mismatch.ll new file mode 100644 index 000000000000..706a361dd767 --- /dev/null +++ b/test/wasm/symbol-type-mismatch.ll @@ -0,0 +1,9 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o +; RUN: not lld -flavor wasm -o %t.wasm %t.o %t.ret32.o 2>&1 | FileCheck %s + +@ret32 = extern_weak global i32, align 4 + +; CHECK: error: symbol type mismatch: ret32 +; CHECK: >>> defined as Global in {{.*}}symbol-type-mismatch.ll.tmp.o +; CHECK: >>> defined as Function in {{.*}}.ret32.o diff --git a/test/wasm/undefined-entry.test b/test/wasm/undefined-entry.test new file mode 100644 index 000000000000..00a0761f4b6c --- /dev/null +++ b/test/wasm/undefined-entry.test @@ -0,0 +1,4 @@ +RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o +RUN: not lld -flavor wasm -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s + +CHECK: error: undefined symbol: _start diff --git a/test/wasm/undefined.ll b/test/wasm/undefined.ll new file mode 100644 index 000000000000..c5f266431702 --- /dev/null +++ b/test/wasm/undefined.ll @@ -0,0 +1,20 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm --allow-undefined -o %t.wasm %t.o + +; Fails due to undefined 'foo' +; RUN: not lld -flavor wasm -o %t.wasm %t.o 2>&1 | FileCheck %s +; CHECK: error: {{.*}}.o: undefined symbol: foo + +; But succeeds if we pass a file containing 'foo' as --allow-undefined-file. +; RUN: echo 'foo' > %t.txt +; RUN: lld -flavor wasm --allow-undefined-file=%t.txt -o %t.wasm %t.o + +; Takes the address of the external foo() resulting in undefined external +@bar = hidden local_unnamed_addr global i8* bitcast (i32 ()* @foo to i8*), align 4 + +declare i32 @foo() #0 + +define hidden void @_start() local_unnamed_addr #0 { +entry: + ret void +} diff --git a/test/wasm/version.ll b/test/wasm/version.ll new file mode 100644 index 000000000000..aed7b39ff3b9 --- /dev/null +++ b/test/wasm/version.ll @@ -0,0 +1,13 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm -o %t.wasm %t.o +; RUN: llvm-readobj -file-headers %t.wasm | FileCheck %s + +define hidden void @_start() local_unnamed_addr #0 { +entry: + ret void +} + +; CHECK: Format: WASM +; CHECK: Arch: wasm32 +; CHECK: AddressSize: 32bit +; CHECK: Version: 0x1 diff --git a/test/wasm/visibility-hidden.ll b/test/wasm/visibility-hidden.ll new file mode 100644 index 000000000000..9960b952492b --- /dev/null +++ b/test/wasm/visibility-hidden.ll @@ -0,0 +1,46 @@ +; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s +; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/hidden.ll -o %t2.o +; RUN: llvm-ar rcs %t2.a %t2.o +; RUN: lld -flavor wasm %t.o %t2.a -o %t.wasm +; RUN: obj2yaml %t.wasm | FileCheck %s + +; Test that hidden symbols are not exported, whether pulled in from an archive +; or directly. + +define hidden i32 @objectHidden() { +entry: + ret i32 0 +} + +define i32 @objectDefault() { +entry: + ret i32 0 +} + +declare i32 @archiveHidden() +declare i32 @archiveDefault() + +define i32 @_start() { +entry: + %call1 = call i32 @objectHidden() + %call2 = call i32 @objectDefault() + %call3 = call i32 @archiveHidden() + %call4 = call i32 @archiveDefault() + ret i32 0 +} + +; CHECK: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: archiveDefault +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 4 +; CHECK-NEXT: - Name: objectDefault +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Type: diff --git a/test/wasm/weak-alias-overide.ll b/test/wasm/weak-alias-overide.ll new file mode 100644 index 000000000000..5f4021e18b0f --- /dev/null +++ b/test/wasm/weak-alias-overide.ll @@ -0,0 +1,92 @@ +; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s +; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o +; RUN: lld -flavor wasm %t.o %t2.o -o %t.wasm +; RUN: obj2yaml %t.wasm | FileCheck %s + +; Test that the strongly defined bar is used correctly despite the existence +; of the weak alias + +define i32 @bar() local_unnamed_addr #1 { + ret i32 1 +} + +; Function Attrs: nounwind uwtable +define void @_start() local_unnamed_addr #1 { +entry: + %call = tail call i32 @bar() #2 + ret void +} + +; CHECK: --- !WASM +; CHECK-NEXT: FileHeader: +; CHECK-NEXT: Version: 0x00000001 +; CHECK-NEXT: Sections: +; CHECK-NEXT: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: ReturnType: NORESULT +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 0 ] +; CHECK-NEXT: - Type: TABLE +; CHECK-NEXT: Tables: +; CHECK-NEXT: - ElemType: ANYFUNC +; CHECK-NEXT: Limits: +; CHECK-NEXT: Flags: [ HAS_MAX ] +; CHECK-NEXT: Initial: 0x00000001 +; CHECK-NEXT: Maximum: 0x00000001 +; CHECK-NEXT: - Type: MEMORY +; CHECK-NEXT: Memories: +; CHECK-NEXT: - Initial: 0x00000002 +; CHECK-NEXT: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: true +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: bar +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: foo +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: call_bar +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 3 +; CHECK-NEXT: - Type: CODE +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41010B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 1080808080001A0B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 1080808080000B +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 0 +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: bar +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: _start +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Name: foo +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Name: call_bar +; CHECK-NEXT: ... diff --git a/test/wasm/weak-alias.ll b/test/wasm/weak-alias.ll new file mode 100644 index 000000000000..6f96d4d17643 --- /dev/null +++ b/test/wasm/weak-alias.ll @@ -0,0 +1,82 @@ +; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s +; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o +; RUN: lld -flavor wasm %t.o %t2.o -o %t.wasm +; RUN: obj2yaml %t.wasm | FileCheck %s + +; Test that weak aliases (bar is a weak alias of foo) are linked correctly + +declare i32 @bar() local_unnamed_addr #1 + +; Function Attrs: nounwind uwtable +define i32 @_start() local_unnamed_addr #1 { +entry: + %call = tail call i32 @bar() #2 + ret i32 %call +} + +; CHECK: --- !WASM +; CHECK-NEXT: FileHeader: +; CHECK-NEXT: Version: 0x00000001 +; CHECK-NEXT: Sections: +; CHECK-NEXT: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0, 0, 0 ] +; CHECK-NEXT: - Type: TABLE +; CHECK-NEXT: Tables: +; CHECK-NEXT: - ElemType: ANYFUNC +; CHECK-NEXT: Limits: +; CHECK-NEXT: Flags: [ HAS_MAX ] +; CHECK-NEXT: Initial: 0x00000001 +; CHECK-NEXT: Maximum: 0x00000001 +; CHECK-NEXT: - Type: MEMORY +; CHECK-NEXT: Memories: +; CHECK-NEXT: - Initial: 0x00000002 +; CHECK-NEXT: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: true +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: bar +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: foo +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: call_bar +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Type: CODE +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 1081808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 1081808080000B +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 0 +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: _start +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: foo +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Name: call_bar +; CHECK-NEXT: ... diff --git a/test/wasm/weak-external.ll b/test/wasm/weak-external.ll new file mode 100644 index 000000000000..891f7666ec76 --- /dev/null +++ b/test/wasm/weak-external.ll @@ -0,0 +1,86 @@ +; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s +; RUN: lld -flavor wasm -strip-debug %t.o -o %t.wasm +; RUN: obj2yaml %t.wasm | FileCheck %s + +; Test that undefined weak externals (global_var) and (foo) don't cause +; link failures and resolve to zero. + +@global_var = extern_weak global i32, align 4 + +declare extern_weak i32 @foo() + +define i8* @get_address_of_foo() #0 { +entry: + ret i8* bitcast (i32 ()* @foo to i8*) +} + +define i32* @get_address_of_global_var() #0 { + ret i32* @global_var +} + +define i32 @_start() #0 { +entry: + %0 = load i32, i32* @global_var, align 4 + ret i32 %0 +} + +; CHECK: --- !WASM +; CHECK-NEXT: FileHeader: +; CHECK-NEXT: Version: 0x00000001 +; CHECK-NEXT: Sections: +; CHECK-NEXT: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0, 0, 0 ] +; CHECK-NEXT: - Type: TABLE +; CHECK-NEXT: Tables: +; CHECK-NEXT: - ElemType: ANYFUNC +; CHECK-NEXT: Limits: +; CHECK-NEXT: Flags: [ HAS_MAX ] +; CHECK-NEXT: Initial: 0x00000002 +; CHECK-NEXT: Maximum: 0x00000002 +; CHECK-NEXT: - Type: MEMORY +; CHECK-NEXT: Memories: +; CHECK-NEXT: - Initial: 0x00000002 +; CHECK-NEXT: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: true +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: get_address_of_foo +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: get_address_of_global_var +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Type: ELEM +; CHECK-NEXT: Segments: +; CHECK-NEXT: - Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1 +; CHECK-NEXT: Functions: [ 0 ] +; CHECK-NEXT: - Type: CODE +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4181808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41FFFFFFFF7F0B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41002802FFFFFFFF0F0B +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 0 +; CHECK-NEXT: ... diff --git a/test/wasm/weak-symbols.ll b/test/wasm/weak-symbols.ll new file mode 100644 index 000000000000..c282d005623f --- /dev/null +++ b/test/wasm/weak-symbols.ll @@ -0,0 +1,93 @@ +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/weak-symbol1.ll -o %t1.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/weak-symbol2.ll -o %t2.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o +; RUN: lld -flavor wasm -o %t.wasm %t.o %t1.o %t2.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +declare i32 @weakFn() local_unnamed_addr + +define void @_start() local_unnamed_addr { +entry: + %call = call i32 @weakFn() + ret void +} + +; CHECK: --- !WASM +; CHECK-NEXT: FileHeader: +; CHECK-NEXT: Version: 0x00000001 +; CHECK-NEXT: Sections: +; CHECK-NEXT: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: NORESULT +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Type: FUNCTION +; CHECK-NEXT: FunctionTypes: [ 0, 1, 1, 1, 1 ] +; CHECK-NEXT: - Type: TABLE +; CHECK-NEXT: Tables: +; CHECK-NEXT: - ElemType: ANYFUNC +; CHECK-NEXT: Limits: +; CHECK-NEXT: Flags: [ HAS_MAX ] +; CHECK-NEXT: Initial: 0x00000002 +; CHECK-NEXT: Maximum: 0x00000002 +; CHECK-NEXT: - Type: MEMORY +; CHECK-NEXT: Memories: +; CHECK-NEXT: - Initial: 0x00000002 +; CHECK-NEXT: - Type: GLOBAL +; CHECK-NEXT: Globals: +; CHECK-NEXT: - Type: I32 +; CHECK-NEXT: Mutable: true +; CHECK-NEXT: InitExpr: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 66560 +; CHECK-NEXT: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: weakFn +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: exportWeak1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: exportWeak2 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 4 +; CHECK-NEXT: - Type: ELEM +; CHECK-NEXT: Segments: +; CHECK-NEXT: - Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 1 +; CHECK-NEXT: Functions: [ 1 ] +; CHECK-NEXT: - Type: CODE +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 1081808080001A0B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41010B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4181808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41020B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 4181808080000B +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 0 +; CHECK-NEXT: - Type: CUSTOM +; CHECK-NEXT: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: _start +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Name: exportWeak1 +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: Name: exportWeak2 +; CHECK-NEXT: ... |