Index: test/wasm/alias.ll =================================================================== --- test/wasm/alias.ll +++ test/wasm/alias.ll @@ -44,12 +44,6 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66560 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -61,9 +55,6 @@ ; CHECK-NEXT: - Name: start_alias ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 0 Index: test/wasm/archive.ll =================================================================== --- test/wasm/archive.ll +++ test/wasm/archive.ll @@ -9,7 +9,7 @@ ; CHECK-UNDEFINED: undefined symbol: missing_func ; RUN: echo 'missing_func' > %t.imports -; RUN: lld -flavor wasm %t.a %t.o -o %t.wasm +; RUN: lld -flavor wasm -r %t.a %t.o -o %t.wasm ; RUN: llvm-nm -a %t.wasm | FileCheck %s @@ -25,8 +25,8 @@ ret i32 %call2 } -; Verify that multually dependant object files in an archive is handled -; correctly. +; Verify that mutually dependant object files in an archive is handled +; correctly. Since we're using llvm-nm, we must link with --relocatable. ; CHECK: 00000003 T _start ; CHECK-NEXT: 00000001 T bar Index: test/wasm/call-indirect.ll =================================================================== --- test/wasm/call-indirect.ll +++ test/wasm/call-indirect.ll @@ -76,12 +76,6 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66576 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -102,9 +96,6 @@ ; CHECK-NEXT: - Name: call_ptr ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 4 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/comdats.ll =================================================================== --- test/wasm/comdats.ll +++ test/wasm/comdats.ll @@ -22,12 +22,6 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66576 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -45,9 +39,6 @@ ; CHECK-NEXT: - Name: callInline2 ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 3 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/data-layout.ll =================================================================== --- test/wasm/data-layout.ll +++ test/wasm/data-layout.ll @@ -20,12 +20,6 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66608 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66608 ; CHECK: - Type: DATA ; CHECK-NEXT: Segments: @@ -46,21 +40,6 @@ ; RUN: lld -flavor wasm --relocatable -o %t_reloc.wasm %t.o %t.hello.o ; RUN: obj2yaml %t_reloc.wasm | FileCheck %s -check-prefix=RELOC -; RELOC: - Type: GLOBAL -; RELOC-NEXT: Globals: -; RELOC-NEXT: - Index: 0 -; RELOC-NEXT: Type: I32 -; RELOC-NEXT: Mutable: false -; RELOC-NEXT: InitExpr: -; RELOC-NEXT: Opcode: I32_CONST -; RELOC-NEXT: Value: 0 -; RELOC-NEXT: - Index: 1 -; RELOC-NEXT: Type: I32 -; RELOC-NEXT: Mutable: false -; RELOC-NEXT: InitExpr: -; RELOC-NEXT: Opcode: I32_CONST -; RELOC-NEXT: Value: 16 - ; RELOC: - Type: DATA ; RELOC-NEXT: Relocations: ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 @@ -92,6 +71,31 @@ ; RELOC-NEXT: Value: 28 ; RELOC-NEXT: Content: 68656C6C6F0A00 -; RELOC: - Type: CUSTOM +; RELOC: - Type: CUSTOM ; RELOC-NEXT: Name: linking ; RELOC-NEXT: DataSize: 35 +; RELOC-NEXT: SymbolTable: +; RELOC-NEXT: - Index: 0 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: foo +; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: SegmentIndex: 0 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 1 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: aligned_bar +; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: SegmentIndex: 1 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 2 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: external_ref +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: SegmentIndex: 2 +; RELOC-NEXT: Size: 4 +; RELOC: - Index: 5 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: hello_str +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: SegmentIndex: 3 +; RELOC-NEXT: Size: 7 Index: test/wasm/export.ll =================================================================== --- test/wasm/export.ll +++ test/wasm/export.ll @@ -28,7 +28,4 @@ ; CHECK-NEXT: - Name: _start ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: CODE Index: test/wasm/init-fini.ll =================================================================== --- test/wasm/init-fini.ll +++ test/wasm/init-fini.ll @@ -109,52 +109,119 @@ ; RELOC: Name: linking ; RELOC-NEXT: DataSize: 0 -; RELOC-NEXT: SymbolInfo: -; RELOC-NEXT: - Name: __dso_handle +; RELOC-NEXT: SymbolTable: + +; RELOC-NEXT: - Index: 0 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: __dso_handle ; RELOC-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] -; RELOC-NEXT: - Name: func1 +; RELOC-NEXT: - Index: 1 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: func1 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; RELOC-NEXT: - Name: func2 +; RELOC-NEXT: FunctionIndex: 0 +; RELOC-NEXT: - Index: 2 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: func2 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; RELOC-NEXT: - Name: func3 +; RELOC-NEXT: FunctionIndex: 1 +; RELOC-NEXT: - Index: 3 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: func3 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; RELOC-NEXT: - Name: func4 +; RELOC-NEXT: FunctionIndex: 2 +; RELOC-NEXT: - Index: 4 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: func4 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; RELOC-NEXT: - Name: _start +; RELOC-NEXT: FunctionIndex: 3 +; RELOC-NEXT: - Index: 5 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: __cxa_atexit +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 4 +; RELOC-NEXT: - Index: 6 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: _start ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; RELOC-NEXT: - Name: .Lcall_dtors.101 +; RELOC-NEXT: FunctionIndex: 5 +; RELOC-NEXT: - Index: 7 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lcall_dtors.101 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: .Lregister_call_dtors.101 +; RELOC-NEXT: FunctionIndex: 6 +; RELOC-NEXT: - Index: 8 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lregister_call_dtors.101 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: .Lbitcast +; RELOC-NEXT: FunctionIndex: 7 +; RELOC-NEXT: - Index: 9 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lbitcast ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: .Lcall_dtors.1001 +; RELOC-NEXT: FunctionIndex: 8 +; RELOC-NEXT: - Index: 10 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lcall_dtors.1001 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: .Lregister_call_dtors.1001 +; RELOC-NEXT: FunctionIndex: 9 +; RELOC-NEXT: - Index: 11 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lregister_call_dtors.1001 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: myctor +; RELOC-NEXT: FunctionIndex: 10 +; RELOC-NEXT: - Index: 12 +; RELOC-NEXT: Kind: GLOBAL +; RELOC-NEXT: Name: __stack_pointer +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: GlobalIndex: 0 +; RELOC-NEXT: - Index: 13 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: myctor ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; RELOC-NEXT: - Name: mydtor +; RELOC-NEXT: FunctionIndex: 11 +; RELOC-NEXT: - Index: 14 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: mydtor ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; RELOC-NEXT: - Name: .Lcall_dtors.101.1 +; RELOC-NEXT: FunctionIndex: 12 +; RELOC-NEXT: - Index: 15 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lcall_dtors.101 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: .Lregister_call_dtors.101.1 +; RELOC-NEXT: FunctionIndex: 13 +; RELOC-NEXT: - Index: 16 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lregister_call_dtors.101 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: .Lcall_dtors.202 +; RELOC-NEXT: FunctionIndex: 14 +; RELOC-NEXT: - Index: 17 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lcall_dtors.202 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: .Lregister_call_dtors.202 +; RELOC-NEXT: FunctionIndex: 15 +; RELOC-NEXT: - Index: 18 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lregister_call_dtors.202 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: .Lcall_dtors.2002 +; RELOC-NEXT: FunctionIndex: 16 +; RELOC-NEXT: - Index: 19 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lcall_dtors.2002 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: .Lregister_call_dtors.2002 +; RELOC-NEXT: FunctionIndex: 17 +; RELOC-NEXT: - Index: 20 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: .Lregister_call_dtors.2002 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 18 ; RELOC-NEXT: InitFunctions: ; RELOC-NEXT: - Priority: 101 +; RELOC-NEXT: FunctionIndex: 1 +; RELOC-NEXT: - Priority: 101 ; RELOC-NEXT: FunctionIndex: 2 ; RELOC-NEXT: - Priority: 101 -; RELOC-NEXT: FunctionIndex: 3 -; RELOC-NEXT: - Priority: 101 -; RELOC-NEXT: FunctionIndex: 9 +; RELOC-NEXT: FunctionIndex: 8 ; RELOC-NEXT: - Priority: 101 ; RELOC-NEXT: FunctionIndex: 13 ; RELOC-NEXT: - Priority: 101 @@ -164,9 +231,9 @@ ; RELOC-NEXT: - Priority: 202 ; RELOC-NEXT: FunctionIndex: 18 ; RELOC-NEXT: - Priority: 1001 -; RELOC-NEXT: FunctionIndex: 2 +; RELOC-NEXT: FunctionIndex: 1 ; RELOC-NEXT: - Priority: 1001 -; RELOC-NEXT: FunctionIndex: 12 +; RELOC-NEXT: FunctionIndex: 11 ; RELOC-NEXT: - Priority: 2002 ; RELOC-NEXT: FunctionIndex: 13 ; RELOC-NEXT: - Priority: 2002 Index: test/wasm/load-undefined.test =================================================================== --- test/wasm/load-undefined.test +++ test/wasm/load-undefined.test @@ -22,9 +22,6 @@ ; CHECK-NEXT: - Name: ret64 ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: Index: test/wasm/local-symbols.ll =================================================================== --- test/wasm/local-symbols.ll +++ test/wasm/local-symbols.ll @@ -51,12 +51,6 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66576 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -65,9 +59,6 @@ ; CHECK-NEXT: - Name: _start ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 0 Index: test/wasm/locals-duplicate.test =================================================================== --- test/wasm/locals-duplicate.test +++ test/wasm/locals-duplicate.test @@ -36,12 +36,6 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66592 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66592 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -89,9 +83,6 @@ ; CHECK-NEXT: - Name: get_func3B ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 17 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: @@ -237,118 +228,6 @@ ; RELOC-NEXT: - Type: MEMORY ; RELOC-NEXT: Memories: ; RELOC-NEXT: - Initial: 0x00000001 -; RELOC-NEXT: - Type: GLOBAL -; RELOC-NEXT: Globals: -; RELOC-NEXT: - Index: 0 -; RELOC-NEXT: Type: I32 -; RELOC-NEXT: Mutable: false -; RELOC-NEXT: InitExpr: -; RELOC-NEXT: Opcode: I32_CONST -; RELOC-NEXT: Value: 0 -; RELOC-NEXT: - Index: 1 -; RELOC-NEXT: Type: I32 -; RELOC-NEXT: Mutable: false -; RELOC-NEXT: InitExpr: -; RELOC-NEXT: Opcode: I32_CONST -; RELOC-NEXT: Value: 8 -; RELOC-NEXT: - Index: 2 -; RELOC-NEXT: Type: I32 -; RELOC-NEXT: Mutable: false -; RELOC-NEXT: InitExpr: -; RELOC-NEXT: Opcode: I32_CONST -; RELOC-NEXT: Value: 16 -; RELOC-NEXT: - Index: 3 -; RELOC-NEXT: Type: I32 -; RELOC-NEXT: Mutable: false -; RELOC-NEXT: InitExpr: -; RELOC-NEXT: Opcode: I32_CONST -; RELOC-NEXT: Value: 4 -; RELOC-NEXT: - Index: 4 -; RELOC-NEXT: Type: I32 -; RELOC-NEXT: Mutable: false -; RELOC-NEXT: InitExpr: -; RELOC-NEXT: Opcode: I32_CONST -; RELOC-NEXT: Value: 12 -; RELOC-NEXT: - Index: 5 -; RELOC-NEXT: Type: I32 -; RELOC-NEXT: Mutable: false -; RELOC-NEXT: InitExpr: -; RELOC-NEXT: Opcode: I32_CONST -; RELOC-NEXT: Value: 20 -; RELOC-NEXT: - Type: EXPORT -; RELOC-NEXT: Exports: -; RELOC-NEXT: - Name: colliding_func1.1 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 0 -; RELOC-NEXT: - Name: colliding_func2 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 1 -; RELOC-NEXT: - Name: colliding_func3 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 2 -; RELOC-NEXT: - Name: get_global1A -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 3 -; RELOC-NEXT: - Name: get_global2A -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 4 -; RELOC-NEXT: - Name: get_global3A -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 5 -; RELOC-NEXT: - Name: get_func1A -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 6 -; RELOC-NEXT: - Name: get_func2A -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 7 -; RELOC-NEXT: - Name: get_func3A -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 8 -; RELOC-NEXT: - Name: colliding_func1 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 9 -; RELOC-NEXT: - Name: colliding_func2.1 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 10 -; RELOC-NEXT: - Name: colliding_func3.1 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 11 -; RELOC-NEXT: - Name: get_global1B -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 12 -; RELOC-NEXT: - Name: get_global2B -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 13 -; RELOC-NEXT: - Name: get_global3B -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 14 -; RELOC-NEXT: - Name: get_func1B -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 15 -; RELOC-NEXT: - Name: get_func2B -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 16 -; RELOC-NEXT: - Name: get_func3B -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 17 -; RELOC-NEXT: - Name: colliding_global1.1 -; RELOC-NEXT: Kind: GLOBAL -; RELOC-NEXT: Index: 0 -; RELOC-NEXT: - Name: colliding_global2 -; RELOC-NEXT: Kind: GLOBAL -; RELOC-NEXT: Index: 1 -; RELOC-NEXT: - Name: colliding_global3 -; RELOC-NEXT: Kind: GLOBAL -; RELOC-NEXT: Index: 2 -; RELOC-NEXT: - Name: colliding_global1 -; RELOC-NEXT: Kind: GLOBAL -; RELOC-NEXT: Index: 3 -; RELOC-NEXT: - Name: colliding_global2.1 -; RELOC-NEXT: Kind: GLOBAL -; RELOC-NEXT: Index: 4 -; RELOC-NEXT: - Name: colliding_global3.1 -; RELOC-NEXT: Kind: GLOBAL -; RELOC-NEXT: Index: 5 ; RELOC-NEXT: - Type: ELEM ; RELOC-NEXT: Segments: ; RELOC-NEXT: - Offset: @@ -358,13 +237,13 @@ ; RELOC-NEXT: - Type: CODE ; RELOC-NEXT: Relocations: ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 18 +; RELOC-NEXT: Index: 4 ; RELOC-NEXT: Offset: 0x00000013 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 19 +; RELOC-NEXT: Index: 6 ; RELOC-NEXT: Offset: 0x0000001C ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 20 +; RELOC-NEXT: Index: 8 ; RELOC-NEXT: Offset: 0x00000025 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB ; RELOC-NEXT: Index: 0 @@ -376,22 +255,22 @@ ; RELOC-NEXT: Index: 2 ; RELOC-NEXT: Offset: 0x00000040 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 21 +; RELOC-NEXT: Index: 16 ; RELOC-NEXT: Offset: 0x00000058 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 22 +; RELOC-NEXT: Index: 18 ; RELOC-NEXT: Offset: 0x00000061 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 23 +; RELOC-NEXT: Index: 20 ; RELOC-NEXT: Offset: 0x0000006A ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 9 +; RELOC-NEXT: Index: 12 ; RELOC-NEXT: Offset: 0x00000073 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 10 +; RELOC-NEXT: Index: 13 ; RELOC-NEXT: Offset: 0x0000007C ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 11 +; RELOC-NEXT: Index: 14 ; RELOC-NEXT: Offset: 0x00000085 ; RELOC-NEXT: Functions: ; RELOC-NEXT: - Index: 0 @@ -471,23 +350,136 @@ ; RELOC-NEXT: - Type: CUSTOM ; RELOC-NEXT: Name: linking ; RELOC-NEXT: DataSize: 24 -; RELOC-NEXT: SymbolInfo: -; RELOC-NEXT: - Name: colliding_func1.1 +; RELOC-NEXT: SymbolTable: +; RELOC-NEXT: - Index: 0 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: colliding_func1 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_func3 +; RELOC-NEXT: FunctionIndex: 0 +; RELOC-NEXT: - Index: 1 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: colliding_func2 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 1 +; RELOC-NEXT: - Index: 2 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: colliding_func3 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_func2.1 +; RELOC-NEXT: FunctionIndex: 2 +; RELOC-NEXT: - Index: 3 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_global1A +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 3 +; RELOC-NEXT: - Index: 4 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: colliding_global1 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_func3.1 +; RELOC-NEXT: SegmentIndex: 0 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 5 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_global2A +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 4 +; RELOC-NEXT: - Index: 6 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: colliding_global2 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: SegmentIndex: 1 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 7 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_global3A +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 5 +; RELOC-NEXT: - Index: 8 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: colliding_global3 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_global1.1 +; RELOC-NEXT: SegmentIndex: 2 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 9 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_func1A +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 6 +; RELOC-NEXT: - Index: 10 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_func2A +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 7 +; RELOC-NEXT: - Index: 11 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_func3A +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 8 +; RELOC-NEXT: - Index: 12 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: colliding_func1 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 9 +; RELOC-NEXT: - Index: 13 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: colliding_func2 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_global3 +; RELOC-NEXT: FunctionIndex: 10 +; RELOC-NEXT: - Index: 14 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: colliding_func3 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_global2.1 +; RELOC-NEXT: FunctionIndex: 11 +; RELOC-NEXT: - Index: 15 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_global1B +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 12 +; RELOC-NEXT: - Index: 16 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: colliding_global1 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: SegmentIndex: 0 +; RELOC-NEXT: Offset: 4 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 17 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_global2B +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 13 +; RELOC-NEXT: - Index: 18 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: colliding_global2 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_global3.1 +; RELOC-NEXT: SegmentIndex: 1 +; RELOC-NEXT: Offset: 4 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 19 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_global3B +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 14 +; RELOC-NEXT: - Index: 20 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: colliding_global3 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: SegmentIndex: 2 +; RELOC-NEXT: Offset: 4 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 21 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_func1B +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 15 +; RELOC-NEXT: - Index: 22 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_func2B +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 16 +; RELOC-NEXT: - Index: 23 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: get_func3B +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 17 ; RELOC-NEXT: SegmentInfo: ; RELOC-NEXT: - Index: 0 ; RELOC-NEXT: Name: .bss.colliding_global1 Index: test/wasm/many-functions.ll =================================================================== --- test/wasm/many-functions.ll +++ test/wasm/many-functions.ll @@ -19,394 +19,394 @@ ; CHECK: - Type: CODE ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000008 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000014 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000020 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000002C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000038 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000044 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000050 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000005C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000068 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000074 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000080 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000008C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000098 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000000A4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000000B0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000000BC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000000C8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000000D4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000000E0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000000EC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000000F8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000104 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000110 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000011C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000128 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000134 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000140 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000014C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000158 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000164 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000170 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000017C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000188 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000194 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000001A0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000001AC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000001B8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000001C4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000001D0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000001DC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000001E8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000001F4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000200 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000020C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000218 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000224 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000230 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000023C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000248 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000254 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000260 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000026C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000278 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000284 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000290 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000029C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000002A8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000002B4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000002C0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000002CC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000002D8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000002E4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000002F0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000002FC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000308 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000314 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000320 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000032C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000338 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000344 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000350 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000035C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000368 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000374 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000380 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000038C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000398 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000003A4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000003B0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000003BC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000003C8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000003D4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000003E0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000003EC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000003F8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000404 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000410 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000041C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000428 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000434 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000440 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000044C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000458 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000464 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000470 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000047C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000488 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000494 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000004A0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000004AC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000004B8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000004C4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000004D0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000004DC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000004E8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000004F4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000500 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000050C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000518 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000524 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000530 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000053C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000548 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000554 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000560 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000056C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000578 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000584 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000590 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000059C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000005A8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000005B4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000005C0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000005CC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000005D8 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000005E4 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 130 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x000005F0 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 129 ; CHECK-NEXT: Offset: 0x000005FC ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 129 ; CHECK-NEXT: Offset: 0x00000608 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; CHECK-NEXT: Index: 129 +; CHECK-NEXT: Index: 131 ; CHECK-NEXT: Offset: 0x00000611 ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 0 @@ -816,6 +816,669 @@ ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 8 +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: foo +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f2 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 1 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f3 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 2 +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f4 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: - Index: 5 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f5 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 4 +; CHECK-NEXT: - Index: 6 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f6 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 5 +; CHECK-NEXT: - Index: 7 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f7 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 6 +; CHECK-NEXT: - Index: 8 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f8 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 7 +; CHECK-NEXT: - Index: 9 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f9 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 8 +; CHECK-NEXT: - Index: 10 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f10 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 9 +; CHECK-NEXT: - Index: 11 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f11 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 10 +; CHECK-NEXT: - Index: 12 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f12 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 11 +; CHECK-NEXT: - Index: 13 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f13 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 12 +; CHECK-NEXT: - Index: 14 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f14 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 13 +; CHECK-NEXT: - Index: 15 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f15 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 14 +; CHECK-NEXT: - Index: 16 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f16 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 15 +; CHECK-NEXT: - Index: 17 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f17 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 16 +; CHECK-NEXT: - Index: 18 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f18 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 17 +; CHECK-NEXT: - Index: 19 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f19 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 18 +; CHECK-NEXT: - Index: 20 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f20 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 19 +; CHECK-NEXT: - Index: 21 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f21 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 20 +; CHECK-NEXT: - Index: 22 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f22 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 21 +; CHECK-NEXT: - Index: 23 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f23 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 22 +; CHECK-NEXT: - Index: 24 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f24 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 23 +; CHECK-NEXT: - Index: 25 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f25 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 24 +; CHECK-NEXT: - Index: 26 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f26 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 25 +; CHECK-NEXT: - Index: 27 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f27 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 26 +; CHECK-NEXT: - Index: 28 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f28 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 27 +; CHECK-NEXT: - Index: 29 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f29 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 28 +; CHECK-NEXT: - Index: 30 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f30 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 29 +; CHECK-NEXT: - Index: 31 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f31 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 30 +; CHECK-NEXT: - Index: 32 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f32 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 31 +; CHECK-NEXT: - Index: 33 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f33 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 32 +; CHECK-NEXT: - Index: 34 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f34 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 33 +; CHECK-NEXT: - Index: 35 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f35 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 34 +; CHECK-NEXT: - Index: 36 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f36 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 35 +; CHECK-NEXT: - Index: 37 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f37 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 36 +; CHECK-NEXT: - Index: 38 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f38 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 37 +; CHECK-NEXT: - Index: 39 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f39 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 38 +; CHECK-NEXT: - Index: 40 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f40 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 39 +; CHECK-NEXT: - Index: 41 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f41 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 40 +; CHECK-NEXT: - Index: 42 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f42 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 41 +; CHECK-NEXT: - Index: 43 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f43 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 42 +; CHECK-NEXT: - Index: 44 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f44 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 43 +; CHECK-NEXT: - Index: 45 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f45 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 44 +; CHECK-NEXT: - Index: 46 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f46 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 45 +; CHECK-NEXT: - Index: 47 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f47 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 46 +; CHECK-NEXT: - Index: 48 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f48 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 47 +; CHECK-NEXT: - Index: 49 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f49 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 48 +; CHECK-NEXT: - Index: 50 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f50 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 49 +; CHECK-NEXT: - Index: 51 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f51 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 50 +; CHECK-NEXT: - Index: 52 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f52 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 51 +; CHECK-NEXT: - Index: 53 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f53 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 52 +; CHECK-NEXT: - Index: 54 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f54 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 53 +; CHECK-NEXT: - Index: 55 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f55 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 54 +; CHECK-NEXT: - Index: 56 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f56 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 55 +; CHECK-NEXT: - Index: 57 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f57 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 56 +; CHECK-NEXT: - Index: 58 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f58 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 57 +; CHECK-NEXT: - Index: 59 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f59 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 58 +; CHECK-NEXT: - Index: 60 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f60 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 59 +; CHECK-NEXT: - Index: 61 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f61 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 60 +; CHECK-NEXT: - Index: 62 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f62 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 61 +; CHECK-NEXT: - Index: 63 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f63 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 62 +; CHECK-NEXT: - Index: 64 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f64 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 63 +; CHECK-NEXT: - Index: 65 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f65 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 64 +; CHECK-NEXT: - Index: 66 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f66 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 65 +; CHECK-NEXT: - Index: 67 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f67 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 66 +; CHECK-NEXT: - Index: 68 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f68 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 67 +; CHECK-NEXT: - Index: 69 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f69 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 68 +; CHECK-NEXT: - Index: 70 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f70 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 69 +; CHECK-NEXT: - Index: 71 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f71 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 70 +; CHECK-NEXT: - Index: 72 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f72 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 71 +; CHECK-NEXT: - Index: 73 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f73 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 72 +; CHECK-NEXT: - Index: 74 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f74 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 73 +; CHECK-NEXT: - Index: 75 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f75 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 74 +; CHECK-NEXT: - Index: 76 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f76 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 75 +; CHECK-NEXT: - Index: 77 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f77 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 76 +; CHECK-NEXT: - Index: 78 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f78 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 77 +; CHECK-NEXT: - Index: 79 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f79 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 78 +; CHECK-NEXT: - Index: 80 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f80 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 79 +; CHECK-NEXT: - Index: 81 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f81 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 80 +; CHECK-NEXT: - Index: 82 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f82 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 81 +; CHECK-NEXT: - Index: 83 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f83 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 82 +; CHECK-NEXT: - Index: 84 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f84 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 83 +; CHECK-NEXT: - Index: 85 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f85 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 84 +; CHECK-NEXT: - Index: 86 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f86 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 85 +; CHECK-NEXT: - Index: 87 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f87 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 86 +; CHECK-NEXT: - Index: 88 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f88 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 87 +; CHECK-NEXT: - Index: 89 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f89 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 88 +; CHECK-NEXT: - Index: 90 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f90 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 89 +; CHECK-NEXT: - Index: 91 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f91 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 90 +; CHECK-NEXT: - Index: 92 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f92 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 91 +; CHECK-NEXT: - Index: 93 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f93 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 92 +; CHECK-NEXT: - Index: 94 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f94 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 93 +; CHECK-NEXT: - Index: 95 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f95 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 94 +; CHECK-NEXT: - Index: 96 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f96 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 95 +; CHECK-NEXT: - Index: 97 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f97 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 96 +; CHECK-NEXT: - Index: 98 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f98 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 97 +; CHECK-NEXT: - Index: 99 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f99 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 98 +; CHECK-NEXT: - Index: 100 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f100 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 99 +; CHECK-NEXT: - Index: 101 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f101 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 100 +; CHECK-NEXT: - Index: 102 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f102 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 101 +; CHECK-NEXT: - Index: 103 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f103 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 102 +; CHECK-NEXT: - Index: 104 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f104 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 103 +; CHECK-NEXT: - Index: 105 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f105 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 104 +; CHECK-NEXT: - Index: 106 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f106 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 105 +; CHECK-NEXT: - Index: 107 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f107 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 106 +; CHECK-NEXT: - Index: 108 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f108 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 107 +; CHECK-NEXT: - Index: 109 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f109 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 108 +; CHECK-NEXT: - Index: 110 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f110 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 109 +; CHECK-NEXT: - Index: 111 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f111 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 110 +; CHECK-NEXT: - Index: 112 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f112 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 111 +; CHECK-NEXT: - Index: 113 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f113 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 112 +; CHECK-NEXT: - Index: 114 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f114 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 113 +; CHECK-NEXT: - Index: 115 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f115 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 114 +; CHECK-NEXT: - Index: 116 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f116 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 115 +; CHECK-NEXT: - Index: 117 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f117 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 116 +; CHECK-NEXT: - Index: 118 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f118 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 117 +; CHECK-NEXT: - Index: 119 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f119 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 118 +; CHECK-NEXT: - Index: 120 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f120 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 119 +; CHECK-NEXT: - Index: 121 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f121 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 120 +; CHECK-NEXT: - Index: 122 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f122 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 121 +; CHECK-NEXT: - Index: 123 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f123 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 122 +; CHECK-NEXT: - Index: 124 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f124 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 123 +; CHECK-NEXT: - Index: 125 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f125 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 124 +; CHECK-NEXT: - Index: 126 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f126 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 125 +; CHECK-NEXT: - Index: 127 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f127 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 126 +; CHECK-NEXT: - Index: 128 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f128 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 127 +; CHECK-NEXT: - Index: 129 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: g0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 130 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: f129 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 128 +; CHECK-NEXT: - Index: 131 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: func +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 129 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data.g0 Index: test/wasm/relocatable.ll =================================================================== --- test/wasm/relocatable.ll +++ test/wasm/relocatable.ll @@ -59,11 +59,6 @@ ; CHECK-NEXT: Field: bar_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, 2 ] ; CHECK-NEXT: - Type: TABLE @@ -76,73 +71,6 @@ ; CHECK-NEXT: - Type: MEMORY ; CHECK-NEXT: Memories: ; CHECK-NEXT: - Initial: 0x00000001 -; CHECK-NEXT: - Type: GLOBAL -; CHECK-NEXT: Globals: -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 -; CHECK-NEXT: - Index: 2 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 28 -; CHECK-NEXT: - Index: 3 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 8 -; CHECK-NEXT: - Index: 4 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 12 -; CHECK-NEXT: - Index: 5 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 16 -; CHECK-NEXT: - Index: 6 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 24 -; CHECK-NEXT: - Type: EXPORT -; CHECK-NEXT: Exports: -; CHECK-NEXT: - Name: hello -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 3 -; CHECK-NEXT: - Name: my_func -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 4 -; CHECK-NEXT: - Name: func_comdat -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 5 -; CHECK-NEXT: - Name: hello_str -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: data_comdat -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: func_addr1 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 3 -; CHECK-NEXT: - Name: func_addr2 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 4 -; CHECK-NEXT: - Name: func_addr3 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 5 -; CHECK-NEXT: - Name: data_addr1 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 6 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: @@ -152,16 +80,16 @@ ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; CHECK-NEXT: Index: 7 +; CHECK-NEXT: Index: 2 ; 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: Index: 3 ; CHECK-NEXT: Offset: 0x00000013 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; CHECK-NEXT: Index: 2 +; CHECK-NEXT: Index: 4 ; CHECK-NEXT: Offset: 0x0000001A ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB ; CHECK-NEXT: Index: 8 @@ -179,16 +107,16 @@ ; CHECK-NEXT: - Type: DATA ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 -; CHECK-NEXT: Index: 5 +; CHECK-NEXT: Index: 6 ; CHECK-NEXT: Offset: 0x00000012 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 3 ; CHECK-NEXT: Offset: 0x0000001B ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 -; CHECK-NEXT: Index: 2 +; CHECK-NEXT: Index: 4 ; CHECK-NEXT: Offset: 0x00000024 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 -; CHECK-NEXT: Index: 3 +; CHECK-NEXT: Index: 5 ; CHECK-NEXT: Offset: 0x0000002D ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 @@ -230,25 +158,77 @@ ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 31 -; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: bar_import +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: puts +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: hello +; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: hello_str +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: Size: 7 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: foo_import +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 1 +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: bar_import ; CHECK-NEXT: Flags: [ BINDING_WEAK ] -; CHECK-NEXT: - Name: hello +; CHECK-NEXT: FunctionIndex: 2 +; CHECK-NEXT: - Index: 5 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: data_import +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: - Index: 6 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: my_func ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: my_func -; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: func_comdat +; CHECK-NEXT: FunctionIndex: 4 +; CHECK-NEXT: - Index: 7 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: func_comdat ; CHECK-NEXT: Flags: [ BINDING_WEAK ] -; CHECK-NEXT: - Name: data_comdat +; CHECK-NEXT: FunctionIndex: 5 +; CHECK-NEXT: - Index: 8 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: data_comdat ; CHECK-NEXT: Flags: [ BINDING_WEAK ] -; CHECK-NEXT: - Name: func_addr1 +; CHECK-NEXT: SegmentIndex: 5 +; CHECK-NEXT: Size: 3 +; CHECK-NEXT: - Index: 9 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: func_addr1 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: func_addr2 +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 10 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: func_addr2 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: func_addr3 +; CHECK-NEXT: SegmentIndex: 2 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 11 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: func_addr3 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: data_addr1 +; CHECK-NEXT: SegmentIndex: 3 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 12 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: data_addr1 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: SegmentIndex: 4 +; CHECK-NEXT: Size: 4 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .rodata.hello_str Index: test/wasm/signature-mismatch.ll =================================================================== --- test/wasm/signature-mismatch.ll +++ test/wasm/signature-mismatch.ll @@ -13,6 +13,6 @@ declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1 -; CHECK: error: function signature mismatch: ret32 +; 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 Index: test/wasm/stack-pointer.ll =================================================================== --- test/wasm/stack-pointer.ll +++ test/wasm/stack-pointer.ll @@ -26,7 +26,7 @@ ; CHECK-NEXT: Field: __stack_pointer ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: GlobalType: I32 -; CHECK-NEXT: GlobalMutable: false +; CHECK-NEXT: GlobalMutable: true ; CHECK-NEXT: - Type: FUNCTION ; CHECK-NEXT: FunctionTypes: [ 0 ] ; CHECK-NEXT: - Type: TABLE @@ -39,11 +39,6 @@ ; CHECK-NEXT: - Type: MEMORY ; CHECK-NEXT: Memories: ; CHECK-NEXT: - Initial: 0x00000000 -; CHECK-NEXT: - Type: EXPORT -; CHECK-NEXT: Exports: -; 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 @@ -56,6 +51,17 @@ ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 0 +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Name: __stack_pointer +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: GlobalIndex: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: _start +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: name ; CHECK-NEXT: FunctionNames: Index: test/wasm/symbol-type-mismatch.ll =================================================================== --- test/wasm/symbol-type-mismatch.ll +++ test/wasm/symbol-type-mismatch.ll @@ -7,5 +7,5 @@ @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 Data in {{.*}}symbol-type-mismatch.ll.tmp.o ; CHECK: >>> defined as Function in {{.*}}.ret32.o Index: test/wasm/visibility-hidden.ll =================================================================== --- test/wasm/visibility-hidden.ll +++ test/wasm/visibility-hidden.ll @@ -45,7 +45,4 @@ ; CHECK-NEXT: - Name: archiveDefault ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 4 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: Index: test/wasm/weak-alias-overide.ll =================================================================== --- test/wasm/weak-alias-overide.ll +++ test/wasm/weak-alias-overide.ll @@ -51,12 +51,6 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66560 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -83,9 +77,6 @@ ; CHECK-NEXT: - Name: call_direct_ptr ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 6 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/weak-alias.ll =================================================================== --- test/wasm/weak-alias.ll +++ test/wasm/weak-alias.ll @@ -48,12 +48,6 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66560 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -80,9 +74,6 @@ ; CHECK-NEXT: - Name: alias_fn ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: @@ -156,7 +147,7 @@ ; RELOC-NEXT: Field: __stack_pointer ; RELOC-NEXT: Kind: GLOBAL ; RELOC-NEXT: GlobalType: I32 -; RELOC-NEXT: GlobalMutable: false +; RELOC-NEXT: GlobalMutable: true ; RELOC-NEXT: - Type: FUNCTION ; RELOC-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0, 0 ] ; RELOC-NEXT: - Type: TABLE @@ -169,29 +160,6 @@ ; RELOC-NEXT: - Type: MEMORY ; RELOC-NEXT: Memories: ; RELOC-NEXT: - Initial: 0x00000000 -; RELOC-NEXT: - Type: EXPORT -; RELOC-NEXT: Exports: -; RELOC-NEXT: - Name: _start -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 0 -; RELOC-NEXT: - Name: direct_fn -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 1 -; RELOC-NEXT: - Name: call_direct -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 2 -; RELOC-NEXT: - Name: call_alias -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 3 -; RELOC-NEXT: - Name: call_alias_ptr -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 4 -; RELOC-NEXT: - Name: call_direct_ptr -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 5 -; RELOC-NEXT: - Name: alias_fn -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Index: 1 ; RELOC-NEXT: - Type: ELEM ; RELOC-NEXT: Segments: ; RELOC-NEXT: - Offset: @@ -210,10 +178,10 @@ ; RELOC-NEXT: Index: 7 ; RELOC-NEXT: Offset: 0x0000001B ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB -; RELOC-NEXT: Index: 0 +; RELOC-NEXT: Index: 1 ; RELOC-NEXT: Offset: 0x00000026 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB -; RELOC-NEXT: Index: 0 +; RELOC-NEXT: Index: 1 ; RELOC-NEXT: Offset: 0x00000031 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB ; RELOC-NEXT: Index: 7 @@ -222,13 +190,13 @@ ; RELOC-NEXT: Index: 7 ; RELOC-NEXT: Offset: 0x00000042 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB -; RELOC-NEXT: Index: 0 +; RELOC-NEXT: Index: 1 ; RELOC-NEXT: Offset: 0x0000004F ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB -; RELOC-NEXT: Index: 0 +; RELOC-NEXT: Index: 1 ; RELOC-NEXT: Offset: 0x0000005C ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB -; RELOC-NEXT: Index: 0 +; RELOC-NEXT: Index: 1 ; RELOC-NEXT: Offset: 0x00000067 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB ; RELOC-NEXT: Index: 2 @@ -237,7 +205,7 @@ ; RELOC-NEXT: Index: 2 ; RELOC-NEXT: Offset: 0x00000078 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB -; RELOC-NEXT: Index: 0 +; RELOC-NEXT: Index: 1 ; RELOC-NEXT: Offset: 0x00000085 ; RELOC-NEXT: Functions: ; RELOC-NEXT: - Index: 0 @@ -265,9 +233,47 @@ ; RELOC-NEXT: - Type: CUSTOM ; RELOC-NEXT: Name: linking ; RELOC-NEXT: DataSize: 0 -; RELOC-NEXT: SymbolInfo: -; RELOC-NEXT: - Name: alias_fn +; RELOC-NEXT: SymbolTable: +; RELOC-NEXT: - Index: 0 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: _start +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 0 +; RELOC-NEXT: - Index: 1 +; RELOC-NEXT: Kind: GLOBAL +; RELOC-NEXT: Name: __stack_pointer +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: GlobalIndex: 0 +; RELOC-NEXT: - Index: 2 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: direct_fn +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 1 +; RELOC-NEXT: - Index: 3 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: call_direct +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 2 +; RELOC-NEXT: - Index: 4 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: call_alias +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 3 +; RELOC-NEXT: - Index: 5 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: call_alias_ptr +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 4 +; RELOC-NEXT: - Index: 6 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: call_direct_ptr +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 5 +; RELOC-NEXT: - Index: 7 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: alias_fn ; RELOC-NEXT: Flags: [ BINDING_WEAK ] +; RELOC-NEXT: FunctionIndex: 1 ; RELOC-NEXT: - Type: CUSTOM ; RELOC-NEXT: Name: name ; RELOC-NEXT: FunctionNames: Index: test/wasm/weak-symbols.ll =================================================================== --- test/wasm/weak-symbols.ll +++ test/wasm/weak-symbols.ll @@ -48,12 +48,6 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66576 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66576 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -71,9 +65,6 @@ ; CHECK-NEXT: - Name: exportWeak2 ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 4 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: test/wasm/weak-undefined.ll =================================================================== --- test/wasm/weak-undefined.ll +++ test/wasm/weak-undefined.ll @@ -58,12 +58,6 @@ ; CHECK-NEXT: InitExpr: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 66560 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 66560 ; CHECK-NEXT: - Type: EXPORT ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: memory @@ -78,9 +72,6 @@ ; CHECK-NEXT: - Name: _start ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: __heap_base -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 0 Index: wasm/Config.h =================================================================== --- wasm/Config.h +++ wasm/Config.h @@ -41,6 +41,7 @@ Symbol *StackPointerSymbol = nullptr; Symbol *HeapBaseSymbol = nullptr; Symbol *CtorSymbol = nullptr; + llvm::wasm::ValType PtrType = llvm::wasm::ValType::I32; }; // The only instance of Configuration struct. Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -292,9 +292,11 @@ Symbol *EntrySym = nullptr; if (!Config->Relocatable) { - static WasmSignature Signature = {{}, WASM_TYPE_NORESULT}; + static WasmSignature EntrySignature = {{}, WASM_TYPE_NORESULT}; + static WasmGlobalType StackPointerSignature = + {static_cast(Config->PtrType), true}; if (!Config->Entry.empty()) - EntrySym = Symtab->addUndefinedFunction(Config->Entry, &Signature); + EntrySym = Symtab->addUndefinedFunction(Config->Entry, &EntrySignature); // Handle the `--undefined ` options. for (auto* Arg : Args.filtered(OPT_undefined)) @@ -309,10 +311,15 @@ // __dso_handle; // Global in calls to __cxa_atexit to determine current DLL Config->CtorSymbol = Symtab->addDefinedFunction( - "__wasm_call_ctors", &Signature, WASM_SYMBOL_VISIBILITY_HIDDEN); - Config->StackPointerSymbol = Symtab->addDefinedGlobal("__stack_pointer"); - Config->HeapBaseSymbol = Symtab->addDefinedGlobal("__heap_base"); - Symtab->addDefinedGlobal("__dso_handle")->setVirtualAddress(0); + "__wasm_call_ctors", &EntrySignature, WASM_SYMBOL_VISIBILITY_HIDDEN); + Config->StackPointerSymbol = Symtab->addDefinedGlobal( + "__stack_pointer", &StackPointerSignature, + // Can't export the SP right now because it's mutable, and mutable + // globals aren't yet supported in the official binary format. + // TODO(sbc): Remove this if/when the "mutable global" proposal is accepted. + WASM_SYMBOL_VISIBILITY_HIDDEN); + Config->HeapBaseSymbol = Symtab->addDefinedData("__heap_base"); + Symtab->addDefinedData("__dso_handle")->setVirtualAddress(0); } createFiles(Args); Index: wasm/InputChunks.h =================================================================== --- wasm/InputChunks.h +++ wasm/InputChunks.h @@ -23,8 +23,10 @@ using llvm::object::WasmSegment; using llvm::wasm::WasmFunction; +using llvm::wasm::WasmGlobal; using llvm::wasm::WasmRelocation; using llvm::wasm::WasmSignature; +using llvm::wasm::WasmInitExpr; using llvm::object::WasmSection; namespace lld { @@ -35,9 +37,9 @@ class InputChunk { public: - enum Kind { DataSegment, Function }; + enum Kind { DataSegment, Function, Global }; - Kind kind() const { return SectionKind; }; + Kind kind() const { return SectionKind; } uint32_t getSize() const { return data().size(); } @@ -56,6 +58,8 @@ virtual StringRef getComdat() const = 0; virtual StringRef getName() const = 0; + virtual bool hasOutputIndex() const = 0; + virtual uint32_t getOutputIndex() const = 0; bool Discarded = false; std::vector OutRelocations; @@ -109,6 +113,8 @@ uint32_t endVA() const { return startVA() + getSize(); } StringRef getName() const override { return Segment.Data.Name; } StringRef getComdat() const override { return Segment.Data.Comdat; } + bool hasOutputIndex() const override { return OutputSeg != nullptr; } + uint32_t getOutputIndex() const override; int32_t OutputSegmentOffset = 0; @@ -136,8 +142,8 @@ StringRef getName() const override { return Function->Name; } StringRef getComdat() const override { return Function->Comdat; } - uint32_t getOutputIndex() const { return OutputIndex.getValue(); } - bool hasOutputIndex() const { return OutputIndex.hasValue(); } + uint32_t getOutputIndex() const override { return OutputIndex.getValue(); } + bool hasOutputIndex() const override { return OutputIndex.hasValue(); } void setOutputIndex(uint32_t Index); uint32_t getTableIndex() const { return TableIndex.getValue(); } bool hasTableIndex() const { return TableIndex.hasValue(); } @@ -163,7 +169,8 @@ public: SyntheticFunction(const WasmSignature &S, ArrayRef Body, StringRef Name) - : InputFunction(S, nullptr, nullptr), Name(Name), Body(Body) {} + : InputFunction(S, nullptr, nullptr), Name(Name), Body(Body) + { Live = true; } StringRef getName() const override { return Name; } @@ -174,6 +181,47 @@ ArrayRef Body; }; +// Represents a single Wasm Global within an input file. These are combined to +// form the final GLOBALS section. +class InputGlobal : public InputChunk { +public: + InputGlobal(const WasmGlobalType &Signature, const WasmGlobal *G, + const ObjFile *F) + : InputChunk(F, InputChunk::Global), Signature(Signature), Global(G) {} + + static bool classof(const InputChunk *C) { + return C->kind() == InputChunk::Global; + } + + virtual const WasmInitExpr &initExpr() const { return Global->InitExpr; } + StringRef getComdat() const override { return StringRef(); } + uint32_t getOutputIndex() const override { return OutputIndex.getValue(); } + bool hasOutputIndex() const override { return OutputIndex.hasValue(); } + void setOutputIndex(uint32_t Index); + + const WasmGlobalType &Signature; + +protected: + StringRef getName() const override { return {}; } + ArrayRef data() const override { return {}; } + uint32_t getInputSectionOffset() const override { return 0; } + + const WasmGlobal *Global; + llvm::Optional OutputIndex; +}; + +class SyntheticGlobal : public InputGlobal { +public: + SyntheticGlobal(const WasmGlobalType &Signature, const WasmInitExpr &InitExpr) + : InputGlobal(Signature, nullptr, nullptr), InitExpr(InitExpr) + { Live = true; } + + const WasmInitExpr &initExpr() const override { return InitExpr; } + +protected: + const WasmInitExpr InitExpr; +}; + } // namespace wasm } // namespace lld Index: wasm/InputChunks.cpp =================================================================== --- wasm/InputChunks.cpp +++ wasm/InputChunks.cpp @@ -22,7 +22,7 @@ using namespace lld::wasm; uint32_t InputSegment::translateVA(uint32_t Address) const { - assert(Address >= startVA() && Address < endVA()); + assert(Address >= startVA() && Address <= endVA()); int32_t Delta = OutputSeg->StartVA + OutputSegmentOffset - startVA(); DEBUG(dbgs() << "translateVA: " << getName() << " Delta=" << Delta << " Address=" << Address << "\n"); @@ -112,6 +112,10 @@ } } +uint32_t InputSegment::getOutputIndex() const { + return OutputSeg->Index; +} + void InputFunction::setOutputIndex(uint32_t Index) { DEBUG(dbgs() << "InputFunction::setOutputIndex: " << getName() << " -> " << Index << "\n"); assert(!hasOutputIndex()); @@ -123,3 +127,10 @@ assert(!hasTableIndex()); TableIndex = Index; } + + +void InputGlobal::setOutputIndex(uint32_t Index) { + DEBUG(dbgs() << "InputGlobal::setOutputIndex: " << Index << "\n"); + assert(!hasOutputIndex()); + OutputIndex = Index; +} Index: wasm/InputFiles.h =================================================================== --- wasm/InputFiles.h +++ wasm/InputFiles.h @@ -35,6 +35,7 @@ class InputChunk; class InputFunction; +class InputGlobal; class InputSegment; class InputFile { @@ -101,10 +102,12 @@ std::vector TypeMap; std::vector Segments; + std::vector Globals; std::vector Functions; ArrayRef getSymbols() const { return Symbols; } Symbol *getFunctionSymbol(uint32_t Index) const; + Symbol *getDataSymbol(uint32_t Index) const; Symbol *getGlobalSymbol(uint32_t Index) const; private: @@ -115,17 +118,20 @@ uint32_t relocateTableIndex(uint32_t Original) const; uint32_t relocateFunctionSymbolIndex(uint32_t Original) const; uint32_t relocateGlobalSymbolIndex(uint32_t Original) const; + uint32_t relocateDataSymbolIndex(uint32_t Original) const; Symbol *createDefined(const WasmSymbol &Sym, Symbol::Kind Kind, InputChunk *Chunk = nullptr, - uint32_t Address = UINT32_MAX); - Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind, - const WasmSignature *Signature = nullptr); + uint32_t DataAddress = UINT32_MAX, + uint32_t DataSize = 0); + Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind); + void initializeSymbols(); InputSegment *getSegment(const WasmSymbol &WasmSym) const; - const WasmSignature *getFunctionSig(const WasmSymbol &Sym) const; - uint32_t getGlobalValue(const WasmSymbol &Sym) const; + std::pair getDataAddressAndSize( + const WasmSymbol &WasmSym) const; InputFunction *getFunction(const WasmSymbol &Sym) const; + InputGlobal *getGlobal(const WasmSymbol &Sym) const; bool isExcludedByComdat(InputChunk *Chunk) const; // List of all symbols referenced or defined by this file. Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -47,8 +47,8 @@ " Symbols : " + Twine(Symbols.size()) + "\n"); } -uint32_t ObjFile::relocateVirtualAddress(uint32_t GlobalIndex) const { - return getGlobalSymbol(GlobalIndex)->getVirtualAddress(); +uint32_t ObjFile::relocateVirtualAddress(uint32_t Index) const { + return getDataSymbol(Index)->getVirtualAddress(); } uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const { @@ -97,6 +97,14 @@ return Index; } +uint32_t ObjFile::relocateDataSymbolIndex(uint32_t Original) const { + Symbol *Sym = getDataSymbol(Original); + uint32_t Index = Sym->getOutputSymbolIndex(); + DEBUG(dbgs() << "relocateDataSymbolIndex: " << toString(*Sym) << ": " + << Original << " -> " << Index << "\n"); + return Index; +} + // Relocations contain an index into the function, global or table index // space of the input file. This function takes a relocation and returns the // relocated index (i.e. translates from the input index space to the output @@ -110,10 +118,11 @@ case R_WEBASSEMBLY_TABLE_INDEX_SLEB: return relocateFunctionSymbolIndex(Reloc.Index); case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: + return relocateGlobalSymbolIndex(Reloc.Index); case R_WEBASSEMBLY_MEMORY_ADDR_LEB: case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: case R_WEBASSEMBLY_MEMORY_ADDR_I32: - return relocateGlobalSymbolIndex(Reloc.Index); + return relocateDataSymbolIndex(Reloc.Index); default: llvm_unreachable("unknown relocation type"); } @@ -169,35 +178,14 @@ // Return the InputSegment in which a given symbol is defined. InputSegment *ObjFile::getSegment(const WasmSymbol &WasmSym) const { - uint32_t Address = WasmObj->getWasmSymbolValue(WasmSym); - for (InputSegment *Segment : Segments) { - if (Address >= Segment->startVA() && Address < Segment->endVA()) { - DEBUG(dbgs() << "Found symbol in segment: " << WasmSym.Name << " -> " - << Segment->getName() << "\n"); - - return Segment; - } - } - error("symbol not found in any segment: " + WasmSym.Name); - return nullptr; + return Segments[WasmSym.Segment.getValue().Segment]; } -// Get the value stored in the wasm global represented by this symbol. -// This represents the virtual address of the symbol in the input file. -uint32_t ObjFile::getGlobalValue(const WasmSymbol &Sym) const { - assert(Sym.ElementIndex >= NumGlobalImports); - const WasmGlobal &Global = - getWasmObj()->globals()[Sym.ElementIndex - NumGlobalImports]; - assert(Global.Type.Type == llvm::wasm::WASM_TYPE_I32); - return Global.InitExpr.Value.Int32; -} - -// Get the signature for a given function symbol, either by looking -// it up in function sections (for defined functions), of the imports section -// (for imported functions). -const WasmSignature *ObjFile::getFunctionSig(const WasmSymbol &Sym) const { - DEBUG(dbgs() << "getFunctionSig: " << Sym.Name << "\n"); - return &WasmObj->types()[Sym.FunctionType]; +std::pair ObjFile::getDataAddressAndSize( + const WasmSymbol &WasmSym) const { + auto &Segment = WasmSym.Segment.getValue(); + return std::make_pair(getSegment(WasmSym)->startVA() + Segment.Offset, + Segment.Size); } InputFunction *ObjFile::getFunction(const WasmSymbol &Sym) const { @@ -206,6 +194,12 @@ return Functions[FunctionIndex]; } +InputGlobal *ObjFile::getGlobal(const WasmSymbol &Sym) const { + assert(Sym.ElementIndex >= NumGlobalImports); + uint32_t GlobalIndex = Sym.ElementIndex - NumGlobalImports; + return Globals[GlobalIndex]; +} + bool ObjFile::isExcludedByComdat(InputChunk *Chunk) const { StringRef Comdat = Chunk->getComdat(); return !Comdat.empty() && Symtab->findComdat(Comdat) != this; @@ -217,6 +211,12 @@ return Sym; } +Symbol *ObjFile::getDataSymbol(uint32_t Index) const { + Symbol *Sym = Symbols[Index]; + assert(Sym->isData()); + return Sym; +} + Symbol *ObjFile::getGlobalSymbol(uint32_t Index) const { Symbol *Sym = Symbols[Index]; assert(Sym->isGlobal()); @@ -242,6 +242,12 @@ Segments.emplace_back(Seg); } + for (const WasmGlobal &G : WasmObj->globals()) { + const WasmGlobalType &Sig = G.Type; + InputGlobal *Global = make(Sig, &G, this); + Globals.emplace_back(Global); + } + for (size_t I = 0; I < Funcs.size(); ++I) { const WasmFunction &Func = Funcs[I]; const WasmSignature &Sig = Types[FuncTypes[I]]; @@ -250,38 +256,49 @@ Functions.emplace_back(F); } - // Populate `FunctionSymbols` and `GlobalSymbols` based on the WasmSymbols - // in the object + // Populate `Symbols` based on the WasmSymbols in the object for (const SymbolRef &Sym : WasmObj->symbols()) { const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl()); Symbol *S; switch (WasmSym.Type) { - case WasmSymbol::SymbolType::FUNCTION_EXPORT: { - InputFunction *Function = getFunction(WasmSym); - if (!isExcludedByComdat(Function)) { - S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionKind, Function); - break; - } else { - Function->Discarded = true; - LLVM_FALLTHROUGH; // Exclude function, and add the symbol as undefined + case WasmSymbol::SymbolType::FUNCTION: + if (WasmSym.ElementIndex >= NumFunctionImports) { + InputFunction *Function = getFunction(WasmSym); + if (!isExcludedByComdat(Function)) { + S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionKind, + Function); + break; + } else { + Function->Discarded = true; + // Exclude function, and add the symbol as undefined + } } - } - case WasmSymbol::SymbolType::FUNCTION_IMPORT: - S = createUndefined(WasmSym, Symbol::Kind::UndefinedFunctionKind, - getFunctionSig(WasmSym)); + S = createUndefined(WasmSym, Symbol::Kind::UndefinedFunctionKind); break; - case WasmSymbol::SymbolType::GLOBAL_EXPORT: { - InputSegment *Segment = getSegment(WasmSym); - if (!isExcludedByComdat(Segment)) { - S = createDefined(WasmSym, Symbol::Kind::DefinedGlobalKind, Segment, - getGlobalValue(WasmSym)); - break; - } else { - Segment->Discarded = true; - LLVM_FALLTHROUGH; // Exclude global, and add the symbol as undefined + + case WasmSymbol::SymbolType::DATA: + if (WasmSym.Segment.hasValue()) { + InputSegment *Segment = getSegment(WasmSym); + if (!isExcludedByComdat(Segment)) { + uint32_t DataAddress, DataSize; + std::tie(DataAddress, DataSize) = getDataAddressAndSize(WasmSym); + S = createDefined(WasmSym, Symbol::Kind::DefinedDataKind, Segment, + DataAddress, DataSize); + break; + } else { + Segment->Discarded = true; + // Exclude data, and add the symbol as undefined + } + } + S = createUndefined(WasmSym, Symbol::Kind::UndefinedDataKind); + break; + + case WasmSymbol::SymbolType::GLOBAL: + if (WasmSym.ElementIndex >= NumGlobalImports) { + InputGlobal *Global = getGlobal(WasmSym); + S = createDefined(WasmSym, Symbol::Kind::DefinedGlobalKind, Global); + break; } - } - case WasmSymbol::SymbolType::GLOBAL_IMPORT: S = createUndefined(WasmSym, Symbol::Kind::UndefinedGlobalKind); break; } @@ -290,20 +307,22 @@ } } -Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind, - const WasmSignature *Signature) { - return Symtab->addUndefined(Sym.Name, Kind, Sym.Flags, this, Signature); +Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind) { + return Symtab->addUndefined(Sym.Name, Kind, Sym.Flags, this, Sym.FunctionType, + Sym.GlobalType); } Symbol *ObjFile::createDefined(const WasmSymbol &Sym, Symbol::Kind Kind, - InputChunk *Chunk, uint32_t Address) { + InputChunk *Chunk, uint32_t DataAddress, + uint32_t DataSize) { Symbol *S; if (Sym.isBindingLocal()) { S = make(Sym.Name, true); - S->update(Kind, this, Sym.Flags, Chunk, Address); + S->update(Kind, this, Sym.Flags, Chunk, DataAddress, DataSize); return S; } - return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Chunk, Address); + return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Chunk, DataAddress, + DataSize); } void ArchiveFile::parse() { Index: wasm/MarkLive.cpp =================================================================== --- wasm/MarkLive.cpp +++ wasm/MarkLive.cpp @@ -77,10 +77,12 @@ Enqueue(Chunk.File->getFunctionSymbol(Reloc.Index)); break; case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: + Enqueue(Chunk.File->getGlobalSymbol(Reloc.Index)); + break; case R_WEBASSEMBLY_MEMORY_ADDR_LEB: case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: case R_WEBASSEMBLY_MEMORY_ADDR_I32: - Enqueue(Chunk.File->getGlobalSymbol(Reloc.Index)); + Enqueue(Chunk.File->getDataSymbol(Reloc.Index)); break; } } @@ -100,6 +102,8 @@ for (const ObjFile *Obj : Symtab->ObjectFiles) { for (InputChunk *C : Obj->Functions) CheckChunk(C); + for (InputChunk *C : Obj->Globals) + CheckChunk(C); for (InputChunk *C : Obj->Segments) CheckChunk(C); } Index: wasm/OutputSegment.h =================================================================== --- wasm/OutputSegment.h +++ wasm/OutputSegment.h @@ -21,7 +21,7 @@ class OutputSegment { public: - OutputSegment(StringRef N) : Name(N) {} + OutputSegment(StringRef N, uint32_t Index) : Name(N), Index(Index) {} void addInputSegment(InputSegment *Segment) { Alignment = std::max(Alignment, Segment->getAlignment()); @@ -36,6 +36,7 @@ void setSectionOffset(uint32_t Offset) { SectionOffset = Offset; } StringRef Name; + const uint32_t Index; uint32_t Alignment = 0; uint32_t StartVA = 0; std::vector InputSegments; Index: wasm/SymbolTable.h =================================================================== --- wasm/SymbolTable.h +++ wasm/SymbolTable.h @@ -18,6 +18,7 @@ #include "llvm/Support/raw_ostream.h" using llvm::wasm::WasmSignature; +using llvm::wasm::WasmGlobalType; namespace lld { namespace wasm { @@ -51,13 +52,17 @@ Symbol *addDefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags, InputFile *F, InputChunk *Chunk = nullptr, - uint32_t Address = 0); + uint32_t DataAddress = UINT32_MAX, uint32_t DataSize = 0); Symbol *addUndefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags, - InputFile *F, const WasmSignature *Signature = nullptr); + InputFile *F, + const WasmSignature *FunctionSignature = nullptr, + const WasmGlobalType *GlobalSignature = nullptr); Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type); - Symbol *addDefinedGlobal(StringRef Name); Symbol *addDefinedFunction(StringRef Name, const WasmSignature *Type, - uint32_t Flags); + uint32_t Flags = 0); + Symbol *addDefinedData(StringRef Name, uint32_t Flags = 0); + Symbol *addDefinedGlobal(StringRef Name, const WasmGlobalType *Type, + uint32_t Flags = 0); void addLazy(ArchiveFile *F, const Archive::Symbol *Sym); bool addComdat(StringRef Name, ObjFile *); Index: wasm/SymbolTable.cpp =================================================================== --- wasm/SymbolTable.cpp +++ wasm/SymbolTable.cpp @@ -81,50 +81,73 @@ // Check the type of new symbol matches that of the symbol is replacing. // For functions this can also involve verifying that the signatures match. static void checkSymbolTypes(const Symbol &Existing, const InputFile &F, - Symbol::Kind Kind, const WasmSignature *NewSig) { + Symbol::Kind Kind, + const WasmSignature *NewFunctionSig, + const WasmGlobalType *NewGlobalSig) { if (Existing.isLazy()) return; - bool NewIsFunction = Kind == Symbol::Kind::UndefinedFunctionKind || - Kind == Symbol::Kind::DefinedFunctionKind; + WasmSymbol::SymbolType NewType = toWasmType(Kind); + WasmSymbol::SymbolType ExistingType = toWasmType(Existing.getKind()); // First check the symbol types match (i.e. either both are function // symbols or both are data symbols). - if (Existing.isFunction() != NewIsFunction) { + if (NewType != ExistingType) { error("symbol type mismatch: " + Existing.getName() + "\n>>> defined as " + - (Existing.isFunction() ? "Function" : "Global") + " in " + - toString(Existing.getFile()) + "\n>>> defined as " + - (NewIsFunction ? "Function" : "Global") + " in " + F.getName()); + toString(ExistingType) + " in " + toString(Existing.getFile()) + + "\n>>> defined as " + toString(NewType) + " in " + F.getName()); return; } - // For function symbols, optionally check the function signature matches too. - if (!NewIsFunction || !Config->CheckSignatures) - return; - // Skip the signature check if the existing function has no signature (e.g. - // if it is an undefined symbol generated by --undefined command line flag). - if (!Existing.hasFunctionType()) + // For function/global symbols, optionally check the signature matches too. + if (NewType == WasmSymbol::SymbolType::DATA || !Config->CheckSignatures) return; DEBUG(dbgs() << "checkSymbolTypes: " << Existing.getName() << "\n"); - assert(NewSig); - const WasmSignature &OldSig = Existing.getFunctionType(); - if (*NewSig == OldSig) - return; + std::string OldSigStr, NewSigStr; + if (NewType == WasmSymbol::SymbolType::FUNCTION) { + // Skip the signature check if the existing function has no signature (e.g. + // if it is an undefined symbol generated by --undefined command line flag). + if (!Existing.hasFunctionType()) + return; - error("function signature mismatch: " + Existing.getName() + - "\n>>> defined as " + toString(OldSig) + " in " + - toString(Existing.getFile()) + "\n>>> defined as " + toString(*NewSig) + + assert(NewFunctionSig != nullptr); + const WasmSignature& OldSig = Existing.getFunctionType(); + if (*NewFunctionSig == OldSig) + return; + + OldSigStr = toString(OldSig); + NewSigStr = toString(*NewFunctionSig); + } else { + assert(NewType == WasmSymbol::SymbolType::GLOBAL); + if (!Existing.hasGlobalType()) + return; + + assert(NewGlobalSig != nullptr); + const WasmGlobalType &OldSig = Existing.getGlobalType(); + if (*NewGlobalSig == OldSig) + return; + + OldSigStr = toString(OldSig); + NewSigStr = toString(*NewGlobalSig); + } + + error(toString(NewType) + " signature mismatch: " + Existing.getName() + + "\n>>> defined as " + OldSigStr + " in " + + toString(Existing.getFile()) + "\n>>> defined as " + NewSigStr + " in " + F.getName()); } static void checkSymbolTypes(const Symbol &Existing, const InputFile &F, Symbol::Kind Kind, const InputChunk *Chunk) { - const WasmSignature *Sig = nullptr; - if (auto *F = dyn_cast_or_null(Chunk)) - Sig = &F->Signature; - return checkSymbolTypes(Existing, F, Kind, Sig); + const WasmSignature *FunctionSig = nullptr; + if (auto *Function = dyn_cast_or_null(Chunk)) + FunctionSig = &Function->Signature; + const WasmGlobalType *GlobalSig = nullptr; + if (auto *Global = dyn_cast_or_null(Chunk)) + GlobalSig = &Global->Signature; + return checkSymbolTypes(Existing, F, Kind, FunctionSig, GlobalSig); } Symbol *SymbolTable::addDefinedFunction(StringRef Name, @@ -146,43 +169,62 @@ return S; } -Symbol *SymbolTable::addDefinedGlobal(StringRef Name) { +Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags) { + DEBUG(dbgs() << "addDefinedData: " << Name << "\n"); + Symbol *S; + bool WasInserted; + std::tie(S, WasInserted) = insert(Name); + if (WasInserted) { + S->update(Symbol::DefinedDataKind, nullptr, Flags); + } else if (!S->isData()) { + error("symbol type mismatch: " + Name); + } else if (!S->isDefined()) { + DEBUG(dbgs() << "resolving existing undefined data: " << Name << "\n"); + S->update(Symbol::DefinedDataKind, nullptr, Flags); + } + return S; +} + +Symbol *SymbolTable::addDefinedGlobal(StringRef Name, + const WasmGlobalType *Type, + uint32_t Flags) { DEBUG(dbgs() << "addDefinedGlobal: " << Name << "\n"); Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name); if (WasInserted) { - S->update(Symbol::DefinedGlobalKind); + S->update(Symbol::DefinedGlobalKind, nullptr, Flags); + S->setGlobalType(Type); } else if (!S->isGlobal()) { error("symbol type mismatch: " + Name); } else { DEBUG(dbgs() << "resolving existing undefined global: " << Name << "\n"); - S->update(Symbol::DefinedGlobalKind); + S->update(Symbol::DefinedGlobalKind, nullptr, Flags); } return S; } Symbol *SymbolTable::addDefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags, InputFile *F, InputChunk *Chunk, - uint32_t Address) { - DEBUG(dbgs() << "addDefined: " << Name << " addr:" << Address << "\n"); + uint32_t DataAddress, uint32_t DataSize) { + DEBUG(dbgs() << "addDefined: " << Name << "\n"); Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name); if (WasInserted) { - S->update(Kind, F, Flags, Chunk, Address); + S->update(Kind, F, Flags, Chunk, DataAddress, DataSize); } else if (S->isLazy()) { // The existing symbol is lazy. Replace it without checking types since // lazy symbols don't have any type information. DEBUG(dbgs() << "replacing existing lazy symbol: " << Name << "\n"); - S->update(Kind, F, Flags, Chunk, Address); + S->update(Kind, F, Flags, Chunk, DataAddress, DataSize); } else if (!S->isDefined()) { // The existing symbol table entry is undefined. The new symbol replaces // it, after checking the type matches DEBUG(dbgs() << "resolving existing undefined symbol: " << Name << "\n"); checkSymbolTypes(*S, *F, Kind, Chunk); - S->update(Kind, F, Flags, Chunk, Address); + S->update(Kind, F, Flags, Chunk, DataAddress, DataSize); } else if ((Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) { // the new symbol is weak we can ignore it DEBUG(dbgs() << "existing symbol takes precedence\n"); @@ -191,7 +233,7 @@ // it DEBUG(dbgs() << "replacing existing weak symbol\n"); checkSymbolTypes(*S, *F, Kind, Chunk); - S->update(Kind, F, Flags, Chunk, Address); + S->update(Kind, F, Flags, Chunk, DataAddress, DataSize); } else { // neither symbol is week. They conflict. reportDuplicate(S, F); @@ -216,22 +258,25 @@ Symbol *SymbolTable::addUndefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags, InputFile *F, - const WasmSignature *Type) { + const WasmSignature *FunctionType, + const WasmGlobalType *GlobalType) { DEBUG(dbgs() << "addUndefined: " << Name << "\n"); Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name); if (WasInserted) { S->update(Kind, F, Flags); - if (Type) - S->setFunctionType(Type); + if (FunctionType) + S->setFunctionType(FunctionType); + if (GlobalType) + S->setGlobalType(GlobalType); } else if (S->isLazy()) { DEBUG(dbgs() << "resolved by existing lazy\n"); auto *AF = cast(S->getFile()); AF->addMember(&S->getArchiveSymbol()); } else if (S->isDefined()) { DEBUG(dbgs() << "resolved by existing\n"); - checkSymbolTypes(*S, *F, Kind, Type); + checkSymbolTypes(*S, *F, Kind, FunctionType, GlobalType); } return S; } Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -15,7 +15,9 @@ #include "llvm/Object/Wasm.h" using llvm::object::Archive; +using llvm::object::WasmSymbol; using llvm::wasm::WasmSignature; +using llvm::wasm::WasmGlobalType; namespace lld { namespace wasm { @@ -27,10 +29,12 @@ public: enum Kind { DefinedFunctionKind, + DefinedDataKind, DefinedGlobalKind, LazyKind, UndefinedFunctionKind, + UndefinedDataKind, UndefinedGlobalKind, LastDefinedKind = DefinedGlobalKind, @@ -44,14 +48,22 @@ bool isLazy() const { return SymbolKind == LazyKind; } bool isDefined() const { return SymbolKind <= LastDefinedKind; } bool isUndefined() const { - return SymbolKind == UndefinedGlobalKind || - SymbolKind == UndefinedFunctionKind; + return SymbolKind == UndefinedFunctionKind || + SymbolKind == UndefinedDataKind || + SymbolKind == UndefinedGlobalKind; } bool isFunction() const { return SymbolKind == DefinedFunctionKind || SymbolKind == UndefinedFunctionKind; } - bool isGlobal() const { return !isFunction(); } + bool isData() const { + return SymbolKind == DefinedDataKind || + SymbolKind == UndefinedDataKind; + } + bool isGlobal() const { + return SymbolKind == DefinedGlobalKind || + SymbolKind == UndefinedGlobalKind; + } bool isLocal() const; bool isWeak() const; bool isHidden() const; @@ -66,6 +78,11 @@ bool hasFunctionType() const { return FunctionType != nullptr; } const WasmSignature &getFunctionType() const; void setFunctionType(const WasmSignature *Type); + + bool hasGlobalType() const { return GlobalType != nullptr; } + const WasmGlobalType &getGlobalType() const; + void setGlobalType(const WasmGlobalType *Type); + void setHidden(bool IsHidden); uint32_t getOutputIndex() const; @@ -73,13 +90,12 @@ // Returns true if an output index has been set for this symbol bool hasOutputIndex() const; - // Set the output index of the symbol, in the function or global Wasm - // index space of the output object - that is, for defined symbols only, - // its position in the list of defined function bodies / global decls. + // Set the output index of the symbol, in the Wasm index space of the output + // object - that is, for defined symbols only, its position in the list of + // Wasm imports+code for functions, imports+globals for globals. void setOutputIndex(uint32_t Index); - // Get/set the output symbol index, in the function or global Symbol index - // space - that is, the position in the list of imports+exports. This is + // Get/set the output symbol index, in the Symbol index space. This is // only used for relocatable output. uint32_t getOutputSymbolIndex() const; void setOutputSymbolIndex(uint32_t Index); @@ -92,14 +108,18 @@ // Set the table index of the symbol void setTableIndex(uint32_t Index); - // Returns the virtual address of a defined global. - // Only works for globals, not functions. + // Returns the output virtual address of a defined data symbol. uint32_t getVirtualAddress() const; + void setVirtualAddress(uint32_t Value); - void setVirtualAddress(uint32_t VA); + // Returns the offset of a defined data symbol within its OutputSegment. + uint32_t getOutputSegmentOffset() const; + uint32_t getVirtualSize() const { return VirtualSize; } void update(Kind K, InputFile *F = nullptr, uint32_t Flags = 0, - InputChunk *chunk = nullptr, uint32_t Address = UINT32_MAX); + InputChunk *Chunk = nullptr, uint32_t Address = UINT32_MAX, + uint32_t Size = 0); + void updateChunk(InputChunk *C) { Chunk = C; } void setArchiveSymbol(const Archive::Symbol &Sym) { ArchiveSymbol = Sym; } const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; } @@ -107,6 +127,7 @@ protected: uint32_t Flags; uint32_t VirtualAddress = 0; + uint32_t VirtualSize = 0; StringRef Name; Archive::Symbol ArchiveSymbol = {nullptr, 0, 0}; @@ -117,6 +138,7 @@ llvm::Optional OutputSymbolIndex; llvm::Optional TableIndex; const WasmSignature *FunctionType = nullptr; + const WasmGlobalType *GlobalType = nullptr; }; } // namespace wasm @@ -124,6 +146,8 @@ // Returns a symbol name for an error message. std::string toString(const wasm::Symbol &Sym); std::string toString(wasm::Symbol::Kind Kind); +std::string toString(WasmSymbol::SymbolType Type); +WasmSymbol::SymbolType toWasmType(wasm::Symbol::Kind Kind); } // namespace lld Index: wasm/Symbols.cpp =================================================================== --- wasm/Symbols.cpp +++ wasm/Symbols.cpp @@ -36,23 +36,40 @@ FunctionType = Type; } +const WasmGlobalType &Symbol::getGlobalType() const { + if (auto *G = dyn_cast_or_null(Chunk)) + return G->Signature; + + assert(GlobalType != nullptr); + return *GlobalType; +} + +void Symbol::setGlobalType(const WasmGlobalType *Type) { + assert(GlobalType == nullptr); + assert(Chunk == nullptr); + GlobalType = Type; +} + uint32_t Symbol::getVirtualAddress() const { - assert(isGlobal()); + assert(isData()); DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); return Chunk ? dyn_cast(Chunk)->translateVA(VirtualAddress) : VirtualAddress; } +uint32_t Symbol::getOutputSegmentOffset() const { + assert(isData() && hasOutputIndex()); + DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n"); + const InputSegment *Segment = dyn_cast(Chunk); + return Segment->OutputSegmentOffset + (VirtualAddress - Segment->startVA()); +} + bool Symbol::hasOutputIndex() const { - if (auto *F = dyn_cast_or_null(Chunk)) - return F->hasOutputIndex(); - return OutputIndex.hasValue(); + return Chunk ? Chunk->hasOutputIndex() : OutputIndex.hasValue(); } uint32_t Symbol::getOutputIndex() const { - if (auto *F = dyn_cast_or_null(Chunk)) - return F->getOutputIndex(); - return OutputIndex.getValue(); + return Chunk ? Chunk->getOutputIndex() : OutputIndex.getValue(); } uint32_t Symbol::getOutputSymbolIndex() const { @@ -61,13 +78,13 @@ void Symbol::setVirtualAddress(uint32_t Value) { DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n"); - assert(isGlobal()); + assert(isData()); VirtualAddress = Value; } void Symbol::setOutputIndex(uint32_t Index) { DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n"); - assert(!dyn_cast_or_null(Chunk)); + assert(!Chunk); assert(!OutputIndex.hasValue()); OutputIndex = Index; } @@ -104,13 +121,15 @@ } void Symbol::update(Kind K, InputFile *F, uint32_t Flags_, InputChunk *Chunk_, - uint32_t Address) { + uint32_t Address, uint32_t Size) { SymbolKind = K; File = F; Flags = Flags_; Chunk = Chunk_; - if (Address != UINT32_MAX) + if (Address != UINT32_MAX) { setVirtualAddress(Address); + VirtualSize = Size; + } } bool Symbol::isWeak() const { @@ -145,10 +164,14 @@ switch (Kind) { case wasm::Symbol::DefinedFunctionKind: return "DefinedFunction"; + case wasm::Symbol::DefinedDataKind: + return "DefinedData"; case wasm::Symbol::DefinedGlobalKind: return "DefinedGlobal"; case wasm::Symbol::UndefinedFunctionKind: return "UndefinedFunction"; + case wasm::Symbol::UndefinedDataKind: + return "UndefinedData"; case wasm::Symbol::UndefinedGlobalKind: return "UndefinedGlobal"; case wasm::Symbol::LazyKind: @@ -156,3 +179,33 @@ } llvm_unreachable("Invalid symbol kind!"); } + +std::string lld::toString(WasmSymbol::SymbolType Type) { + switch (Type) { + case WasmSymbol::SymbolType::FUNCTION: + return "Function"; + case WasmSymbol::SymbolType::DATA: + return "Data"; + case WasmSymbol::SymbolType::GLOBAL: + return "Global"; + } + llvm_unreachable("Invalid symbol type"); +} + +WasmSymbol::SymbolType lld::toWasmType(wasm::Symbol::Kind Kind) { + switch (Kind) { + case wasm::Symbol::DefinedFunctionKind: + case wasm::Symbol::UndefinedFunctionKind: + return WasmSymbol::SymbolType::FUNCTION; + case wasm::Symbol::DefinedDataKind: + case wasm::Symbol::UndefinedDataKind: + return WasmSymbol::SymbolType::DATA; + case wasm::Symbol::DefinedGlobalKind: + case wasm::Symbol::UndefinedGlobalKind: + return WasmSymbol::SymbolType::GLOBAL; + default: + llvm_unreachable("kind with no type"); + break; + } + return static_cast(-1); +} Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -63,13 +63,7 @@ } }; -// A Wasm export to be written into the export section. -struct WasmExportEntry { - const Symbol *Sym; - StringRef FieldName; // may not match the Symbol name -}; - -// An init entry to be written to either the synthentic init func or the +// An init entry to be written to either the synthetic init func or the // linking metadata. struct WasmInitEntry { const Symbol *Sym; @@ -91,6 +85,7 @@ void assignIndexes(); void calculateImports(); void calculateExports(); + void assignSymtab(); void calculateTypes(); void createOutputSegments(); void layoutMemory(); @@ -129,10 +124,11 @@ std::vector ImportedSymbols; unsigned NumImportedFunctions = 0; unsigned NumImportedGlobals = 0; - std::vector ExportedSymbols; - std::vector DefinedGlobals; + std::vector ExportedSymbols; + std::vector DefinedGlobals; std::vector DefinedFunctions; std::vector IndirectFunctions; + std::vector SymtabEntries; std::vector InitFunctions; // Elements that are used to construct the final output @@ -142,6 +138,7 @@ std::unique_ptr Buffer; std::unique_ptr CtorFunction; std::string CtorFunctionBody; + std::unique_ptr StackPtrGlobal; std::vector Segments; llvm::SmallDenseMap SegmentMap; @@ -189,10 +186,11 @@ if (Sym->isFunction()) { Import.Kind = WASM_EXTERNAL_FUNCTION; Import.SigIndex = lookupType(Sym->getFunctionType()); - } else { + } else if (Sym->isGlobal()) { Import.Kind = WASM_EXTERNAL_GLOBAL; - Import.Global.Mutable = false; - Import.Global.Type = WASM_TYPE_I32; + Import.Global = Sym->getGlobalType(); + } else { + llvm_unreachable("invalid import type"); } writeImport(OS, Import); } @@ -238,12 +236,10 @@ raw_ostream &OS = Section->getStream(); writeUleb128(OS, DefinedGlobals.size(), "global count"); - for (const Symbol *Sym : DefinedGlobals) { + for (const InputGlobal *G : DefinedGlobals) { WasmGlobal Global; - Global.Type.Type = WASM_TYPE_I32; - Global.Type.Mutable = Sym == Config->StackPointerSymbol; - Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; - Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); + Global.Type = G->Signature; + Global.InitExpr = G->initExpr(); writeGlobal(OS, Global); } } @@ -289,15 +285,17 @@ writeExport(OS, MemoryExport); } - for (const WasmExportEntry &E : ExportedSymbols) { - DEBUG(dbgs() << "Export: " << E.Sym->getName() << "\n"); + for (const Symbol *Sym : ExportedSymbols) { + DEBUG(dbgs() << "Export: " << Sym->getName() << "\n"); WasmExport Export; - Export.Name = E.FieldName; - Export.Index = E.Sym->getOutputIndex(); - if (E.Sym->isFunction()) + Export.Name = Sym->getName(); + Export.Index = Sym->getOutputIndex(); + if (Sym->isFunction()) Export.Kind = WASM_EXTERNAL_FUNCTION; - else + else if (Sym->isGlobal()) Export.Kind = WASM_EXTERNAL_GLOBAL; + else + llvm_unreachable("invalid export kind"); writeExport(OS, Export); } } @@ -389,26 +387,41 @@ if (!Config->Relocatable) return; - std::vector> SymbolInfo; - auto addSymInfo = [&](const Symbol *Sym, StringRef ExternalName) { - uint32_t Flags = - (Sym->isLocal() ? WASM_SYMBOL_BINDING_LOCAL : - Sym->isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0) | - (Sym->isHidden() ? WASM_SYMBOL_VISIBILITY_HIDDEN : 0); - if (Flags) - SymbolInfo.emplace_back(ExternalName, Flags); - }; - // (Imports can't have internal linkage, their names don't need to be budged.) - for (const Symbol *Sym : ImportedSymbols) - addSymInfo(Sym, Sym->getName()); - for (const WasmExportEntry &E : ExportedSymbols) - addSymInfo(E.Sym, E.FieldName); - if (!SymbolInfo.empty()) { - SubSection SubSection(WASM_SYMBOL_INFO); - writeUleb128(SubSection.getStream(), SymbolInfo.size(), "num sym info"); - for (auto Pair: SymbolInfo) { - writeStr(SubSection.getStream(), Pair.first, "sym name"); - writeUleb128(SubSection.getStream(), Pair.second, "sym flags"); + if (!SymtabEntries.empty()) { + SubSection SubSection(WASM_SYMBOL_TABLE); + writeUleb128(SubSection.getStream(), SymtabEntries.size(), "num sym info"); + for (const Symbol *Sym : SymtabEntries) { + assert(Sym->isDefined() || Sym->isUndefined()); + uint32_t Kind = Sym->isFunction() ? llvm::wasm::WASM_SYMTAB_FUNCTION : + Sym->isGlobal() ? llvm::wasm::WASM_SYMTAB_GLOBAL + : llvm::wasm::WASM_SYMTAB_DATA; + uint32_t Flags = + (Sym->isLocal() ? WASM_SYMBOL_BINDING_LOCAL : + Sym->isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0) | + (Sym->isHidden() ? WASM_SYMBOL_VISIBILITY_HIDDEN : 0); + writeUleb128(SubSection.getStream(), Kind, "sym kind"); + writeUleb128(SubSection.getStream(), Flags, "sym flags"); + switch (Kind) { + case llvm::wasm::WASM_SYMTAB_FUNCTION: + case llvm::wasm::WASM_SYMTAB_GLOBAL: + writeUleb128(SubSection.getStream(), Sym->getOutputIndex(), + "index"); + if (Sym->isDefined()) + writeStr(SubSection.getStream(), Sym->getName(), "sym name"); + break; + case llvm::wasm::WASM_SYMTAB_DATA: + writeStr(SubSection.getStream(), Sym->getName(), "sym name"); + SubSection.getStream() << static_cast(Sym->isDefined()); + if (Sym->isDefined()) { + writeUleb128(SubSection.getStream(), Sym->getOutputIndex(), + "index"); + writeUleb128(SubSection.getStream(), Sym->getOutputSegmentOffset(), + "data offset"); + writeUleb128(SubSection.getStream(), Sym->getVirtualSize(), + "data size"); + } + break; + } } SubSection.finalizeContents(); SubSection.writeToStream(OS); @@ -556,8 +569,17 @@ debugPrint("mem: stack size = %d\n", Config->ZStackSize); debugPrint("mem: stack base = %d\n", MemoryPtr); MemoryPtr += Config->ZStackSize; - Config->StackPointerSymbol->setVirtualAddress(MemoryPtr); + + WasmInitExpr StackInit; + StackInit.Opcode = WASM_OPCODE_I32_CONST; + StackInit.Value.Int32 = MemoryPtr; + StackPtrGlobal.reset(new SyntheticGlobal( + Config->StackPointerSymbol->getGlobalType(), StackInit)); + StackPtrGlobal->setOutputIndex(NumImportedGlobals + DefinedGlobals.size()); + DefinedGlobals.emplace_back(StackPtrGlobal.get()); + Config->StackPointerSymbol->updateChunk(StackPtrGlobal.get()); debugPrint("mem: stack top = %d\n", MemoryPtr); + // Set `__heap_base` to directly follow the end of the stack. We don't // allocate any heap memory up front, but instead really on the malloc/brk // implementation growing the memory at runtime. @@ -608,11 +630,11 @@ void Writer::calculateImports() { for (Symbol *Sym : Symtab->getSymbols()) { - if (!Sym->isUndefined() || (Sym->isWeak() && !Config->Relocatable)) + if (!Sym->isUndefined() || Sym->isData() || + (Sym->isWeak() && !Config->Relocatable)) continue; Sym->setOutputIndex(ImportedSymbols.size()); - Sym->setOutputSymbolIndex(ImportedSymbols.size()); ImportedSymbols.emplace_back(Sym); if (Sym->isFunction()) ++NumImportedFunctions; @@ -622,63 +644,64 @@ } void Writer::calculateExports() { - bool ExportHidden = Config->Relocatable; - StringSet<> UsedNames; - auto BudgeLocalName = [&](const Symbol *Sym) { - StringRef SymName = Sym->getName(); - // We can't budge non-local names. - if (!Sym->isLocal()) - return SymName; - // We must budge local names that have a collision with a symbol that we - // haven't yet processed. - if (!Symtab->find(SymName) && UsedNames.insert(SymName).second) - return SymName; - for (unsigned I = 1; ; ++I) { - std::string NameBuf = (SymName + "." + Twine(I)).str(); - if (!UsedNames.count(NameBuf)) { - StringRef Name = Saver.save(NameBuf); - UsedNames.insert(Name); // Insert must use safe StringRef from save() - return Name; - } - } + if (Config->Relocatable) + return; + + auto ExportSym = [&](Symbol *Sym) { + if (!Sym->isDefined() || Sym->isData()) + return; + if (Sym->isHidden() || Sym->isLocal()) + return; + if (Sym->getChunk()->Discarded) + return; + // We should never be exporting a non-live symbol + assert(Sym->getChunk()->Live); + ExportedSymbols.emplace_back(Sym); }; - unsigned SymbolIndex = ImportedSymbols.size(); - if (Config->CtorSymbol && (!Config->CtorSymbol->isHidden() || ExportHidden)) { - Config->CtorSymbol->setOutputSymbolIndex(SymbolIndex++); - ExportedSymbols.emplace_back( - WasmExportEntry{Config->CtorSymbol, Config->CtorSymbol->getName()}); - } + // TODO The two loops below should be replaced with this single loop, with + // ExportSym inlined: +// for (Symbol *Sym : Symtab->getSymbols()) +// ExportSym(Sym); + // Making that change would reorder the output though, so it should be done as + // a separate commit. for (ObjFile *File : Symtab->ObjectFiles) { for (Symbol *Sym : File->getSymbols()) { - if (!Sym->isDefined() || File != Sym->getFile()) - continue; - if (Sym->isGlobal()) - continue; - if (Sym->getChunk()->Discarded) - continue; + if (File == Sym->getFile()) + ExportSym(Sym); + } + } + for (Symbol *Sym : Symtab->getSymbols()) { + if (Sym->getFile() == nullptr) + ExportSym(Sym); + } +} - if ((Sym->isHidden() || Sym->isLocal()) && !ExportHidden) +void Writer::assignSymtab() { + if (!Config->Relocatable) + return; + + unsigned SymbolIndex = SymtabEntries.size(); + for (ObjFile* File : Symtab->ObjectFiles) { + DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n"); + for (Symbol *Sym : File->getSymbols()) { + if (Sym->getFile() != File) continue; - - // We should never be exporting a non-live symbol - assert(Sym->getChunk()->Live); - + if (Sym->isDefined()) { + if (Sym->getChunk()->Discarded) + continue; + } else { + assert(Sym->isUndefined()); // Can't be lazy + } Sym->setOutputSymbolIndex(SymbolIndex++); - ExportedSymbols.emplace_back(WasmExportEntry{Sym, BudgeLocalName(Sym)}); + SymtabEntries.emplace_back(Sym); } } - for (Symbol *Sym : DefinedGlobals) { - // Can't export the SP right now because its mutable, and mutuable globals - // are yet supported in the official binary format. - // TODO(sbc): Remove this if/when the "mutable global" proposal is accepted. - if (Sym == Config->StackPointerSymbol) - continue; - Sym->setOutputSymbolIndex(SymbolIndex++); - ExportedSymbols.emplace_back(WasmExportEntry{Sym, BudgeLocalName(Sym)}); - } + // For the moment, relocatable output doesn't contain any synthetic functions, + // so no need to look through the Symtab for symbols not referenced by + // Symtab->ObjectFiles. } uint32_t Writer::lookupType(const WasmSignature &Sig) { @@ -713,39 +736,17 @@ void Writer::assignIndexes() { uint32_t GlobalIndex = NumImportedGlobals + DefinedGlobals.size(); - uint32_t FunctionIndex = NumImportedFunctions + DefinedFunctions.size(); - - if (Config->StackPointerSymbol) { - DefinedGlobals.emplace_back(Config->StackPointerSymbol); - Config->StackPointerSymbol->setOutputIndex(GlobalIndex++); - } - - if (Config->HeapBaseSymbol) { - DefinedGlobals.emplace_back(Config->HeapBaseSymbol); - Config->HeapBaseSymbol->setOutputIndex(GlobalIndex++); - } - - if (Config->Relocatable) - DefinedGlobals.reserve(Symtab->getSymbols().size()); - - uint32_t TableIndex = kInitialTableOffset; - for (ObjFile *File : Symtab->ObjectFiles) { - if (Config->Relocatable) { - DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); - for (Symbol *Sym : File->getSymbols()) { - // Create wasm globals for data symbols defined in this file - if (!Sym->isDefined() || File != Sym->getFile()) - continue; - if (Sym->isFunction()) - continue; - - DefinedGlobals.emplace_back(Sym); - Sym->setOutputIndex(GlobalIndex++); - } + DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); + for (InputGlobal *Global : File->Globals) { + if (Global->Discarded || !Global->Live) + continue; + DefinedGlobals.emplace_back(Global); + Global->setOutputIndex(GlobalIndex++); } } + uint32_t FunctionIndex = NumImportedFunctions + DefinedFunctions.size(); for (ObjFile *File : Symtab->ObjectFiles) { DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); for (InputFunction *Func : File->Functions) { @@ -756,6 +757,7 @@ } } + uint32_t TableIndex = kInitialTableOffset; for (ObjFile *File : Symtab->ObjectFiles) { DEBUG(dbgs() << "Table Indexes: " << File->getName() << "\n"); auto HandleTableRelocs = [&](InputChunk *Chunk) { @@ -804,7 +806,7 @@ OutputSegment *&S = SegmentMap[Name]; if (S == nullptr) { DEBUG(dbgs() << "new segment: " << Name << "\n"); - S = make(Name); + S = make(Name, Segments.size()); Segments.push_back(S); } S->addInputSegment(Segment); @@ -846,6 +848,7 @@ CtorFunction = llvm::make_unique( Signature, BodyArray, Config->CtorSymbol->getName()); CtorFunction->setOutputIndex(FunctionIndex); + Config->CtorSymbol->updateChunk(CtorFunction.get()); DefinedFunctions.emplace_back(CtorFunction.get()); } @@ -875,12 +878,16 @@ calculateImports(); log("-- assignIndexes"); assignIndexes(); - log("-- calculateExports"); - calculateExports(); log("-- calculateInitFunctions"); calculateInitFunctions(); if (!Config->Relocatable) createCtorFunction(); + log("-- layoutMemory"); + layoutMemory(); + log("-- calculateExports"); + calculateExports(); + log("-- assignSymtab"); + assignSymtab(); if (errorHandler().Verbose) { log("Defined Functions: " + Twine(DefinedFunctions.size())); @@ -891,9 +898,6 @@ File->dumpInfo(); } - log("-- layoutMemory"); - layoutMemory(); - createHeader(); log("-- createSections"); createSections(); Index: wasm/WriterUtils.h =================================================================== --- wasm/WriterUtils.h +++ wasm/WriterUtils.h @@ -27,6 +27,17 @@ return !(LHS == RHS); } +// Used for general comparison +inline bool operator==(const llvm::wasm::WasmGlobalType &LHS, + const llvm::wasm::WasmGlobalType &RHS) { + return LHS.Type == RHS.Type && LHS.Mutable == RHS.Mutable; +} + +inline bool operator!=(const llvm::wasm::WasmGlobalType &LHS, + const llvm::wasm::WasmGlobalType &RHS) { + return !(LHS == RHS); +} + namespace lld { namespace wasm { @@ -74,6 +85,7 @@ std::string toString(const llvm::wasm::ValType Type); std::string toString(const llvm::wasm::WasmSignature &Sig); +std::string toString(const llvm::wasm::WasmGlobalType &Sig); } // namespace lld Index: wasm/WriterUtils.cpp =================================================================== --- wasm/WriterUtils.cpp +++ wasm/WriterUtils.cpp @@ -216,3 +216,11 @@ S += toString(static_cast(Sig.ReturnType)); return S.str(); } + +std::string lld::toString(const WasmGlobalType &Sig) { + SmallString<128> S; + if (Sig.Mutable) + S += "mutable "; + S += toString(static_cast(Sig.Type)); + return S.str(); +}