mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 14:20:17 +00:00
[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 llvm-svn: 322908
This commit is contained in:
parent
a19b748f6d
commit
d3052d5522
49
lld/test/wasm/Inputs/locals-duplicate1.ll
Normal file
49
lld/test/wasm/Inputs/locals-duplicate1.ll
Normal file
@ -0,0 +1,49 @@
|
||||
; Will collide: local (internal linkage) with global (external) linkage
|
||||
@colliding_global1 = internal default global i32 0, align 4
|
||||
; Will collide: global with local
|
||||
@colliding_global2 = default global i32 0, align 4
|
||||
; Will collide: local with local
|
||||
@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
|
||||
}
|
49
lld/test/wasm/Inputs/locals-duplicate2.ll
Normal file
49
lld/test/wasm/Inputs/locals-duplicate2.ll
Normal file
@ -0,0 +1,49 @@
|
||||
; Will collide: local (internal linkage) with global (external) linkage
|
||||
@colliding_global1 = default global i32 0, align 4
|
||||
; Will collide: global with local
|
||||
@colliding_global2 = internal default global i32 0, align 4
|
||||
; Will collide: local with local
|
||||
@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
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
543
lld/test/wasm/locals-duplicate.test
Normal file
543
lld/test/wasm/locals-duplicate.test
Normal file
@ -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: ...
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user