summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COFF/PDB.cpp18
-rw-r--r--ELF/Driver.cpp2
-rw-r--r--ELF/ScriptParser.cpp3
-rw-r--r--docs/ReleaseNotes.rst60
-rw-r--r--docs/index.rst1
-rw-r--r--docs/missingkeyfunction.rst4
-rw-r--r--test/COFF/pdb-relative-source-lines.test60
-rw-r--r--test/ELF/emulation-mips.s3
-rw-r--r--test/ELF/emulation-ppc.s37
-rw-r--r--test/wasm/data-layout.ll6
-rw-r--r--test/wasm/import-module.ll21
-rw-r--r--test/wasm/import-names.ll27
-rw-r--r--test/wasm/init-fini.ll86
-rw-r--r--test/wasm/locals-duplicate.test146
-rw-r--r--test/wasm/lto/relocatable-undefined.ll36
-rw-r--r--test/wasm/weak-alias.ll28
-rw-r--r--wasm/Driver.cpp4
-rw-r--r--wasm/InputChunks.cpp6
-rw-r--r--wasm/InputFiles.cpp11
-rw-r--r--wasm/LTO.cpp5
-rw-r--r--wasm/LTO.h1
-rw-r--r--wasm/MarkLive.cpp2
-rw-r--r--wasm/SymbolTable.cpp14
-rw-r--r--wasm/SymbolTable.h10
-rw-r--r--wasm/Symbols.h19
-rw-r--r--wasm/Writer.cpp106
-rw-r--r--wasm/Writer.h2
27 files changed, 468 insertions, 250 deletions
diff --git a/COFF/PDB.cpp b/COFF/PDB.cpp
index 7862b6ce4cc5..7757b89e2b36 100644
--- a/COFF/PDB.cpp
+++ b/COFF/PDB.cpp
@@ -288,18 +288,24 @@ static void pdbMakeAbsolute(SmallVectorImpl<char> &FileName) {
// It's not absolute in any path syntax. Relative paths necessarily refer to
// the local file system, so we can make it native without ending up with a
// nonsensical path.
- sys::path::native(FileName);
if (Config->PDBSourcePath.empty()) {
+ sys::path::native(FileName);
sys::fs::make_absolute(FileName);
return;
}
- // Only apply native and dot removal to the relative file path. We want to
- // leave the path the user specified untouched since we assume they specified
- // it for a reason.
- sys::path::remove_dots(FileName, /*remove_dot_dots=*/true);
+ // Try to guess whether /PDBSOURCEPATH is a unix path or a windows path.
+ // Since PDB's are more of a Windows thing, we make this conservative and only
+ // decide that it's a unix path if we're fairly certain. Specifically, if
+ // it starts with a forward slash.
SmallString<128> AbsoluteFileName = Config->PDBSourcePath;
- sys::path::append(AbsoluteFileName, FileName);
+ sys::path::Style GuessedStyle = AbsoluteFileName.startswith("/")
+ ? sys::path::Style::posix
+ : sys::path::Style::windows;
+ sys::path::append(AbsoluteFileName, GuessedStyle, FileName);
+ sys::path::native(AbsoluteFileName, GuessedStyle);
+ sys::path::remove_dots(AbsoluteFileName, true, GuessedStyle);
+
FileName = std::move(AbsoluteFileName);
}
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index 2e2036310fb2..bce9d944a4a6 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -130,7 +130,7 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {
.Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})
.Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})
.Case("elf32lriscv", {ELF32LEKind, EM_RISCV})
- .Case("elf32ppc", {ELF32BEKind, EM_PPC})
+ .Cases("elf32ppc", "elf32ppclinux", {ELF32BEKind, EM_PPC})
.Case("elf64btsmip", {ELF64BEKind, EM_MIPS})
.Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})
.Case("elf64lriscv", {ELF64LEKind, EM_RISCV})
diff --git a/ELF/ScriptParser.cpp b/ELF/ScriptParser.cpp
index 7cce94659c9e..7dbe1641622b 100644
--- a/ELF/ScriptParser.cpp
+++ b/ELF/ScriptParser.cpp
@@ -392,10 +392,11 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
.Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
.Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
.Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
+ .Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
.Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
.Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
.Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
- .Case("elf32-tradbigmips", {ELF32BEKind, EM_MIPS})
+ .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS})
.Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS})
.Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS})
.Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index c02cc586c795..0bebfb3fb1ce 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -13,10 +13,12 @@ lld 8.0.0 Release Notes
Introduction
============
-This document contains the release notes for the lld linker, release 8.0.0.
-Here we describe the status of lld, including major improvements
-from the previous release. All lld releases may be downloaded
-from the `LLVM releases web site <https://llvm.org/releases/>`_.
+lld is a high-performance linker that supports ELF (Unix), COFF (Windows),
+Mach-O (macOS), MinGW and WebAssembly. lld is command-line-compatible with
+GNU linkers and Microsoft link.exe and is significantly faster than the
+system default linkers.
+
+nlld 8.0.0 has lots of feature improvements and bug fixes.
Non-comprehensive list of changes in this release
=================================================
@@ -33,27 +35,66 @@ ELF Improvements
non-superpages to a superpage if they are aligned to the superpage
size. (`r342746 <https://reviews.llvm.org/rL342746>`_)
+* lld now attempts to place a ``.note`` segment in the first page of a
+ generated file, so that you can find some important information
+ (``.note.gnu.build-id`` in particular) in a core file even if a core
+ file is truncated by ulimit.
+ (`r349524 <https://reviews.llvm.org/rL349524>`_)
+
+* lld now reports an error if ``_GLOBAL_OFFSET_TABLE_`` symbol is
+ defined by an input object file, as the symbol is supposed to be
+ synthesized by the linker.
+ (`r347854 <https://reviews.llvm.org/rL347854>`_)
+
* lld/Hexagon can now link Linux kernel and musl libc for Qualcomm
Hexagon ISA.
* Initial MSP430 ISA support has landed.
-* The following flags have been added: ``-z interpose``, ``-z global``
-
* lld now uses the ``sigrie`` instruction as a trap instruction for
MIPS targets.
+* lld now creates a TLS segment for AArch64 with a slightly larger
+ alignment requirement, so that the loader makes a few bytes room
+ before each TLS segment at runtime. The aim of this change is to
+ make room to accomodate nonstandard Android TLS slots while keeping
+ the compatibility with the standard AArch64 ABI.
+ (`r350681 <https://reviews.llvm.org/rL350681>`_)
+
+* The following flags have been added: ``--call-graph-profile``,
+ ``--no-call-graph-profile``, ``--warn-ifunc-textrel``,
+ ``-z interpose``, ``-z global``, ``-z nodefaultlib``
+
COFF Improvements
-----------------
* PDB GUID is set to hash of PDB contents instead to a random byte
sequence for build reproducibility.
+* ``/pdbsourcepath:`` is now also used to make ``"cwd"``, ``"exe"``, ``"pdb"``
+ in the env block of PDB outputs absolute if they are relative, and to make
+ paths to obj files referenced in PDB outputs absolute if they are relative.
+ Together with the previous item, this makes it possible to generate
+ executables and PDBs that are fully deterministic and independent of the
+ absolute path to the build directory, so that different machines building
+ the same code in different directories can produce exactly the same output.
+
* The following flags have been added: ``/force:multiple``
* lld now can link against import libraries produced by GNU tools.
-* lld can create thunks for ARM, to allow linking images over 16 MB.
+* lld can create thunks for ARM and ARM64, to allow linking larger images
+ (over 16 MB for ARM and over 128 MB for ARM64)
+
+* Several speed and memory usage improvements.
+
+* lld now creates debug info for typedefs.
+
+* lld can now link obj files produced by ``cl.exe /Z7 /Yc``.
+
+* lld now understands ``%_PDB%`` and ``%_EXT%`` in ``/pdbaltpath:``.
+
+* Undefined symbols are now printed in demangled form in addition to raw form.
MinGW Improvements
------------------
@@ -76,11 +117,6 @@ MinGW Improvements
Previously, the ``--build-id`` option did not actually generate a build id
unless ``--pdb`` was specified.
-MachO Improvements
-------------------
-
-* Item 1.
-
WebAssembly Improvements
------------------------
diff --git a/docs/index.rst b/docs/index.rst
index da1c894f3d83..2564e9b6310f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -173,4 +173,5 @@ document soon.
AtomLLD
WebAssembly
windows_support
+ missingkeyfunction
ReleaseNotes
diff --git a/docs/missingkeyfunction.rst b/docs/missingkeyfunction.rst
index 410c749c3b03..54ad3251f794 100644
--- a/docs/missingkeyfunction.rst
+++ b/docs/missingkeyfunction.rst
@@ -1,5 +1,5 @@
-Missing Key Method
-==================
+Missing Key Function
+====================
If your build failed with a linker error something like this::
diff --git a/test/COFF/pdb-relative-source-lines.test b/test/COFF/pdb-relative-source-lines.test
index 865d7a6d8a0a..547056785962 100644
--- a/test/COFF/pdb-relative-source-lines.test
+++ b/test/COFF/pdb-relative-source-lines.test
@@ -37,26 +37,26 @@ RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=line
RUN: ./lld-link -debug "-pdbsourcepath:/usr/src" -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj
RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck --check-prefix=POSIX %s
-CHECK-LABEL: - Module: 'c:\src{{[\\/]}}pdb_lines_1_relative.obj'
-CHECK-NEXT: ObjFile: 'c:\src{{[\\/]}}pdb_lines_1_relative.obj'
+CHECK-LABEL: - Module: 'c:\src\pdb_lines_1_relative.obj'
+CHECK-NEXT: ObjFile: 'c:\src\pdb_lines_1_relative.obj'
CHECK: SourceFiles:
-CHECK-NEXT: - 'c:\src{{[\\/]}}pdb_lines_1.c'
-CHECK-NEXT: - 'c:\src{{[\\/]}}foo.h'
+CHECK-NEXT: - 'c:\src\pdb_lines_1.c'
+CHECK-NEXT: - 'c:\src\foo.h'
CHECK: Subsections:
-CHECK: - FileName: 'c:\src{{[\\/]}}pdb_lines_1.c'
-CHECK: - FileName: 'c:\src{{[\\/]}}foo.h'
+CHECK: - FileName: 'c:\src\pdb_lines_1.c'
+CHECK: - FileName: 'c:\src\foo.h'
CHECK: - !FileChecksums
-CHECK: - FileName: 'c:\src{{[\\/]}}pdb_lines_1.c'
-CHECK: - FileName: 'c:\src{{[\\/]}}foo.h'
+CHECK: - FileName: 'c:\src\pdb_lines_1.c'
+CHECK: - FileName: 'c:\src\foo.h'
-CHECK-LABEL: - Module: 'c:\src{{[\\/]}}pdb_lines_2_relative.obj'
-CHECK-NEXT: ObjFile: 'c:\src{{[\\/]}}pdb_lines_2_relative.obj'
+CHECK-LABEL: - Module: 'c:\src\pdb_lines_2_relative.obj'
+CHECK-NEXT: ObjFile: 'c:\src\pdb_lines_2_relative.obj'
CHECK: SourceFiles:
-CHECK-NEXT: - 'c:\src{{[\\/]}}pdb_lines_2.c'
+CHECK-NEXT: - 'c:\src\pdb_lines_2.c'
CHECK: Subsections:
-CHECK: - FileName: 'c:\src{{[\\/]}}pdb_lines_2.c'
+CHECK: - FileName: 'c:\src\pdb_lines_2.c'
CHECK: - !FileChecksums
-CHECK: - FileName: 'c:\src{{[\\/]}}pdb_lines_2.c'
+CHECK: - FileName: 'c:\src\pdb_lines_2.c'
CHECK-LABEL: - Kind: S_ENVBLOCK
CHECK-NEXT: EnvBlockSym:
@@ -64,33 +64,33 @@ CHECK-NEXT: Entries:
CHECK-NEXT: - cwd
CHECK-NEXT: - 'c:\src'
CHECK-NEXT: - exe
-CHECK-NEXT: - 'c:\src{{[\\/]}}lld-link'
+CHECK-NEXT: - 'c:\src\lld-link'
CHECK-NEXT: - pdb
-CHECK-NEXT: - 'c:\src{{[\\/]}}out.pdb'
+CHECK-NEXT: - 'c:\src\out.pdb'
CHECK-NEXT: - cmd
CHECK-NEXT: - '-debug -pdbsourcepath:c:\src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj'
-POSIX-LABEL: - Module: '/usr/src{{[\\/]}}pdb_lines_1_relative.obj'
-POSIX-NEXT: ObjFile: '/usr/src{{[\\/]}}pdb_lines_1_relative.obj'
+POSIX-LABEL: - Module: '/usr/src/pdb_lines_1_relative.obj'
+POSIX-NEXT: ObjFile: '/usr/src/pdb_lines_1_relative.obj'
POSIX: SourceFiles:
-POSIX-NEXT: - '/usr/src{{[\\/]}}pdb_lines_1.c'
-POSIX-NEXT: - '/usr/src{{[\\/]}}foo.h'
+POSIX-NEXT: - '/usr/src/pdb_lines_1.c'
+POSIX-NEXT: - '/usr/src/foo.h'
POSIX: Subsections:
-POSIX: - FileName: '/usr/src{{[\\/]}}pdb_lines_1.c'
-POSIX: - FileName: '/usr/src{{[\\/]}}foo.h'
+POSIX: - FileName: '/usr/src/pdb_lines_1.c'
+POSIX: - FileName: '/usr/src/foo.h'
POSIX: - !FileChecksums
-POSIX: - FileName: '/usr/src{{[\\/]}}pdb_lines_1.c'
-POSIX: - FileName: '/usr/src{{[\\/]}}foo.h'
+POSIX: - FileName: '/usr/src/pdb_lines_1.c'
+POSIX: - FileName: '/usr/src/foo.h'
-POSIX-LABEL: - Module: '/usr/src{{[\\/]}}pdb_lines_2_relative.obj'
-POSIX-NEXT: ObjFile: '/usr/src{{[\\/]}}pdb_lines_2_relative.obj'
+POSIX-LABEL: - Module: '/usr/src/pdb_lines_2_relative.obj'
+POSIX-NEXT: ObjFile: '/usr/src/pdb_lines_2_relative.obj'
POSIX: SourceFiles:
-POSIX-NEXT: - '/usr/src{{[\\/]}}pdb_lines_2.c'
+POSIX-NEXT: - '/usr/src/pdb_lines_2.c'
POSIX: Subsections:
-POSIX: - FileName: '/usr/src{{[\\/]}}pdb_lines_2.c'
+POSIX: - FileName: '/usr/src/pdb_lines_2.c'
POSIX: - !FileChecksums
-POSIX: - FileName: '/usr/src{{[\\/]}}pdb_lines_2.c'
+POSIX: - FileName: '/usr/src/pdb_lines_2.c'
POSIX-LABEL: - Kind: S_ENVBLOCK
POSIX-NEXT: EnvBlockSym:
@@ -98,8 +98,8 @@ POSIX-NEXT: Entries:
POSIX-NEXT: - cwd
POSIX-NEXT: - '/usr/src'
POSIX-NEXT: - exe
-POSIX-NEXT: - '/usr/src{{[\\/]}}lld-link'
+POSIX-NEXT: - '/usr/src/lld-link'
POSIX-NEXT: - pdb
-POSIX-NEXT: - '/usr/src{{[\\/]}}out.pdb'
+POSIX-NEXT: - '/usr/src/out.pdb'
POSIX-NEXT: - cmd
POSIX-NEXT: - '-debug -pdbsourcepath:/usr/src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj'
diff --git a/test/ELF/emulation-mips.s b/test/ELF/emulation-mips.s
index 42d0dd973eb3..6d7a1198b761 100644
--- a/test/ELF/emulation-mips.s
+++ b/test/ELF/emulation-mips.s
@@ -7,6 +7,9 @@
# RUN: echo 'OUTPUT_FORMAT(elf32-tradbigmips)' > %tmips.script
# RUN: ld.lld %tmips.script -e _start %tmips -o %t4mips
# RUN: llvm-readobj -file-headers %t4mips | FileCheck --check-prefix=MIPS %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-bigmips)' > %tmips2.script
+# RUN: ld.lld %tmips2.script -e _start %tmips -o %t5mips
+# RUN: llvm-readobj -file-headers %t5mips | FileCheck --check-prefix=MIPS %s
# MIPS: ElfHeader {
# MIPS-NEXT: Ident {
# MIPS-NEXT: Magic: (7F 45 4C 46)
diff --git a/test/ELF/emulation-ppc.s b/test/ELF/emulation-ppc.s
index 843e77604779..4c8beb10159e 100644
--- a/test/ELF/emulation-ppc.s
+++ b/test/ELF/emulation-ppc.s
@@ -103,5 +103,42 @@
# PPC64LE-NEXT: StringTableSectionIndex:
# PPC64LE-NEXT: }
+# RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-linux %s -o %tppc32
+# RUN: ld.lld -m elf32ppc %tppc32 -o %t2ppc32
+# RUN: llvm-readobj -file-headers %t2ppc32 | FileCheck --check-prefix=PPC32 %s
+# RUN: ld.lld %tppc32 -o %t3ppc32
+# RUN: llvm-readobj -file-headers %t3ppc32 | FileCheck --check-prefix=PPC32 %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-powerpc)' > %tppc32.script
+# RUN: ld.lld %tppc32.script %tppc32 -o %t4ppc32
+# RUN: llvm-readobj -file-headers %t4ppc32 | FileCheck --check-prefix=PPC32 %s
+# RUN: ld.lld -m elf32ppclinux %tppc32 -o %t5ppc32
+# RUN: llvm-readobj -file-headers %t5ppc32 | FileCheck --check-prefix=PPC32 %s
+
+# PPC32: ElfHeader {
+# PPC32-NEXT: Ident {
+# PPC32-NEXT: Magic: (7F 45 4C 46)
+# PPC32-NEXT: Class: 32-bit (0x1)
+# PPC32-NEXT: DataEncoding: BigEndian (0x2)
+# PPC32-NEXT: FileVersion: 1
+# PPC32-NEXT: OS/ABI: SystemV (0x0)
+# PPC32-NEXT: ABIVersion: 0
+# PPC32-NEXT: Unused: (00 00 00 00 00 00 00)
+# PPC32-NEXT: }
+# PPC32-NEXT: Type: Executable (0x2)
+# PPC32-NEXT: Machine: EM_PPC (0x14)
+# PPC32-NEXT: Version: 1
+# PPC32-NEXT: Entry:
+# PPC32-NEXT: ProgramHeaderOffset: 0x34
+# PPC32-NEXT: SectionHeaderOffset:
+# PPC32-NEXT: Flags [ (0x0)
+# PPC32-NEXT: ]
+# PPC32-NEXT: HeaderSize: 52
+# PPC32-NEXT: ProgramHeaderEntrySize: 32
+# PPC32-NEXT: ProgramHeaderCount:
+# PPC32-NEXT: SectionHeaderEntrySize: 40
+# PPC32-NEXT: SectionHeaderCount:
+# PPC32-NEXT: StringTableSectionIndex:
+# PPC32-NEXT: }
+
.globl _start
_start:
diff --git a/test/wasm/data-layout.ll b/test/wasm/data-layout.ll
index b01c13ac9b82..7c215efb0d8f 100644
--- a/test/wasm/data-layout.ll
+++ b/test/wasm/data-layout.ll
@@ -85,10 +85,10 @@ target triple = "wasm32-unknown-unknown"
; RELOC: - Type: DATA
; RELOC-NEXT: Relocations:
; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
-; RELOC-NEXT: Index: 6
+; RELOC-NEXT: Index: 3
; RELOC-NEXT: Offset: 0x00000018
; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
-; RELOC-NEXT: Index: 3
+; RELOC-NEXT: Index: 4
; RELOC-NEXT: Offset: 0x0000002E
; RELOC-NEXT: Addend: 4
; RELOC-NEXT: Segments:
@@ -148,7 +148,7 @@ target triple = "wasm32-unknown-unknown"
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Segment: 2
; RELOC-NEXT: Size: 4
-; RELOC: - Index: 6
+; RELOC-NEXT: - Index: 3
; RELOC-NEXT: Kind: DATA
; RELOC-NEXT: Name: hello_str
; RELOC-NEXT: Flags: [ ]
diff --git a/test/wasm/import-module.ll b/test/wasm/import-module.ll
new file mode 100644
index 000000000000..9a473194ce2c
--- /dev/null
+++ b/test/wasm/import-module.ll
@@ -0,0 +1,21 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown-wasm"
+
+define void @_start() {
+ call void @foo();
+ ret void
+}
+
+declare void @foo() #0
+
+attributes #0 = { "wasm-import-module"="bar" }
+
+; CHECK: - Type: IMPORT
+; CHECK-NEXT: Imports:
+; CHECK-NEXT: - Module: bar
+; CHECK-NEXT: Field: foo
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: SigIndex: 0
diff --git a/test/wasm/import-names.ll b/test/wasm/import-names.ll
new file mode 100644
index 000000000000..a3953d335619
--- /dev/null
+++ b/test/wasm/import-names.ll
@@ -0,0 +1,27 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+declare void @f0() #0
+
+define void @_start() {
+ call void @f0()
+ ret void
+}
+
+attributes #0 = { "wasm-import-module"="somewhere" "wasm-import-name"="something" }
+
+; CHECK: - Type: IMPORT
+; CHECK-NEXT: Imports:
+; CHECK-NEXT: - Module: somewhere
+; CHECK-NEXT: Field: something
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: SigIndex: 0
+
+; CHECK: - Type: CUSTOM
+; CHECK-NEXT: Name: name
+; CHECK-NEXT: FunctionNames:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Name: f0
diff --git a/test/wasm/init-fini.ll b/test/wasm/init-fini.ll
index 9a7f5357ef01..b17020b177c7 100644
--- a/test/wasm/init-fini.ll
+++ b/test/wasm/init-fini.ll
@@ -163,64 +163,64 @@ entry:
; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
; RELOC-NEXT: Function: 7
; RELOC-NEXT: - Index: 6
+; RELOC-NEXT: Kind: DATA
+; RELOC-NEXT: Name: __dso_handle
+; RELOC-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ]
+; RELOC-NEXT: - Index: 7
+; RELOC-NEXT: Kind: FUNCTION
+; RELOC-NEXT: Name: externDtor
+; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ]
+; RELOC-NEXT: Function: 0
+; RELOC-NEXT: - Index: 8
+; RELOC-NEXT: Kind: FUNCTION
+; RELOC-NEXT: Name: externCtor
+; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ]
+; RELOC-NEXT: Function: 1
+; RELOC-NEXT: - Index: 9
+; RELOC-NEXT: Kind: FUNCTION
+; RELOC-NEXT: Name: myctor
+; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT: Function: 14
+; RELOC-NEXT: - Index: 10
+; RELOC-NEXT: Kind: FUNCTION
+; RELOC-NEXT: Name: mydtor
+; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
+; RELOC-NEXT: Function: 15
+; 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: .Lcall_dtors.101
; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
; RELOC-NEXT: Function: 8
-; RELOC-NEXT: - Index: 7
+; RELOC-NEXT: - Index: 13
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: .Lregister_call_dtors.101
; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
; RELOC-NEXT: Function: 9
-; RELOC-NEXT: - Index: 8
-; RELOC-NEXT: Kind: DATA
-; RELOC-NEXT: Name: __dso_handle
-; RELOC-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ]
-; RELOC-NEXT: - Index: 9
+; RELOC-NEXT: - Index: 14
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: .Lcall_dtors.1001
; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
; RELOC-NEXT: Function: 10
-; RELOC-NEXT: - Index: 10
+; RELOC-NEXT: - Index: 15
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: .Lregister_call_dtors.1001
; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
; RELOC-NEXT: Function: 11
-; RELOC-NEXT: - Index: 11
+; RELOC-NEXT: - Index: 16
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: .Lcall_dtors.4000
; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
; RELOC-NEXT: Function: 12
-; RELOC-NEXT: - Index: 12
-; RELOC-NEXT: Kind: FUNCTION
-; RELOC-NEXT: Name: externDtor
-; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ]
-; RELOC-NEXT: Function: 0
-; RELOC-NEXT: - Index: 13
+; RELOC-NEXT: - Index: 17
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: .Lregister_call_dtors.4000
; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
; RELOC-NEXT: Function: 13
-; RELOC-NEXT: - Index: 14
-; RELOC-NEXT: Kind: FUNCTION
-; RELOC-NEXT: Name: externCtor
-; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ]
-; RELOC-NEXT: Function: 1
-; RELOC-NEXT: - Index: 15
-; RELOC-NEXT: Kind: FUNCTION
-; RELOC-NEXT: Name: myctor
-; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
-; RELOC-NEXT: Function: 14
-; RELOC-NEXT: - Index: 16
-; RELOC-NEXT: Kind: FUNCTION
-; RELOC-NEXT: Name: mydtor
-; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
-; RELOC-NEXT: Function: 15
-; RELOC-NEXT: - Index: 17
-; RELOC-NEXT: Kind: GLOBAL
-; RELOC-NEXT: Name: __stack_pointer
-; RELOC-NEXT: Flags: [ UNDEFINED ]
-; RELOC-NEXT: Global: 0
; RELOC-NEXT: - Index: 18
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: .Lcall_dtors.101
@@ -251,36 +251,36 @@ entry:
; RELOC-NEXT: Name: .Lregister_call_dtors.2002
; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
; RELOC-NEXT: Function: 21
-; RELOC-NEXT: InitFunctions:
+; RELOC-NEXT: InitFunctions:
; RELOC-NEXT: - Priority: 101
; RELOC-NEXT: Symbol: 0
; RELOC-NEXT: - Priority: 101
; RELOC-NEXT: Symbol: 1
; RELOC-NEXT: - Priority: 101
-; RELOC-NEXT: Symbol: 7
+; RELOC-NEXT: Symbol: 13
; RELOC-NEXT: - Priority: 101
-; RELOC-NEXT: Symbol: 15
+; RELOC-NEXT: Symbol: 9
; RELOC-NEXT: - Priority: 101
; RELOC-NEXT: Symbol: 19
; RELOC-NEXT: - Priority: 202
-; RELOC-NEXT: Symbol: 15
+; RELOC-NEXT: Symbol: 9
; RELOC-NEXT: - Priority: 202
; RELOC-NEXT: Symbol: 21
; RELOC-NEXT: - Priority: 1001
; RELOC-NEXT: Symbol: 0
; RELOC-NEXT: - Priority: 1001
-; RELOC-NEXT: Symbol: 10
-; RELOC-NEXT: - Priority: 2002
; RELOC-NEXT: Symbol: 15
; RELOC-NEXT: - Priority: 2002
+; RELOC-NEXT: Symbol: 9
+; RELOC-NEXT: - Priority: 2002
; RELOC-NEXT: Symbol: 23
; RELOC-NEXT: - Priority: 4000
-; RELOC-NEXT: Symbol: 14
+; RELOC-NEXT: Symbol: 8
; RELOC-NEXT: - Priority: 4000
-; RELOC-NEXT: Symbol: 13
+; RELOC-NEXT: Symbol: 17
; RELOC-NEXT: - Type: CUSTOM
; RELOC-NEXT: Name: name
-; RELOC-NEXT: FunctionNames:
+; RELOC-NEXT: FunctionNames:
; RELOC-NEXT: - Index: 0
; RELOC-NEXT: Name: externDtor
; RELOC-NEXT: - Index: 1
diff --git a/test/wasm/locals-duplicate.test b/test/wasm/locals-duplicate.test
index 2d6bd0df5314..74383bf429f6 100644
--- a/test/wasm/locals-duplicate.test
+++ b/test/wasm/locals-duplicate.test
@@ -270,40 +270,40 @@
; RELOC-NEXT: - Type: CODE
; RELOC-NEXT: Relocations:
; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 4
+; RELOC-NEXT: Index: 18
; RELOC-NEXT: Offset: 0x00000013
; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 6
+; RELOC-NEXT: Index: 3
; RELOC-NEXT: Offset: 0x0000001C
; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 8
+; RELOC-NEXT: Index: 19
; RELOC-NEXT: Offset: 0x00000025
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 0
+; RELOC-NEXT: Index: 16
; RELOC-NEXT: Offset: 0x0000002E
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 1
+; RELOC-NEXT: Index: 0
; RELOC-NEXT: Offset: 0x00000037
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 2
+; RELOC-NEXT: Index: 17
; RELOC-NEXT: Offset: 0x00000040
; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 16
+; RELOC-NEXT: Index: 10
; RELOC-NEXT: Offset: 0x00000058
; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 18
+; RELOC-NEXT: Index: 22
; RELOC-NEXT: Offset: 0x00000061
; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 20
+; RELOC-NEXT: Index: 23
; RELOC-NEXT: Offset: 0x0000006A
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 12
+; RELOC-NEXT: Index: 8
; RELOC-NEXT: Offset: 0x00000073
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 13
+; RELOC-NEXT: Index: 20
; RELOC-NEXT: Offset: 0x0000007C
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 14
+; RELOC-NEXT: Index: 21
; RELOC-NEXT: Offset: 0x00000085
; RELOC-NEXT: Functions:
; RELOC-NEXT: - Index: 0
@@ -386,133 +386,133 @@
; RELOC-NEXT: SymbolTable:
; RELOC-NEXT: - Index: 0
; RELOC-NEXT: Kind: FUNCTION
-; RELOC-NEXT: Name: colliding_func1
-; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
-; 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: Function: 2
-; RELOC-NEXT: - Index: 3
+; RELOC-NEXT: - Index: 1
; 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: Segment: 0
-; RELOC-NEXT: Size: 4
-; RELOC-NEXT: - Index: 5
+; RELOC-NEXT: - Index: 2
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: get_global2A
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 4
-; RELOC-NEXT: - Index: 6
+; RELOC-NEXT: - Index: 3
; 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: - Index: 4
; 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: Segment: 2
-; RELOC-NEXT: Size: 4
-; RELOC-NEXT: - Index: 9
+; RELOC-NEXT: - Index: 5
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: get_func1A
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 6
-; RELOC-NEXT: - Index: 10
+; RELOC-NEXT: - Index: 6
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: get_func2A
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 7
-; RELOC-NEXT: - Index: 11
+; RELOC-NEXT: - Index: 7
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: get_func3A
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 8
-; RELOC-NEXT: - Index: 12
+; RELOC-NEXT: - Index: 8
; 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: Function: 10
-; RELOC-NEXT: - Index: 14
-; RELOC-NEXT: Kind: FUNCTION
-; RELOC-NEXT: Name: colliding_func3
-; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
-; RELOC-NEXT: Function: 11
-; RELOC-NEXT: - Index: 15
+; RELOC-NEXT: - Index: 9
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: get_global1B
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 12
-; RELOC-NEXT: - Index: 16
+; RELOC-NEXT: - Index: 10
; 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: - Index: 11
; 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: Segment: 1
-; RELOC-NEXT: Offset: 4
-; RELOC-NEXT: Size: 4
-; RELOC-NEXT: - Index: 19
+; RELOC-NEXT: - Index: 12
; 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: - Index: 13
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: get_func1B
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 15
-; RELOC-NEXT: - Index: 22
+; RELOC-NEXT: - Index: 14
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: get_func2B
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 16
-; RELOC-NEXT: - Index: 23
+; RELOC-NEXT: - Index: 15
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: get_func3B
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 17
+; RELOC-NEXT: - Index: 16
+; RELOC-NEXT: Kind: FUNCTION
+; RELOC-NEXT: Name: colliding_func1
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: Function: 0
+; RELOC-NEXT: - Index: 17
+; RELOC-NEXT: Kind: FUNCTION
+; RELOC-NEXT: Name: colliding_func3
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: Function: 2
+; RELOC-NEXT: - Index: 18
+; RELOC-NEXT: Kind: DATA
+; RELOC-NEXT: Name: colliding_global1
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: Segment: 0
+; RELOC-NEXT: Size: 4
+; RELOC-NEXT: - Index: 19
+; RELOC-NEXT: Kind: DATA
+; RELOC-NEXT: Name: colliding_global3
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: Segment: 2
+; RELOC-NEXT: Size: 4
+; RELOC-NEXT: - Index: 20
+; RELOC-NEXT: Kind: FUNCTION
+; RELOC-NEXT: Name: colliding_func2
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: Function: 10
+; RELOC-NEXT: - Index: 21
+; RELOC-NEXT: Kind: FUNCTION
+; RELOC-NEXT: Name: colliding_func3
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: Function: 11
+; RELOC-NEXT: - Index: 22
+; RELOC-NEXT: Kind: DATA
+; RELOC-NEXT: Name: colliding_global2
+; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
+; RELOC-NEXT: Segment: 1
+; RELOC-NEXT: Offset: 4
+; RELOC-NEXT: Size: 4
+; RELOC-NEXT: - Index: 23
+; 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: SegmentInfo:
; RELOC-NEXT: - Index: 0
; RELOC-NEXT: Name: .bss.colliding_global1
diff --git a/test/wasm/lto/relocatable-undefined.ll b/test/wasm/lto/relocatable-undefined.ll
new file mode 100644
index 000000000000..b9780ee0309b
--- /dev/null
+++ b/test/wasm/lto/relocatable-undefined.ll
@@ -0,0 +1,36 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: wasm-ld -r -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+@missing_data = external global i32
+declare i32 @missing_func() local_unnamed_addr
+
+define i32 @foo() {
+entry:
+ %0 = call i32 @missing_func()
+ %1 = load i32, i32* @missing_data, align 4
+ ret i32 %1
+}
+
+
+; CHECK: - Type: CUSTOM
+; CHECK-NEXT: Name: linking
+; CHECK-NEXT: Version: 2
+; CHECK-NEXT: SymbolTable:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: missing_func
+; CHECK-NEXT: Flags: [ UNDEFINED ]
+; CHECK-NEXT: Function: 0
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Name: foo
+; CHECK-NEXT: Flags: [ ]
+; CHECK-NEXT: Function: 1
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Kind: DATA
+; CHECK-NEXT: Name: missing_data
+; CHECK-NEXT: Flags: [ UNDEFINED ]
diff --git a/test/wasm/weak-alias.ll b/test/wasm/weak-alias.ll
index 0c856e1eafa0..a925c10ccda4 100644
--- a/test/wasm/weak-alias.ll
+++ b/test/wasm/weak-alias.ll
@@ -187,13 +187,13 @@ entry:
; RELOC-NEXT: - Type: CODE
; RELOC-NEXT: Relocations:
; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT: Index: 4
+; RELOC-NEXT: Index: 1
; 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: 4
+; RELOC-NEXT: Index: 1
; RELOC-NEXT: Offset: 0x0000001C
; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
; RELOC-NEXT: Index: 6
@@ -202,10 +202,10 @@ entry:
; RELOC-NEXT: Index: 6
; RELOC-NEXT: Offset: 0x00000032
; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 4
+; RELOC-NEXT: Index: 1
; RELOC-NEXT: Offset: 0x0000003A
; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT: Index: 4
+; RELOC-NEXT: Index: 1
; RELOC-NEXT: Offset: 0x00000043
; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
; RELOC-NEXT: Index: 6
@@ -217,10 +217,10 @@ entry:
; RELOC-NEXT: Index: 6
; 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: 6
@@ -259,24 +259,24 @@ entry:
; RELOC-NEXT: Function: 0
; RELOC-NEXT: - Index: 1
; RELOC-NEXT: Kind: FUNCTION
+; RELOC-NEXT: Name: alias_fn
+; RELOC-NEXT: Flags: [ BINDING_WEAK ]
+; RELOC-NEXT: Function: 1
+; RELOC-NEXT: - Index: 2
+; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: direct_fn
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 1
-; RELOC-NEXT: - Index: 2
+; RELOC-NEXT: - Index: 3
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: call_direct
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 2
-; RELOC-NEXT: - Index: 3
+; RELOC-NEXT: - Index: 4
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: call_alias
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: Function: 3
-; RELOC-NEXT: - Index: 4
-; RELOC-NEXT: Kind: FUNCTION
-; RELOC-NEXT: Name: alias_fn
-; RELOC-NEXT: Flags: [ BINDING_WEAK ]
-; RELOC-NEXT: Function: 1
; RELOC-NEXT: - Index: 5
; RELOC-NEXT: Kind: FUNCTION
; RELOC-NEXT: Name: call_alias_ptr
diff --git a/wasm/Driver.cpp b/wasm/Driver.cpp
index fab4c0c4ed8b..ade15a19f66e 100644
--- a/wasm/Driver.cpp
+++ b/wasm/Driver.cpp
@@ -434,7 +434,9 @@ static Symbol *handleUndefined(StringRef Name) {
static UndefinedGlobal *
createUndefinedGlobal(StringRef Name, llvm::wasm::WasmGlobalType *Type) {
auto *Sym =
- cast<UndefinedGlobal>(Symtab->addUndefinedGlobal(Name, 0, nullptr, Type));
+ cast<UndefinedGlobal>(Symtab->addUndefinedGlobal(Name, Name,
+ DefaultModule, 0,
+ nullptr, Type));
Config->AllowUndefinedSymbols.insert(Sym->getName());
Sym->IsUsedInRegularObj = true;
return Sym;
diff --git a/wasm/InputChunks.cpp b/wasm/InputChunks.cpp
index 1145c670253c..f5884a1beea4 100644
--- a/wasm/InputChunks.cpp
+++ b/wasm/InputChunks.cpp
@@ -23,7 +23,7 @@ using namespace llvm::support::endian;
using namespace lld;
using namespace lld::wasm;
-static StringRef ReloctTypeToString(uint8_t RelocType) {
+static StringRef reloctTypeToString(uint8_t RelocType) {
switch (RelocType) {
#define WASM_RELOC(NAME, REL) \
case REL: \
@@ -77,7 +77,7 @@ void InputChunk::verifyRelocTargets() const {
warn("expected LEB at relocation site be 5-byte padded");
uint32_t ExpectedValue = File->calcExpectedValue(Rel);
if (ExpectedValue != ExistingValue)
- warn("unexpected existing value for " + ReloctTypeToString(Rel.Type) +
+ warn("unexpected existing value for " + reloctTypeToString(Rel.Type) +
": existing=" + Twine(ExistingValue) +
" expected=" + Twine(ExpectedValue));
}
@@ -103,7 +103,7 @@ void InputChunk::writeTo(uint8_t *Buf) const {
for (const WasmRelocation &Rel : Relocations) {
uint8_t *Loc = Buf + Rel.Offset + Off;
uint32_t Value = File->calcNewValue(Rel);
- LLVM_DEBUG(dbgs() << "apply reloc: type=" << ReloctTypeToString(Rel.Type)
+ LLVM_DEBUG(dbgs() << "apply reloc: type=" << reloctTypeToString(Rel.Type)
<< " addend=" << Rel.Addend << " index=" << Rel.Index
<< " value=" << Value << " offset=" << Rel.Offset
<< "\n");
diff --git a/wasm/InputFiles.cpp b/wasm/InputFiles.cpp
index e5da23db3773..1e5427216354 100644
--- a/wasm/InputFiles.cpp
+++ b/wasm/InputFiles.cpp
@@ -377,11 +377,15 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) {
switch (Sym.Info.Kind) {
case WASM_SYMBOL_TYPE_FUNCTION:
- return Symtab->addUndefinedFunction(Name, Flags, this, Sym.Signature);
+ return Symtab->addUndefinedFunction(Name, Sym.Info.ImportName,
+ Sym.Info.ImportModule, Flags, this,
+ Sym.Signature);
case WASM_SYMBOL_TYPE_DATA:
return Symtab->addUndefinedData(Name, Flags, this);
case WASM_SYMBOL_TYPE_GLOBAL:
- return Symtab->addUndefinedGlobal(Name, Flags, this, Sym.GlobalType);
+ return Symtab->addUndefinedGlobal(Name, Sym.Info.ImportName,
+ Sym.Info.ImportModule, Flags, this,
+ Sym.GlobalType);
case WASM_SYMBOL_TYPE_SECTION:
llvm_unreachable("section symbols cannot be undefined");
}
@@ -445,7 +449,8 @@ static Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &ObjSym,
if (ObjSym.isUndefined()) {
if (ObjSym.isExecutable())
- return Symtab->addUndefinedFunction(Name, Flags, &F, nullptr);
+ return Symtab->addUndefinedFunction(Name, Name, DefaultModule, Flags, &F,
+ nullptr);
return Symtab->addUndefinedData(Name, Flags, &F);
}
diff --git a/wasm/LTO.cpp b/wasm/LTO.cpp
index 96a947e29d41..e994691cceb2 100644
--- a/wasm/LTO.cpp
+++ b/wasm/LTO.cpp
@@ -79,8 +79,9 @@ BitcodeCompiler::~BitcodeCompiler() = default;
static void undefine(Symbol *S) {
if (auto F = dyn_cast<DefinedFunction>(S))
- replaceSymbol<UndefinedFunction>(F, F->getName(), 0, F->getFile(),
- F->Signature);
+ replaceSymbol<UndefinedFunction>(F, F->getName(), F->getName(),
+ DefaultModule, 0,
+ F->getFile(), F->Signature);
else if (isa<DefinedData>(S))
replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile());
else
diff --git a/wasm/LTO.h b/wasm/LTO.h
index cf726de5643a..d771301f224d 100644
--- a/wasm/LTO.h
+++ b/wasm/LTO.h
@@ -23,6 +23,7 @@
#include "lld/Common/LLVM.h"
#include "llvm/ADT/SmallString.h"
+#include "Writer.h"
#include <memory>
#include <vector>
diff --git a/wasm/MarkLive.cpp b/wasm/MarkLive.cpp
index 3bbd1148f6ad..723ac4e3c6ba 100644
--- a/wasm/MarkLive.cpp
+++ b/wasm/MarkLive.cpp
@@ -85,7 +85,7 @@ void lld::wasm::markLive() {
// equal to null pointer, only reachable via direct call).
if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB ||
Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32) {
- FunctionSymbol *FuncSym = cast<FunctionSymbol>(Sym);
+ auto *FuncSym = cast<FunctionSymbol>(Sym);
if (FuncSym->hasTableIndex() && FuncSym->getTableIndex() == 0)
continue;
}
diff --git a/wasm/SymbolTable.cpp b/wasm/SymbolTable.cpp
index c7983196db36..65441d293b50 100644
--- a/wasm/SymbolTable.cpp
+++ b/wasm/SymbolTable.cpp
@@ -314,8 +314,9 @@ Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags,
return S;
}
-Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
- InputFile *File,
+Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef ImportName,
+ StringRef ImportModule,
+ uint32_t Flags, InputFile *File,
const WasmSignature *Sig) {
LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
" [" << (Sig ? toString(*Sig) : "none") << "]\n");
@@ -325,7 +326,8 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
std::tie(S, WasInserted) = insert(Name, File);
if (WasInserted)
- replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig);
+ replaceSymbol<UndefinedFunction>(S, Name, ImportName, ImportModule, Flags,
+ File, Sig);
else if (auto *Lazy = dyn_cast<LazySymbol>(S))
Lazy->fetch();
else
@@ -351,7 +353,8 @@ Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags,
return S;
}
-Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,
+Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, StringRef ImportName,
+ StringRef ImportModule, uint32_t Flags,
InputFile *File,
const WasmGlobalType *Type) {
LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n");
@@ -361,7 +364,8 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,
std::tie(S, WasInserted) = insert(Name, File);
if (WasInserted)
- replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type);
+ replaceSymbol<UndefinedGlobal>(S, Name, ImportName, ImportModule, Flags,
+ File, Type);
else if (auto *Lazy = dyn_cast<LazySymbol>(S))
Lazy->fetch();
else if (S->isDefined())
diff --git a/wasm/SymbolTable.h b/wasm/SymbolTable.h
index 5e38e30692ab..64678aee5005 100644
--- a/wasm/SymbolTable.h
+++ b/wasm/SymbolTable.h
@@ -59,11 +59,13 @@ public:
Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
InputEvent *E);
- Symbol *addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File,
- const WasmSignature *Signature);
+ Symbol *addUndefinedFunction(StringRef Name, StringRef ImportName,
+ StringRef ImportModule, uint32_t Flags,
+ InputFile *File, const WasmSignature *Signature);
Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File);
- Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
- const WasmGlobalType *Type);
+ Symbol *addUndefinedGlobal(StringRef Name, StringRef ImportName,
+ StringRef ImportModule, uint32_t Flags,
+ InputFile *File, const WasmGlobalType *Type);
void addLazy(ArchiveFile *F, const llvm::object::Archive::Symbol *Sym);
diff --git a/wasm/Symbols.h b/wasm/Symbols.h
index 11ee66550cdc..a065338ac1e4 100644
--- a/wasm/Symbols.h
+++ b/wasm/Symbols.h
@@ -149,13 +149,19 @@ public:
class UndefinedFunction : public FunctionSymbol {
public:
- UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File = nullptr,
+ UndefinedFunction(StringRef Name, StringRef ImportName,
+ StringRef ImportModule, uint32_t Flags,
+ InputFile *File = nullptr,
const WasmSignature *Type = nullptr)
- : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type) {}
+ : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type),
+ ImportName(ImportName), ImportModule(ImportModule) {}
static bool classof(const Symbol *S) {
return S->kind() == UndefinedFunctionKind;
}
+
+ StringRef ImportName;
+ StringRef ImportModule;
};
class SectionSymbol : public Symbol {
@@ -261,13 +267,18 @@ public:
class UndefinedGlobal : public GlobalSymbol {
public:
- UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File = nullptr,
+ UndefinedGlobal(StringRef Name, StringRef ImportName, StringRef ImportModule,
+ uint32_t Flags, InputFile *File = nullptr,
const WasmGlobalType *Type = nullptr)
- : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type) {}
+ : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type),
+ ImportName(ImportName), ImportModule(ImportModule) {}
static bool classof(const Symbol *S) {
return S->kind() == UndefinedGlobalKind;
}
+
+ StringRef ImportName;
+ StringRef ImportModule;
};
// Wasm events are features that suspend the current execution and transfer the
diff --git a/wasm/Writer.cpp b/wasm/Writer.cpp
index 819d4298fef2..902ca61ca19b 100644
--- a/wasm/Writer.cpp
+++ b/wasm/Writer.cpp
@@ -39,8 +39,9 @@ using namespace llvm::wasm;
using namespace lld;
using namespace lld::wasm;
-static constexpr int kStackAlignment = 16;
-static constexpr const char *kFunctionTableName = "__indirect_function_table";
+static constexpr int StackAlignment = 16;
+static constexpr const char *FunctionTableName = "__indirect_function_table";
+const char *lld::wasm::DefaultModule = "env";
namespace {
@@ -155,7 +156,7 @@ void Writer::createImportSection() {
if (Config->ImportMemory) {
WasmImport Import;
- Import.Module = "env";
+ Import.Module = DefaultModule;
Import.Field = "memory";
Import.Kind = WASM_EXTERNAL_MEMORY;
Import.Memory.Flags = 0;
@@ -172,8 +173,8 @@ void Writer::createImportSection() {
if (Config->ImportTable) {
uint32_t TableSize = TableBase + IndirectFunctions.size();
WasmImport Import;
- Import.Module = "env";
- Import.Field = kFunctionTableName;
+ Import.Module = DefaultModule;
+ Import.Field = FunctionTableName;
Import.Kind = WASM_EXTERNAL_TABLE;
Import.Table.ElemType = WASM_TYPE_FUNCREF;
Import.Table.Limits = {0, TableSize, 0};
@@ -182,8 +183,17 @@ void Writer::createImportSection() {
for (const Symbol *Sym : ImportedSymbols) {
WasmImport Import;
- Import.Module = "env";
- Import.Field = Sym->getName();
+ if (auto *F = dyn_cast<UndefinedFunction>(Sym)) {
+ Import.Field = F->ImportName;
+ Import.Module = F->ImportModule;
+ } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) {
+ Import.Field = G->ImportName;
+ Import.Module = G->ImportModule;
+ } else {
+ Import.Field = Sym->getName();
+ Import.Module = DefaultModule;
+ }
+
if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
Import.Kind = WASM_EXTERNAL_FUNCTION;
Import.SigIndex = lookupType(*FunctionSym->Signature);
@@ -441,6 +451,13 @@ static uint32_t getWasmFlags(const Symbol *Sym) {
Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
if (Sym->isUndefined())
Flags |= WASM_SYMBOL_UNDEFINED;
+ if (auto *F = dyn_cast<UndefinedFunction>(Sym)) {
+ if (F->getName() != F->ImportName)
+ Flags |= WASM_SYMBOL_EXPLICIT_NAME;
+ } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) {
+ if (G->getName() != G->ImportName)
+ Flags |= WASM_SYMBOL_EXPLICIT_NAME;
+ }
return Flags;
}
@@ -506,15 +523,18 @@ void Writer::createLinkingSection() {
if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
writeUleb128(Sub.OS, F->getFunctionIndex(), "index");
- if (Sym->isDefined())
+ if (Sym->isDefined() ||
+ (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
writeStr(Sub.OS, Sym->getName(), "sym name");
} else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) {
writeUleb128(Sub.OS, G->getGlobalIndex(), "index");
- if (Sym->isDefined())
+ if (Sym->isDefined() ||
+ (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
writeStr(Sub.OS, Sym->getName(), "sym name");
} else if (auto *E = dyn_cast<EventSymbol>(Sym)) {
writeUleb128(Sub.OS, E->getEventIndex(), "index");
- if (Sym->isDefined())
+ if (Sym->isDefined() ||
+ (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
writeStr(Sub.OS, Sym->getName(), "sym name");
} else if (isa<DataSymbol>(Sym)) {
writeStr(Sub.OS, Sym->getName(), "sym name");
@@ -663,9 +683,9 @@ void Writer::layoutMemory() {
auto PlaceStack = [&]() {
if (Config->Relocatable || Config->Shared)
return;
- MemoryPtr = alignTo(MemoryPtr, kStackAlignment);
- if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))
- error("stack size must be " + Twine(kStackAlignment) + "-byte aligned");
+ MemoryPtr = alignTo(MemoryPtr, StackAlignment);
+ if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment))
+ error("stack size must be " + Twine(StackAlignment) + "-byte aligned");
log("mem: stack size = " + Twine(Config->ZStackSize));
log("mem: stack base = " + Twine(MemoryPtr));
MemoryPtr += Config->ZStackSize;
@@ -814,7 +834,7 @@ void Writer::calculateExports() {
Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0});
if (!Config->Relocatable && Config->ExportTable)
- Exports.push_back(WasmExport{kFunctionTableName, WASM_EXTERNAL_TABLE, 0});
+ Exports.push_back(WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0});
unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size();
@@ -858,40 +878,42 @@ void Writer::assignSymtab() {
StringMap<uint32_t> SectionSymbolIndices;
unsigned SymbolIndex = SymtabEntries.size();
- for (ObjFile *File : Symtab->ObjectFiles) {
- LLVM_DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n");
- for (Symbol *Sym : File->getSymbols()) {
- if (Sym->getFile() != File)
- continue;
-
- if (auto *S = dyn_cast<SectionSymbol>(Sym)) {
- StringRef Name = S->getName();
- if (CustomSectionMapping.count(Name) == 0)
- continue;
-
- auto SSI = SectionSymbolIndices.find(Name);
- if (SSI != SectionSymbolIndices.end()) {
- Sym->setOutputSymbolIndex(SSI->second);
- continue;
- }
- SectionSymbolIndices[Name] = SymbolIndex;
- CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym);
+ auto AddSymbol = [&](Symbol *Sym) {
+ if (auto *S = dyn_cast<SectionSymbol>(Sym)) {
+ StringRef Name = S->getName();
+ if (CustomSectionMapping.count(Name) == 0)
+ return;
- Sym->markLive();
+ auto SSI = SectionSymbolIndices.find(Name);
+ if (SSI != SectionSymbolIndices.end()) {
+ Sym->setOutputSymbolIndex(SSI->second);
+ return;
}
- // (Since this is relocatable output, GC is not performed so symbols must
- // be live.)
- assert(Sym->isLive());
- Sym->setOutputSymbolIndex(SymbolIndex++);
- SymtabEntries.emplace_back(Sym);
+ SectionSymbolIndices[Name] = SymbolIndex;
+ CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym);
+
+ Sym->markLive();
}
- }
- // 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.
+ // (Since this is relocatable output, GC is not performed so symbols must
+ // be live.)
+ assert(Sym->isLive());
+ Sym->setOutputSymbolIndex(SymbolIndex++);
+ SymtabEntries.emplace_back(Sym);
+ };
+
+ for (Symbol *Sym : Symtab->getSymbols())
+ if (!Sym->isLazy())
+ AddSymbol(Sym);
+
+ for (ObjFile *File : Symtab->ObjectFiles) {
+ LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n");
+ for (Symbol *Sym : File->getSymbols())
+ if (Sym->isLocal())
+ AddSymbol(Sym);
+ }
}
uint32_t Writer::lookupType(const WasmSignature &Sig) {
diff --git a/wasm/Writer.h b/wasm/Writer.h
index a931ba9c29a8..e62f47064228 100644
--- a/wasm/Writer.h
+++ b/wasm/Writer.h
@@ -15,6 +15,8 @@ namespace wasm {
void writeResult();
+extern const char *DefaultModule;
+
} // namespace wasm
} // namespace lld