[lld] r322908 - [WebAssembly] Add missing function exports and SYM_INFO to --relocatable output
Sam Clegg via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 18 15:40:49 PST 2018
Author: sbc
Date: Thu Jan 18 15:40:49 2018
New Revision: 322908
URL: http://llvm.org/viewvc/llvm-project?rev=322908&view=rev
Log:
[WebAssembly] Add missing function exports and SYM_INFO to --relocatable output
When writing relocatable files we were exporting for all globals
(including file-local syms), but not for functions. Oops. To be
consistent with non-relocatable output, all symbols (file-local
and global) should be exported. Any symbol targetted by further
relocations needs to be exported. The lack of local function
exports was just an omission, I think.
Second bug: Local symbol names can collide, causing an illegal
Wasm file to be generated! Oops again. This only previously affected
producing relocatable output from two files, where each had a global
with the same name. We need to "budge" the symbol names for locals
that are exported on relocatable output.
Third bug: LLD's relocatable output wasn't writing out any symbol
flags! Thus the local globals weren't being marked as local, and
the hidden flag was also stripped...
Added tests to exercise colliding local names with/without
relocatable flag
Patch by Nicholas Wilson!
Differential Revision: https://reviews.llvm.org/D42105
Added:
lld/trunk/test/wasm/Inputs/locals-duplicate1.ll
lld/trunk/test/wasm/Inputs/locals-duplicate2.ll
lld/trunk/test/wasm/locals-duplicate.test
Modified:
lld/trunk/test/wasm/call-indirect.ll
lld/trunk/test/wasm/init-fini.ll
lld/trunk/test/wasm/relocatable.ll
lld/trunk/test/wasm/visibility-hidden.ll
lld/trunk/wasm/Writer.cpp
Added: lld/trunk/test/wasm/Inputs/locals-duplicate1.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/Inputs/locals-duplicate1.ll?rev=322908&view=auto
==============================================================================
--- lld/trunk/test/wasm/Inputs/locals-duplicate1.ll (added)
+++ lld/trunk/test/wasm/Inputs/locals-duplicate1.ll Thu Jan 18 15:40:49 2018
@@ -0,0 +1,49 @@
+; Will collide: local (internal linkage) with global (external) linkage
+ at colliding_global1 = internal default global i32 0, align 4
+; Will collide: global with local
+ at colliding_global2 = default global i32 0, align 4
+; Will collide: local with local
+ at colliding_global3 = internal default global i32 0, align 4
+
+; Will collide: local with global
+define internal i32 @colliding_func1() {
+entry:
+ ret i32 2
+}
+; Will collide: global with local
+define i32 @colliding_func2() {
+entry:
+ ret i32 2
+}
+; Will collide: local with local
+define internal i32 @colliding_func3() {
+entry:
+ ret i32 2
+}
+
+
+define i32* @get_global1A() {
+entry:
+ ret i32* @colliding_global1
+}
+define i32* @get_global2A() {
+entry:
+ ret i32* @colliding_global2
+}
+define i32* @get_global3A() {
+entry:
+ ret i32* @colliding_global3
+}
+
+define i32 ()* @get_func1A() {
+entry:
+ ret i32 ()* @colliding_func1
+}
+define i32 ()* @get_func2A() {
+entry:
+ ret i32 ()* @colliding_func2
+}
+define i32 ()* @get_func3A() {
+entry:
+ ret i32 ()* @colliding_func3
+}
Added: lld/trunk/test/wasm/Inputs/locals-duplicate2.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/Inputs/locals-duplicate2.ll?rev=322908&view=auto
==============================================================================
--- lld/trunk/test/wasm/Inputs/locals-duplicate2.ll (added)
+++ lld/trunk/test/wasm/Inputs/locals-duplicate2.ll Thu Jan 18 15:40:49 2018
@@ -0,0 +1,49 @@
+; Will collide: local (internal linkage) with global (external) linkage
+ at colliding_global1 = default global i32 0, align 4
+; Will collide: global with local
+ at colliding_global2 = internal default global i32 0, align 4
+; Will collide: local with local
+ at colliding_global3 = internal default global i32 0, align 4
+
+; Will collide: local with global
+define i32 @colliding_func1() {
+entry:
+ ret i32 2
+}
+; Will collide: global with local
+define internal i32 @colliding_func2() {
+entry:
+ ret i32 2
+}
+; Will collide: local with local
+define internal i32 @colliding_func3() {
+entry:
+ ret i32 2
+}
+
+
+define i32* @get_global1B() {
+entry:
+ ret i32* @colliding_global1
+}
+define i32* @get_global2B() {
+entry:
+ ret i32* @colliding_global2
+}
+define i32* @get_global3B() {
+entry:
+ ret i32* @colliding_global3
+}
+
+define i32 ()* @get_func1B() {
+entry:
+ ret i32 ()* @colliding_func1
+}
+define i32 ()* @get_func2B() {
+entry:
+ ret i32 ()* @colliding_func2
+}
+define i32 ()* @get_func3B() {
+entry:
+ ret i32 ()* @colliding_func3
+}
Modified: lld/trunk/test/wasm/call-indirect.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/call-indirect.ll?rev=322908&r1=322907&r2=322908&view=diff
==============================================================================
--- lld/trunk/test/wasm/call-indirect.ll (original)
+++ lld/trunk/test/wasm/call-indirect.ll Thu Jan 18 15:40:49 2018
@@ -85,15 +85,15 @@ define void @call_ptr(i64 (i64)* %arg) {
; CHECK-NEXT: - Name: _start
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 3
-; CHECK-NEXT: - Name: foo
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 2
; CHECK-NEXT: - Name: bar
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 0
; CHECK-NEXT: - Name: call_bar_indirect
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 1
+; CHECK-NEXT: - Name: foo
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 2
; CHECK-NEXT: - Name: call_ptr
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 4
Modified: lld/trunk/test/wasm/init-fini.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/init-fini.ll?rev=322908&r1=322907&r2=322908&view=diff
==============================================================================
--- lld/trunk/test/wasm/init-fini.ll (original)
+++ lld/trunk/test/wasm/init-fini.ll Thu Jan 18 15:40:49 2018
@@ -107,7 +107,44 @@ entry:
; RELOC: Name: linking
; RELOC-NEXT: DataSize: 0
-; RELOC-NEXT: InitFunctions:
+; RELOC-NEXT: SymbolInfo:
+; 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: .Lbitcast
+; 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: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: InitFunctions:
; RELOC-NEXT: - Priority: 101
; RELOC-NEXT: FunctionIndex: 0
; RELOC-NEXT: - Priority: 101
Added: lld/trunk/test/wasm/locals-duplicate.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/locals-duplicate.test?rev=322908&view=auto
==============================================================================
--- lld/trunk/test/wasm/locals-duplicate.test (added)
+++ lld/trunk/test/wasm/locals-duplicate.test Thu Jan 18 15:40:49 2018
@@ -0,0 +1,543 @@
+; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/locals-duplicate1.ll -o %t1.o
+; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/locals-duplicate2.ll -o %t2.o
+; RUN: lld -flavor wasm --no-entry -o %t.wasm %t1.o %t2.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; CHECK: --- !WASM
+; CHECK-NEXT: FileHeader:
+; CHECK-NEXT: Version: 0x00000001
+; CHECK-NEXT: Sections:
+; CHECK-NEXT: - Type: TYPE
+; CHECK-NEXT: Signatures:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: ReturnType: I32
+; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: ReturnType: NORESULT
+; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: - Type: FUNCTION
+; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+; CHECK-NEXT: 0, 0, 1 ]
+; CHECK-NEXT: - Type: TABLE
+; CHECK-NEXT: Tables:
+; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: Limits:
+; CHECK-NEXT: Flags: [ HAS_MAX ]
+; CHECK-NEXT: Initial: 0x00000007
+; CHECK-NEXT: Maximum: 0x00000007
+; CHECK-NEXT: - Type: MEMORY
+; CHECK-NEXT: Memories:
+; CHECK-NEXT: - Initial: 0x00000002
+; CHECK-NEXT: - Type: GLOBAL
+; CHECK-NEXT: Globals:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Type: I32
+; CHECK-NEXT: Mutable: true
+; CHECK-NEXT: InitExpr:
+; CHECK-NEXT: Opcode: I32_CONST
+; CHECK-NEXT: Value: 66592
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Type: I32
+; CHECK-NEXT: Mutable: false
+; CHECK-NEXT: InitExpr:
+; CHECK-NEXT: Opcode: I32_CONST
+; CHECK-NEXT: Value: 66592
+; CHECK-NEXT: - Type: EXPORT
+; CHECK-NEXT: Exports:
+; CHECK-NEXT: - Name: memory
+; CHECK-NEXT: Kind: MEMORY
+; CHECK-NEXT: Index: 0
+; CHECK-NEXT: - Name: colliding_func2
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 1
+; CHECK-NEXT: - Name: get_global1A
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 3
+; CHECK-NEXT: - Name: get_global2A
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 4
+; CHECK-NEXT: - Name: get_global3A
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 5
+; CHECK-NEXT: - Name: get_func1A
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 6
+; CHECK-NEXT: - Name: get_func2A
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 7
+; CHECK-NEXT: - Name: get_func3A
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 8
+; CHECK-NEXT: - Name: colliding_func1
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 9
+; CHECK-NEXT: - Name: get_global1B
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 12
+; CHECK-NEXT: - Name: get_global2B
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 13
+; CHECK-NEXT: - Name: get_global3B
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 14
+; CHECK-NEXT: - Name: get_func1B
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 15
+; CHECK-NEXT: - Name: get_func2B
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 16
+; CHECK-NEXT: - Name: get_func3B
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 17
+; CHECK-NEXT: - Name: __heap_base
+; CHECK-NEXT: Kind: GLOBAL
+; CHECK-NEXT: Index: 1
+; CHECK-NEXT: - Type: ELEM
+; CHECK-NEXT: Segments:
+; CHECK-NEXT: - Offset:
+; CHECK-NEXT: Opcode: I32_CONST
+; CHECK-NEXT: Value: 1
+; CHECK-NEXT: Functions: [ 0, 1, 2, 9, 10, 11 ]
+; CHECK-NEXT: - Type: CODE
+; CHECK-NEXT: Functions:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 41020B
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 41020B
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 41020B
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4180888080000B
+; CHECK-NEXT: - Index: 4
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4184888080000B
+; CHECK-NEXT: - Index: 5
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4188888080000B
+; CHECK-NEXT: - Index: 6
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4181808080000B
+; CHECK-NEXT: - Index: 7
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4182808080000B
+; CHECK-NEXT: - Index: 8
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4183808080000B
+; CHECK-NEXT: - Index: 9
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 41020B
+; CHECK-NEXT: - Index: 10
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 41020B
+; CHECK-NEXT: - Index: 11
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 41020B
+; CHECK-NEXT: - Index: 12
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 418C888080000B
+; CHECK-NEXT: - Index: 13
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4190888080000B
+; CHECK-NEXT: - Index: 14
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4194888080000B
+; CHECK-NEXT: - Index: 15
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4184808080000B
+; CHECK-NEXT: - Index: 16
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4185808080000B
+; CHECK-NEXT: - Index: 17
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 4186808080000B
+; CHECK-NEXT: - Index: 18
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 0B
+; CHECK-NEXT: - Type: DATA
+; CHECK-NEXT: Segments:
+; CHECK-NEXT: - SectionOffset: 7
+; CHECK-NEXT: MemoryIndex: 0
+; CHECK-NEXT: Offset:
+; CHECK-NEXT: Opcode: I32_CONST
+; CHECK-NEXT: Value: 1024
+; CHECK-NEXT: Content: '000000000000000000000000000000000000000000000000'
+; CHECK-NEXT: - Type: CUSTOM
+; CHECK-NEXT: Name: linking
+; CHECK-NEXT: DataSize: 24
+; CHECK-NEXT: - Type: CUSTOM
+; CHECK-NEXT: Name: name
+; CHECK-NEXT: FunctionNames:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Name: colliding_func1
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Name: colliding_func2
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Name: colliding_func3
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Name: get_global1A
+; CHECK-NEXT: - Index: 4
+; CHECK-NEXT: Name: get_global2A
+; CHECK-NEXT: - Index: 5
+; CHECK-NEXT: Name: get_global3A
+; CHECK-NEXT: - Index: 6
+; CHECK-NEXT: Name: get_func1A
+; CHECK-NEXT: - Index: 7
+; CHECK-NEXT: Name: get_func2A
+; CHECK-NEXT: - Index: 8
+; CHECK-NEXT: Name: get_func3A
+; CHECK-NEXT: - Index: 9
+; CHECK-NEXT: Name: colliding_func1
+; CHECK-NEXT: - Index: 10
+; CHECK-NEXT: Name: colliding_func2
+; CHECK-NEXT: - Index: 11
+; CHECK-NEXT: Name: colliding_func3
+; CHECK-NEXT: - Index: 12
+; CHECK-NEXT: Name: get_global1B
+; CHECK-NEXT: - Index: 13
+; CHECK-NEXT: Name: get_global2B
+; CHECK-NEXT: - Index: 14
+; CHECK-NEXT: Name: get_global3B
+; CHECK-NEXT: - Index: 15
+; CHECK-NEXT: Name: get_func1B
+; CHECK-NEXT: - Index: 16
+; CHECK-NEXT: Name: get_func2B
+; CHECK-NEXT: - Index: 17
+; CHECK-NEXT: Name: get_func3B
+; CHECK-NEXT: - Index: 18
+; CHECK-NEXT: Name: __wasm_call_ctors
+; CHECK-NEXT: ...
+
+
+; RUN: lld -flavor wasm -r --no-entry -o %t.reloc.wasm %t1.o %t2.o
+; RUN: obj2yaml %t.reloc.wasm | FileCheck -check-prefix=RELOC %s
+
+; RELOC: --- !WASM
+; RELOC-NEXT: FileHeader:
+; RELOC-NEXT: Version: 0x00000001
+; RELOC-NEXT: Sections:
+; RELOC-NEXT: - Type: TYPE
+; RELOC-NEXT: Signatures:
+; RELOC-NEXT: - Index: 0
+; RELOC-NEXT: ReturnType: I32
+; RELOC-NEXT: ParamTypes:
+; RELOC-NEXT: - Type: FUNCTION
+; RELOC-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+; RELOC-NEXT: 0, 0 ]
+; RELOC-NEXT: - Type: TABLE
+; RELOC-NEXT: Tables:
+; RELOC-NEXT: - ElemType: ANYFUNC
+; RELOC-NEXT: Limits:
+; RELOC-NEXT: Flags: [ HAS_MAX ]
+; RELOC-NEXT: Initial: 0x00000006
+; RELOC-NEXT: Maximum: 0x00000006
+; 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:
+; RELOC-NEXT: Opcode: I32_CONST
+; RELOC-NEXT: Value: 0
+; RELOC-NEXT: Functions: [ 0, 1, 2, 9, 10, 11 ]
+; RELOC-NEXT: - Type: CODE
+; RELOC-NEXT: Relocations:
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 0
+; RELOC-NEXT: Offset: 0x00000013
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 1
+; RELOC-NEXT: Offset: 0x0000001C
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 2
+; RELOC-NEXT: Offset: 0x00000025
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 0
+; RELOC-NEXT: Offset: 0x0000002E
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 1
+; RELOC-NEXT: Offset: 0x00000037
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 2
+; RELOC-NEXT: Offset: 0x00000040
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 3
+; RELOC-NEXT: Offset: 0x00000058
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 4
+; RELOC-NEXT: Offset: 0x00000061
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 5
+; RELOC-NEXT: Offset: 0x0000006A
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 3
+; RELOC-NEXT: Offset: 0x00000073
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 4
+; RELOC-NEXT: Offset: 0x0000007C
+; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 5
+; RELOC-NEXT: Offset: 0x00000085
+; RELOC-NEXT: Functions:
+; RELOC-NEXT: - Index: 0
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 41020B
+; RELOC-NEXT: - Index: 1
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 41020B
+; RELOC-NEXT: - Index: 2
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 41020B
+; RELOC-NEXT: - Index: 3
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4180808080000B
+; RELOC-NEXT: - Index: 4
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4188808080000B
+; RELOC-NEXT: - Index: 5
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4190808080000B
+; RELOC-NEXT: - Index: 6
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4180808080000B
+; RELOC-NEXT: - Index: 7
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4181808080000B
+; RELOC-NEXT: - Index: 8
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4182808080000B
+; RELOC-NEXT: - Index: 9
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 41020B
+; RELOC-NEXT: - Index: 10
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 41020B
+; RELOC-NEXT: - Index: 11
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 41020B
+; RELOC-NEXT: - Index: 12
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4184808080000B
+; RELOC-NEXT: - Index: 13
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 418C808080000B
+; RELOC-NEXT: - Index: 14
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4194808080000B
+; RELOC-NEXT: - Index: 15
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4183808080000B
+; RELOC-NEXT: - Index: 16
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4184808080000B
+; RELOC-NEXT: - Index: 17
+; RELOC-NEXT: Locals:
+; RELOC-NEXT: Body: 4185808080000B
+; RELOC-NEXT: - Type: DATA
+; RELOC-NEXT: Segments:
+; RELOC-NEXT: - SectionOffset: 6
+; RELOC-NEXT: MemoryIndex: 0
+; RELOC-NEXT: Offset:
+; RELOC-NEXT: Opcode: I32_CONST
+; RELOC-NEXT: Value: 0
+; RELOC-NEXT: Content: '0000000000000000'
+; RELOC-NEXT: - SectionOffset: 19
+; RELOC-NEXT: MemoryIndex: 0
+; RELOC-NEXT: Offset:
+; RELOC-NEXT: Opcode: I32_CONST
+; RELOC-NEXT: Value: 8
+; RELOC-NEXT: Content: '0000000000000000'
+; RELOC-NEXT: - SectionOffset: 32
+; RELOC-NEXT: MemoryIndex: 0
+; RELOC-NEXT: Offset:
+; RELOC-NEXT: Opcode: I32_CONST
+; RELOC-NEXT: Value: 16
+; RELOC-NEXT: Content: '0000000000000000'
+; RELOC-NEXT: - Type: CUSTOM
+; RELOC-NEXT: Name: linking
+; RELOC-NEXT: DataSize: 24
+; RELOC-NEXT: SymbolInfo:
+; RELOC-NEXT: - Name: colliding_func1.1
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: - Name: colliding_func3
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: - Name: colliding_func2.1
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: - Name: colliding_func3.1
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: - Name: colliding_global1.1
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: - Name: colliding_global3
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: - Name: colliding_global2.1
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: - Name: colliding_global3.1
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: SegmentInfo:
+; RELOC-NEXT: - Index: 0
+; RELOC-NEXT: Name: .bss.colliding_global1
+; RELOC-NEXT: Alignment: 4
+; RELOC-NEXT: Flags: [ ]
+; RELOC-NEXT: - Index: 1
+; RELOC-NEXT: Name: .bss.colliding_global2
+; RELOC-NEXT: Alignment: 4
+; RELOC-NEXT: Flags: [ ]
+; RELOC-NEXT: - Index: 2
+; RELOC-NEXT: Name: .bss.colliding_global3
+; RELOC-NEXT: Alignment: 4
+; RELOC-NEXT: Flags: [ ]
+; RELOC-NEXT: - Type: CUSTOM
+; RELOC-NEXT: Name: name
+; RELOC-NEXT: FunctionNames:
+; RELOC-NEXT: - Index: 0
+; RELOC-NEXT: Name: colliding_func1
+; RELOC-NEXT: - Index: 1
+; RELOC-NEXT: Name: colliding_func2
+; RELOC-NEXT: - Index: 2
+; RELOC-NEXT: Name: colliding_func3
+; RELOC-NEXT: - Index: 3
+; RELOC-NEXT: Name: get_global1A
+; RELOC-NEXT: - Index: 4
+; RELOC-NEXT: Name: get_global2A
+; RELOC-NEXT: - Index: 5
+; RELOC-NEXT: Name: get_global3A
+; RELOC-NEXT: - Index: 6
+; RELOC-NEXT: Name: get_func1A
+; RELOC-NEXT: - Index: 7
+; RELOC-NEXT: Name: get_func2A
+; RELOC-NEXT: - Index: 8
+; RELOC-NEXT: Name: get_func3A
+; RELOC-NEXT: - Index: 9
+; RELOC-NEXT: Name: colliding_func1
+; RELOC-NEXT: - Index: 10
+; RELOC-NEXT: Name: colliding_func2
+; RELOC-NEXT: - Index: 11
+; RELOC-NEXT: Name: colliding_func3
+; RELOC-NEXT: - Index: 12
+; RELOC-NEXT: Name: get_global1B
+; RELOC-NEXT: - Index: 13
+; RELOC-NEXT: Name: get_global2B
+; RELOC-NEXT: - Index: 14
+; RELOC-NEXT: Name: get_global3B
+; RELOC-NEXT: - Index: 15
+; RELOC-NEXT: Name: get_func1B
+; RELOC-NEXT: - Index: 16
+; RELOC-NEXT: Name: get_func2B
+; RELOC-NEXT: - Index: 17
+; RELOC-NEXT: Name: get_func3B
+; RELOC-NEXT: ...
Modified: lld/trunk/test/wasm/relocatable.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/relocatable.ll?rev=322908&r1=322907&r2=322908&view=diff
==============================================================================
--- lld/trunk/test/wasm/relocatable.ll (original)
+++ lld/trunk/test/wasm/relocatable.ll Thu Jan 18 15:40:49 2018
@@ -200,6 +200,21 @@ entry:
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 23
+; CHECK-NEXT: SymbolInfo:
+; CHECK-NEXT: - Name: hello
+; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT: - Name: my_func
+; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT: - Name: func_comdat
+; CHECK-NEXT: Flags: [ BINDING_WEAK ]
+; 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: data_addr1
+; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .rodata.hello_str
Modified: lld/trunk/test/wasm/visibility-hidden.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/visibility-hidden.ll?rev=322908&r1=322907&r2=322908&view=diff
==============================================================================
--- lld/trunk/test/wasm/visibility-hidden.ll (original)
+++ lld/trunk/test/wasm/visibility-hidden.ll Thu Jan 18 15:40:49 2018
@@ -37,12 +37,12 @@ entry:
; CHECK-NEXT: - Name: _start
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 2
-; CHECK-NEXT: - Name: archiveDefault
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: Index: 4
; CHECK-NEXT: - Name: objectDefault
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 1
+; CHECK-NEXT: - Name: archiveDefault
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 4
; CHECK-NEXT: - Name: __heap_base
; CHECK-NEXT: Kind: GLOBAL
; CHECK-NEXT: Index: 1
Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=322908&r1=322907&r2=322908&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Thu Jan 18 15:40:49 2018
@@ -62,6 +62,12 @@ struct WasmSignatureDenseMapInfo {
}
};
+// A Wasm export to be written into the export section.
+struct WasmExportEntry {
+ const Symbol *Symbol;
+ StringRef FieldName; // may not match the Symbol name
+};
+
// The writer writes a SymbolTable result to a file.
class Writer {
public:
@@ -76,6 +82,7 @@ private:
void calculateInitFunctions();
void assignIndexes();
void calculateImports();
+ void calculateExports();
void calculateTypes();
void createOutputSegments();
void layoutMemory();
@@ -114,6 +121,7 @@ private:
DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices;
std::vector<const Symbol *> ImportedFunctions;
std::vector<const Symbol *> ImportedGlobals;
+ std::vector<WasmExportEntry> ExportedSymbols;
std::vector<const Symbol *> DefinedGlobals;
std::vector<InputFunction *> DefinedFunctions;
std::vector<const Symbol *> IndirectFunctions;
@@ -259,35 +267,8 @@ void Writer::createTableSection() {
void Writer::createExportSection() {
bool ExportMemory = !Config->Relocatable && !Config->ImportMemory;
- Symbol *EntrySym = Symtab->find(Config->Entry);
- bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined();
- bool ExportHidden = Config->EmitRelocs;
-
- uint32_t NumExports = ExportMemory ? 1 : 0;
-
- std::vector<const Symbol *> SymbolExports;
- if (ExportEntry)
- SymbolExports.emplace_back(EntrySym);
-
- for (const Symbol *Sym : Symtab->getSymbols()) {
- if (Sym->isUndefined() || Sym->isGlobal())
- continue;
- if (Sym->isHidden() && !ExportHidden)
- continue;
- if (ExportEntry && Sym == EntrySym)
- continue;
- SymbolExports.emplace_back(Sym);
- }
- for (const Symbol *Sym : DefinedGlobals) {
- // Can't export the SP right now because it mutable and mutable globals
- // connot be exported.
- if (Sym == Config->StackPointerSymbol)
- continue;
- SymbolExports.emplace_back(Sym);
- }
-
- NumExports += SymbolExports.size();
+ uint32_t NumExports = (ExportMemory ? 1 : 0) + ExportedSymbols.size();
if (!NumExports)
return;
@@ -304,12 +285,12 @@ void Writer::createExportSection() {
writeExport(OS, MemoryExport);
}
- for (const Symbol *Sym : SymbolExports) {
- DEBUG(dbgs() << "Export: " << Sym->getName() << "\n");
+ for (const WasmExportEntry &E : ExportedSymbols) {
+ DEBUG(dbgs() << "Export: " << E.Symbol->getName() << "\n");
WasmExport Export;
- Export.Name = Sym->getName();
- Export.Index = Sym->getOutputIndex();
- if (Sym->isFunction())
+ Export.Name = E.FieldName;
+ Export.Index = E.Symbol->getOutputIndex();
+ if (E.Symbol->isFunction())
Export.Kind = WASM_EXTERNAL_FUNCTION;
else
Export.Kind = WASM_EXTERNAL_GLOBAL;
@@ -404,6 +385,26 @@ void Writer::createLinkingSection() {
if (!Config->Relocatable)
return;
+ std::vector<std::pair<StringRef, uint32_t>> SymbolInfo;
+ for (const WasmExportEntry &E : ExportedSymbols) {
+ uint32_t Flags =
+ (E.Symbol->isLocal() ? WASM_SYMBOL_BINDING_LOCAL :
+ E.Symbol->isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0) |
+ (E.Symbol->isHidden() ? WASM_SYMBOL_VISIBILITY_HIDDEN : 0);
+ if (Flags)
+ SymbolInfo.emplace_back(E.FieldName, Flags);
+ }
+ 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");
+ }
+ SubSection.finalizeContents();
+ SubSection.writeToStream(OS);
+ }
+
if (Segments.size()) {
SubSection SubSection(WASM_SEGMENT_INFO);
writeUleb128(SubSection.getStream(), Segments.size(), "num data segments");
@@ -608,6 +609,64 @@ void Writer::calculateImports() {
}
}
+void Writer::calculateExports() {
+ Symbol *EntrySym = Symtab->find(Config->Entry);
+ bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined();
+ bool ExportHidden = Config->EmitRelocs;
+ StringSet<> UsedNames;
+ auto BudgeLocalName = [&](const Symbol *Sym) {
+ StringRef SymName = Sym->getName();
+ // We can't budge non-local names.
+ if (!Sym->isLocal())
+ return SymName;
+ // We must budge local names that have a collision with a symbol that we
+ // haven't yet processed.
+ if (!Symtab->find(SymName) && UsedNames.insert(SymName).second)
+ return SymName;
+ for (unsigned I = 1; ; ++I) {
+ std::string NameBuf = (SymName + "." + Twine(I)).str();
+ if (!UsedNames.count(NameBuf)) {
+ StringRef Name = Saver.save(NameBuf);
+ UsedNames.insert(Name); // Insert must use safe StringRef from save()
+ return Name;
+ }
+ }
+ };
+
+ if (ExportEntry)
+ ExportedSymbols.emplace_back(WasmExportEntry{EntrySym, EntrySym->getName()});
+
+ if (Config->CtorSymbol && ExportHidden &&
+ !(ExportEntry && Config->CtorSymbol == EntrySym))
+ ExportedSymbols.emplace_back(
+ WasmExportEntry{Config->CtorSymbol, Config->CtorSymbol->getName()});
+
+ for (ObjFile *File : Symtab->ObjectFiles) {
+ for (Symbol *Sym : File->getSymbols()) {
+ if (!Sym->isDefined() || File != Sym->getFile())
+ continue;
+ if (Sym->isGlobal())
+ continue;
+ if (Sym->getFunction()->Discarded)
+ continue;
+
+ if ((Sym->isHidden() || Sym->isLocal()) && !ExportHidden)
+ continue;
+ if (ExportEntry && Sym == EntrySym)
+ continue;
+ ExportedSymbols.emplace_back(WasmExportEntry{Sym, BudgeLocalName(Sym)});
+ }
+ }
+
+ for (const Symbol *Sym : DefinedGlobals) {
+ // Can't export the SP right now because it's mutable and mutable globals
+ // cannot be exported.
+ if (Sym == Config->StackPointerSymbol)
+ continue;
+ ExportedSymbols.emplace_back(WasmExportEntry{Sym, BudgeLocalName(Sym)});
+ }
+}
+
uint32_t Writer::lookupType(const WasmSignature &Sig) {
auto It = TypeIndices.find(Sig);
if (It == TypeIndices.end()) {
@@ -793,6 +852,8 @@ void Writer::run() {
calculateImports();
log("-- assignIndexes");
assignIndexes();
+ log("-- calculateExports");
+ calculateExports();
log("-- calculateInitFunctions");
calculateInitFunctions();
if (!Config->Relocatable)
More information about the llvm-commits
mailing list