From 1827005cfcfff2100535d35c22e0cf7caa469c46 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Wed, 18 Nov 2020 21:38:23 -0800 Subject: [PATCH] [WebAssembly] Add support for named globals in the object format. Differential Revision: https://reviews.llvm.org/D91769 --- lld/test/wasm/alias.s | 3 + lld/test/wasm/call-indirect.ll | 3 + lld/test/wasm/ctor_return_value.s | 3 + lld/test/wasm/cxx-mangling.ll | 3 + lld/test/wasm/data-segment-merging.ll | 6 ++ lld/test/wasm/function-imports-first.ll | 3 + lld/test/wasm/function-imports.ll | 3 + lld/test/wasm/gc-imports.s | 12 +++ lld/test/wasm/gc-sections.ll | 12 +++ lld/test/wasm/init-fini.ll | 3 + lld/test/wasm/load-undefined.test | 6 ++ lld/test/wasm/local-symbols.ll | 3 + lld/test/wasm/locals-duplicate.test | 3 + lld/test/wasm/map-file.s | 2 +- lld/test/wasm/signature-mismatch-export.ll | 3 + lld/test/wasm/signature-mismatch.ll | 3 + lld/test/wasm/stack-pointer.ll | 3 + lld/test/wasm/target-feature-disallowed.yaml | 8 +- lld/test/wasm/target-feature-none.yaml | 2 +- lld/test/wasm/target-feature-required.yaml | 10 +-- lld/test/wasm/target-feature-used.yaml | 12 +-- lld/test/wasm/undefined-weak-call.ll | 3 + lld/test/wasm/weak-alias-overide.ll | 3 + lld/test/wasm/weak-alias.ll | 6 ++ lld/test/wasm/weak-symbols.ll | 3 + lld/wasm/SyntheticSections.cpp | 83 +++++++++++++++----- lld/wasm/SyntheticSections.h | 10 ++- llvm/include/llvm/BinaryFormat/Wasm.h | 9 ++- llvm/include/llvm/Object/Wasm.h | 4 +- llvm/include/llvm/ObjectYAML/WasmYAML.h | 1 + llvm/lib/Object/WasmObjectFile.cpp | 37 ++++++--- llvm/lib/ObjectYAML/WasmEmitter.cpp | 13 +++ llvm/lib/ObjectYAML/WasmYAML.cpp | 1 + llvm/tools/obj2yaml/wasm2yaml.cpp | 13 ++- 34 files changed, 233 insertions(+), 59 deletions(-) diff --git a/lld/test/wasm/alias.s b/lld/test/wasm/alias.s index 9145c2e46c26a..6c99f69da8b87 100644 --- a/lld/test/wasm/alias.s +++ b/lld/test/wasm/alias.s @@ -62,4 +62,7 @@ _start: # CHECK-NEXT: FunctionNames: # CHECK-NEXT: - Index: 0 # CHECK-NEXT: Name: _start +# CHECK-NEXT: GlobalNames: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Name: __stack_pointer # CHECK-NEXT: ... diff --git a/lld/test/wasm/call-indirect.ll b/lld/test/wasm/call-indirect.ll index 421d729205756..84a84710f2baf 100644 --- a/lld/test/wasm/call-indirect.ll +++ b/lld/test/wasm/call-indirect.ll @@ -153,4 +153,7 @@ define void @call_ptr(i64 (i64)* %arg) { ; CHECK-NEXT: Name: _start ; CHECK-NEXT: - Index: 4 ; CHECK-NEXT: Name: call_ptr +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/test/wasm/ctor_return_value.s b/lld/test/wasm/ctor_return_value.s index 8fa28eac07558..d21b58eaaca13 100644 --- a/lld/test/wasm/ctor_return_value.s +++ b/lld/test/wasm/ctor_return_value.s @@ -43,4 +43,7 @@ _start: # CHECK-NEXT: Name: myctor # CHECK-NEXT: - Index: 2 # CHECK-NEXT: Name: _start +# CHECK-NEXT: GlobalNames: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Name: __stack_pointer # CHECK-NEXT: ... diff --git a/lld/test/wasm/cxx-mangling.ll b/lld/test/wasm/cxx-mangling.ll index 8c97ae0e6b842..0a69f5ef85ad1 100644 --- a/lld/test/wasm/cxx-mangling.ll +++ b/lld/test/wasm/cxx-mangling.ll @@ -54,4 +54,7 @@ define void @_start() { ; MANGLE-NEXT: Name: _Z3fooi ; CHECK-NEXT: - Index: 2 ; CHECK-NEXT: Name: _start +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/test/wasm/data-segment-merging.ll b/lld/test/wasm/data-segment-merging.ll index 453382337038b..a7d2e55524836 100644 --- a/lld/test/wasm/data-segment-merging.ll +++ b/lld/test/wasm/data-segment-merging.ll @@ -29,6 +29,9 @@ target triple = "wasm32-unknown-unknown" ; MERGE-NEXT: FunctionNames: ; MERGE-NEXT: - Index: 0 ; MERGE-NEXT: Name: __wasm_call_ctors +; MERGE-NEXT: GlobalNames: +; MERGE-NEXT: - Index: 0 +; MERGE-NEXT: Name: __stack_pointer ; MERGE-NOT: - Index: ; RUN: wasm-ld -no-gc-sections --no-entry --no-merge-data-segments -o %t.separate.wasm %t.o @@ -66,6 +69,9 @@ target triple = "wasm32-unknown-unknown" ; SEPARATE-NEXT: FunctionNames: ; SEPARATE-NEXT: - Index: 0 ; SEPARATE-NEXT: Name: __wasm_call_ctors +; SEPARATE-NEXT: GlobalNames: +; SEPARATE-NEXT: - Index: 0 +; SEPARATE-NEXT: Name: __stack_pointer ; SEPARATE-NOT: - Index: ; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 -o %t.merged.passive.wasm %t.passive.o diff --git a/lld/test/wasm/function-imports-first.ll b/lld/test/wasm/function-imports-first.ll index b2751e047bd40..7552fb428b0ba 100644 --- a/lld/test/wasm/function-imports-first.ll +++ b/lld/test/wasm/function-imports-first.ll @@ -41,4 +41,7 @@ declare i32 @ret32(float) local_unnamed_addr #1 ; CHECK-NEXT: Name: _start ; CHECK-NEXT: - Index: 1 ; CHECK-NEXT: Name: ret32 +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/test/wasm/function-imports.ll b/lld/test/wasm/function-imports.ll index 5f2d6f9ee611e..4b18532fc2207 100644 --- a/lld/test/wasm/function-imports.ll +++ b/lld/test/wasm/function-imports.ll @@ -37,4 +37,7 @@ declare i32 @ret32(float) local_unnamed_addr #1 ; CHECK-NEXT: Name: ret32 ; CHECK-NEXT: - Index: 1 ; CHECK-NEXT: Name: _start +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/test/wasm/gc-imports.s b/lld/test/wasm/gc-imports.s index 1f8bca9064e09..644e9f951a335 100644 --- a/lld/test/wasm/gc-imports.s +++ b/lld/test/wasm/gc-imports.s @@ -42,6 +42,11 @@ _start: # CHECK-NEXT: Name: _start # CHECK-NEXT: - Index: 2 # CHECK-NEXT: Name: use_undef_global +# CHECK-NEXT: GlobalNames: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Name: used_undef_global +# CHECK-NEXT: - Index: 1 +# CHECK-NEXT: Name: __stack_pointer # CHECK-NEXT: ... # RUN: wasm-ld --no-gc-sections --allow-undefined \ @@ -84,4 +89,11 @@ _start: # NO-GC-NEXT: Name: _start # NO-GC-NEXT: - Index: 5 # NO-GC-NEXT: Name: use_undef_global +# NO-GC-NEXT: GlobalNames: +# NO-GC-NEXT: - Index: 0 +# NO-GC-NEXT: Name: unused_undef_global +# NO-GC-NEXT: - Index: 1 +# NO-GC-NEXT: Name: used_undef_global +# NO-GC-NEXT: - Index: 2 +# NO-GC-NEXT: Name: __stack_pointer # NO-GC-NEXT: ... diff --git a/lld/test/wasm/gc-sections.ll b/lld/test/wasm/gc-sections.ll index a91bbecf32481..8bac2fd078278 100644 --- a/lld/test/wasm/gc-sections.ll +++ b/lld/test/wasm/gc-sections.ll @@ -82,6 +82,11 @@ entry: ; CHECK-NEXT: Name: _start ; CHECK-NEXT: - Index: 2 ; CHECK-NEXT: Name: use_global +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: used_global ; CHECK-NEXT: ... ; RUN: wasm-ld -print-gc-sections --no-gc-sections -o %t1.no-gc.wasm \ @@ -150,6 +155,13 @@ entry: ; NO-GC-NEXT: Name: _start ; NO-GC-NEXT: - Index: 4 ; NO-GC-NEXT: Name: use_global +; NO-GC-NEXT: GlobalNames: +; NO-GC-NEXT: - Index: 0 +; NO-GC-NEXT: Name: __stack_pointer +; NO-GC-NEXT: - Index: 1 +; NO-GC-NEXT: Name: unused_global +; NO-GC-NEXT: - Index: 2 +; NO-GC-NEXT: Name: used_global ; NO-GC-NEXT: ... ; RUN: not wasm-ld --gc-sections --relocatable -o %t1.no-gc.wasm %t.o 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR diff --git a/lld/test/wasm/init-fini.ll b/lld/test/wasm/init-fini.ll index 57be1a60d2d00..1e7644bc6d357 100644 --- a/lld/test/wasm/init-fini.ll +++ b/lld/test/wasm/init-fini.ll @@ -127,6 +127,9 @@ entry: ; CHECK-NEXT: Name: .Lcall_dtors.2002 ; CHECK-NEXT: - Index: 22 ; CHECK-NEXT: Name: .Lregister_call_dtors.2002 +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... ; RUN: wasm-ld -r %t.o %t.global-ctor-dtor.o -o %t.reloc.wasm diff --git a/lld/test/wasm/load-undefined.test b/lld/test/wasm/load-undefined.test index 3171d4a4a4aa0..a27c4c0a08cb3 100644 --- a/lld/test/wasm/load-undefined.test +++ b/lld/test/wasm/load-undefined.test @@ -21,6 +21,9 @@ ; CHECK-NEXT: Name: ret64 ; CHECK-NEXT: - Index: 3 ; CHECK-NEXT: Name: ret32 +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... ; NO-LOAD: Name: name @@ -31,6 +34,9 @@ ; NO-LOAD-NEXT: Name: _start ; NO-LOAD-NEXT: - Index: 2 ; NO-LOAD-NEXT: Name: ret64 +; NO-LOAD-NEXT: GlobalNames: +; NO-LOAD-NEXT: - Index: 0 +; NO-LOAD-NEXT: Name: __stack_pointer ; NO-LOAD-NEXT: ... ; Verify that referencing a symbol that is not found doesn't result in a link diff --git a/lld/test/wasm/local-symbols.ll b/lld/test/wasm/local-symbols.ll index 808ff64cca63c..d0a520a950a29 100644 --- a/lld/test/wasm/local-symbols.ll +++ b/lld/test/wasm/local-symbols.ll @@ -94,4 +94,7 @@ entry: ; CHECK-NEXT: Name: baz ; CHECK-NEXT: - Index: 1 ; CHECK-NEXT: Name: _start +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/test/wasm/locals-duplicate.test b/lld/test/wasm/locals-duplicate.test index c0ae1863badb9..dc6b9c88be296 100644 --- a/lld/test/wasm/locals-duplicate.test +++ b/lld/test/wasm/locals-duplicate.test @@ -209,6 +209,9 @@ ; CHECK-NEXT: Name: get_func2B ; CHECK-NEXT: - Index: 17 ; CHECK-NEXT: Name: get_func3B +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/test/wasm/map-file.s b/lld/test/wasm/map-file.s index c2ec089ccb137..e194662ea5d15 100644 --- a/lld/test/wasm/map-file.s +++ b/lld/test/wasm/map-file.s @@ -40,7 +40,7 @@ somedata: # CHECK-NEXT: 400 5a 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.data.somedata) # CHECK-NEXT: 400 5a 4 somedata # CHECK-NEXT: - 60 12 CUSTOM(.debug_info) -# CHECK-NEXT: - 72 17 CUSTOM(name) +# CHECK-NEXT: - 72 2b CUSTOM(name) # RUN: not wasm-ld %t1.o -o /dev/null -Map=/ 2>&1 \ # RUN: | FileCheck -check-prefix=FAIL %s diff --git a/lld/test/wasm/signature-mismatch-export.ll b/lld/test/wasm/signature-mismatch-export.ll index 80c05c33913fc..1d5e2a77a6c49 100644 --- a/lld/test/wasm/signature-mismatch-export.ll +++ b/lld/test/wasm/signature-mismatch-export.ll @@ -27,4 +27,7 @@ entry: ; CHECK-NEXT: Name: _start ; CHECK-NEXT: - Index: 2 ; CHECK-NEXT: Name: ret32 +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/test/wasm/signature-mismatch.ll b/lld/test/wasm/signature-mismatch.ll index b797b013820b2..3e42a74d0f058 100644 --- a/lld/test/wasm/signature-mismatch.ll +++ b/lld/test/wasm/signature-mismatch.ll @@ -52,6 +52,9 @@ declare i32 @ret32(i32, i64, i32) local_unnamed_addr ; YAML-NEXT: Name: ret32 ; YAML-NEXT: - Index: 3 ; YAML-NEXT: Name: call_ret32 +; YAML-NEXT: GlobalNames: +; YAML-NEXT: - Index: 0 +; YAML-NEXT: Name: __stack_pointer ; YAML-NEXT: ... ; RELOC: Name: linking diff --git a/lld/test/wasm/stack-pointer.ll b/lld/test/wasm/stack-pointer.ll index cbabaacadc1f4..8efb2aae1ee5e 100644 --- a/lld/test/wasm/stack-pointer.ll +++ b/lld/test/wasm/stack-pointer.ll @@ -69,4 +69,7 @@ entry: ; CHECK-NEXT: FunctionNames: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: _start +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/test/wasm/target-feature-disallowed.yaml b/lld/test/wasm/target-feature-disallowed.yaml index 9eaf7f6c9c114..96f7a64635096 100644 --- a/lld/test/wasm/target-feature-disallowed.yaml +++ b/lld/test/wasm/target-feature-disallowed.yaml @@ -36,7 +36,7 @@ Sections: ... # SPECIFIED: - Type: CUSTOM -# SPECIFIED-NEXT: Name: target_features +# SPECIFIED: Name: target_features # SPECIFIED-NEXT: Features: # SPECIFIED-NEXT: - Prefix: USED # SPECIFIED-NEXT: Name: bar @@ -47,7 +47,7 @@ Sections: # SPECIFIED-NEXT: ... # UNSPECIFIED: - Type: CUSTOM -# UNSPECIFIED-NEXT: Name: target_features +# UNSPECIFIED: Name: target_features # UNSPECIFIED-NEXT: Features: # UNSPECIFIED-NEXT: - Prefix: USED # UNSPECIFIED-NEXT: Name: bar @@ -58,14 +58,14 @@ Sections: # UNSPECIFIED-NEXT: ... # DISALLOWED: - Type: CUSTOM -# DISALLOWED-NEXT: Name: target_features +# DISALLOWED: Name: target_features # DISALLOWED-NEXT: Features: # DISALLOWED-NEXT: - Prefix: USED # DISALLOWED-NEXT: Name: bar # DISALLOWED-NEXT: ... # NONE: - Type: CUSTOM -# NONE-NEXT: Name: target_features +# NONE: Name: target_features # NONE-NEXT: Features: # NONE-NEXT: - Prefix: USED # NONE-NEXT: Name: bar diff --git a/lld/test/wasm/target-feature-none.yaml b/lld/test/wasm/target-feature-none.yaml index 82fc527570701..fa53ce42f9256 100644 --- a/lld/test/wasm/target-feature-none.yaml +++ b/lld/test/wasm/target-feature-none.yaml @@ -22,7 +22,7 @@ Sections: # EMPTY-NOT: target_features # SPECIFIED: - Type: CUSTOM -# SPECIFIED-NEXT: Name: target_features +# SPECIFIED: Name: target_features # SPECIFIED-NEXT: Features: # SPECIFIED-NEXT: - Prefix: USED # SPECIFIED-NEXT: Name: bar diff --git a/lld/test/wasm/target-feature-required.yaml b/lld/test/wasm/target-feature-required.yaml index ce9857a7e89ad..9300f88983ae7 100644 --- a/lld/test/wasm/target-feature-required.yaml +++ b/lld/test/wasm/target-feature-required.yaml @@ -41,7 +41,7 @@ Sections: ... # SPECIFIED: - Type: CUSTOM -# SPECIFIED-NEXT: Name: target_features +# SPECIFIED: Name: target_features # SPECIFIED-NEXT: Features: # SPECIFIED-NEXT: - Prefix: USED # SPECIFIED-NEXT: Name: bar @@ -54,7 +54,7 @@ Sections: # UNSPECIFIED: Target feature 'foo' used by {{.*}}target-feature-required.yaml.tmp1.o is not allowed.{{$}} # UNSPECIFIED-NOCHECK: - Type: CUSTOM -# UNSPECIFIED-NOCHECK-NEXT: Name: target_features +# UNSPECIFIED-NOCHECK: Name: target_features # UNSPECIFIED-NOCHECK-NEXT: Features: # UNSPECIFIED-NOCHECK-NEXT: - Prefix: USED # UNSPECIFIED-NOCHECK-NEXT: Name: bar @@ -65,7 +65,7 @@ Sections: # UNSPECIFIED-NOCHECK-NEXT: ... # REQUIRED: - Type: CUSTOM -# REQUIRED-NEXT: Name: target_features +# REQUIRED: Name: target_features # REQUIRED-NEXT: Features: # REQUIRED-NEXT: - Prefix: USED # REQUIRED-NEXT: Name: foo @@ -74,7 +74,7 @@ Sections: # DISALLOWED: Target feature 'foo' used in {{.*}}target-feature-required.yaml.tmp1.o is disallowed by {{.*}}target-feature-required.yaml.tmp.disallowed.o. Use --no-check-features to suppress.{{$}} # DISALLOWED-NOCHECK: - Type: CUSTOM -# DISALLOWED-NOCHECK-NEXT: Name: target_features +# DISALLOWED-NOCHECK: Name: target_features # DISALLOWED-NOCHECK-NEXT: Features: # DISALLOWED-NOCHECK-NEXT: - Prefix: USED # DISALLOWED-NOCHECK-NEXT: Name: foo @@ -83,7 +83,7 @@ Sections: # NONE: Missing target feature 'foo' in {{.*}}target-feature-required.yaml.tmp.none.o, required by {{.*}}target-feature-required.yaml.tmp1.o. Use --no-check-features to suppress.{{$}} # NONE-NOCHECK: - Type: CUSTOM -# NONE-NOCHECK-NEXT: Name: target_features +# NONE-NOCHECK: Name: target_features # NONE-NOCHECK-NEXT: Features: # NONE-NOCHECK-NEXT: - Prefix: USED # NONE-NOCHECK-NEXT: Name: foo diff --git a/lld/test/wasm/target-feature-used.yaml b/lld/test/wasm/target-feature-used.yaml index c9c19c7494c0a..5b3d47fc6ae3a 100644 --- a/lld/test/wasm/target-feature-used.yaml +++ b/lld/test/wasm/target-feature-used.yaml @@ -43,7 +43,7 @@ Sections: ... # SPECIFIED: - Type: CUSTOM -# SPECIFIED-NEXT: Name: target_features +# SPECIFIED: Name: target_features # SPECIFIED-NEXT: Features: # SPECIFIED-NEXT: - Prefix: USED # SPECIFIED-NEXT: Name: bar @@ -56,7 +56,7 @@ Sections: # UNSPECIFIED: Target feature 'foo' used by {{.*}}target-feature-used.yaml.tmp1.o is not allowed.{{$}} # UNSPECIFIED-NOCHECK: - Type: CUSTOM -# UNSPECIFIED-NOCHECK-NEXT: Name: target_features +# UNSPECIFIED-NOCHECK: Name: target_features # UNSPECIFIED-NOCHECK-NEXT: Features: # UNSPECIFIED-NOCHECK-NEXT: - Prefix: USED # UNSPECIFIED-NOCHECK-NEXT: Name: bar @@ -67,14 +67,14 @@ Sections: # UNSPECIFIED-NOCHECK-NEXT: ... # USED: - Type: CUSTOM -# USED-NEXT: Name: target_features +# USED: Name: target_features # USED-NEXT: Features: # USED-NEXT: - Prefix: USED # USED-NEXT: Name: foo # USED-NEXT: ... # REQUIRED: - Type: CUSTOM -# REQUIRED-NEXT: Name: target_features +# REQUIRED: Name: target_features # REQUIRED-NEXT: Features: # REQUIRED-NEXT: - Prefix: USED # REQUIRED-NEXT: Name: foo @@ -83,14 +83,14 @@ Sections: # DISALLOWED: Target feature 'foo' used in {{.*}}target-feature-used.yaml.tmp1.o is disallowed by {{.*}}target-feature-used.yaml.tmp.disallowed.o. Use --no-check-features to suppress.{{$}} # DISALLOWED-NOCHECK: - Type: CUSTOM -# DISALLOWED-NOCHECK-NEXT: Name: target_features +# DISALLOWED-NOCHECK: Name: target_features # DISALLOWED-NOCHECK-NEXT: Features: # DISALLOWED-NOCHECK-NEXT: - Prefix: USED # DISALLOWED-NOCHECK-NEXT: Name: foo # DISALLOWED-NOCHECK-NEXT: ... # NONE: - Type: CUSTOM -# NONE-NEXT: Name: target_features +# NONE: Name: target_features # NONE-NEXT: Features: # NONE-NEXT: - Prefix: USED # NONE-NEXT: Name: foo diff --git a/lld/test/wasm/undefined-weak-call.ll b/lld/test/wasm/undefined-weak-call.ll index c09476e734b9d..c57f088948524 100644 --- a/lld/test/wasm/undefined-weak-call.ll +++ b/lld/test/wasm/undefined-weak-call.ll @@ -96,4 +96,7 @@ define i32 @callWeakFuncs() { ; CHECK-NEXT: Name: 'undefined_weak:weakFunc3' ; CHECK-NEXT: - Index: 3 ; CHECK-NEXT: Name: callWeakFuncs +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/test/wasm/weak-alias-overide.ll b/lld/test/wasm/weak-alias-overide.ll index 96af4e4419522..4d47341e22688 100644 --- a/lld/test/wasm/weak-alias-overide.ll +++ b/lld/test/wasm/weak-alias-overide.ll @@ -129,4 +129,7 @@ entry: ; CHECK-NEXT: Name: call_alias_ptr ; CHECK-NEXT: - Index: 6 ; CHECK-NEXT: Name: call_direct_ptr +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/test/wasm/weak-alias.ll b/lld/test/wasm/weak-alias.ll index 8493be38eca48..9d903f73dd320 100644 --- a/lld/test/wasm/weak-alias.ll +++ b/lld/test/wasm/weak-alias.ll @@ -121,6 +121,9 @@ entry: ; CHECK-NEXT: Name: call_alias_ptr ; CHECK-NEXT: - Index: 5 ; CHECK-NEXT: Name: call_direct_ptr +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... ; RUN: wasm-ld --relocatable %t.o %t2.o -o %t.reloc.o @@ -288,4 +291,7 @@ entry: ; RELOC-NEXT: Name: call_alias_ptr ; RELOC-NEXT: - Index: 5 ; RELOC-NEXT: Name: call_direct_ptr +; RELOC-NEXT: GlobalNames: +; RELOC-NEXT: - Index: 0 +; RELOC-NEXT: Name: __stack_pointer ; RELOC-NEXT: ... diff --git a/lld/test/wasm/weak-symbols.ll b/lld/test/wasm/weak-symbols.ll index 6a217b666b105..c924ec892b844 100644 --- a/lld/test/wasm/weak-symbols.ll +++ b/lld/test/wasm/weak-symbols.ll @@ -115,4 +115,7 @@ entry: ; CHECK-NEXT: Name: exportWeak1 ; CHECK-NEXT: - Index: 3 ; CHECK-NEXT: Name: exportWeak2 +; CHECK-NEXT: GlobalNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: __stack_pointer ; CHECK-NEXT: ... diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp index 3c702b71e34af..407eb8084d0e5 100644 --- a/lld/wasm/SyntheticSections.cpp +++ b/lld/wasm/SyntheticSections.cpp @@ -532,8 +532,9 @@ void LinkingSection::addToSymtab(Symbol *sym) { symtabEntries.emplace_back(sym); } -unsigned NameSection::numNames() const { +unsigned NameSection::numNamedFunctions() const { unsigned numNames = out.importSec->getNumImportedFunctions(); + for (const InputFunction *f : out.functionSec->inputFunctions) if (!f->getName().empty() || !f->getDebugName().empty()) ++numNames; @@ -541,32 +542,74 @@ unsigned NameSection::numNames() const { return numNames; } +unsigned NameSection::numNamedGlobals() const { + unsigned numNames = out.importSec->getNumImportedGlobals(); + + for (const InputGlobal *g : out.globalSec->inputGlobals) + if (!g->getName().empty()) + ++numNames; + + numNames += out.globalSec->internalGotSymbols.size(); + return numNames; +} + // Create the custom "name" section containing debug symbol names. void NameSection::writeBody() { - SubSection sub(WASM_NAMES_FUNCTION); - writeUleb128(sub.os, numNames(), "name count"); - - // Names must appear in function index order. As it happens importedSymbols - // and inputFunctions are numbered in order with imported functions coming - // first. - for (const Symbol *s : out.importSec->importedSymbols) { - if (auto *f = dyn_cast(s)) { - writeUleb128(sub.os, f->getFunctionIndex(), "func index"); - writeStr(sub.os, toString(*s), "symbol name"); + unsigned count = numNamedFunctions(); + if (count) { + SubSection sub(WASM_NAMES_FUNCTION); + writeUleb128(sub.os, count, "name count"); + + // Function names appear in function index order. As it happens + // importedSymbols and inputFunctions are numbered in order with imported + // functions coming first. + for (const Symbol *s : out.importSec->importedSymbols) { + if (auto *f = dyn_cast(s)) { + writeUleb128(sub.os, f->getFunctionIndex(), "func index"); + writeStr(sub.os, toString(*s), "symbol name"); + } } - } - for (const InputFunction *f : out.functionSec->inputFunctions) { - if (!f->getName().empty()) { - writeUleb128(sub.os, f->getFunctionIndex(), "func index"); - if (!f->getDebugName().empty()) { - writeStr(sub.os, f->getDebugName(), "symbol name"); - } else { - writeStr(sub.os, maybeDemangleSymbol(f->getName()), "symbol name"); + for (const InputFunction *f : out.functionSec->inputFunctions) { + if (!f->getName().empty()) { + writeUleb128(sub.os, f->getFunctionIndex(), "func index"); + if (!f->getDebugName().empty()) { + writeStr(sub.os, f->getDebugName(), "symbol name"); + } else { + writeStr(sub.os, maybeDemangleSymbol(f->getName()), "symbol name"); + } } } + sub.writeTo(bodyOutputStream); } - sub.writeTo(bodyOutputStream); + count = numNamedGlobals(); + if (count) { + SubSection sub(WASM_NAMES_GLOBAL); + writeUleb128(sub.os, count, "name count"); + + for (const Symbol *s : out.importSec->importedSymbols) { + if (auto *g = dyn_cast(s)) { + writeUleb128(sub.os, g->getGlobalIndex(), "global index"); + writeStr(sub.os, toString(*s), "symbol name"); + } + } + for (const Symbol *s : out.importSec->gotSymbols) { + writeUleb128(sub.os, s->getGOTIndex(), "global index"); + writeStr(sub.os, toString(*s), "symbol name"); + } + for (const InputGlobal *g : out.globalSec->inputGlobals) { + if (!g->getName().empty()) { + writeUleb128(sub.os, g->getGlobalIndex(), "global index"); + writeStr(sub.os, maybeDemangleSymbol(g->getName()), "symbol name"); + } + } + for (Symbol *s : out.globalSec->internalGotSymbols) { + writeUleb128(sub.os, s->getGOTIndex(), "global index"); + writeStr(sub.os, toString(*s), "symbol name"); + } + + sub.writeTo(bodyOutputStream); + } } void ProducersSection::addInfo(const WasmProducerInfo &info) { diff --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h index 8e40194401713..af0566e02e90f 100644 --- a/lld/wasm/SyntheticSections.h +++ b/lld/wasm/SyntheticSections.h @@ -119,13 +119,13 @@ class ImportSection : public SyntheticSection { } std::vector importedSymbols; + std::vector gotSymbols; protected: bool isSealed = false; unsigned numImportedGlobals = 0; unsigned numImportedFunctions = 0; unsigned numImportedEvents = 0; - std::vector gotSymbols; }; class FunctionSection : public SyntheticSection { @@ -221,11 +221,11 @@ class GlobalSection : public SyntheticSection { void generateRelocationCode(raw_ostream &os) const; std::vector dataAddressGlobals; + std::vector inputGlobals; + std::vector internalGotSymbols; protected: bool isSealed = false; - std::vector inputGlobals; - std::vector internalGotSymbols; }; class ExportSection : public SyntheticSection { @@ -302,7 +302,9 @@ class NameSection : public SyntheticSection { return !config->stripDebug && !config->stripAll && numNames() > 0; } void writeBody() override; - unsigned numNames() const; + unsigned numNames() const { return numNamedGlobals() + numNamedFunctions(); } + unsigned numNamedGlobals() const; + unsigned numNamedFunctions() const; }; class ProducersSection : public SyntheticSection { diff --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h index dd05bb02cea7e..f1441c7e07947 100644 --- a/llvm/include/llvm/BinaryFormat/Wasm.h +++ b/llvm/include/llvm/BinaryFormat/Wasm.h @@ -195,7 +195,13 @@ struct WasmSymbolInfo { }; }; -struct WasmFunctionName { +enum class NameType { + FUNCTION, + GLOBAL +}; + +struct WasmDebugName { + NameType Type; uint32_t Index; StringRef Name; }; @@ -303,6 +309,7 @@ enum : uint8_t { enum : unsigned { WASM_NAMES_FUNCTION = 0x1, WASM_NAMES_LOCAL = 0x2, + WASM_NAMES_GLOBAL = 0x7, }; // Kind codes used in the custom "linking" section diff --git a/llvm/include/llvm/Object/Wasm.h b/llvm/include/llvm/Object/Wasm.h index 292a05f2a40d0..72e4403a45cbe 100644 --- a/llvm/include/llvm/Object/Wasm.h +++ b/llvm/include/llvm/Object/Wasm.h @@ -149,7 +149,7 @@ class WasmObjectFile : public ObjectFile { ArrayRef elements() const { return ElemSegments; } ArrayRef dataSegments() const { return DataSegments; } ArrayRef functions() const { return Functions; } - ArrayRef debugNames() const { return DebugNames; } + ArrayRef debugNames() const { return DebugNames; } uint32_t startFunction() const { return StartFunction; } uint32_t getNumImportedGlobals() const { return NumImportedGlobals; } uint32_t getNumImportedTables() const { return NumImportedTables; } @@ -284,7 +284,7 @@ class WasmObjectFile : public ObjectFile { llvm::Optional DataCount; std::vector Functions; std::vector Symbols; - std::vector DebugNames; + std::vector DebugNames; uint32_t StartFunction = -1; bool HasLinkingSection = false; bool HasDylinkSection = false; diff --git a/llvm/include/llvm/ObjectYAML/WasmYAML.h b/llvm/include/llvm/ObjectYAML/WasmYAML.h index c2f4d4af8231c..28cd56061a3cf 100644 --- a/llvm/include/llvm/ObjectYAML/WasmYAML.h +++ b/llvm/include/llvm/ObjectYAML/WasmYAML.h @@ -221,6 +221,7 @@ struct NameSection : CustomSection { } std::vector FunctionNames; + std::vector GlobalNames; }; struct LinkingSection : CustomSection { diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index d6bb96f82cd6e..2504fda1a8cb3 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -356,7 +356,8 @@ Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) { } Error WasmObjectFile::parseNameSection(ReadContext &Ctx) { - llvm::DenseSet Seen; + llvm::DenseSet SeenFunctions; + llvm::DenseSet SeenGlobals; if (FunctionTypes.size() && !SeenCodeSection) { return make_error("Names must come after code section", object_error::parse_failed); @@ -367,20 +368,34 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) { uint32_t Size = readVaruint32(Ctx); const uint8_t *SubSectionEnd = Ctx.Ptr + Size; switch (Type) { - case wasm::WASM_NAMES_FUNCTION: { + case wasm::WASM_NAMES_FUNCTION: + case wasm::WASM_NAMES_GLOBAL: { uint32_t Count = readVaruint32(Ctx); while (Count--) { uint32_t Index = readVaruint32(Ctx); - if (!Seen.insert(Index).second) - return make_error("Function named more than once", - object_error::parse_failed); StringRef Name = readString(Ctx); - if (!isValidFunctionIndex(Index) || Name.empty()) - return make_error("Invalid name entry", - object_error::parse_failed); - DebugNames.push_back(wasm::WasmFunctionName{Index, Name}); - if (isDefinedFunctionIndex(Index)) - getDefinedFunction(Index).DebugName = Name; + if (Type == wasm::WASM_NAMES_FUNCTION) { + if (!SeenFunctions.insert(Index).second) + return make_error( + "Function named more than once", object_error::parse_failed); + if (!isValidFunctionIndex(Index) || Name.empty()) + return make_error("Invalid name entry", + object_error::parse_failed); + + if (isDefinedFunctionIndex(Index)) + getDefinedFunction(Index).DebugName = Name; + } else { + if (!SeenGlobals.insert(Index).second) + return make_error("Global named more than once", + object_error::parse_failed); + if (!isValidGlobalIndex(Index) || Name.empty()) + return make_error("Invalid name entry", + object_error::parse_failed); + } + wasm::NameType T = Type == wasm::WASM_NAMES_FUNCTION + ? wasm::NameType::FUNCTION + : wasm::NameType::GLOBAL; + DebugNames.push_back(wasm::WasmDebugName{T, Index, Name}); } break; } diff --git a/llvm/lib/ObjectYAML/WasmEmitter.cpp b/llvm/lib/ObjectYAML/WasmEmitter.cpp index 7b21d56be5030..64498c82232bb 100644 --- a/llvm/lib/ObjectYAML/WasmEmitter.cpp +++ b/llvm/lib/ObjectYAML/WasmEmitter.cpp @@ -268,6 +268,19 @@ void WasmWriter::writeSectionContent(raw_ostream &OS, writeStringRef(NameEntry.Name, SubSection.getStream()); } + SubSection.done(); + } + if (Section.GlobalNames.size()) { + writeUint8(OS, wasm::WASM_NAMES_GLOBAL); + + SubSectionWriter SubSection(OS); + + encodeULEB128(Section.GlobalNames.size(), SubSection.getStream()); + for (const WasmYAML::NameEntry &NameEntry : Section.GlobalNames) { + encodeULEB128(NameEntry.Index, SubSection.getStream()); + writeStringRef(NameEntry.Name, SubSection.getStream()); + } + SubSection.done(); } } diff --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp index f99ff69812aa5..5898ece19667d 100644 --- a/llvm/lib/ObjectYAML/WasmYAML.cpp +++ b/llvm/lib/ObjectYAML/WasmYAML.cpp @@ -61,6 +61,7 @@ static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) { commonSectionMapping(IO, Section); IO.mapRequired("Name", Section.Name); IO.mapOptional("FunctionNames", Section.FunctionNames); + IO.mapOptional("GlobalNames", Section.GlobalNames); } static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) { diff --git a/llvm/tools/obj2yaml/wasm2yaml.cpp b/llvm/tools/obj2yaml/wasm2yaml.cpp index 3a40829b34aa8..9ca351e1ce9fb 100644 --- a/llvm/tools/obj2yaml/wasm2yaml.cpp +++ b/llvm/tools/obj2yaml/wasm2yaml.cpp @@ -65,11 +65,16 @@ WasmDumper::dumpCustomSection(const WasmSection &WasmSec) { } else if (WasmSec.Name == "name") { std::unique_ptr NameSec = std::make_unique(); - for (const llvm::wasm::WasmFunctionName &Func : Obj.debugNames()) { + for (const llvm::wasm::WasmDebugName &Name : Obj.debugNames()) { WasmYAML::NameEntry NameEntry; - NameEntry.Name = Func.Name; - NameEntry.Index = Func.Index; - NameSec->FunctionNames.push_back(NameEntry); + NameEntry.Name = Name.Name; + NameEntry.Index = Name.Index; + if (Name.Type == llvm::wasm::NameType::FUNCTION) { + NameSec->FunctionNames.push_back(NameEntry); + } else { + assert(Name.Type == llvm::wasm::NameType::GLOBAL); + NameSec->GlobalNames.push_back(NameEntry); + } } CustomSec = std::move(NameSec); } else if (WasmSec.Name == "linking") {