[lld] r325861 - [WebAssembly] Add explicit symbol table

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 22 21:08:54 PST 2018


Author: sbc
Date: Thu Feb 22 21:08:53 2018
New Revision: 325861

URL: http://llvm.org/viewvc/llvm-project?rev=325861&view=rev
Log:
[WebAssembly] Add explicit symbol table

This change modified lld to in response the llvm change which
moved to a more explicit symbol table in the object format.

Based on patches by Nicholas Wilson:
 1. https://reviews.llvm.org/D41955
 2. https://reviews.llvm.org/D42585

The primary difference that we see in the test output is that
for relocatable (-r) output we now have symbol table which
replaces exports/imports and globals.

See: https://github.com/WebAssembly/tool-conventions/issues/38
Differential Revision: https://reviews.llvm.org/D43264

Added:
    lld/trunk/wasm/InputGlobal.h   (with props)
Modified:
    lld/trunk/test/wasm/alias.ll
    lld/trunk/test/wasm/archive.ll
    lld/trunk/test/wasm/data-layout.ll
    lld/trunk/test/wasm/init-fini.ll
    lld/trunk/test/wasm/locals-duplicate.test
    lld/trunk/test/wasm/many-functions.ll
    lld/trunk/test/wasm/relocatable.ll
    lld/trunk/test/wasm/signature-mismatch-weak.ll
    lld/trunk/test/wasm/signature-mismatch.ll
    lld/trunk/test/wasm/stack-pointer.ll
    lld/trunk/test/wasm/weak-alias.ll
    lld/trunk/wasm/Driver.cpp
    lld/trunk/wasm/InputChunks.cpp
    lld/trunk/wasm/InputChunks.h
    lld/trunk/wasm/InputFiles.cpp
    lld/trunk/wasm/InputFiles.h
    lld/trunk/wasm/MarkLive.cpp
    lld/trunk/wasm/OutputSegment.h
    lld/trunk/wasm/SymbolTable.cpp
    lld/trunk/wasm/SymbolTable.h
    lld/trunk/wasm/Symbols.cpp
    lld/trunk/wasm/Symbols.h
    lld/trunk/wasm/Writer.cpp
    lld/trunk/wasm/WriterUtils.cpp
    lld/trunk/wasm/WriterUtils.h

Modified: lld/trunk/test/wasm/alias.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/alias.ll?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/alias.ll (original)
+++ lld/trunk/test/wasm/alias.ll Thu Feb 22 21:08:53 2018
@@ -58,10 +58,10 @@ entry:
 ; CHECK-NEXT:       - Name:            memory
 ; CHECK-NEXT:         Kind:            MEMORY
 ; CHECK-NEXT:         Index:           0
-; CHECK-NEXT:       - Name:            start_alias
+; CHECK-NEXT:       - Name:            _start
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           0
-; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:       - Name:            start_alias
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           0
 ; CHECK-NEXT:       - Name:            __heap_base

Modified: lld/trunk/test/wasm/archive.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/archive.ll?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/archive.ll (original)
+++ lld/trunk/test/wasm/archive.ll Thu Feb 22 21:08:53 2018
@@ -9,7 +9,7 @@
 ; CHECK-UNDEFINED: undefined symbol: missing_func
 
 ; RUN: echo 'missing_func' > %t.imports
-; RUN: wasm-ld --check-signatures %t.a %t.o -o %t.wasm
+; RUN: wasm-ld --check-signatures -r %t.a %t.o -o %t.wasm
 
 ; RUN: llvm-nm -a %t.wasm | FileCheck %s
 
@@ -25,12 +25,16 @@ entry:
   ret void
 }
 
-; 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.
+;
+; TODO(ncw): Update LLD so that the symbol table is written out for
+;   non-relocatable output (with an option to strip it)
 
 ; CHECK:      00000003 T _start
 ; CHECK-NEXT: 00000001 T bar
 ; CHECK-NEXT: 00000002 T foo
+; CHECK-NEXT:          U missing_func
 
 ; Verify that symbols from unused objects don't appear in the symbol table
 ; CHECK-NOT: hello

Modified: lld/trunk/test/wasm/data-layout.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/data-layout.ll?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/data-layout.ll (original)
+++ lld/trunk/test/wasm/data-layout.ll Thu Feb 22 21:08:53 2018
@@ -46,25 +46,10 @@ target triple = "wasm32-unknown-unknown-
 ; RUN: wasm-ld --check-signatures --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
-; RELOC-NEXT:         Index:           3
+; RELOC-NEXT:         Index:           5
 ; RELOC-NEXT:         Offset:          0x00000018
 ; RELOC-NEXT:     Segments:
 ; RELOC-NEXT:       - SectionOffset:   6
@@ -92,6 +77,31 @@ target triple = "wasm32-unknown-unknown-
 ; RELOC-NEXT:           Value:           28
 ; RELOC-NEXT:         Content:         68656C6C6F0A00
 
-; RELOC:       - Type:            CUSTOM
+; RELOC:        - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            linking
 ; RELOC-NEXT:     DataSize:        35
+; RELOC-NEXT:     SymbolTable:
+; RELOC-NEXT:       - Index:           0
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            foo
+; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Segment:         0
+; RELOC-NEXT:         Size:            4
+; RELOC-NEXT:       - Index:           1
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            aligned_bar
+; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Segment:         1
+; RELOC-NEXT:         Size:            4
+; RELOC-NEXT:       - Index:           2
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            external_ref
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Segment:         2
+; RELOC-NEXT:         Size:            4
+; RELOC:            - Index:           5
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            hello_str
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Segment:         3
+; RELOC-NEXT:         Size:            7

Modified: lld/trunk/test/wasm/init-fini.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/init-fini.ll?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/init-fini.ll (original)
+++ lld/trunk/test/wasm/init-fini.ll Thu Feb 22 21:08:53 2018
@@ -107,66 +107,129 @@ entry:
 
 ; RELOC:          Name:            linking
 ; RELOC-NEXT:     DataSize:        0
-; RELOC-NEXT:     SymbolInfo:
-; RELOC-NEXT:       - Name:            __dso_handle
-; RELOC-NEXT:         Flags:           [ BINDING_WEAK, VISIBILITY_HIDDEN ]
-; RELOC-NEXT:       - Name:            func1
-; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; RELOC-NEXT:       - Name:            func2
-; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; RELOC-NEXT:       - Name:            func3
-; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; RELOC-NEXT:       - Name:            func4
-; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; RELOC-NEXT:       - Name:            _start
-; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; RELOC-NEXT:       - Name:            .Lcall_dtors.101
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            .Lregister_call_dtors.101
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            .Lcall_dtors.1001
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            .Lregister_call_dtors.1001
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            myctor
-; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; RELOC-NEXT:       - Name:            mydtor
-; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; RELOC-NEXT:       - Name:            .Lcall_dtors.101.1
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            .Lregister_call_dtors.101.1
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            .Lcall_dtors.202
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            .Lregister_call_dtors.202
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            .Lcall_dtors.2002
-; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            .Lregister_call_dtors.2002
+; RELOC-NEXT:     SymbolTable:
+; RELOC-NEXT:       - Index:           0
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            __dso_handle
+; RELOC-NEXT:         Flags:           [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ]
+; RELOC-NEXT:       - Index:           1
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            func1
+; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Function:        0
+; RELOC-NEXT:       - Index:           2
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            func2
+; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Function:        1
+; RELOC-NEXT:       - Index:           3
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            func3
+; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Function:        2
+; RELOC-NEXT:       - Index:           4
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            func4
+; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Function:        3
+; RELOC-NEXT:       - Index:           5
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            __cxa_atexit
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        4
+; RELOC-NEXT:       - Index:           6
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            _start
+; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Function:        5
+; RELOC-NEXT:       - Index:           7
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lcall_dtors.101
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        6
+; RELOC-NEXT:       - Index:           8
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lregister_call_dtors.101
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        7
+; RELOC-NEXT:       - Index:           9
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lcall_dtors.1001
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        8
+; RELOC-NEXT:       - Index:           10
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lregister_call_dtors.1001
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        9
+; RELOC-NEXT:       - Index:           11
+; RELOC-NEXT:         Kind:            GLOBAL
+; RELOC-NEXT:         Name:            __stack_pointer
+; RELOC-NEXT:         Flags:           [ UNDEFINED ]
+; RELOC-NEXT:         Global:          0
+; RELOC-NEXT:       - Index:           12
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            myctor
+; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Function:        10
+; RELOC-NEXT:       - Index:           13
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            mydtor
+; RELOC-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT:         Function:        11
+; RELOC-NEXT:       - Index:           14
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lcall_dtors.101
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        12
+; RELOC-NEXT:       - Index:           15
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lregister_call_dtors.101
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        13
+; RELOC-NEXT:       - Index:           16
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lcall_dtors.202
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        14
+; RELOC-NEXT:       - Index:           17
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lregister_call_dtors.202
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        15
+; RELOC-NEXT:       - Index:           18
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lcall_dtors.2002
+; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        16
+; RELOC-NEXT:       - Index:           19
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            .Lregister_call_dtors.2002
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Function:        17
 ; RELOC-NEXT:     InitFunctions:
 ; RELOC-NEXT:       - Priority:        101
-; RELOC-NEXT:         FunctionIndex:   0
+; RELOC-NEXT:         Symbol:          1
 ; RELOC-NEXT:       - Priority:        101
-; RELOC-NEXT:         FunctionIndex:   1
+; RELOC-NEXT:         Symbol:          2
 ; RELOC-NEXT:       - Priority:        101
-; RELOC-NEXT:         FunctionIndex:   7
+; RELOC-NEXT:         Symbol:          8
 ; RELOC-NEXT:       - Priority:        101
-; RELOC-NEXT:         FunctionIndex:   10
+; RELOC-NEXT:         Symbol:          12
 ; RELOC-NEXT:       - Priority:        101
-; RELOC-NEXT:         FunctionIndex:   13
+; RELOC-NEXT:         Symbol:          15
 ; RELOC-NEXT:       - Priority:        202
-; RELOC-NEXT:         FunctionIndex:   10
+; RELOC-NEXT:         Symbol:          12
 ; RELOC-NEXT:       - Priority:        202
-; RELOC-NEXT:         FunctionIndex:   15
+; RELOC-NEXT:         Symbol:          17
 ; RELOC-NEXT:       - Priority:        1001
-; RELOC-NEXT:         FunctionIndex:   0
+; RELOC-NEXT:         Symbol:          1
 ; RELOC-NEXT:       - Priority:        1001
-; RELOC-NEXT:         FunctionIndex:   9
+; RELOC-NEXT:         Symbol:          10
 ; RELOC-NEXT:       - Priority:        2002
-; RELOC-NEXT:         FunctionIndex:   10
+; RELOC-NEXT:         Symbol:          12
 ; RELOC-NEXT:       - Priority:        2002
-; RELOC-NEXT:         FunctionIndex:   17
+; RELOC-NEXT:         Symbol:          19
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            name
 ; RELOC-NEXT:     FunctionNames:

Modified: lld/trunk/test/wasm/locals-duplicate.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/locals-duplicate.test?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/locals-duplicate.test (original)
+++ lld/trunk/test/wasm/locals-duplicate.test Thu Feb 22 21:08:53 2018
@@ -246,118 +246,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:
@@ -367,13 +255,13 @@
 ; RELOC-NEXT:   - Type:            CODE
 ; RELOC-NEXT:     Relocations:
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           0
+; RELOC-NEXT:         Index:           4
 ; RELOC-NEXT:         Offset:          0x00000013
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:         Index:           6
 ; RELOC-NEXT:         Offset:          0x0000001C
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           2
+; RELOC-NEXT:         Index:           8
 ; RELOC-NEXT:         Offset:          0x00000025
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
 ; RELOC-NEXT:         Index:           0
@@ -385,22 +273,22 @@
 ; RELOC-NEXT:         Index:           2
 ; RELOC-NEXT:         Offset:          0x00000040
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           3
+; RELOC-NEXT:         Index:           16
 ; RELOC-NEXT:         Offset:          0x00000058
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           4
+; RELOC-NEXT:         Index:           18
 ; RELOC-NEXT:         Offset:          0x00000061
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT:         Index:           5
+; 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
@@ -480,23 +368,136 @@
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            linking
 ; RELOC-NEXT:     DataSize:        24
-; RELOC-NEXT:     SymbolInfo:
-; RELOC-NEXT:       - Name:            colliding_func1.1
+; RELOC-NEXT:     SymbolTable:
+; RELOC-NEXT:       - Index:           0
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            colliding_func1
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            colliding_func3
+; RELOC-NEXT:         Function:        0
+; RELOC-NEXT:       - Index:           1
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            colliding_func2
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        1
+; RELOC-NEXT:       - Index:           2
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            colliding_func3
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            colliding_func2.1
+; RELOC-NEXT:         Function:        2
+; RELOC-NEXT:       - Index:           3
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_global1A
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        3
+; RELOC-NEXT:       - Index:           4
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            colliding_global1
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            colliding_func3.1
+; RELOC-NEXT:         Segment:         0
+; RELOC-NEXT:         Size:            4
+; RELOC-NEXT:       - Index:           5
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_global2A
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        4
+; RELOC-NEXT:       - Index:           6
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            colliding_global2
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Segment:         1
+; RELOC-NEXT:         Size:            4
+; RELOC-NEXT:       - Index:           7
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_global3A
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        5
+; RELOC-NEXT:       - Index:           8
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            colliding_global3
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            colliding_global1.1
+; RELOC-NEXT:         Segment:         2
+; RELOC-NEXT:         Size:            4
+; RELOC-NEXT:       - Index:           9
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_func1A
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        6
+; RELOC-NEXT:       - Index:           10
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_func2A
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        7
+; RELOC-NEXT:       - Index:           11
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_func3A
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        8
+; RELOC-NEXT:       - Index:           12
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            colliding_func1
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        9
+; RELOC-NEXT:       - Index:           13
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            colliding_func2
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            colliding_global3
+; RELOC-NEXT:         Function:        10
+; RELOC-NEXT:       - Index:           14
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            colliding_func3
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            colliding_global2.1
+; RELOC-NEXT:         Function:        11
+; RELOC-NEXT:       - Index:           15
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_global1B
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        12
+; RELOC-NEXT:       - Index:           16
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            colliding_global1
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Segment:         0
+; RELOC-NEXT:         Offset:          4
+; RELOC-NEXT:         Size:            4
+; RELOC-NEXT:       - Index:           17
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_global2B
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        13
+; RELOC-NEXT:       - Index:           18
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            colliding_global2
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
-; RELOC-NEXT:       - Name:            colliding_global3.1
+; RELOC-NEXT:         Segment:         1
+; RELOC-NEXT:         Offset:          4
+; RELOC-NEXT:         Size:            4
+; RELOC-NEXT:       - Index:           19
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_global3B
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        14
+; RELOC-NEXT:       - Index:           20
+; RELOC-NEXT:         Kind:            DATA
+; RELOC-NEXT:         Name:            colliding_global3
 ; RELOC-NEXT:         Flags:           [ BINDING_LOCAL ]
+; RELOC-NEXT:         Segment:         2
+; RELOC-NEXT:         Offset:          4
+; RELOC-NEXT:         Size:            4
+; RELOC-NEXT:       - Index:           21
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_func1B
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        15
+; RELOC-NEXT:       - Index:           22
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_func2B
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        16
+; RELOC-NEXT:       - Index:           23
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            get_func3B
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        17
 ; RELOC-NEXT:     SegmentInfo:
 ; RELOC-NEXT:       - Index:           0
 ; RELOC-NEXT:         Name:            .bss.colliding_global1

Modified: lld/trunk/test/wasm/many-functions.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/many-functions.ll?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/many-functions.ll (original)
+++ lld/trunk/test/wasm/many-functions.ll Thu Feb 22 21:08:53 2018
@@ -19,394 +19,394 @@ entry:
 ; CHECK:        - Type:            CODE
 ; CHECK-NEXT:     Relocations:
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000008
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000014
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000020
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000002C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000038
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000044
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000050
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000005C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000068
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000074
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000080
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000008C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000098
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000A4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000B0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000BC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000C8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000D4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000E0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000EC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000000F8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000104
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000110
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000011C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000128
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000134
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000140
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000014C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000158
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000164
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000170
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000017C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000188
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000194
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001A0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001AC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001B8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001C4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001D0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001DC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001E8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000001F4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000200
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000020C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000218
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000224
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000230
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000023C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000248
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000254
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000260
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000026C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000278
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000284
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000290
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000029C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002A8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002B4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002C0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002CC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002D8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002E4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002F0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000002FC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000308
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000314
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000320
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000032C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000338
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000344
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000350
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000035C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000368
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000374
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000380
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000038C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000398
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003A4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003B0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003BC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003C8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003D4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003E0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003EC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000003F8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000404
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000410
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000041C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000428
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000434
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000440
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000044C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000458
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000464
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000470
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000047C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000488
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000494
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004A0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004AC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004B8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004C4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004D0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004DC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004E8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000004F4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000500
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000050C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000518
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000524
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000530
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000053C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000548
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000554
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000560
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000056C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000578
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000584
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x00000590
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x0000059C
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005A8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005B4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005C0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005CC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005D8
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005E4
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:         Offset:          0x000005F0
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:         Index:           129
 ; CHECK-NEXT:         Offset:          0x000005FC
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
-; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:         Index:           129
 ; CHECK-NEXT:         Offset:          0x00000608
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; CHECK-NEXT:         Index:           129
+; CHECK-NEXT:         Index:           131
 ; CHECK-NEXT:         Offset:          0x00000611
 ; CHECK-NEXT:     Functions:
 ; CHECK-NEXT:       - Index:           0
@@ -816,6 +816,669 @@ entry:
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
 ; CHECK-NEXT:     DataSize:        8
+; CHECK-NEXT:     SymbolTable:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f1
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        0
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            foo
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Segment:         1
+; CHECK-NEXT:         Size:            4
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f2
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        1
+; CHECK-NEXT:       - Index:           3
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f3
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        2
+; CHECK-NEXT:       - Index:           4
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f4
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        3
+; CHECK-NEXT:       - Index:           5
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f5
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        4
+; CHECK-NEXT:       - Index:           6
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f6
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        5
+; CHECK-NEXT:       - Index:           7
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f7
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        6
+; CHECK-NEXT:       - Index:           8
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f8
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        7
+; CHECK-NEXT:       - Index:           9
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f9
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        8
+; CHECK-NEXT:       - Index:           10
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f10
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        9
+; CHECK-NEXT:       - Index:           11
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f11
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        10
+; CHECK-NEXT:       - Index:           12
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f12
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        11
+; CHECK-NEXT:       - Index:           13
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f13
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        12
+; CHECK-NEXT:       - Index:           14
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f14
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        13
+; CHECK-NEXT:       - Index:           15
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f15
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        14
+; CHECK-NEXT:       - Index:           16
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f16
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        15
+; CHECK-NEXT:       - Index:           17
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f17
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        16
+; CHECK-NEXT:       - Index:           18
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f18
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        17
+; CHECK-NEXT:       - Index:           19
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f19
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        18
+; CHECK-NEXT:       - Index:           20
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f20
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        19
+; CHECK-NEXT:       - Index:           21
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f21
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        20
+; CHECK-NEXT:       - Index:           22
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f22
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        21
+; CHECK-NEXT:       - Index:           23
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f23
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        22
+; CHECK-NEXT:       - Index:           24
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f24
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        23
+; CHECK-NEXT:       - Index:           25
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f25
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        24
+; CHECK-NEXT:       - Index:           26
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f26
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        25
+; CHECK-NEXT:       - Index:           27
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f27
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        26
+; CHECK-NEXT:       - Index:           28
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f28
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        27
+; CHECK-NEXT:       - Index:           29
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f29
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        28
+; CHECK-NEXT:       - Index:           30
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f30
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        29
+; CHECK-NEXT:       - Index:           31
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f31
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        30
+; CHECK-NEXT:       - Index:           32
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f32
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        31
+; CHECK-NEXT:       - Index:           33
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f33
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        32
+; CHECK-NEXT:       - Index:           34
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f34
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        33
+; CHECK-NEXT:       - Index:           35
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f35
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        34
+; CHECK-NEXT:       - Index:           36
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f36
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        35
+; CHECK-NEXT:       - Index:           37
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f37
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        36
+; CHECK-NEXT:       - Index:           38
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f38
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        37
+; CHECK-NEXT:       - Index:           39
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f39
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        38
+; CHECK-NEXT:       - Index:           40
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f40
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        39
+; CHECK-NEXT:       - Index:           41
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f41
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        40
+; CHECK-NEXT:       - Index:           42
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f42
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        41
+; CHECK-NEXT:       - Index:           43
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f43
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        42
+; CHECK-NEXT:       - Index:           44
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f44
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        43
+; CHECK-NEXT:       - Index:           45
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f45
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        44
+; CHECK-NEXT:       - Index:           46
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f46
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        45
+; CHECK-NEXT:       - Index:           47
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f47
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        46
+; CHECK-NEXT:       - Index:           48
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f48
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        47
+; CHECK-NEXT:       - Index:           49
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f49
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        48
+; CHECK-NEXT:       - Index:           50
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f50
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        49
+; CHECK-NEXT:       - Index:           51
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f51
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        50
+; CHECK-NEXT:       - Index:           52
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f52
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        51
+; CHECK-NEXT:       - Index:           53
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f53
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        52
+; CHECK-NEXT:       - Index:           54
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f54
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        53
+; CHECK-NEXT:       - Index:           55
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f55
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        54
+; CHECK-NEXT:       - Index:           56
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f56
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        55
+; CHECK-NEXT:       - Index:           57
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f57
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        56
+; CHECK-NEXT:       - Index:           58
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f58
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        57
+; CHECK-NEXT:       - Index:           59
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f59
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        58
+; CHECK-NEXT:       - Index:           60
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f60
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        59
+; CHECK-NEXT:       - Index:           61
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f61
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        60
+; CHECK-NEXT:       - Index:           62
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f62
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        61
+; CHECK-NEXT:       - Index:           63
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f63
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        62
+; CHECK-NEXT:       - Index:           64
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f64
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        63
+; CHECK-NEXT:       - Index:           65
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f65
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        64
+; CHECK-NEXT:       - Index:           66
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f66
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        65
+; CHECK-NEXT:       - Index:           67
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f67
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        66
+; CHECK-NEXT:       - Index:           68
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f68
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        67
+; CHECK-NEXT:       - Index:           69
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f69
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        68
+; CHECK-NEXT:       - Index:           70
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f70
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        69
+; CHECK-NEXT:       - Index:           71
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f71
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        70
+; CHECK-NEXT:       - Index:           72
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f72
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        71
+; CHECK-NEXT:       - Index:           73
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f73
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        72
+; CHECK-NEXT:       - Index:           74
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f74
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        73
+; CHECK-NEXT:       - Index:           75
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f75
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        74
+; CHECK-NEXT:       - Index:           76
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f76
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        75
+; CHECK-NEXT:       - Index:           77
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f77
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        76
+; CHECK-NEXT:       - Index:           78
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f78
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        77
+; CHECK-NEXT:       - Index:           79
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f79
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        78
+; CHECK-NEXT:       - Index:           80
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f80
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        79
+; CHECK-NEXT:       - Index:           81
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f81
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        80
+; CHECK-NEXT:       - Index:           82
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f82
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        81
+; CHECK-NEXT:       - Index:           83
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f83
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        82
+; CHECK-NEXT:       - Index:           84
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f84
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        83
+; CHECK-NEXT:       - Index:           85
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f85
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        84
+; CHECK-NEXT:       - Index:           86
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f86
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        85
+; CHECK-NEXT:       - Index:           87
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f87
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        86
+; CHECK-NEXT:       - Index:           88
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f88
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        87
+; CHECK-NEXT:       - Index:           89
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f89
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        88
+; CHECK-NEXT:       - Index:           90
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f90
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        89
+; CHECK-NEXT:       - Index:           91
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f91
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        90
+; CHECK-NEXT:       - Index:           92
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f92
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        91
+; CHECK-NEXT:       - Index:           93
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f93
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        92
+; CHECK-NEXT:       - Index:           94
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f94
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        93
+; CHECK-NEXT:       - Index:           95
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f95
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        94
+; CHECK-NEXT:       - Index:           96
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f96
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        95
+; CHECK-NEXT:       - Index:           97
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f97
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        96
+; CHECK-NEXT:       - Index:           98
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f98
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        97
+; CHECK-NEXT:       - Index:           99
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f99
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        98
+; CHECK-NEXT:       - Index:           100
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f100
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        99
+; CHECK-NEXT:       - Index:           101
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f101
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        100
+; CHECK-NEXT:       - Index:           102
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f102
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        101
+; CHECK-NEXT:       - Index:           103
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f103
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        102
+; CHECK-NEXT:       - Index:           104
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f104
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        103
+; CHECK-NEXT:       - Index:           105
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f105
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        104
+; CHECK-NEXT:       - Index:           106
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f106
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        105
+; CHECK-NEXT:       - Index:           107
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f107
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        106
+; CHECK-NEXT:       - Index:           108
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f108
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        107
+; CHECK-NEXT:       - Index:           109
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f109
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        108
+; CHECK-NEXT:       - Index:           110
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f110
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        109
+; CHECK-NEXT:       - Index:           111
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f111
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        110
+; CHECK-NEXT:       - Index:           112
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f112
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        111
+; CHECK-NEXT:       - Index:           113
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f113
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        112
+; CHECK-NEXT:       - Index:           114
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f114
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        113
+; CHECK-NEXT:       - Index:           115
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f115
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        114
+; CHECK-NEXT:       - Index:           116
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f116
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        115
+; CHECK-NEXT:       - Index:           117
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f117
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        116
+; CHECK-NEXT:       - Index:           118
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f118
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        117
+; CHECK-NEXT:       - Index:           119
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f119
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        118
+; CHECK-NEXT:       - Index:           120
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f120
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        119
+; CHECK-NEXT:       - Index:           121
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f121
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        120
+; CHECK-NEXT:       - Index:           122
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f122
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        121
+; CHECK-NEXT:       - Index:           123
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f123
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        122
+; CHECK-NEXT:       - Index:           124
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f124
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        123
+; CHECK-NEXT:       - Index:           125
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f125
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        124
+; CHECK-NEXT:       - Index:           126
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f126
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        125
+; CHECK-NEXT:       - Index:           127
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f127
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        126
+; CHECK-NEXT:       - Index:           128
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f128
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        127
+; CHECK-NEXT:       - Index:           129
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            g0
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Segment:         0
+; CHECK-NEXT:         Size:            4
+; CHECK-NEXT:       - Index:           130
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            f129
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        128
+; CHECK-NEXT:       - Index:           131
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            func
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        129
 ; CHECK-NEXT:     SegmentInfo:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            .data.g0

Modified: lld/trunk/test/wasm/relocatable.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/relocatable.ll?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/relocatable.ll (original)
+++ lld/trunk/test/wasm/relocatable.ll Thu Feb 22 21:08:53 2018
@@ -59,11 +59,6 @@ entry:
 ; CHECK-NEXT:         Field:           bar_import
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         SigIndex:        1
-; 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:   [ 2, 1, 1 ]
 ; CHECK-NEXT:   - Type:            TABLE
@@ -76,73 +71,6 @@ entry:
 ; 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,19 +80,19 @@ entry:
 ; CHECK-NEXT:   - Type:            CODE
 ; CHECK-NEXT:     Relocations:
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; CHECK-NEXT:         Index:           1
+; 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:           2
+; CHECK-NEXT:         Index:           8
 ; CHECK-NEXT:         Offset:          0x00000026
 ; CHECK-NEXT:     Functions:
 ; CHECK-NEXT:       - Index:         3
@@ -179,16 +107,16 @@ entry:
 ; CHECK-NEXT:   - Type:            DATA
 ; CHECK-NEXT:     Relocations:
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_I32
-; CHECK-NEXT:         Index:           4
+; 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:           0
+; CHECK-NEXT:         Index:           5
 ; CHECK-NEXT:         Offset:          0x0000002D
 ; CHECK-NEXT:     Segments:
 ; CHECK-NEXT:       - SectionOffset:   6
@@ -230,25 +158,77 @@ entry:
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
 ; CHECK-NEXT:     DataSize:        31
-; CHECK-NEXT:     SymbolInfo:
-; CHECK-NEXT:       - Name:            bar_import
-; CHECK-NEXT:         Flags:           [ BINDING_WEAK ]
-; CHECK-NEXT:       - Name:            hello
+; CHECK-NEXT:     SymbolTable:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            puts
+; CHECK-NEXT:         Flags:           [ UNDEFINED ]
+; CHECK-NEXT:         Function:        0
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            hello
 ; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT:       - Name:            my_func
+; CHECK-NEXT:         Function:        3
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            hello_str
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Segment:         0
+; CHECK-NEXT:         Size:            7
+; CHECK-NEXT:       - Index:           3
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            foo_import
+; CHECK-NEXT:         Flags:           [ UNDEFINED ]
+; CHECK-NEXT:         Function:        1
+; CHECK-NEXT:       - Index:           4
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            bar_import
+; CHECK-NEXT:         Flags:           [ BINDING_WEAK, UNDEFINED ]
+; CHECK-NEXT:         Function:        2
+; CHECK-NEXT:       - Index:           5
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            data_import
+; CHECK-NEXT:         Flags:           [ UNDEFINED ]
+; CHECK-NEXT:       - Index:           6
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            my_func
 ; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT:       - Name:            func_comdat
+; CHECK-NEXT:         Function:        4
+; CHECK-NEXT:       - Index:           7
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            func_comdat
 ; CHECK-NEXT:         Flags:           [ BINDING_WEAK ]
-; CHECK-NEXT:       - Name:            data_comdat
+; CHECK-NEXT:         Function:        5
+; CHECK-NEXT:       - Index:           8
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            data_comdat
 ; CHECK-NEXT:         Flags:           [ BINDING_WEAK ]
-; CHECK-NEXT:       - Name:            func_addr1
-; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT:       - Name:            func_addr2
-; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT:       - Name:            func_addr3
-; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT:       - Name:            data_addr1
+; CHECK-NEXT:         Segment:         5
+; CHECK-NEXT:         Size:            3
+; CHECK-NEXT:       - Index:           9
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            func_addr1
+; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT:         Segment:         1
+; CHECK-NEXT:         Size:            4
+; CHECK-NEXT:       - Index:           10
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            func_addr2
+; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT:         Segment:         2
+; CHECK-NEXT:         Size:            4
+; CHECK-NEXT:       - Index:           11
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            func_addr3
+; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT:         Segment:         3
+; CHECK-NEXT:         Size:            4
+; CHECK-NEXT:       - Index:           12
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            data_addr1
 ; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT:         Segment:         4
+; CHECK-NEXT:         Size:            4
 ; CHECK-NEXT:     SegmentInfo:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            .rodata.hello_str

Modified: lld/trunk/test/wasm/signature-mismatch-weak.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/signature-mismatch-weak.ll?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/signature-mismatch-weak.ll (original)
+++ lld/trunk/test/wasm/signature-mismatch-weak.ll Thu Feb 22 21:08:53 2018
@@ -14,6 +14,6 @@ entry:
   ret void
 }
 
-; CHECK: error: function signature mismatch: weakFn
+; CHECK: error: Function type mismatch: weakFn
 ; CHECK-NEXT: >>> defined as () -> I32 in {{.*}}signature-mismatch-weak.ll.tmp.o
 ; CHECK-NEXT: >>> defined as () -> I64 in {{.*}}signature-mismatch-weak.ll.tmp.strong.o

Modified: lld/trunk/test/wasm/signature-mismatch.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/signature-mismatch.ll?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/signature-mismatch.ll (original)
+++ lld/trunk/test/wasm/signature-mismatch.ll Thu Feb 22 21:08:53 2018
@@ -17,10 +17,10 @@ entry:
 
 declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1
 
-; CHECK: error: function signature mismatch: ret32
+; CHECK: error: Function type mismatch: ret32
 ; CHECK-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o
 ; CHECK-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o
 
-; REVERSE: error: function signature mismatch: ret32
+; REVERSE: error: Function type mismatch: ret32
 ; REVERSE-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o
 ; REVERSE-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o

Modified: lld/trunk/test/wasm/stack-pointer.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/stack-pointer.ll?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/stack-pointer.ll (original)
+++ lld/trunk/test/wasm/stack-pointer.ll Thu Feb 22 21:08:53 2018
@@ -26,7 +26,7 @@ entry:
 ; 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 @@ entry:
 ; 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 @@ entry:
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
 ; CHECK-NEXT:     DataSize:        0
+; CHECK-NEXT:     SymbolTable:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Name:            __stack_pointer
+; CHECK-NEXT:         Flags:           [ UNDEFINED ]
+; CHECK-NEXT:         Global:          0
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Name:            _start
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:         Function:        0
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            name
 ; CHECK-NEXT:     FunctionNames:

Modified: lld/trunk/test/wasm/weak-alias.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/weak-alias.ll?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/test/wasm/weak-alias.ll (original)
+++ lld/trunk/test/wasm/weak-alias.ll Thu Feb 22 21:08:53 2018
@@ -68,9 +68,6 @@ entry:
 ; CHECK-NEXT:       - Name:            _start
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           0
-; CHECK-NEXT:       - Name:            alias_fn
-; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:       - Name:            direct_fn
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           1
@@ -86,6 +83,9 @@ entry:
 ; CHECK-NEXT:       - Name:            call_direct_ptr
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           5
+; 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
@@ -168,7 +168,7 @@ entry:
 ; 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, 1, 1, 1, 1, 1 ]
 ; RELOC-NEXT:   - Type:            TABLE
@@ -181,29 +181,6 @@ entry:
 ; 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:            alias_fn
-; RELOC-NEXT:         Kind:            FUNCTION
-; RELOC-NEXT:         Index:           1
-; 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:   - Type:            ELEM
 ; RELOC-NEXT:     Segments:
 ; RELOC-NEXT:       - Offset:
@@ -213,43 +190,43 @@ entry:
 ; RELOC-NEXT:   - Type:            CODE
 ; RELOC-NEXT:     Relocations:
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:         Index:           7
 ; RELOC-NEXT:         Offset:          0x00000004
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:         Index:           2
 ; RELOC-NEXT:         Offset:          0x00000013
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:         Index:           7
 ; RELOC-NEXT:         Offset:          0x0000001C
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
-; RELOC-NEXT:         Index:           0
+; RELOC-NEXT:         Index:           1
 ; RELOC-NEXT:         Offset:          0x00000027
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
-; RELOC-NEXT:         Index:           0
+; RELOC-NEXT:         Index:           1
 ; RELOC-NEXT:         Offset:          0x00000032
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:         Index:           7
 ; RELOC-NEXT:         Offset:          0x0000003A
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:         Index:           7
 ; RELOC-NEXT:         Offset:          0x00000043
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
-; RELOC-NEXT:         Index:           0
+; RELOC-NEXT:         Index:           1
 ; RELOC-NEXT:         Offset:          0x00000050
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
-; RELOC-NEXT:         Index:           0
+; RELOC-NEXT:         Index:           1
 ; RELOC-NEXT:         Offset:          0x0000005D
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
-; RELOC-NEXT:         Index:           0
+; RELOC-NEXT:         Index:           1
 ; RELOC-NEXT:         Offset:          0x00000068
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:         Index:           2
 ; RELOC-NEXT:         Offset:          0x00000070
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT:         Index:           1
+; RELOC-NEXT:         Index:           2
 ; RELOC-NEXT:         Offset:          0x00000079
 ; RELOC-NEXT:       - Type:            R_WEBASSEMBLY_GLOBAL_INDEX_LEB
-; RELOC-NEXT:         Index:           0
+; RELOC-NEXT:         Index:           1
 ; RELOC-NEXT:         Offset:          0x00000086
 ; RELOC-NEXT:     Functions:
 ; RELOC-NEXT:       - Index:           0
@@ -277,9 +254,47 @@ entry:
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            linking
 ; RELOC-NEXT:     DataSize:        0
-; RELOC-NEXT:     SymbolInfo:
-; RELOC-NEXT:       - Name:            alias_fn
+; RELOC-NEXT:     SymbolTable:
+; RELOC-NEXT:       - Index:           0
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            _start
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        0
+; RELOC-NEXT:       - Index:           1
+; RELOC-NEXT:         Kind:            GLOBAL
+; RELOC-NEXT:         Name:            __stack_pointer
+; RELOC-NEXT:         Flags:           [ UNDEFINED ]
+; RELOC-NEXT:         Global:          0
+; RELOC-NEXT:       - Index:           2
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            direct_fn
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        1
+; RELOC-NEXT:       - Index:           3
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            call_direct
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        2
+; RELOC-NEXT:       - Index:           4
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            call_alias
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        3
+; RELOC-NEXT:       - Index:           5
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            call_alias_ptr
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        4
+; RELOC-NEXT:       - Index:           6
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            call_direct_ptr
+; RELOC-NEXT:         Flags:           [  ]
+; RELOC-NEXT:         Function:        5
+; RELOC-NEXT:       - Index:           7
+; RELOC-NEXT:         Kind:            FUNCTION
+; RELOC-NEXT:         Name:            alias_fn
 ; RELOC-NEXT:         Flags:           [ BINDING_WEAK ]
+; RELOC-NEXT:         Function:        1
 ; RELOC-NEXT:   - Type:            CUSTOM
 ; RELOC-NEXT:     Name:            name
 ; RELOC-NEXT:     FunctionNames:

Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Thu Feb 22 21:08:53 2018
@@ -9,6 +9,7 @@
 
 #include "lld/Common/Driver.h"
 #include "Config.h"
+#include "InputGlobal.h"
 #include "MarkLive.h"
 #include "SymbolTable.h"
 #include "Writer.h"
@@ -59,6 +60,7 @@ private:
   void addFile(StringRef Path);
   void addLibrary(StringRef Name);
   std::vector<InputFile *> Files;
+  llvm::wasm::WasmGlobal StackPointerGlobal;
 };
 
 } // anonymous namespace
@@ -222,8 +224,8 @@ static StringRef getEntry(opt::InputArgL
   return Arg->getValue();
 }
 
-static Symbol* addUndefinedFunction(StringRef Name, const WasmSignature *Type) {
-  return Symtab->addUndefined(Name, Symbol::UndefinedFunctionKind, 0, nullptr,
+static Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type) {
+  return Symtab->addUndefined(Name, WASM_SYMBOL_TYPE_FUNCTION, 0, nullptr,
                               Type);
 }
 
@@ -296,14 +298,25 @@ void LinkerDriver::link(ArrayRef<const c
 
   Symbol *EntrySym = nullptr;
   if (!Config->Relocatable) {
-    static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT};
+    // 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 WASM_SYMBOL_VISIBILITY_HIDDEN if/when the
+    // "mutable global" proposal is accepted.
+    StackPointerGlobal.Type = {WASM_TYPE_I32, true};
+    StackPointerGlobal.InitExpr.Value.Int32 = 0;
+    StackPointerGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
+    InputGlobal *StackPointer = make<InputGlobal>(StackPointerGlobal);
+    StackPointer->Live = true;
 
+    static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT};
     // Add synthetic symbols before any others
     WasmSym::CallCtors = Symtab->addSyntheticFunction(
         "__wasm_call_ctors", &NullSignature, WASM_SYMBOL_VISIBILITY_HIDDEN);
-    WasmSym::StackPointer = Symtab->addSyntheticDataSymbol("__stack_pointer");
+    WasmSym::StackPointer = Symtab->addSyntheticGlobal(
+        "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer);
     WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base");
-    WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol("__dso_handle");
+    WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol(
+        "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
     WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end");
 
     if (!Config->Entry.empty())

Modified: lld/trunk/wasm/InputChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputChunks.cpp?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/InputChunks.cpp (original)
+++ lld/trunk/wasm/InputChunks.cpp Thu Feb 22 21:08:53 2018
@@ -27,12 +27,10 @@ std::string lld::toString(const InputChu
   return (toString(C->File) + ":(" + C->getName() + ")").str();
 }
 
-uint32_t InputSegment::translateVA(uint32_t Address) const {
-  assert(Address >= startVA() && Address < endVA());
-  int32_t Delta = OutputSeg->StartVA + OutputSegmentOffset - startVA();
-  DEBUG(dbgs() << "translateVA: " << getName() << " Delta=" << Delta
-               << " Address=" << Address << "\n");
-  return Address + Delta;
+uint32_t InputSegment::translateVA(uint32_t Offset) const {
+  assert(Offset <= getSize());
+  DEBUG(dbgs() << "translateVA: " << getName() << " Offset=" << Offset << "\n");
+  return OutputSeg->StartVA + OutputSegmentOffset + Offset;
 }
 
 void InputChunk::copyRelocations(const WasmSection &Section) {

Modified: lld/trunk/wasm/InputChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputChunks.h?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/InputChunks.h (original)
+++ lld/trunk/wasm/InputChunks.h Thu Feb 22 21:08:53 2018
@@ -7,8 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// An input chunk represents an indivisible blocks of code or data from an input
-// file.  i.e. a single wasm data segment or a single wasm function.
+// An InputChunks represents an indivisible opaque region of a input wasm file.
+// i.e. a single wasm data segment or a single wasm function.
+//
+// They are written directly to the mmap'd output file after which relocations
+// are applied.  Because each Chunk is independent they can be written in
+// parallel.
+//
+// Chunks are also unit on which garbage collection (--gc-sections) operates.
 //
 //===----------------------------------------------------------------------===//
 
@@ -92,7 +98,7 @@ public:
 
   // Translate an offset in the input segment to an offset in the output
   // segment.
-  uint32_t translateVA(uint32_t Address) const;
+  uint32_t translateVA(uint32_t Offset) const;
 
   const OutputSegment *getOutputSegment() const { return OutputSeg; }
 
@@ -102,8 +108,6 @@ public:
   }
 
   uint32_t getAlignment() const { return Segment.Data.Alignment; }
-  uint32_t startVA() const { return Segment.Data.Offset.Value.Int32; }
-  uint32_t endVA() const { return startVA() + getSize(); }
   StringRef getName() const override { return Segment.Data.Name; }
   StringRef getComdat() const override { return Segment.Data.Comdat; }
 

Modified: lld/trunk/wasm/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.cpp?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.cpp (original)
+++ lld/trunk/wasm/InputFiles.cpp Thu Feb 22 21:08:53 2018
@@ -10,6 +10,7 @@
 #include "InputFiles.h"
 #include "Config.h"
 #include "InputChunks.h"
+#include "InputGlobal.h"
 #include "SymbolTable.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
@@ -43,8 +44,7 @@ Optional<MemoryBufferRef> lld::wasm::rea
 
 void ObjFile::dumpInfo() const {
   log("info for: " + getName() + "\n" +
-      "      Total Functions : " + Twine(FunctionSymbols.size()) + "\n" +
-      "   Total Data Symbols : " + Twine(DataSymbols.size()) + "\n" +
+      "              Symbols : " + Twine(Symbols.size()) + "\n" +
       "     Function Imports : " + Twine(NumFunctionImports) + "\n" +
       "       Global Imports : " + Twine(NumGlobalImports) + "\n");
 }
@@ -71,6 +71,8 @@ uint32_t ObjFile::relocateTypeIndex(uint
 
 uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
   const FunctionSymbol *Sym = getFunctionSymbol(Original);
+  // The null case is possible, if you take the address of a weak function
+  // that's simply not supplied.
   uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0;
   DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original
                << " -> " << Index << "\n");
@@ -78,33 +80,30 @@ uint32_t ObjFile::relocateTableIndex(uin
 }
 
 uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
-  const Symbol *Sym = getDataSymbol(Original);
+  const Symbol *Sym = getGlobalSymbol(Original);
   uint32_t Index = Sym->getOutputIndex();
   DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original
                << " -> " << Index << "\n");
   return Index;
 }
 
+uint32_t ObjFile::relocateSymbolIndex(uint32_t Original) const {
+  Symbol *Sym = getSymbol(Original);
+  uint32_t Index = Sym->getOutputSymbolIndex();
+  DEBUG(dbgs() << "relocateSymbolIndex: " << toString(*Sym) << ": " << Original
+               << " -> " << Index << "\n");
+  return Index;
+}
+
 // Relocations contain an index into the function, global or table index
 // space of the input file.  This function takes a relocation and returns the
 // relocated index (i.e. translates from the input index space to the output
 // index space).
 uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
-  switch (Reloc.Type) {
-  case R_WEBASSEMBLY_TYPE_INDEX_LEB:
+  if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB)
     return relocateTypeIndex(Reloc.Index);
-  case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
-  case R_WEBASSEMBLY_TABLE_INDEX_I32:
-  case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
-    return relocateFunctionIndex(Reloc.Index);
-  case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
-  case R_WEBASSEMBLY_MEMORY_ADDR_I32:
-    return relocateGlobalIndex(Reloc.Index);
-  default:
-    llvm_unreachable("unknown relocation type");
-  }
+
+  return relocateSymbolIndex(Reloc.Index);
 }
 
 // Translate from the relocation's index into the final linked output value.
@@ -160,80 +159,60 @@ void ObjFile::parse() {
 
 // 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;
-}
-
-// 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 {
-  const WasmGlobal &Global =
-      getWasmObj()->globals()[Sym.ElementIndex - NumGlobalImports];
-  assert(Global.Type.Type == llvm::wasm::WASM_TYPE_I32);
-  return Global.InitExpr.Value.Int32;
-}
-
-// Get the signature for a given function symbol, either by looking
-// it up in function sections (for defined functions), of the imports section
-// (for imported functions).
-const WasmSignature *ObjFile::getFunctionSig(const WasmSymbol &Sym) const {
-  DEBUG(dbgs() << "getFunctionSig: " << Sym.Name << "\n");
-  return &WasmObj->types()[Sym.FunctionType];
+  return Segments[WasmSym.Info.DataRef.Segment];
 }
 
 InputFunction *ObjFile::getFunction(const WasmSymbol &Sym) const {
-  uint32_t FunctionIndex = Sym.ElementIndex - NumFunctionImports;
+  assert(Sym.Info.ElementIndex >= NumFunctionImports);
+  uint32_t FunctionIndex = Sym.Info.ElementIndex - NumFunctionImports;
   return Functions[FunctionIndex];
 }
 
+InputGlobal *ObjFile::getGlobal(const WasmSymbol &Sym) const {
+  assert(Sym.Info.ElementIndex >= NumGlobalImports);
+  uint32_t GlobalIndex = Sym.Info.ElementIndex - NumGlobalImports;
+  return Globals[GlobalIndex];
+}
+
 bool ObjFile::isExcludedByComdat(InputChunk *Chunk) const {
   StringRef Comdat = Chunk->getComdat();
   return !Comdat.empty() && Symtab->findComdat(Comdat) != this;
 }
 
+FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t Index) const {
+  return cast<FunctionSymbol>(Symbols[Index]);
+}
+
+GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t Index) const {
+  return cast<GlobalSymbol>(Symbols[Index]);
+}
+
+DataSymbol *ObjFile::getDataSymbol(uint32_t Index) const {
+  return cast<DataSymbol>(Symbols[Index]);
+}
+
 void ObjFile::initializeSymbols() {
   Symbols.reserve(WasmObj->getNumberOfSymbols());
 
-  for (const WasmImport &Import : WasmObj->imports()) {
-    switch (Import.Kind) {
-    case WASM_EXTERNAL_FUNCTION:
-      ++NumFunctionImports;
-      break;
-    case WASM_EXTERNAL_GLOBAL:
-      ++NumGlobalImports;
-      break;
-    }
-  }
-
-  FunctionSymbols.resize(NumFunctionImports + WasmObj->functions().size());
-  DataSymbols.resize(NumGlobalImports + WasmObj->globals().size());
+  NumFunctionImports = WasmObj->getNumImportedFunctions();
+  NumGlobalImports = WasmObj->getNumImportedGlobals();
 
   ArrayRef<WasmFunction> Funcs = WasmObj->functions();
   ArrayRef<uint32_t> FuncTypes = WasmObj->functionTypes();
   ArrayRef<WasmSignature> Types = WasmObj->types();
-  ArrayRef<WasmGlobal> Globals = WasmObj->globals();
 
   for (const auto &C : WasmObj->comdats())
     Symtab->addComdat(C, this);
 
-  FunctionSymbols.resize(NumFunctionImports + Funcs.size());
-  DataSymbols.resize(NumGlobalImports + Globals.size());
-
   for (const WasmSegment &S : WasmObj->dataSegments()) {
     InputSegment *Seg = make<InputSegment>(S, this);
     Seg->copyRelocations(*DataSection);
     Segments.emplace_back(Seg);
   }
 
+  for (const WasmGlobal &G : WasmObj->globals())
+    Globals.emplace_back(make<InputGlobal>(G));
+
   for (size_t I = 0; I < Funcs.size(); ++I) {
     const WasmFunction &Func = Funcs[I];
     const WasmSignature &Sig = Types[FuncTypes[I]];
@@ -242,77 +221,80 @@ void ObjFile::initializeSymbols() {
     Functions.emplace_back(F);
   }
 
-  // Populate `FunctionSymbols` and `DataSymbols` 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 = createDefinedFunction(WasmSym, Function);
+    bool IsDefined = WasmSym.isDefined();
+
+    if (IsDefined) {
+      switch (WasmSym.Info.Kind) {
+      case WASM_SYMBOL_TYPE_FUNCTION: {
+        InputFunction *Function = getFunction(WasmSym);
+        if (isExcludedByComdat(Function)) {
+          Function->Live = false;
+          IsDefined = false;
+          break;
+        }
+        Symbols.push_back(createDefinedFunction(WasmSym, Function));
         break;
       }
-      Function->Live = false;
-      LLVM_FALLTHROUGH; // Exclude function, and add the symbol as undefined
-    }
-    case WasmSymbol::SymbolType::FUNCTION_IMPORT:
-      S = createUndefined(WasmSym, Symbol::Kind::UndefinedFunctionKind,
-                          getFunctionSig(WasmSym));
-      break;
-    case WasmSymbol::SymbolType::GLOBAL_EXPORT: {
-      InputSegment *Segment = getSegment(WasmSym);
-      if (!isExcludedByComdat(Segment)) {
-        S = createDefinedData(WasmSym, Segment, getGlobalValue(WasmSym));
+      case WASM_SYMBOL_TYPE_DATA: {
+        InputSegment *Segment = getSegment(WasmSym);
+        if (isExcludedByComdat(Segment)) {
+          Segment->Live = false;
+          IsDefined = false;
+          break;
+        }
+        Symbols.push_back(createDefinedData(WasmSym, Segment,
+                                            WasmSym.Info.DataRef.Offset,
+                                            WasmSym.Info.DataRef.Size));
+        break;
+      }
+      case WASM_SYMBOL_TYPE_GLOBAL:
+        Symbols.push_back(createDefinedGlobal(WasmSym, getGlobal(WasmSym)));
+        break;
+      default:
+        llvm_unreachable("unkown symbol kind");
         break;
       }
-      Segment->Live = false;
-      LLVM_FALLTHROUGH; // Exclude global, and add the symbol as undefined
-    }
-    case WasmSymbol::SymbolType::GLOBAL_IMPORT:
-      S = createUndefined(WasmSym, Symbol::Kind::UndefinedDataKind);
-      break;
     }
 
-    Symbols.push_back(S);
-    if (WasmSym.isTypeFunction()) {
-      FunctionSymbols[WasmSym.ElementIndex] = S;
-      if (WasmSym.HasAltIndex)
-        FunctionSymbols[WasmSym.AltIndex] = S;
-    } else {
-      DataSymbols[WasmSym.ElementIndex] = S;
-      if (WasmSym.HasAltIndex)
-        DataSymbols[WasmSym.AltIndex] = S;
-    }
+    // Either the the symbol itself was undefined, or was excluded via comdat
+    // in which case this simply insertes the existing symbol into the correct
+    // slot in the Symbols array.
+    if (!IsDefined)
+      Symbols.push_back(createUndefined(WasmSym));
   }
-
-  DEBUG(for (size_t I = 0; I < FunctionSymbols.size(); ++I)
-            assert(FunctionSymbols[I] != nullptr);
-        for (size_t I = 0; I < DataSymbols.size(); ++I)
-            assert(DataSymbols[I] != nullptr););
-
-  DEBUG(dbgs() << "Functions   : " << FunctionSymbols.size() << "\n");
-  DEBUG(dbgs() << "Globals     : " << DataSymbols.size() << "\n");
 }
 
-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) {
+  return Symtab->addUndefined(
+      Sym.Info.Name, static_cast<WasmSymbolType>(Sym.Info.Kind), Sym.Info.Flags,
+      this, Sym.FunctionType, Sym.GlobalType);
 }
 
 Symbol *ObjFile::createDefinedFunction(const WasmSymbol &Sym,
                                        InputFunction *Function) {
   if (Sym.isBindingLocal())
-    return make<DefinedFunction>(Sym.Name, Sym.Flags, this, Function);
-  return Symtab->addDefinedFunction(Sym.Name, Sym.Flags, this, Function);
+    return make<DefinedFunction>(Sym.Info.Name, Sym.Info.Flags, this, Function);
+  return Symtab->addDefinedFunction(Sym.Info.Name, Sym.Info.Flags, this,
+                                    Function);
 }
 
 Symbol *ObjFile::createDefinedData(const WasmSymbol &Sym, InputSegment *Segment,
-                                   uint32_t Address) {
+                                   uint32_t Offset, uint32_t Size) {
+  if (Sym.isBindingLocal())
+    return make<DefinedData>(Sym.Info.Name, Sym.Info.Flags, this, Segment,
+                             Offset, Size);
+  return Symtab->addDefinedData(Sym.Info.Name, Sym.Info.Flags, this, Segment,
+                                Offset, Size);
+}
+
+Symbol *ObjFile::createDefinedGlobal(const WasmSymbol &Sym,
+                                     InputGlobal *Global) {
   if (Sym.isBindingLocal())
-    return make<DefinedData>(Sym.Name, Sym.Flags, this, Segment, Address);
-  return Symtab->addDefinedData(Sym.Name, Sym.Flags, this, Segment, Address);
+    return make<DefinedGlobal>(Sym.Info.Name, Sym.Info.Flags, this, Global);
+  return Symtab->addDefinedGlobal(Sym.Info.Name, Sym.Info.Flags, this, Global);
 }
 
 void ArchiveFile::parse() {

Modified: lld/trunk/wasm/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.h?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.h (original)
+++ lld/trunk/wasm/InputFiles.h Thu Feb 22 21:08:53 2018
@@ -23,6 +23,7 @@ using llvm::object::Archive;
 using llvm::object::WasmObjectFile;
 using llvm::object::WasmSection;
 using llvm::object::WasmSymbol;
+using llvm::wasm::WasmGlobal;
 using llvm::wasm::WasmImport;
 using llvm::wasm::WasmSignature;
 using llvm::wasm::WasmRelocation;
@@ -33,6 +34,7 @@ namespace wasm {
 class InputChunk;
 class InputFunction;
 class InputSegment;
+class InputGlobal;
 
 class InputFile {
 public:
@@ -90,7 +92,6 @@ public:
 
   void dumpInfo() const;
 
-  uint32_t relocateFunctionIndex(uint32_t Original) const;
   uint32_t calcNewIndex(const WasmRelocation &Reloc) const;
   uint32_t calcNewValue(const WasmRelocation &Reloc) const;
 
@@ -101,44 +102,37 @@ public:
   std::vector<bool> TypeIsUsed;
   std::vector<InputSegment *> Segments;
   std::vector<InputFunction *> Functions;
+  std::vector<InputGlobal *> Globals;
 
   ArrayRef<Symbol *> getSymbols() const { return Symbols; }
-
-  FunctionSymbol *getFunctionSymbol(uint32_t Index) const {
-    return cast<FunctionSymbol>(FunctionSymbols[Index]);
-  }
-
-  DataSymbol *getDataSymbol(uint32_t Index) const {
-    return cast<DataSymbol>(DataSymbols[Index]);
-  }
+  Symbol *getSymbol(uint32_t Index) const { return Symbols[Index]; }
+  FunctionSymbol *getFunctionSymbol(uint32_t Index) const;
+  DataSymbol *getDataSymbol(uint32_t Index) const;
+  GlobalSymbol *getGlobalSymbol(uint32_t Index) const;
 
 private:
   uint32_t relocateVirtualAddress(uint32_t Index) const;
+  uint32_t relocateFunctionIndex(uint32_t Original) const;
   uint32_t relocateTypeIndex(uint32_t Original) const;
   uint32_t relocateGlobalIndex(uint32_t Original) const;
   uint32_t relocateTableIndex(uint32_t Original) const;
+  uint32_t relocateSymbolIndex(uint32_t Original) const;
 
   Symbol *createDefinedData(const WasmSymbol &Sym, InputSegment *Segment,
-                            uint32_t Address);
+                            uint32_t Offset, uint32_t DataSize);
   Symbol *createDefinedFunction(const WasmSymbol &Sym, InputFunction *Function);
-  Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
-                          const WasmSignature *Signature = nullptr);
+  Symbol *createDefinedGlobal(const WasmSymbol &Sym, InputGlobal *Global);
+  Symbol *createUndefined(const WasmSymbol &Sym);
+
   void initializeSymbols();
   InputSegment *getSegment(const WasmSymbol &WasmSym) const;
-  const WasmSignature *getFunctionSig(const WasmSymbol &Sym) const;
-  uint32_t getGlobalValue(const WasmSymbol &Sym) 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.
   std::vector<Symbol *> Symbols;
 
-  // List of all function symbols indexed by the function index space
-  std::vector<Symbol *> FunctionSymbols;
-
-  // List of all global symbols indexed by the global index space
-  std::vector<Symbol *> DataSymbols;
-
   uint32_t NumGlobalImports = 0;
   uint32_t NumFunctionImports = 0;
   std::unique_ptr<WasmObjectFile> WasmObj;

Added: lld/trunk/wasm/InputGlobal.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputGlobal.h?rev=325861&view=auto
==============================================================================
--- lld/trunk/wasm/InputGlobal.h (added)
+++ lld/trunk/wasm/InputGlobal.h Thu Feb 22 21:08:53 2018
@@ -0,0 +1,52 @@
+//===- InputGlobal.h --------------------------------------------*- C++ -*-===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_WASM_INPUT_GLOBAL_H
+#define LLD_WASM_INPUT_GLOBAL_H
+
+#include "Config.h"
+#include "InputFiles.h"
+#include "WriterUtils.h"
+#include "lld/Common/ErrorHandler.h"
+#include "llvm/Object/Wasm.h"
+
+using llvm::wasm::WasmGlobal;
+using llvm::wasm::WasmInitExpr;
+
+namespace lld {
+namespace wasm {
+
+// Represents a single Wasm Global Variable within an input file. These are
+// combined to form the final GLOBALS section.
+class InputGlobal {
+public:
+  InputGlobal(const WasmGlobal &G) : Global(G) {}
+
+  const WasmGlobalType &getType() const { return Global.Type; }
+
+  uint32_t getOutputIndex() const { return OutputIndex.getValue(); }
+  bool hasOutputIndex() const { return OutputIndex.hasValue(); }
+  void setOutputIndex(uint32_t Index) {
+    assert(!hasOutputIndex());
+    OutputIndex = Index;
+  }
+
+  bool Live = false;
+
+  WasmGlobal Global;
+
+protected:
+  llvm::Optional<uint32_t> OutputIndex;
+};
+
+} // namespace wasm
+
+} // namespace lld
+
+#endif // LLD_WASM_INPUT_GLOBAL_H

Propchange: lld/trunk/wasm/InputGlobal.h
------------------------------------------------------------------------------
    svn:eol-style = LF

Modified: lld/trunk/wasm/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/MarkLive.cpp?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/MarkLive.cpp (original)
+++ lld/trunk/wasm/MarkLive.cpp Thu Feb 22 21:08:53 2018
@@ -65,7 +65,7 @@ void lld::wasm::markLive() {
   for (const ObjFile *Obj : Symtab->ObjectFiles) {
     const WasmLinkingData &L = Obj->getWasmObj()->linkingData();
     for (const WasmInitFunc &F : L.InitFunctions)
-      Enqueue(Obj->getFunctionSymbol(F.FunctionIndex));
+      Enqueue(Obj->getFunctionSymbol(F.Symbol));
   }
 
   // Follow relocations to mark all reachable chunks.
@@ -73,19 +73,8 @@ void lld::wasm::markLive() {
     InputChunk *C = Q.pop_back_val();
 
     for (const WasmRelocation Reloc : C->getRelocations()) {
-      switch (Reloc.Type) {
-      case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
-      case R_WEBASSEMBLY_TABLE_INDEX_I32:
-      case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
-        Enqueue(C->File->getFunctionSymbol(Reloc.Index));
-        break;
-      case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
-      case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
-      case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
-      case R_WEBASSEMBLY_MEMORY_ADDR_I32:
-        Enqueue(C->File->getDataSymbol(Reloc.Index));
-        break;
-      }
+      if (Reloc.Type != R_WEBASSEMBLY_TYPE_INDEX_LEB)
+        Enqueue(C->File->getSymbol(Reloc.Index));
     }
   }
 

Modified: lld/trunk/wasm/OutputSegment.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/OutputSegment.h?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/OutputSegment.h (original)
+++ lld/trunk/wasm/OutputSegment.h Thu Feb 22 21:08:53 2018
@@ -21,7 +21,7 @@ class InputSegment;
 
 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 @@ public:
   void setSectionOffset(uint32_t Offset) { SectionOffset = Offset; }
 
   StringRef Name;
+  const uint32_t Index;
   uint32_t Alignment = 0;
   uint32_t StartVA = 0;
   std::vector<InputSegment *> InputSegments;

Modified: lld/trunk/wasm/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.cpp (original)
+++ lld/trunk/wasm/SymbolTable.cpp Thu Feb 22 21:08:53 2018
@@ -10,6 +10,7 @@
 #include "SymbolTable.h"
 #include "Config.h"
 #include "InputChunks.h"
+#include "InputGlobal.h"
 #include "WriterUtils.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
@@ -73,50 +74,58 @@ std::pair<Symbol *, bool> SymbolTable::i
 // 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,
-                             bool NewIsFunction, const WasmSignature *NewSig) {
+                             WasmSymbolType NewType,
+                             const WasmSignature *NewFunctionSig,
+                             const WasmGlobalType *NewGlobalType) {
   if (Existing.isLazy())
     return;
 
+  WasmSymbolType ExistingType = Existing.getWasmType();
+
   // First check the symbol types match (i.e. either both are function
   // symbols or both are data symbols).
-  if (isa<FunctionSymbol>(Existing) != NewIsFunction) {
+  if (NewType != ExistingType) {
     error("symbol type mismatch: " + Existing.getName() + "\n>>> defined as " +
-          (isa<FunctionSymbol>(Existing) ? "Function" : "Data") + " in " +
-          toString(Existing.getFile()) + "\n>>> defined as " +
-          (NewIsFunction ? "Function" : "Data") + " 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.
-  auto *ExistingFunc = dyn_cast<FunctionSymbol>(&Existing);
-  if (!ExistingFunc || !Config->CheckSignatures)
-    return;
-
-  const WasmSignature *OldSig = ExistingFunc->getFunctionType();
-
-  // 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 (OldSig == nullptr)
+  // For function/global symbols, optionally check the type matches too.
+  if (NewType == WASM_SYMBOL_TYPE_DATA || !Config->CheckSignatures)
     return;
 
-  DEBUG(dbgs() << "checkSymbolTypes: " << ExistingFunc->getName() << "\n");
-  assert(NewSig);
-
-  if (*NewSig == *OldSig)
-    return;
+  DEBUG(dbgs() << "checkSymbolTypes: " << Existing.getName() << "\n");
 
-  error("function signature mismatch: " + ExistingFunc->getName() +
-        "\n>>> defined as " + toString(*OldSig) + " in " +
-        toString(ExistingFunc->getFile()) + "\n>>> defined as " +
-        toString(*NewSig) + " in " + F.getName());
-}
+  auto ReportError = [&](const Twine &Old, const Twine &New) {
+    error(toString(NewType) + " type mismatch: " + Existing.getName() +
+          "\n>>> defined as " + Old + " in " + toString(Existing.getFile()) +
+          "\n>>> defined as " + New + " in " + F.getName());
+  };
+
+  if (NewType == WASM_SYMBOL_TYPE_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).
+    auto &Sym = cast<FunctionSymbol>(Existing);
+    const WasmSignature *OldSig = Sym.getFunctionType();
+    if (!OldSig)
+      return;
+
+    assert(NewFunctionSig);
+    if (*NewFunctionSig == *OldSig)
+      return;
+
+    ReportError(toString(*OldSig), toString(*NewFunctionSig));
+  } else {
+    auto &Sym = cast<GlobalSymbol>(Existing);
+
+    assert(NewGlobalType != nullptr);
+    const WasmGlobalType *OldType = Sym.getGlobalType();
+    if (*NewGlobalType == *OldType)
+      return;
 
-static void checkSymbolTypes(const Symbol &Existing, const InputFile &F,
-                             bool IsFunction, const InputChunk *Chunk) {
-  const WasmSignature *Sig = nullptr;
-  if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
-    Sig = &F->Signature;
-  return checkSymbolTypes(Existing, F, IsFunction, Sig);
+    ReportError(toString(*OldType), toString(*NewGlobalType));
+  }
 }
 
 DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
@@ -140,9 +149,21 @@ DefinedData *SymbolTable::addSyntheticDa
   return replaceSymbol<DefinedData>(S, Name, Flags);
 }
 
+DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,
+                                               InputGlobal *Global) {
+  DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global << "\n");
+  Symbol *S;
+  bool WasInserted;
+  std::tie(S, WasInserted) = insert(Name);
+  assert(WasInserted);
+  return replaceSymbol<DefinedGlobal>(S, Name, Flags, nullptr, Global);
+}
+
 static bool shouldReplace(const Symbol &Existing, InputFile *NewFile,
-                          uint32_t NewFlags, InputChunk *NewChunk,
-                          bool NewIsFunction) {
+                          WasmSymbolType NewType, uint32_t NewFlags,
+                          const WasmSignature *NewFuncType = nullptr,
+                          const WasmGlobalType *NewGlobalType = nullptr) {
+
   // If existing symbol is lazy, replace it without checking types since
   // lazy symbols don't have any type information.
   if (Existing.isLazy()) {
@@ -155,7 +176,7 @@ static bool shouldReplace(const Symbol &
   // symbol name must have the same type, even if they are undefined. This
   // is different from ELF because symbol types are not that significant
   // in ELF, and undefined symbols in ELF don't have type in the first place.
-  checkSymbolTypes(Existing, *NewFile, NewIsFunction, NewChunk);
+  checkSymbolTypes(Existing, *NewFile, NewType, NewFuncType, NewGlobalType);
 
   // If existing symbol is undefined, replace it.
   if (!Existing.isDefined()) {
@@ -188,38 +209,58 @@ Symbol *SymbolTable::addDefinedFunction(
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
-  if (WasInserted || shouldReplace(*S, F, Flags, Function, true))
+  if (WasInserted || shouldReplace(*S, F, WASM_SYMBOL_TYPE_FUNCTION, Flags,
+                                   &Function->Signature))
     replaceSymbol<DefinedFunction>(S, Name, Flags, F, Function);
   return S;
 }
 
 Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
-                                      InputFile *F, InputSegment *Segment,
-                                      uint32_t Address) {
+                                    InputFile *F, InputSegment *Segment,
+                                    uint32_t Address, uint32_t Size) {
   DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address << "\n");
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
-  if (WasInserted || shouldReplace(*S, F, Flags, Segment, false))
-    replaceSymbol<DefinedData>(S, Name, Flags, F, Segment, Address);
+  if (WasInserted || shouldReplace(*S, F, WASM_SYMBOL_TYPE_DATA, Flags))
+    replaceSymbol<DefinedData>(S, Name, Flags, F, Segment, Address, Size);
+  return S;
+}
+
+Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
+                                      InputFile *F, InputGlobal *Global) {
+  DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n");
+  Symbol *S;
+  bool WasInserted;
+  std::tie(S, WasInserted) = insert(Name);
+  if (WasInserted || shouldReplace(*S, F, WASM_SYMBOL_TYPE_GLOBAL, Flags,
+                                   nullptr, &Global->getType()))
+    replaceSymbol<DefinedGlobal>(S, Name, Flags, F, Global);
   return S;
 }
 
-Symbol *SymbolTable::addUndefined(StringRef Name, Symbol::Kind Kind,
+Symbol *SymbolTable::addUndefined(StringRef Name, WasmSymbolType Type,
                                   uint32_t Flags, InputFile *F,
-                                  const WasmSignature *Type) {
-  DEBUG(dbgs() << "addUndefined: " << Name << "\n");
+                                  const WasmSignature *FunctionType,
+                                  const WasmGlobalType *GlobalType) {
+  DEBUG(dbgs() << "addUndefined type=" << Type << ": " << Name << "\n");
 
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
 
-  bool IsFunction = Kind == Symbol::UndefinedFunctionKind;
   if (WasInserted) {
-    if (IsFunction)
-      replaceSymbol<UndefinedFunction>(S, Name, Flags, F, Type);
-    else
+    switch (Type) {
+    case WASM_SYMBOL_TYPE_FUNCTION:
+      replaceSymbol<UndefinedFunction>(S, Name, Flags, F, FunctionType);
+      break;
+    case WASM_SYMBOL_TYPE_GLOBAL:
+      replaceSymbol<UndefinedGlobal>(S, Name, Flags, F, GlobalType);
+      break;
+    case WASM_SYMBOL_TYPE_DATA:
       replaceSymbol<UndefinedData>(S, Name, Flags, F);
+      break;
+    }
     return S;
   }
 
@@ -231,8 +272,9 @@ Symbol *SymbolTable::addUndefined(String
 
   if (S->isDefined()) {
     DEBUG(dbgs() << "resolved by existing\n");
-    checkSymbolTypes(*S, *F, IsFunction, Type);
+    checkSymbolTypes(*S, *F, Type, FunctionType, GlobalType);
   }
+
   return S;
 }
 

Modified: lld/trunk/wasm/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.h?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.h (original)
+++ lld/trunk/wasm/SymbolTable.h Thu Feb 22 21:08:53 2018
@@ -17,6 +17,7 @@
 #include "llvm/Support/raw_ostream.h"
 
 using llvm::wasm::WasmSignature;
+using llvm::wasm::WasmGlobalType;
 
 namespace lld {
 namespace wasm {
@@ -50,17 +51,26 @@ public:
   Symbol *addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
                              InputFunction *Function = nullptr);
   Symbol *addDefinedData(StringRef Name, uint32_t Flags, InputFile *F,
-                         InputSegment *Segment = nullptr, uint32_t Address = 0);
+                         InputSegment *Segment = nullptr, uint32_t Address = 0,
+                         uint32_t Size = 0);
+  Symbol *addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *F,
+                           InputGlobal *G);
   Symbol *addUndefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags,
                        InputFile *F, const WasmSignature *Signature = nullptr);
   Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type);
+  Symbol *addUndefined(StringRef Name, WasmSymbolType Type, uint32_t Flags,
+                       InputFile *F, const WasmSignature *Signature = nullptr,
+                       const WasmGlobalType *GlobalType = nullptr);
   void addLazy(ArchiveFile *F, const Archive::Symbol *Sym);
   bool addComdat(StringRef Name, ObjFile *);
 
   DefinedData *addSyntheticDataSymbol(StringRef Name, uint32_t Flags = 0);
+  DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags,
+                                    InputGlobal *Global);
   DefinedFunction *addSyntheticFunction(StringRef Name,
                                         const WasmSignature *Type,
                                         uint32_t Flags = 0);
+
 private:
   std::pair<Symbol *, bool> insert(StringRef Name);
 

Modified: lld/trunk/wasm/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.cpp?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.cpp (original)
+++ lld/trunk/wasm/Symbols.cpp Thu Feb 22 21:08:53 2018
@@ -11,6 +11,8 @@
 #include "Config.h"
 #include "InputChunks.h"
 #include "InputFiles.h"
+#include "InputGlobal.h"
+#include "OutputSegment.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Strings.h"
 
@@ -25,19 +27,42 @@ DefinedFunction *WasmSym::CallCtors;
 DefinedData *WasmSym::DsoHandle;
 DefinedData *WasmSym::DataEnd;
 DefinedData *WasmSym::HeapBase;
-DefinedData *WasmSym::StackPointer;
+DefinedGlobal *WasmSym::StackPointer;
+
+WasmSymbolType Symbol::getWasmType() const {
+  switch (SymbolKind) {
+  case Symbol::DefinedFunctionKind:
+  case Symbol::UndefinedFunctionKind:
+    return llvm::wasm::WASM_SYMBOL_TYPE_FUNCTION;
+  case Symbol::DefinedDataKind:
+  case Symbol::UndefinedDataKind:
+    return llvm::wasm::WASM_SYMBOL_TYPE_DATA;
+  case Symbol::DefinedGlobalKind:
+  case Symbol::UndefinedGlobalKind:
+    return llvm::wasm::WASM_SYMBOL_TYPE_GLOBAL;
+  default:
+    llvm_unreachable("invalid symbol kind");
+  }
+}
 
 bool Symbol::hasOutputIndex() const {
   if (auto *F = dyn_cast<DefinedFunction>(this))
     if (F->Function)
       return F->Function->hasOutputIndex();
+  if (auto *G = dyn_cast<DefinedGlobal>(this))
+    if (G->Global)
+      return G->Global->hasOutputIndex();
   return OutputIndex != INVALID_INDEX;
 }
 
 uint32_t Symbol::getOutputIndex() const {
+  assert(!isa<DataSymbol>(this));
   if (auto *F = dyn_cast<DefinedFunction>(this))
     if (F->Function)
       return F->Function->getOutputIndex();
+  if (auto *G = dyn_cast<DefinedGlobal>(this))
+    if (G->Global)
+      return G->Global->getOutputIndex();
   assert(OutputIndex != INVALID_INDEX);
   return OutputIndex;
 }
@@ -45,13 +70,34 @@ uint32_t Symbol::getOutputIndex() const
 InputChunk *Symbol::getChunk() const {
   if (auto *F = dyn_cast<DefinedFunction>(this))
     return F->Function;
-  if (auto *G = dyn_cast<DefinedData>(this))
-    return G->Segment;
+  if (auto *D = dyn_cast<DefinedData>(this))
+    return D->Segment;
   return nullptr;
 }
 
+bool Symbol::isLive() const {
+  if (auto *G = dyn_cast<DefinedGlobal>(this))
+    return G->Global->Live;
+  if (InputChunk *C = getChunk())
+    return C->Live;
+  // Assume any other kind of symbol is live.
+  return true;
+}
+
+uint32_t Symbol::getOutputSymbolIndex() const {
+  assert(OutputSymbolIndex != INVALID_INDEX);
+  return OutputSymbolIndex;
+}
+
+void Symbol::setOutputSymbolIndex(uint32_t Index) {
+  DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index << "\n");
+  assert(OutputSymbolIndex == INVALID_INDEX);
+  OutputSymbolIndex = Index;
+}
+
 void Symbol::setOutputIndex(uint32_t Index) {
   DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n");
+  assert(!isa<DataSymbol>(this));
   assert(OutputIndex == INVALID_INDEX);
   OutputIndex = Index;
 }
@@ -111,14 +157,31 @@ DefinedFunction::DefinedFunction(StringR
 
 uint32_t DefinedData::getVirtualAddress() const {
   DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
-  return Segment ? Segment->translateVA(VirtualAddress) : VirtualAddress;
+  return Segment ? Segment->translateVA(Offset) : Offset;
 }
 
 void DefinedData::setVirtualAddress(uint32_t Value) {
   DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
-  VirtualAddress = Value;
+  assert(!Segment);
+  Offset = Value;
+}
+
+uint32_t DefinedData::getOutputSegmentOffset() const {
+  DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n");
+  return Segment->OutputSegmentOffset + Offset;
 }
 
+uint32_t DefinedData::getOutputSegmentIndex() const {
+  DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n");
+  return Segment->getOutputSegment()->Index;
+}
+
+DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
+                             InputGlobal *Global)
+    : GlobalSymbol(Name, DefinedGlobalKind, Flags, File,
+                   Global ? &Global->getType() : nullptr),
+      Global(Global) {}
+
 std::string lld::toString(const wasm::Symbol &Sym) {
   if (Config->Demangle)
     if (Optional<std::string> S = demangleItanium(Sym.getName()))
@@ -132,12 +195,28 @@ std::string lld::toString(wasm::Symbol::
     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:
     return "LazyKind";
   }
-  llvm_unreachable("Invalid symbol kind!");
+  llvm_unreachable("invalid symbol kind");
+}
+
+std::string lld::toString(WasmSymbolType Type) {
+  switch (Type) {
+  case llvm::wasm::WASM_SYMBOL_TYPE_FUNCTION:
+    return "Function";
+  case llvm::wasm::WASM_SYMBOL_TYPE_DATA:
+    return "Data";
+  case llvm::wasm::WASM_SYMBOL_TYPE_GLOBAL:
+    return "Global";
+  }
+  llvm_unreachable("invalid symbol type");
 }

Modified: lld/trunk/wasm/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.h?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.h (original)
+++ lld/trunk/wasm/Symbols.h Thu Feb 22 21:08:53 2018
@@ -15,7 +15,11 @@
 #include "llvm/Object/Wasm.h"
 
 using llvm::object::Archive;
+using llvm::object::WasmSymbol;
 using llvm::wasm::WasmSignature;
+using llvm::wasm::WasmGlobal;
+using llvm::wasm::WasmGlobalType;
+using llvm::wasm::WasmSymbolType;
 
 namespace lld {
 namespace wasm {
@@ -24,6 +28,7 @@ class InputFile;
 class InputChunk;
 class InputSegment;
 class InputFunction;
+class InputGlobal;
 
 #define INVALID_INDEX UINT32_MAX
 
@@ -33,12 +38,14 @@ public:
   enum Kind {
     DefinedFunctionKind,
     DefinedDataKind,
+    DefinedGlobalKind,
 
     LazyKind,
     UndefinedFunctionKind,
     UndefinedDataKind,
+    UndefinedGlobalKind,
 
-    LastDefinedKind = DefinedDataKind,
+    LastDefinedKind = DefinedGlobalKind,
     InvalidKind,
   };
 
@@ -47,8 +54,8 @@ public:
   bool isLazy() const { return SymbolKind == LazyKind; }
   bool isDefined() const { return SymbolKind <= LastDefinedKind; }
   bool isUndefined() const {
-    return SymbolKind == UndefinedDataKind ||
-           SymbolKind == UndefinedFunctionKind;
+    return SymbolKind == UndefinedFunctionKind ||
+           SymbolKind == UndefinedDataKind || SymbolKind == UndefinedGlobalKind;
   }
   bool isLocal() const;
   bool isWeak() const;
@@ -59,8 +66,12 @@ public:
 
   // Returns the file from which this symbol was created.
   InputFile *getFile() const { return File; }
+
   InputChunk *getChunk() const;
 
+  // Indicates that this symbol will be included in the final image.
+  bool isLive() const;
+
   void setHidden(bool IsHidden);
 
   uint32_t getOutputIndex() const;
@@ -68,10 +79,18 @@ public:
   // 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 index
-  // space of the output object.
+  // 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 Symbol index space.  This is
+  // only used for relocatable output.
+  uint32_t getOutputSymbolIndex() const;
+  void setOutputSymbolIndex(uint32_t Index);
+
+  WasmSymbolType getWasmType() const;
+
 protected:
   Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
       : Name(Name), SymbolKind(K), Flags(Flags), File(F) {}
@@ -81,6 +100,7 @@ protected:
   uint32_t Flags;
   InputFile *File;
   uint32_t OutputIndex = INVALID_INDEX;
+  uint32_t OutputSymbolIndex = INVALID_INDEX;
 };
 
 class FunctionSymbol : public Symbol {
@@ -112,9 +132,11 @@ protected:
 
 class DefinedFunction : public FunctionSymbol {
 public:
+  // Primary constructor for file-defined functions.
   DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
                   InputFunction *Function);
 
+  // Second constructor used when creating synthetic functions.
   DefinedFunction(StringRef Name, uint32_t Flags, const WasmSignature *Type)
       : FunctionSymbol(Name, DefinedFunctionKind, Flags, nullptr, Type) {}
 
@@ -149,22 +171,32 @@ protected:
 
 class DefinedData : public DataSymbol {
 public:
-  DefinedData(StringRef Name, uint32_t Flags, InputFile *F = nullptr,
-              InputSegment *Segment = nullptr, uint32_t Address = 0)
+  // Constructor for for regular data symbols originating from input files.
+  DefinedData(StringRef Name, uint32_t Flags, InputFile *F,
+              InputSegment *Segment, uint32_t Offset, uint32_t Size)
       : DataSymbol(Name, DefinedDataKind, Flags, F), Segment(Segment),
-        VirtualAddress(Address) {}
+        Offset(Offset), Size(Size) {}
 
-  static bool classof(const Symbol *S) {
-    return S->kind() == DefinedDataKind;
-  }
+  // Constructor for linker synthetic data symbols.
+  DefinedData(StringRef Name, uint32_t Flags)
+      : DataSymbol(Name, DefinedDataKind, Flags, nullptr) {}
 
+  static bool classof(const Symbol *S) { return S->kind() == DefinedDataKind; }
+
+  // Returns the output virtual address of a defined data symbol.
   uint32_t getVirtualAddress() const;
   void setVirtualAddress(uint32_t VA);
 
-  InputSegment *Segment;
+  // Returns the offset of a defined data symbol within its OutputSegment.
+  uint32_t getOutputSegmentOffset() const;
+  uint32_t getOutputSegmentIndex() const;
+  uint32_t getSize() const { return Size; }
+
+  InputSegment *Segment = nullptr;
 
 protected:
-  uint32_t VirtualAddress;
+  uint32_t Offset = 0;
+  uint32_t Size = 0;
 };
 
 class UndefinedData : public DataSymbol {
@@ -176,6 +208,47 @@ public:
   }
 };
 
+class GlobalSymbol : public Symbol {
+public:
+  static bool classof(const Symbol *S) {
+    return S->kind() == DefinedGlobalKind || S->kind() == UndefinedGlobalKind;
+  }
+
+  const WasmGlobalType *getGlobalType() const { return GlobalType; }
+
+protected:
+  GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
+               const WasmGlobalType *GlobalType)
+      : Symbol(Name, K, Flags, F), GlobalType(GlobalType) {}
+
+  // Explicit function type, needed for undefined or synthetic functions only.
+  // For regular defined globals this information comes from the InputChunk.
+  const WasmGlobalType *GlobalType;
+};
+
+class DefinedGlobal : public GlobalSymbol {
+public:
+  DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
+                InputGlobal *Global);
+
+  static bool classof(const Symbol *S) {
+    return S->kind() == DefinedGlobalKind;
+  }
+
+  InputGlobal *Global;
+};
+
+class UndefinedGlobal : public GlobalSymbol {
+public:
+  UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File = nullptr,
+                  const WasmGlobalType *Type = nullptr)
+      : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type) {}
+
+  static bool classof(const Symbol *S) {
+    return S->kind() == UndefinedGlobalKind;
+  }
+};
+
 class LazySymbol : public Symbol {
 public:
   LazySymbol(StringRef Name, InputFile *File, const Archive::Symbol &Sym)
@@ -194,7 +267,7 @@ struct WasmSym {
   // __stack_pointer
   // Global that holds the address of the top of the explicit value stack in
   // linear memory.
-  static DefinedData *StackPointer;
+  static DefinedGlobal *StackPointer;
 
   // __data_end
   // Symbol marking the end of the data and bss.
@@ -221,9 +294,11 @@ struct WasmSym {
 union SymbolUnion {
   alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
   alignas(DefinedData) char B[sizeof(DefinedData)];
-  alignas(LazySymbol) char C[sizeof(LazySymbol)];
-  alignas(UndefinedFunction) char D[sizeof(UndefinedFunction)];
-  alignas(UndefinedData) char E[sizeof(UndefinedFunction)];
+  alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)];
+  alignas(LazySymbol) char D[sizeof(LazySymbol)];
+  alignas(UndefinedFunction) char E[sizeof(UndefinedFunction)];
+  alignas(UndefinedData) char F[sizeof(UndefinedData)];
+  alignas(UndefinedGlobal) char G[sizeof(UndefinedGlobal)];
 };
 
 template <typename T, typename... ArgT>
@@ -243,6 +318,7 @@ T *replaceSymbol(Symbol *S, ArgT &&... A
 // 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(WasmSymbolType Type);
 
 } // namespace lld
 

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Thu Feb 22 21:08:53 2018
@@ -10,6 +10,7 @@
 #include "Writer.h"
 #include "Config.h"
 #include "InputChunks.h"
+#include "InputGlobal.h"
 #include "OutputSections.h"
 #include "OutputSegment.h"
 #include "SymbolTable.h"
@@ -18,6 +19,7 @@
 #include "lld/Common/Memory.h"
 #include "lld/Common/Threads.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/Support/FileOutputBuffer.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/FormatVariadic.h"
@@ -62,10 +64,11 @@ struct WasmSignatureDenseMapInfo {
   }
 };
 
-// A Wasm export to be written into the export section.
-struct WasmExportEntry {
+// An init entry to be written to either the synthetic init func or the
+// linking metadata.
+struct WasmInitEntry {
   const Symbol *Sym;
-  StringRef FieldName; // may not match the Symbol name
+  uint32_t Priority;
 };
 
 // The writer writes a SymbolTable result to a file.
@@ -78,11 +81,13 @@ private:
 
   uint32_t lookupType(const WasmSignature &Sig);
   uint32_t registerType(const WasmSignature &Sig);
+
   void createCtorFunction();
   void calculateInitFunctions();
   void assignIndexes();
   void calculateImports();
   void calculateExports();
+  void assignSymtab();
   void calculateTypes();
   void createOutputSegments();
   void layoutMemory();
@@ -118,13 +123,16 @@ private:
 
   std::vector<const WasmSignature *> Types;
   DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices;
-  std::vector<const FunctionSymbol *> ImportedFunctions;
-  std::vector<const DataSymbol *> ImportedGlobals;
-  std::vector<WasmExportEntry> ExportedSymbols;
-  std::vector<const DefinedData *> DefinedDataSymbols;
+  std::vector<const Symbol *> ImportedSymbols;
+  unsigned NumImportedFunctions = 0;
+  unsigned NumImportedGlobals = 0;
+  std::vector<Symbol *> ExportedSymbols;
+  std::vector<const DefinedData *> DefinedFakeGlobals;
+  std::vector<InputGlobal *> InputGlobals;
   std::vector<InputFunction *> InputFunctions;
   std::vector<const FunctionSymbol *> IndirectFunctions;
-  std::vector<WasmInitFunc> InitFunctions;
+  std::vector<const Symbol *> SymtabEntries;
+  std::vector<WasmInitEntry> InitFunctions;
 
   // Elements that are used to construct the final output
   std::string Header;
@@ -150,7 +158,7 @@ static void debugPrint(const char *fmt,
 }
 
 void Writer::createImportSection() {
-  uint32_t NumImports = ImportedFunctions.size() + ImportedGlobals.size();
+  uint32_t NumImports = ImportedSymbols.size();
   if (Config->ImportMemory)
     ++NumImports;
 
@@ -162,15 +170,6 @@ void Writer::createImportSection() {
 
   writeUleb128(OS, NumImports, "import count");
 
-  for (const FunctionSymbol *Sym : ImportedFunctions) {
-    WasmImport Import;
-    Import.Module = "env";
-    Import.Field = Sym->getName();
-    Import.Kind = WASM_EXTERNAL_FUNCTION;
-    Import.SigIndex = lookupType(*Sym->getFunctionType());
-    writeImport(OS, Import);
-  }
-
   if (Config->ImportMemory) {
     WasmImport Import;
     Import.Module = "env";
@@ -181,13 +180,18 @@ void Writer::createImportSection() {
     writeImport(OS, Import);
   }
 
-  for (const Symbol *Sym : ImportedGlobals) {
+  for (const Symbol *Sym : ImportedSymbols) {
     WasmImport Import;
     Import.Module = "env";
     Import.Field = Sym->getName();
-    Import.Kind = WASM_EXTERNAL_GLOBAL;
-    Import.Global.Mutable = false;
-    Import.Global.Type = WASM_TYPE_I32;
+    if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
+      Import.Kind = WASM_EXTERNAL_FUNCTION;
+      Import.SigIndex = lookupType(*FunctionSym->getFunctionType());
+    } else {
+      auto *GlobalSym = cast<GlobalSymbol>(Sym);
+      Import.Kind = WASM_EXTERNAL_GLOBAL;
+      Import.Global = *GlobalSym->getGlobalType();
+    }
     writeImport(OS, Import);
   }
 }
@@ -225,17 +229,19 @@ void Writer::createMemorySection() {
 }
 
 void Writer::createGlobalSection() {
-  if (DefinedDataSymbols.empty())
+  unsigned NumGlobals = InputGlobals.size() + DefinedFakeGlobals.size();
+  if (NumGlobals == 0)
     return;
 
   SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
   raw_ostream &OS = Section->getStream();
 
-  writeUleb128(OS, DefinedDataSymbols.size(), "global count");
-  for (const DefinedData *Sym : DefinedDataSymbols) {
+  writeUleb128(OS, NumGlobals, "global count");
+  for (const InputGlobal *G : InputGlobals)
+    writeGlobal(OS, G->Global);
+  for (const DefinedData *Sym : DefinedFakeGlobals) {
     WasmGlobal Global;
-    Global.Type.Type = WASM_TYPE_I32;
-    Global.Type.Mutable = Sym == WasmSym::StackPointer;
+    Global.Type = {WASM_TYPE_I32, false};
     Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
     Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
     writeGlobal(OS, Global);
@@ -283,15 +289,23 @@ void Writer::createExportSection() {
     writeExport(OS, MemoryExport);
   }
 
-  for (const WasmExportEntry &E : ExportedSymbols) {
-    DEBUG(dbgs() << "Export: " << E.Sym->getName() << "\n");
+  unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size();
+  for (const Symbol *Sym : ExportedSymbols) {
+    DEBUG(dbgs() << "Export: " << Sym->getName() << "\n");
     WasmExport Export;
-    Export.Name = E.FieldName;
-    Export.Index = E.Sym->getOutputIndex();
-    if (isa<FunctionSymbol>(E.Sym))
+    Export.Name = Sym->getName();
+    if (isa<FunctionSymbol>(Sym)) {
+      Export.Index = Sym->getOutputIndex();
       Export.Kind = WASM_EXTERNAL_FUNCTION;
-    else
+    } else if (isa<GlobalSymbol>(Sym)) {
+      Export.Index = Sym->getOutputIndex();
       Export.Kind = WASM_EXTERNAL_GLOBAL;
+    } else if (isa<DataSymbol>(Sym)) {
+      Export.Index = FakeGlobalIndex++;
+      Export.Kind = WASM_EXTERNAL_GLOBAL;
+    } else {
+      llvm_unreachable("unexpected symbol type");
+    }
     writeExport(OS, Export);
   }
 }
@@ -383,28 +397,39 @@ void Writer::createLinkingSection() {
   if (!Config->Relocatable)
     return;
 
-  std::vector<std::pair<StringRef, uint32_t>> 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 : ImportedFunctions)
-    addSymInfo(Sym, Sym->getName());
-  for (const Symbol *Sym : ImportedGlobals)
-    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 symbols");
+    for (const Symbol *Sym : SymtabEntries) {
+      assert(Sym->isDefined() || Sym->isUndefined());
+      WasmSymbolType Kind = Sym->getWasmType();
+      uint32_t Flags = Sym->isLocal() ? WASM_SYMBOL_BINDING_LOCAL : 0;
+      if (Sym->isWeak())
+        Flags |= WASM_SYMBOL_BINDING_WEAK;
+      if (Sym->isHidden())
+        Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
+      if (Sym->isUndefined())
+        Flags |= WASM_SYMBOL_UNDEFINED;
+      writeUleb128(SubSection.getStream(), Kind, "sym kind");
+      writeUleb128(SubSection.getStream(), Flags, "sym flags");
+      switch (Kind) {
+      case llvm::wasm::WASM_SYMBOL_TYPE_FUNCTION:
+      case llvm::wasm::WASM_SYMBOL_TYPE_GLOBAL:
+        writeUleb128(SubSection.getStream(), Sym->getOutputIndex(), "index");
+        if (Sym->isDefined())
+          writeStr(SubSection.getStream(), Sym->getName(), "sym name");
+        break;
+      case llvm::wasm::WASM_SYMBOL_TYPE_DATA:
+        writeStr(SubSection.getStream(), Sym->getName(), "sym name");
+        if (auto *DataSym = dyn_cast<DefinedData>(Sym)) {
+          writeUleb128(SubSection.getStream(), DataSym->getOutputSegmentIndex(),
+                       "index");
+          writeUleb128(SubSection.getStream(),
+                       DataSym->getOutputSegmentOffset(), "data offset");
+          writeUleb128(SubSection.getStream(), DataSym->getSize(), "data size");
+        }
+        break;
+      }
     }
     SubSection.finalizeContents();
     SubSection.writeToStream(OS);
@@ -426,9 +451,10 @@ void Writer::createLinkingSection() {
     SubSection SubSection(WASM_INIT_FUNCS);
     writeUleb128(SubSection.getStream(), InitFunctions.size(),
                  "num init functions");
-    for (const WasmInitFunc &F : InitFunctions) {
+    for (const WasmInitEntry &F : InitFunctions) {
       writeUleb128(SubSection.getStream(), F.Priority, "priority");
-      writeUleb128(SubSection.getStream(), F.FunctionIndex, "function index");
+      writeUleb128(SubSection.getStream(), F.Sym->getOutputSymbolIndex(),
+                   "function index");
     }
     SubSection.finalizeContents();
     SubSection.writeToStream(OS);
@@ -475,7 +501,7 @@ void Writer::createLinkingSection() {
 
 // Create the custom "name" section containing debug symbol names.
 void Writer::createNameSection() {
-  unsigned NumNames = ImportedFunctions.size();
+  unsigned NumNames = NumImportedFunctions;
   for (const InputFunction *F : InputFunctions)
     if (!F->getName().empty())
       ++NumNames;
@@ -489,10 +515,12 @@ void Writer::createNameSection() {
   raw_ostream &OS = FunctionSubsection.getStream();
   writeUleb128(OS, NumNames, "name count");
 
-  // Names must appear in function index order.  As it happens ImportedFunctions
-  // and InputFunctions are numbers in order with imported functions coming
+  // Names must appear in function index order.  As it happens ImportedSymbols
+  // and InputFunctions are numbered in order with imported functions coming
   // first.
-  for (const Symbol *S : ImportedFunctions) {
+  for (const Symbol *S : ImportedSymbols) {
+    if (!isa<FunctionSymbol>(S))
+      continue;
     writeUleb128(OS, S->getOutputIndex(), "import index");
     writeStr(OS, S->getName(), "symbol name");
   }
@@ -562,8 +590,9 @@ void Writer::layoutMemory() {
     debugPrint("mem: stack size  = %d\n", Config->ZStackSize);
     debugPrint("mem: stack base  = %d\n", MemoryPtr);
     MemoryPtr += Config->ZStackSize;
-    WasmSym::StackPointer->setVirtualAddress(MemoryPtr);
+    WasmSym::StackPointer->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
     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.
@@ -614,69 +643,85 @@ void Writer::createSections() {
 
 void Writer::calculateImports() {
   for (Symbol *Sym : Symtab->getSymbols()) {
-    if (!Sym->isUndefined() || (Sym->isWeak() && !Config->Relocatable))
+    if (!Sym->isUndefined())
+      continue;
+    if (isa<DataSymbol>(Sym))
+      continue;
+    if (Sym->isWeak() && !Config->Relocatable)
       continue;
 
-    if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
-      F->setOutputIndex(ImportedFunctions.size());
-      ImportedFunctions.push_back(F);
-    } else if (auto *G = dyn_cast<DataSymbol>(Sym)) {
-      G->setOutputIndex(ImportedGlobals.size());
-      ImportedGlobals.push_back(G);
-    }
+    DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
+    Sym->setOutputIndex(ImportedSymbols.size());
+    ImportedSymbols.emplace_back(Sym);
+    if (isa<FunctionSymbol>(Sym))
+      ++NumImportedFunctions;
+    else
+      ++NumImportedGlobals;
   }
 }
 
 void Writer::calculateExports() {
-  bool ExportHidden = Config->Relocatable;
-  StringSet<> UsedNames;
+  if (Config->Relocatable)
+    return;
 
-  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;
-      }
+  auto ExportSym = [&](Symbol *Sym) {
+    if (!Sym->isDefined())
+      return;
+    if (Sym->isHidden() || Sym->isLocal())
+      return;
+    if (!Sym->isLive())
+      return;
+
+    DEBUG(dbgs() << "exporting sym: " << Sym->getName() << "\n");
+
+    if (auto *D = dyn_cast<DefinedData>(Sym)) {
+      // TODO Remove this check here; for non-relocatable output we actually
+      // used only to create fake-global exports for the synthetic symbols.  Fix
+      // this in a future commit
+      if (Sym != WasmSym::DataEnd && Sym != WasmSym::HeapBase)
+        return;
+      DefinedFakeGlobals.emplace_back(D);
     }
+    ExportedSymbols.emplace_back(Sym);
   };
 
-  if (WasmSym::CallCtors && (!WasmSym::CallCtors->isHidden() || ExportHidden))
-    ExportedSymbols.emplace_back(
-        WasmExportEntry{WasmSym::CallCtors, WasmSym::CallCtors->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 (File == Sym->getFile())
+        ExportSym(Sym);
+
+  for (Symbol *Sym : Symtab->getSymbols())
+    if (Sym->getFile() == nullptr)
+      ExportSym(Sym);
+}
+
+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->isDefined() || File != Sym->getFile())
-        continue;
-      if (!isa<FunctionSymbol>(Sym))
-        continue;
-      if (!Sym->getChunk()->Live)
-        continue;
-
-      if ((Sym->isHidden() || Sym->isLocal()) && !ExportHidden)
+      if (Sym->getFile() != File)
         continue;
-      ExportedSymbols.emplace_back(WasmExportEntry{Sym, BudgeLocalName(Sym)});
+      if (!Sym->isLive())
+        return;
+      Sym->setOutputSymbolIndex(SymbolIndex++);
+      SymtabEntries.emplace_back(Sym);
     }
   }
 
-  for (const Symbol *Sym : DefinedDataSymbols) {
-    // 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 == WasmSym::StackPointer)
-      continue;
-    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) {
@@ -710,45 +755,16 @@ void Writer::calculateTypes() {
         File->TypeMap[I] = registerType(Types[I]);
   }
 
-  for (const FunctionSymbol *Sym : ImportedFunctions)
-    registerType(*Sym->getFunctionType());
+  for (const Symbol *Sym : ImportedSymbols)
+    if (auto *F = dyn_cast<FunctionSymbol>(Sym))
+      registerType(*F->getFunctionType());
 
   for (const InputFunction *F : InputFunctions)
     registerType(F->Signature);
 }
 
 void Writer::assignIndexes() {
-  uint32_t GlobalIndex = ImportedGlobals.size() + DefinedDataSymbols.size();
-  uint32_t FunctionIndex = ImportedFunctions.size() + InputFunctions.size();
-
-  auto AddDefinedData = [&](DefinedData *Sym) {
-    if (Sym) {
-      DefinedDataSymbols.emplace_back(Sym);
-      Sym->setOutputIndex(GlobalIndex++);
-    }
-  };
-  AddDefinedData(WasmSym::StackPointer);
-  AddDefinedData(WasmSym::HeapBase);
-  AddDefinedData(WasmSym::DataEnd);
-
-  if (Config->Relocatable)
-    DefinedDataSymbols.reserve(Symtab->getSymbols().size());
-
-  uint32_t TableIndex = kInitialTableOffset;
-
-  if (Config->Relocatable) {
-    for (ObjFile *File : Symtab->ObjectFiles) {
-      DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
-      for (Symbol *Sym : File->getSymbols()) {
-        // Create wasm globals for data symbols defined in this file
-        if (File != Sym->getFile())
-          continue;
-        if (auto *G = dyn_cast<DefinedData>(Sym))
-          AddDefinedData(G);
-      }
-    }
-  }
-
+  uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size();
   for (ObjFile *File : Symtab->ObjectFiles) {
     DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
     for (InputFunction *Func : File->Functions) {
@@ -759,12 +775,13 @@ void Writer::assignIndexes() {
     }
   }
 
+  uint32_t TableIndex = kInitialTableOffset;
   auto HandleRelocs = [&](InputChunk *Chunk) {
     if (!Chunk->Live)
       return;
     ObjFile *File = Chunk->File;
     ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
-    for (const WasmRelocation& Reloc : Chunk->getRelocations()) {
+    for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
       if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||
           Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) {
         FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
@@ -773,20 +790,45 @@ void Writer::assignIndexes() {
         Sym->setTableIndex(TableIndex++);
         IndirectFunctions.emplace_back(Sym);
       } else if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
+        // Mark target type as live
         File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
         File->TypeIsUsed[Reloc.Index] = true;
+      } else if (Reloc.Type == R_WEBASSEMBLY_GLOBAL_INDEX_LEB) {
+        // Mark target global as live
+        GlobalSymbol *Sym = File->getGlobalSymbol(Reloc.Index);
+        if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
+          DEBUG(dbgs() << "marking global live: " << Sym->getName() << "\n");
+          G->Global->Live = true;
+        }
       }
     }
   };
 
   for (ObjFile *File : Symtab->ObjectFiles) {
     DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n");
-
-    for (InputChunk* Chunk : File->Functions)
+    for (InputChunk *Chunk : File->Functions)
       HandleRelocs(Chunk);
-    for (InputChunk* Chunk : File->Segments)
+    for (InputChunk *Chunk : File->Segments)
       HandleRelocs(Chunk);
   }
+
+  uint32_t GlobalIndex = NumImportedGlobals + InputGlobals.size();
+  auto AddDefinedGlobal = [&](InputGlobal *Global) {
+    if (Global->Live) {
+      DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");
+      Global->setOutputIndex(GlobalIndex++);
+      InputGlobals.push_back(Global);
+    }
+  };
+
+  if (WasmSym::StackPointer)
+    AddDefinedGlobal(WasmSym::StackPointer->Global);
+
+  for (ObjFile *File : Symtab->ObjectFiles) {
+    DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
+    for (InputGlobal *Global : File->Globals)
+      AddDefinedGlobal(Global);
+  }
 }
 
 static StringRef getOutputDataSegmentName(StringRef Name) {
@@ -814,7 +856,7 @@ void Writer::createOutputSegments() {
       OutputSegment *&S = SegmentMap[Name];
       if (S == nullptr) {
         DEBUG(dbgs() << "new segment: " << Name << "\n");
-        S = make<OutputSegment>(Name);
+        S = make<OutputSegment>(Name, Segments.size());
         Segments.push_back(S);
       }
       S->addInputSegment(Segment);
@@ -829,18 +871,18 @@ static const int OPCODE_END = 0xb;
 // Create synthetic "__wasm_call_ctors" function based on ctor functions
 // in input object.
 void Writer::createCtorFunction() {
-  uint32_t FunctionIndex = ImportedFunctions.size() + InputFunctions.size();
+  uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size();
   WasmSym::CallCtors->setOutputIndex(FunctionIndex);
 
   // First write the body bytes to a string.
   std::string FunctionBody;
-  static WasmSignature Signature = {{}, WASM_TYPE_NORESULT};
+  const WasmSignature *Signature = WasmSym::CallCtors->getFunctionType();
   {
     raw_string_ostream OS(FunctionBody);
     writeUleb128(OS, 0, "num locals");
-    for (const WasmInitFunc &F : InitFunctions) {
+    for (const WasmInitEntry &F : InitFunctions) {
       writeU8(OS, OPCODE_CALL, "CALL");
-      writeUleb128(OS, F.FunctionIndex, "function index");
+      writeUleb128(OS, F.Sym->getOutputIndex(), "function index");
     }
     writeU8(OS, OPCODE_END, "END");
   }
@@ -853,9 +895,11 @@ void Writer::createCtorFunction() {
   ArrayRef<uint8_t> BodyArray(
       reinterpret_cast<const uint8_t *>(CtorFunctionBody.data()),
       CtorFunctionBody.size());
-  SyntheticFunction *F = make<SyntheticFunction>(Signature, BodyArray,
+  SyntheticFunction *F = make<SyntheticFunction>(*Signature, BodyArray,
                                                  WasmSym::CallCtors->getName());
   F->setOutputIndex(FunctionIndex);
+  F->Live = true;
+  WasmSym::CallCtors->Function = F;
   InputFunctions.emplace_back(F);
 }
 
@@ -867,13 +911,13 @@ void Writer::calculateInitFunctions() {
     const WasmLinkingData &L = File->getWasmObj()->linkingData();
     InitFunctions.reserve(InitFunctions.size() + L.InitFunctions.size());
     for (const WasmInitFunc &F : L.InitFunctions)
-      InitFunctions.emplace_back(WasmInitFunc{
-          F.Priority, File->relocateFunctionIndex(F.FunctionIndex)});
+      InitFunctions.emplace_back(
+          WasmInitEntry{File->getFunctionSymbol(F.Symbol), F.Priority});
   }
   // Sort in order of priority (lowest first) so that they are called
   // in the correct order.
   std::stable_sort(InitFunctions.begin(), InitFunctions.end(),
-                   [](const WasmInitFunc &L, const WasmInitFunc &R) {
+                   [](const WasmInitEntry &L, const WasmInitEntry &R) {
                      return L.Priority < R.Priority;
                    });
 }
@@ -883,29 +927,28 @@ void Writer::run() {
   calculateImports();
   log("-- assignIndexes");
   assignIndexes();
-  log("-- calculateExports");
-  calculateExports();
   log("-- calculateInitFunctions");
   calculateInitFunctions();
   if (!Config->Relocatable)
     createCtorFunction();
   log("-- calculateTypes");
   calculateTypes();
+  log("-- layoutMemory");
+  layoutMemory();
+  log("-- calculateExports");
+  calculateExports();
+  log("-- assignSymtab");
+  assignSymtab();
 
   if (errorHandler().Verbose) {
     log("Defined Functions: " + Twine(InputFunctions.size()));
-    log("Defined Data Syms: " + Twine(DefinedDataSymbols.size()));
-    log("Function Imports : " + Twine(ImportedFunctions.size()));
-    log("Global Imports   : " + Twine(ImportedGlobals.size()));
-    log("Total Imports    : " +
-        Twine(ImportedFunctions.size() + ImportedGlobals.size()));
+    log("Defined Globals  : " + Twine(InputGlobals.size()));
+    log("Function Imports : " + Twine(NumImportedFunctions));
+    log("Global Imports   : " + Twine(NumImportedGlobals));
     for (ObjFile *File : Symtab->ObjectFiles)
       File->dumpInfo();
   }
 
-  log("-- layoutMemory");
-  layoutMemory();
-
   createHeader();
   log("-- createSections");
   createSections();

Modified: lld/trunk/wasm/WriterUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/WriterUtils.cpp?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/WriterUtils.cpp (original)
+++ lld/trunk/wasm/WriterUtils.cpp Thu Feb 22 21:08:53 2018
@@ -190,3 +190,10 @@ std::string lld::toString(const WasmSign
     S += toString(static_cast<ValType>(Sig.ReturnType));
   return S.str();
 }
+
+std::string lld::toString(const WasmGlobalType &Sig) {
+  std::string S = toString(static_cast<ValType>(Sig.Type));
+  if (Sig.Mutable)
+    return "mutable " + S;
+  return S;
+}

Modified: lld/trunk/wasm/WriterUtils.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/WriterUtils.h?rev=325861&r1=325860&r2=325861&view=diff
==============================================================================
--- lld/trunk/wasm/WriterUtils.h (original)
+++ lld/trunk/wasm/WriterUtils.h Thu Feb 22 21:08:53 2018
@@ -28,6 +28,17 @@ inline bool operator!=(const llvm::wasm:
   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 {
 
@@ -65,6 +76,7 @@ void writeExport(raw_ostream &OS, const
 
 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
 




More information about the llvm-commits mailing list