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,35 @@ ; RELOC-NEXT: Value: 28 ; RELOC-NEXT: Content: 68656C6C6F0A00 -; RELOC: - Type: CUSTOM +; RELOC: - Type: CUSTOM ; RELOC-NEXT: Name: linking ; RELOC-NEXT: DataSize: 35 +; RELOC-NEXT: SymbolInfo: +; RELOC-NEXT: - Name: foo +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 0 +; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: SegmentIndex: 0 +; RELOC-NEXT: DataOffset: 0 +; RELOC-NEXT: DataSize: 4 +; RELOC-NEXT: - Name: aligned_bar +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 1 +; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: SegmentIndex: 1 +; RELOC-NEXT: DataOffset: 0 +; RELOC-NEXT: DataSize: 4 +; RELOC-NEXT: - Name: external_ref +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 2 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: SegmentIndex: 2 +; RELOC-NEXT: DataOffset: 0 +; RELOC-NEXT: DataSize: 4 +; RELOC: - Name: hello_str +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 5 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: SegmentIndex: 3 +; RELOC-NEXT: DataOffset: 0 +; RELOC-NEXT: DataSize: 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 @@ -110,51 +110,118 @@ ; RELOC: Name: linking ; RELOC-NEXT: DataSize: 0 ; RELOC-NEXT: SymbolInfo: + ; RELOC-NEXT: - Name: __dso_handle +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 0 ; RELOC-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] ; RELOC-NEXT: - Name: func1 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 1 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: FunctionIndex: 0 ; RELOC-NEXT: - Name: func2 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 2 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: FunctionIndex: 1 ; RELOC-NEXT: - Name: func3 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 3 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: FunctionIndex: 2 ; RELOC-NEXT: - Name: func4 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 4 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: FunctionIndex: 3 +; RELOC-NEXT: - Name: __cxa_atexit +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 5 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 4 ; RELOC-NEXT: - Name: _start +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 6 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: FunctionIndex: 5 ; RELOC-NEXT: - Name: .Lcall_dtors.101 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 7 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 6 ; RELOC-NEXT: - Name: .Lregister_call_dtors.101 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 8 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 7 ; RELOC-NEXT: - Name: .Lbitcast +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 9 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 8 ; RELOC-NEXT: - Name: .Lcall_dtors.1001 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 10 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 9 ; RELOC-NEXT: - Name: .Lregister_call_dtors.1001 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 11 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 10 +; RELOC-NEXT: - Name: __stack_pointer +; RELOC-NEXT: Kind: GLOBAL +; RELOC-NEXT: SymbolIndex: 12 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: GlobalIndex: 0 ; RELOC-NEXT: - Name: myctor +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 13 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: FunctionIndex: 11 ; RELOC-NEXT: - Name: mydtor +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 14 ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; RELOC-NEXT: - Name: .Lcall_dtors.101.1 +; RELOC-NEXT: FunctionIndex: 12 +; RELOC-NEXT: - Name: .Lcall_dtors.101 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 15 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: .Lregister_call_dtors.101.1 +; RELOC-NEXT: FunctionIndex: 13 +; RELOC-NEXT: - Name: .Lregister_call_dtors.101 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 16 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 14 ; RELOC-NEXT: - Name: .Lcall_dtors.202 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 17 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 15 ; RELOC-NEXT: - Name: .Lregister_call_dtors.202 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 18 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 16 ; RELOC-NEXT: - Name: .Lcall_dtors.2002 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 19 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 17 ; RELOC-NEXT: - Name: .Lregister_call_dtors.2002 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 20 ; 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.ll =================================================================== --- test/wasm/load-undefined.ll +++ test/wasm/load-undefined.ll @@ -29,9 +29,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 @@ -49,12 +49,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 @@ -63,9 +57,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 @@ -472,22 +351,138 @@ ; RELOC-NEXT: Name: linking ; RELOC-NEXT: DataSize: 24 ; RELOC-NEXT: SymbolInfo: -; RELOC-NEXT: - Name: colliding_func1.1 +; RELOC-NEXT: - Name: colliding_func1 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 0 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 0 +; RELOC-NEXT: - Name: colliding_func2 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 1 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 1 ; RELOC-NEXT: - Name: colliding_func3 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 2 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_func2.1 -; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_func3.1 -; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_global1.1 +; RELOC-NEXT: FunctionIndex: 2 +; RELOC-NEXT: - Name: get_global1A +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 3 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 3 +; RELOC-NEXT: - Name: colliding_global1 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 4 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: SegmentIndex: 0 +; RELOC-NEXT: DataOffset: 0 +; RELOC-NEXT: DataSize: 4 +; RELOC-NEXT: - Name: get_global2A +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 5 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 4 +; RELOC-NEXT: - Name: colliding_global2 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 6 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: SegmentIndex: 1 +; RELOC-NEXT: DataOffset: 0 +; RELOC-NEXT: DataSize: 4 +; RELOC-NEXT: - Name: get_global3A +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 7 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 5 ; RELOC-NEXT: - Name: colliding_global3 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 8 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_global2.1 +; RELOC-NEXT: SegmentIndex: 2 +; RELOC-NEXT: DataOffset: 0 +; RELOC-NEXT: DataSize: 4 +; RELOC-NEXT: - Name: get_func1A +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 9 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 6 +; RELOC-NEXT: - Name: get_func2A +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 10 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 7 +; RELOC-NEXT: - Name: get_func3A +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 11 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 8 +; RELOC-NEXT: - Name: colliding_func1 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 12 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 9 +; RELOC-NEXT: - Name: colliding_func2 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 13 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: - Name: colliding_global3.1 +; RELOC-NEXT: FunctionIndex: 10 +; RELOC-NEXT: - Name: colliding_func3 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 14 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: FunctionIndex: 11 +; RELOC-NEXT: - Name: get_global1B +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 15 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 12 +; RELOC-NEXT: - Name: colliding_global1 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 16 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: SegmentIndex: 0 +; RELOC-NEXT: DataOffset: 4 +; RELOC-NEXT: DataSize: 4 +; RELOC-NEXT: - Name: get_global2B +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 17 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 13 +; RELOC-NEXT: - Name: colliding_global2 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 18 +; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: SegmentIndex: 1 +; RELOC-NEXT: DataOffset: 4 +; RELOC-NEXT: DataSize: 4 +; RELOC-NEXT: - Name: get_global3B +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 19 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 14 +; RELOC-NEXT: - Name: colliding_global3 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: SymbolIndex: 20 +; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: SegmentIndex: 2 +; RELOC-NEXT: DataOffset: 4 +; RELOC-NEXT: DataSize: 4 +; RELOC-NEXT: - Name: get_func1B +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 21 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 15 +; RELOC-NEXT: - Name: get_func2B +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 22 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 16 +; RELOC-NEXT: - Name: get_func3B +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 23 +; 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,671 @@ ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 8 +; CHECK-NEXT: SymbolInfo: +; CHECK-NEXT: - Name: f1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 +; CHECK-NEXT: - Name: foo +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 +; CHECK-NEXT: - Name: f2 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 2 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 1 +; CHECK-NEXT: - Name: f3 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 3 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 2 +; CHECK-NEXT: - Name: f4 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 4 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: - Name: f5 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 5 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 4 +; CHECK-NEXT: - Name: f6 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 6 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 5 +; CHECK-NEXT: - Name: f7 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 7 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 6 +; CHECK-NEXT: - Name: f8 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 8 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 7 +; CHECK-NEXT: - Name: f9 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 9 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 8 +; CHECK-NEXT: - Name: f10 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 10 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 9 +; CHECK-NEXT: - Name: f11 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 11 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 10 +; CHECK-NEXT: - Name: f12 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 12 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 11 +; CHECK-NEXT: - Name: f13 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 13 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 12 +; CHECK-NEXT: - Name: f14 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 14 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 13 +; CHECK-NEXT: - Name: f15 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 15 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 14 +; CHECK-NEXT: - Name: f16 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 16 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 15 +; CHECK-NEXT: - Name: f17 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 17 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 16 +; CHECK-NEXT: - Name: f18 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 18 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 17 +; CHECK-NEXT: - Name: f19 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 19 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 18 +; CHECK-NEXT: - Name: f20 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 20 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 19 +; CHECK-NEXT: - Name: f21 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 21 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 20 +; CHECK-NEXT: - Name: f22 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 22 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 21 +; CHECK-NEXT: - Name: f23 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 23 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 22 +; CHECK-NEXT: - Name: f24 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 24 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 23 +; CHECK-NEXT: - Name: f25 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 25 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 24 +; CHECK-NEXT: - Name: f26 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 26 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 25 +; CHECK-NEXT: - Name: f27 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 27 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 26 +; CHECK-NEXT: - Name: f28 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 28 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 27 +; CHECK-NEXT: - Name: f29 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 29 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 28 +; CHECK-NEXT: - Name: f30 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 30 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 29 +; CHECK-NEXT: - Name: f31 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 31 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 30 +; CHECK-NEXT: - Name: f32 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 32 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 31 +; CHECK-NEXT: - Name: f33 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 33 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 32 +; CHECK-NEXT: - Name: f34 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 34 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 33 +; CHECK-NEXT: - Name: f35 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 35 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 34 +; CHECK-NEXT: - Name: f36 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 36 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 35 +; CHECK-NEXT: - Name: f37 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 37 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 36 +; CHECK-NEXT: - Name: f38 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 38 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 37 +; CHECK-NEXT: - Name: f39 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 39 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 38 +; CHECK-NEXT: - Name: f40 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 40 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 39 +; CHECK-NEXT: - Name: f41 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 41 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 40 +; CHECK-NEXT: - Name: f42 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 42 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 41 +; CHECK-NEXT: - Name: f43 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 43 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 42 +; CHECK-NEXT: - Name: f44 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 44 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 43 +; CHECK-NEXT: - Name: f45 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 45 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 44 +; CHECK-NEXT: - Name: f46 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 46 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 45 +; CHECK-NEXT: - Name: f47 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 47 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 46 +; CHECK-NEXT: - Name: f48 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 48 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 47 +; CHECK-NEXT: - Name: f49 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 49 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 48 +; CHECK-NEXT: - Name: f50 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 50 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 49 +; CHECK-NEXT: - Name: f51 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 51 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 50 +; CHECK-NEXT: - Name: f52 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 52 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 51 +; CHECK-NEXT: - Name: f53 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 53 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 52 +; CHECK-NEXT: - Name: f54 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 54 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 53 +; CHECK-NEXT: - Name: f55 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 55 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 54 +; CHECK-NEXT: - Name: f56 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 56 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 55 +; CHECK-NEXT: - Name: f57 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 57 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 56 +; CHECK-NEXT: - Name: f58 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 58 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 57 +; CHECK-NEXT: - Name: f59 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 59 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 58 +; CHECK-NEXT: - Name: f60 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 60 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 59 +; CHECK-NEXT: - Name: f61 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 61 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 60 +; CHECK-NEXT: - Name: f62 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 62 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 61 +; CHECK-NEXT: - Name: f63 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 63 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 62 +; CHECK-NEXT: - Name: f64 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 64 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 63 +; CHECK-NEXT: - Name: f65 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 65 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 64 +; CHECK-NEXT: - Name: f66 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 66 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 65 +; CHECK-NEXT: - Name: f67 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 67 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 66 +; CHECK-NEXT: - Name: f68 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 68 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 67 +; CHECK-NEXT: - Name: f69 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 69 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 68 +; CHECK-NEXT: - Name: f70 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 70 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 69 +; CHECK-NEXT: - Name: f71 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 71 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 70 +; CHECK-NEXT: - Name: f72 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 72 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 71 +; CHECK-NEXT: - Name: f73 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 73 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 72 +; CHECK-NEXT: - Name: f74 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 74 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 73 +; CHECK-NEXT: - Name: f75 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 75 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 74 +; CHECK-NEXT: - Name: f76 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 76 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 75 +; CHECK-NEXT: - Name: f77 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 77 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 76 +; CHECK-NEXT: - Name: f78 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 78 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 77 +; CHECK-NEXT: - Name: f79 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 79 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 78 +; CHECK-NEXT: - Name: f80 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 80 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 79 +; CHECK-NEXT: - Name: f81 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 81 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 80 +; CHECK-NEXT: - Name: f82 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 82 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 81 +; CHECK-NEXT: - Name: f83 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 83 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 82 +; CHECK-NEXT: - Name: f84 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 84 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 83 +; CHECK-NEXT: - Name: f85 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 85 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 84 +; CHECK-NEXT: - Name: f86 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 86 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 85 +; CHECK-NEXT: - Name: f87 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 87 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 86 +; CHECK-NEXT: - Name: f88 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 88 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 87 +; CHECK-NEXT: - Name: f89 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 89 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 88 +; CHECK-NEXT: - Name: f90 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 90 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 89 +; CHECK-NEXT: - Name: f91 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 91 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 90 +; CHECK-NEXT: - Name: f92 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 92 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 91 +; CHECK-NEXT: - Name: f93 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 93 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 92 +; CHECK-NEXT: - Name: f94 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 94 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 93 +; CHECK-NEXT: - Name: f95 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 95 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 94 +; CHECK-NEXT: - Name: f96 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 96 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 95 +; CHECK-NEXT: - Name: f97 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 97 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 96 +; CHECK-NEXT: - Name: f98 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 98 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 97 +; CHECK-NEXT: - Name: f99 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 99 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 98 +; CHECK-NEXT: - Name: f100 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 100 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 99 +; CHECK-NEXT: - Name: f101 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 101 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 100 +; CHECK-NEXT: - Name: f102 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 102 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 101 +; CHECK-NEXT: - Name: f103 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 103 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 102 +; CHECK-NEXT: - Name: f104 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 104 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 103 +; CHECK-NEXT: - Name: f105 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 105 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 104 +; CHECK-NEXT: - Name: f106 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 106 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 105 +; CHECK-NEXT: - Name: f107 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 107 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 106 +; CHECK-NEXT: - Name: f108 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 108 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 107 +; CHECK-NEXT: - Name: f109 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 109 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 108 +; CHECK-NEXT: - Name: f110 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 110 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 109 +; CHECK-NEXT: - Name: f111 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 111 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 110 +; CHECK-NEXT: - Name: f112 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 112 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 111 +; CHECK-NEXT: - Name: f113 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 113 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 112 +; CHECK-NEXT: - Name: f114 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 114 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 113 +; CHECK-NEXT: - Name: f115 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 115 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 114 +; CHECK-NEXT: - Name: f116 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 116 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 115 +; CHECK-NEXT: - Name: f117 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 117 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 116 +; CHECK-NEXT: - Name: f118 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 118 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 117 +; CHECK-NEXT: - Name: f119 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 119 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 118 +; CHECK-NEXT: - Name: f120 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 120 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 119 +; CHECK-NEXT: - Name: f121 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 121 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 120 +; CHECK-NEXT: - Name: f122 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 122 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 121 +; CHECK-NEXT: - Name: f123 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 123 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 122 +; CHECK-NEXT: - Name: f124 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 124 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 123 +; CHECK-NEXT: - Name: f125 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 125 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 124 +; CHECK-NEXT: - Name: f126 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 126 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 125 +; CHECK-NEXT: - Name: f127 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 127 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 126 +; CHECK-NEXT: - Name: f128 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 128 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 127 +; CHECK-NEXT: - Name: g0 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 129 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 +; CHECK-NEXT: - Name: f129 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 130 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 128 +; CHECK-NEXT: - Name: func +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 131 +; 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 @@ -231,24 +159,82 @@ ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 31 ; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: bar_import -; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: - Name: puts +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 ; CHECK-NEXT: - Name: hello +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 1 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: - Name: hello_str +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 2 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 7 +; CHECK-NEXT: - Name: foo_import +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 3 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 1 +; CHECK-NEXT: - Name: bar_import +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 4 +; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: FunctionIndex: 2 +; CHECK-NEXT: - Name: data_import +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 5 +; CHECK-NEXT: Flags: [ ] ; CHECK-NEXT: - Name: my_func +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 6 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 4 ; CHECK-NEXT: - Name: func_comdat +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 7 ; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: FunctionIndex: 5 ; CHECK-NEXT: - Name: data_comdat +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 8 ; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: SegmentIndex: 5 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 3 ; CHECK-NEXT: - Name: func_addr1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 9 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 ; CHECK-NEXT: - Name: func_addr2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 10 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: SegmentIndex: 2 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 ; CHECK-NEXT: - Name: func_addr3 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 11 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: SegmentIndex: 3 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 ; CHECK-NEXT: - Name: data_addr1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 12 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: SegmentIndex: 4 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 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: SymbolInfo: +; CHECK-NEXT: - Name: __stack_pointer +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: SymbolIndex: 0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: GlobalIndex: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 1 +; 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 @@ -266,8 +234,46 @@ ; RELOC-NEXT: Name: linking ; RELOC-NEXT: DataSize: 0 ; RELOC-NEXT: SymbolInfo: +; RELOC-NEXT: - Name: _start +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 0 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 0 +; RELOC-NEXT: - Name: __stack_pointer +; RELOC-NEXT: Kind: GLOBAL +; RELOC-NEXT: SymbolIndex: 1 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: GlobalIndex: 0 +; RELOC-NEXT: - Name: direct_fn +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 2 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 1 +; RELOC-NEXT: - Name: call_direct +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 3 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 2 +; RELOC-NEXT: - Name: call_alias +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 4 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 3 +; RELOC-NEXT: - Name: call_alias_ptr +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 5 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 4 +; RELOC-NEXT: - Name: call_direct_ptr +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 6 +; RELOC-NEXT: Flags: [ ] +; RELOC-NEXT: FunctionIndex: 5 ; RELOC-NEXT: - Name: alias_fn +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: SymbolIndex: 7 ; 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 @@ -281,9 +281,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)) @@ -298,10 +300,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 @@ -22,8 +22,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 { @@ -83,6 +85,8 @@ uint32_t translateVA(uint32_t Address) const; const OutputSegment *getOutputSegment() const { return OutputSeg; } + bool hasOutputIndex() const { return OutputSeg != nullptr; } + uint32_t getOutputIndex() const; void setOutputSegment(const OutputSegment *Segment, uint32_t Offset) { OutputSeg = Segment; @@ -155,6 +159,41 @@ 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), Signature(Signature), Global(G) {} + + virtual const WasmInitExpr &initExpr() const { return Global->InitExpr; } + StringRef getComdat() const override { return Global->Comdat; } + uint32_t getOutputIndex() const { return OutputIndex.getValue(); } + bool hasOutputIndex() const { return OutputIndex.hasValue(); } + void setOutputIndex(uint32_t Index); + + const WasmGlobalType &Signature; + +protected: + 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) {} + + 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: " << 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: @@ -114,19 +117,22 @@ uint32_t relocateGlobalIndex(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; uint32_t relocateTableIndex(uint32_t Original) const; Symbol *createDefined(const WasmSymbol &Sym, Symbol::Kind Kind, const InputSegment *Segment = nullptr, InputFunction *Function = nullptr, - uint32_t Address = UINT32_MAX); - Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind, - const WasmSignature *Signature = nullptr); + InputGlobal *Global = 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 @@ -48,7 +48,7 @@ } uint32_t ObjFile::relocateVirtualAddress(uint32_t Index) const { - return getGlobalSymbol(Index)->getVirtualAddress(); + return getDataSymbol(Index)->getVirtualAddress(); } uint32_t ObjFile::relocateTypeIndex(uint32_t Original) const { @@ -57,7 +57,7 @@ uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const { Symbol *Sym = getFunctionSymbol(Original); - uint32_t Index = Sym->hasOutputIndex() ? Sym->getOutputIndex() : 0; + uint32_t Index = Sym->getOutputIndex(); DEBUG(dbgs() << "relocateFunctionWasmIndex: " << toString(*Sym) << ": " << Original << " -> " << Index << "\n"); return Index; @@ -65,7 +65,7 @@ uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const { Symbol *Sym = getGlobalSymbol(Original); - uint32_t Index = Sym->hasTableIndex() ? Sym->getOutputIndex() : 0; + uint32_t Index = Sym->getOutputIndex(); DEBUG(dbgs() << "relocateGlobalWasmIndex: " << toString(*Sym) << ": " << Original << " -> " << Index << "\n"); return Index; @@ -87,6 +87,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; +} + uint32_t ObjFile::relocateTableIndex(uint32_t Original) const { Symbol *Sym = getFunctionSymbol(Original); // The null case is possible, if you take the address of a weak function @@ -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().Index]; } -// 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.WasmIndex >= NumGlobalImports); - const WasmGlobal &Global = - getWasmObj()->globals()[Sym.WasmIndex - NumGlobalImports]; - assert(Global.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.WasmIndex >= NumGlobalImports); + uint32_t GlobalIndex = Sym.WasmIndex - 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,39 +256,55 @@ 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, nullptr, - Function); - break; - } else { - Function->Discarded = true; - LLVM_FALLTHROUGH; // Exclude function, and add the symbol as undefined + case WasmSymbol::SymbolType::FUNCTION: + if (WasmSym.WasmIndex >= NumFunctionImports) { + InputFunction *Function = getFunction(WasmSym); + if (!isExcludedByComdat(Function)) { + S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionKind, nullptr, + 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, nullptr, 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, + nullptr, nullptr, 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.WasmIndex >= NumGlobalImports) { + InputGlobal *Global = getGlobal(WasmSym); + if (!isExcludedByComdat(Global)) { + S = createDefined(WasmSym, Symbol::Kind::DefinedGlobalKind, nullptr, + nullptr, Global); + break; + } else { + Global->Discarded = true; + // Exclude global, and add the symbol as undefined + } } - } - case WasmSymbol::SymbolType::GLOBAL_IMPORT: S = createUndefined(WasmSym, Symbol::Kind::UndefinedGlobalKind); break; } @@ -291,22 +313,24 @@ } } -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, const InputSegment *Segment, - InputFunction *Function, uint32_t Address) { + InputFunction *Function, InputGlobal *Global, + uint32_t DataAddress, uint32_t DataSize) { Symbol *S; - if (Sym.isLocal()) { + if (Sym.isBindingLocal()) { S = make(Sym.Name, true); - S->update(Kind, this, Sym.Flags, Segment, Function, Address); + S->update(Kind, this, Sym.Flags, Segment, Function, Global, DataAddress, + DataSize); return S; } return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Segment, Function, - Address); + Global, DataAddress, DataSize); } void ArchiveFile::parse() { 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,19 @@ Symbol *addDefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags, InputFile *F, const InputSegment *Segment = nullptr, - InputFunction *Function = nullptr, uint32_t Address = 0); + InputFunction *Function = nullptr, + InputGlobal *Global = nullptr, + 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,41 +81,61 @@ // 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()); } @@ -138,18 +158,37 @@ 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; } @@ -157,25 +196,27 @@ Symbol *SymbolTable::addDefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags, InputFile *F, const InputSegment *Segment, - InputFunction *Function, uint32_t Address) { - DEBUG(dbgs() << "addDefined: " << Name << " addr:" << Address << "\n"); + InputFunction *Function, InputGlobal *Global, + 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, Segment, Function, Address); + S->update(Kind, F, Flags, Segment, Function, Global, 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, Segment, Function, Address); + S->update(Kind, F, Flags, Segment, Function, Global, 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, Function ? &Function->Signature : nullptr); - S->update(Kind, F, Flags, Segment, Function, Address); + checkSymbolTypes(*S, *F, Kind, Function ? &Function->Signature : nullptr, + Global ? &Global->Signature : nullptr); + S->update(Kind, F, Flags, Segment, Function, Global, 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"); @@ -183,8 +224,9 @@ // the new symbol is not weak and the existing symbol is, so we replace // it DEBUG(dbgs() << "replacing existing weak symbol\n"); - checkSymbolTypes(*S, *F, Kind, Function ? &Function->Signature : nullptr); - S->update(Kind, F, Flags, Segment, Function, Address); + checkSymbolTypes(*S, *F, Kind, Function ? &Function->Signature : nullptr, + Global ? &Global->Signature : nullptr); + S->update(Kind, F, Flags, Segment, Function, Global, DataAddress, DataSize); } else { // neither symbol is week. They conflict. reportDuplicate(S, F); @@ -209,22 +251,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,23 +15,29 @@ #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 { class InputFile; +class InputChunk; class InputSegment; class InputFunction; +class InputGlobal; class Symbol { public: enum Kind { DefinedFunctionKind, + DefinedDataKind, DefinedGlobalKind, LazyKind, UndefinedFunctionKind, + UndefinedDataKind, UndefinedGlobalKind, LastDefinedKind = DefinedGlobalKind, @@ -45,14 +51,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 +80,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 +92,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,23 +110,30 @@ // 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, const InputSegment *Segment = nullptr, - InputFunction *Function = nullptr, uint32_t Address = UINT32_MAX); + InputFunction *Function = nullptr, InputGlobal *Global = nullptr, + uint32_t Address = UINT32_MAX, uint32_t Size = 0); + void updateFunction(InputFunction *F) { Function = F; } + void updateGlobal(InputGlobal *G) { Global = G; } void setArchiveSymbol(const Archive::Symbol &Sym) { ArchiveSymbol = Sym; } const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; } - InputFunction *getFunction() { return Function; } + + const InputChunk *getChunk() const; protected: uint32_t Flags; uint32_t VirtualAddress = 0; + uint32_t VirtualSize = 0; StringRef Name; Archive::Symbol ArchiveSymbol = {nullptr, 0, 0}; @@ -116,10 +141,12 @@ InputFile *File = nullptr; const InputSegment *Segment = nullptr; InputFunction *Function = nullptr; + InputGlobal *Global = nullptr; llvm::Optional OutputIndex; llvm::Optional OutputSymbolIndex; llvm::Optional TableIndex; const WasmSignature *FunctionType = nullptr; + const WasmGlobalType *GlobalType = nullptr; }; } // namespace wasm @@ -127,6 +154,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,21 +36,49 @@ FunctionType = Type; } +const WasmGlobalType &Symbol::getGlobalType() const { + if (Global != nullptr) + return Global->Signature; + + assert(GlobalType != nullptr); + return *GlobalType; +} + +void Symbol::setGlobalType(const WasmGlobalType *Type) { + assert(GlobalType == nullptr); + assert(Global == nullptr); + GlobalType = Type; +} + uint32_t Symbol::getVirtualAddress() const { - assert(isGlobal()); + assert(isData()); DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); return Segment ? Segment->translateVA(VirtualAddress) : VirtualAddress; } +uint32_t Symbol::getOutputSegmentOffset() const { + assert(isData() && hasOutputIndex()); + DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n"); + return Segment->OutputSegmentOffset + (VirtualAddress - Segment->startVA()); +} + bool Symbol::hasOutputIndex() const { if (Function) return Function->hasOutputIndex(); + if (Global) + return Global->hasOutputIndex(); + if (Segment) + return Segment->hasOutputIndex(); return OutputIndex.hasValue(); } uint32_t Symbol::getOutputIndex() const { if (Function) return Function->getOutputIndex(); + if (Global) + return Global->getOutputIndex(); + if (Segment) + return Segment->getOutputIndex(); return OutputIndex.getValue(); } @@ -60,13 +88,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(!Function); + assert(!Function && !Global && !Segment); assert(!OutputIndex.hasValue()); OutputIndex = Index; } @@ -104,14 +132,17 @@ void Symbol::update(Kind K, InputFile *F, uint32_t Flags_, const InputSegment *Seg, InputFunction *Func, - uint32_t Address) { + InputGlobal *Glob, uint32_t Address, uint32_t Size) { SymbolKind = K; File = F; Flags = Flags_; Segment = Seg; Function = Func; - if (Address != UINT32_MAX) - setVirtualAddress(Address); + Global = Glob; + if (Address != UINT32_MAX) { + VirtualAddress = Address; + VirtualSize = Size; + } } bool Symbol::isWeak() const { @@ -135,6 +166,19 @@ Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT; } +const InputChunk *Symbol::getChunk() const { + assert(isDefined()); + const InputChunk *Chunk; + if (isFunction()) + Chunk = Function; + else if (isGlobal()) + Chunk = Global; + else + Chunk = Segment; + assert(Chunk != nullptr); + return Chunk; +} + std::string lld::toString(const wasm::Symbol &Sym) { if (Config->Demangle) if (Optional S = demangleItanium(Sym.getName())) @@ -146,10 +190,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: @@ -157,3 +205,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 = WASM_TYPE_I32; - Global.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,42 @@ 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"); + if (Sym->isDefined()) { + writeSleb128(SubSection.getStream(), + static_cast(Sym->getOutputIndex()), "index"); + writeUleb128(SubSection.getStream(), Sym->getOutputSegmentOffset(), + "data offset"); + writeUleb128(SubSection.getStream(), Sym->getVirtualSize(), + "data size"); + } else { + writeSleb128(SubSection.getStream(), -1, "index"); + } + break; + } } SubSection.finalizeContents(); SubSection.writeToStream(OS); @@ -448,6 +462,12 @@ Comdats[Comdat].emplace_back( ComdatEntry{WASM_COMDAT_FUNCTION, F->getOutputIndex()}); } + for (const InputGlobal *G : DefinedGlobals) { + StringRef Comdat = G->getComdat(); + if (!Comdat.empty()) + Comdats[Comdat].emplace_back( + ComdatEntry{WASM_COMDAT_GLOBAL, G->getOutputIndex()}); + } for (uint32_t I = 0; I < Segments.size(); ++I) { const auto &InputSegments = Segments[I]->InputSegments; if (InputSegments.empty()) @@ -556,8 +576,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->updateGlobal(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 +637,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,59 +651,62 @@ } 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; + 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->getFunction()->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; + 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) { @@ -709,39 +741,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) + 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) { @@ -752,6 +762,7 @@ } } + uint32_t TableIndex = kInitialTableOffset; for (ObjFile *File : Symtab->ObjectFiles) { DEBUG(dbgs() << "Table Indexes: " << File->getName() << "\n"); auto HandleTableRelocs = [&](InputChunk *Chunk) { @@ -800,7 +811,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); @@ -842,6 +853,7 @@ CtorFunction = llvm::make_unique( Signature, BodyArray, Config->CtorSymbol->getName()); CtorFunction->setOutputIndex(FunctionIndex); + Config->CtorSymbol->updateFunction(CtorFunction.get()); DefinedFunctions.emplace_back(CtorFunction.get()); } @@ -871,12 +883,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())); @@ -887,9 +903,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 { @@ -60,6 +71,8 @@ void writeLimits(raw_ostream &OS, const llvm::wasm::WasmLimits &Limits); +void writeGlobalType(raw_ostream &OS, const llvm::wasm::WasmGlobalType &Type); + void writeGlobal(raw_ostream &OS, const llvm::wasm::WasmGlobal &Global); void writeImport(raw_ostream &OS, const llvm::wasm::WasmImport &Import); @@ -72,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 @@ -123,9 +123,13 @@ writeUleb128(OS, Limits.Maximum, "limits max"); } +void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) { + writeValueType(OS, Type.Type, "global type"); + writeUleb128(OS, Type.Mutable, "global mutable"); +} + void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) { - writeValueType(OS, Global.Type, "global type"); - writeUleb128(OS, Global.Mutable, "global mutable"); + writeGlobalType(OS, Global.Type); writeInitExpr(OS, Global.InitExpr); } @@ -138,8 +142,7 @@ writeUleb128(OS, Import.SigIndex, "import sig index"); break; case WASM_EXTERNAL_GLOBAL: - writeValueType(OS, Import.Global.Type, "import global type"); - writeUleb128(OS, Import.Global.Mutable, "import global mutable"); + writeGlobalType(OS, Import.Global); break; case WASM_EXTERNAL_MEMORY: writeLimits(OS, Import.Memory); @@ -213,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(); +}