aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYi Kong <yikong@google.com>2019-02-27 14:18:31 -0800
committerYi Kong <yikong@google.com>2019-02-27 14:18:31 -0800
commit35c021c49f44cd4e06875c4b1398a2b3464132bb (patch)
tree972f829a5ed4f0e4a14f0a713b49a8f0db93a26f
parent958317e226bf38ef5e647d0b056e8e95eb472c70 (diff)
parent14aa57da0f92683f0b8bdac0acda485a6f73edc7 (diff)
downloadlld-35c021c49f44cd4e06875c4b1398a2b3464132bb.tar.gz
Merge 14aa57da0 for LLVM update to 353983
Change-Id: Iee1792355bab030d81eb4cb645257dbac2537641
-rw-r--r--COFF/Chunks.cpp33
-rw-r--r--COFF/Chunks.h25
-rw-r--r--COFF/Config.h8
-rw-r--r--COFF/DLL.cpp23
-rw-r--r--COFF/DLL.h7
-rw-r--r--COFF/Driver.cpp51
-rw-r--r--COFF/Driver.h7
-rw-r--r--COFF/DriverUtils.cpp7
-rw-r--r--COFF/ICF.cpp27
-rw-r--r--COFF/ICF.h7
-rw-r--r--COFF/InputFiles.cpp213
-rw-r--r--COFF/InputFiles.h11
-rw-r--r--COFF/LTO.cpp15
-rw-r--r--COFF/LTO.h7
-rw-r--r--COFF/MapFile.cpp7
-rw-r--r--COFF/MapFile.h7
-rw-r--r--COFF/MarkLive.cpp7
-rw-r--r--COFF/MarkLive.h7
-rw-r--r--COFF/MinGW.cpp7
-rw-r--r--COFF/MinGW.h7
-rw-r--r--COFF/Options.td26
-rw-r--r--COFF/PDB.cpp80
-rw-r--r--COFF/PDB.h7
-rw-r--r--COFF/SymbolTable.cpp16
-rw-r--r--COFF/SymbolTable.h10
-rw-r--r--COFF/Symbols.cpp7
-rw-r--r--COFF/Symbols.h9
-rw-r--r--COFF/Writer.cpp212
-rw-r--r--COFF/Writer.h7
-rw-r--r--Common/Args.cpp16
-rw-r--r--Common/ErrorHandler.cpp7
-rw-r--r--Common/Memory.cpp7
-rw-r--r--Common/Reproduce.cpp7
-rw-r--r--Common/Strings.cpp7
-rw-r--r--Common/TargetOptionsCommandFlags.cpp18
-rw-r--r--Common/Threads.cpp7
-rw-r--r--Common/Timer.cpp7
-rw-r--r--Common/Version.cpp7
-rw-r--r--ELF/AArch64ErrataFix.cpp7
-rw-r--r--ELF/AArch64ErrataFix.h7
-rw-r--r--ELF/Arch/AArch64.cpp7
-rw-r--r--ELF/Arch/AMDGPU.cpp7
-rw-r--r--ELF/Arch/ARM.cpp9
-rw-r--r--ELF/Arch/AVR.cpp7
-rw-r--r--ELF/Arch/Hexagon.cpp7
-rw-r--r--ELF/Arch/MSP430.cpp93
-rw-r--r--ELF/Arch/Mips.cpp7
-rw-r--r--ELF/Arch/MipsArchTree.cpp7
-rw-r--r--ELF/Arch/PPC.cpp7
-rw-r--r--ELF/Arch/PPC64.cpp67
-rw-r--r--ELF/Arch/RISCV.cpp7
-rw-r--r--ELF/Arch/SPARCV9.cpp7
-rw-r--r--ELF/Arch/X86.cpp35
-rw-r--r--ELF/Arch/X86_64.cpp68
-rw-r--r--ELF/Bits.h35
-rw-r--r--ELF/CMakeLists.txt1
-rw-r--r--ELF/CallGraphSort.cpp7
-rw-r--r--ELF/CallGraphSort.h7
-rw-r--r--ELF/Config.h24
-rw-r--r--ELF/DWARF.cpp7
-rw-r--r--ELF/DWARF.h7
-rw-r--r--ELF/Driver.cpp21
-rw-r--r--ELF/Driver.h7
-rw-r--r--ELF/DriverUtils.cpp7
-rw-r--r--ELF/EhFrame.cpp7
-rw-r--r--ELF/EhFrame.h7
-rw-r--r--ELF/Filesystem.cpp7
-rw-r--r--ELF/Filesystem.h7
-rw-r--r--ELF/ICF.cpp32
-rw-r--r--ELF/ICF.h7
-rw-r--r--ELF/InputFiles.cpp67
-rw-r--r--ELF/InputFiles.h25
-rw-r--r--ELF/InputSection.cpp28
-rw-r--r--ELF/InputSection.h7
-rw-r--r--ELF/LTO.cpp17
-rw-r--r--ELF/LTO.h7
-rw-r--r--ELF/LinkerScript.cpp7
-rw-r--r--ELF/LinkerScript.h7
-rw-r--r--ELF/MapFile.cpp7
-rw-r--r--ELF/MapFile.h7
-rw-r--r--ELF/MarkLive.cpp20
-rw-r--r--ELF/MarkLive.h7
-rw-r--r--ELF/Options.td9
-rw-r--r--ELF/OutputSections.cpp7
-rw-r--r--ELF/OutputSections.h7
-rw-r--r--ELF/Relocations.cpp283
-rw-r--r--ELF/Relocations.h17
-rw-r--r--ELF/ScriptLexer.cpp7
-rw-r--r--ELF/ScriptLexer.h7
-rw-r--r--ELF/ScriptParser.cpp75
-rw-r--r--ELF/ScriptParser.h7
-rw-r--r--ELF/SymbolTable.cpp48
-rw-r--r--ELF/SymbolTable.h13
-rw-r--r--ELF/Symbols.cpp18
-rw-r--r--ELF/Symbols.h20
-rw-r--r--ELF/SyntheticSections.cpp44
-rw-r--r--ELF/SyntheticSections.h15
-rw-r--r--ELF/Target.cpp9
-rw-r--r--ELF/Target.h14
-rw-r--r--ELF/Thunks.cpp21
-rw-r--r--ELF/Thunks.h7
-rw-r--r--ELF/Writer.cpp90
-rw-r--r--ELF/Writer.h7
-rw-r--r--LICENSE.TXT258
-rw-r--r--MinGW/Driver.cpp34
-rw-r--r--MinGW/Options.td52
-rw-r--r--docs/NewLLD.rst22
-rw-r--r--docs/Readers.rst2
-rw-r--r--docs/ReleaseNotes.rst42
-rw-r--r--docs/WebAssembly.rst47
-rw-r--r--docs/conf.py4
-rw-r--r--docs/getting_started.rst35
-rw-r--r--docs/index.rst23
-rw-r--r--docs/ld.lld.113
-rw-r--r--docs/missingkeyfunction.rst84
-rw-r--r--docs/open_projects.rst2
-rw-r--r--docs/windows_support.rst4
-rw-r--r--include/lld/Common/Args.h12
-rw-r--r--include/lld/Common/Driver.h7
-rw-r--r--include/lld/Common/ErrorHandler.h7
-rw-r--r--include/lld/Common/LLVM.h7
-rw-r--r--include/lld/Common/Memory.h7
-rw-r--r--include/lld/Common/Reproduce.h7
-rw-r--r--include/lld/Common/Strings.h7
-rw-r--r--include/lld/Common/TargetOptionsCommandFlags.h15
-rw-r--r--include/lld/Common/Threads.h7
-rw-r--r--include/lld/Common/Timer.h7
-rw-r--r--include/lld/Common/Version.h7
-rw-r--r--include/lld/Core/AbsoluteAtom.h7
-rw-r--r--include/lld/Core/ArchiveLibraryFile.h7
-rw-r--r--include/lld/Core/Atom.h7
-rw-r--r--include/lld/Core/DefinedAtom.h7
-rw-r--r--include/lld/Core/Error.h7
-rw-r--r--include/lld/Core/File.h7
-rw-r--r--include/lld/Core/Instrumentation.h7
-rw-r--r--include/lld/Core/LinkingContext.h7
-rw-r--r--include/lld/Core/Node.h7
-rw-r--r--include/lld/Core/Pass.h7
-rw-r--r--include/lld/Core/PassManager.h7
-rw-r--r--include/lld/Core/Reader.h7
-rw-r--r--include/lld/Core/Reference.h7
-rw-r--r--include/lld/Core/Resolver.h7
-rw-r--r--include/lld/Core/SharedLibraryAtom.h7
-rw-r--r--include/lld/Core/SharedLibraryFile.h7
-rw-r--r--include/lld/Core/Simple.h7
-rw-r--r--include/lld/Core/SymbolTable.h7
-rw-r--r--include/lld/Core/TODO.txt14
-rw-r--r--include/lld/Core/UndefinedAtom.h7
-rw-r--r--include/lld/Core/Writer.h7
-rw-r--r--include/lld/ReaderWriter/MachOLinkingContext.h7
-rw-r--r--include/lld/ReaderWriter/YamlContext.h7
-rw-r--r--lib/Core/DefinedAtom.cpp7
-rw-r--r--lib/Core/Error.cpp7
-rw-r--r--lib/Core/File.cpp7
-rw-r--r--lib/Core/LinkingContext.cpp7
-rw-r--r--lib/Core/Reader.cpp7
-rw-r--r--lib/Core/Resolver.cpp7
-rw-r--r--lib/Core/SymbolTable.cpp7
-rw-r--r--lib/Core/Writer.cpp7
-rw-r--r--lib/Driver/DarwinLdDriver.cpp7
-rw-r--r--lib/ReaderWriter/FileArchive.cpp7
-rw-r--r--lib/ReaderWriter/MachO/ArchHandler.cpp7
-rw-r--r--lib/ReaderWriter/MachO/ArchHandler.h7
-rw-r--r--lib/ReaderWriter/MachO/ArchHandler_arm.cpp7
-rw-r--r--lib/ReaderWriter/MachO/ArchHandler_arm64.cpp7
-rw-r--r--lib/ReaderWriter/MachO/ArchHandler_x86.cpp7
-rw-r--r--lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp7
-rw-r--r--lib/ReaderWriter/MachO/Atoms.h7
-rw-r--r--lib/ReaderWriter/MachO/CompactUnwindPass.cpp7
-rw-r--r--lib/ReaderWriter/MachO/DebugInfo.h7
-rw-r--r--lib/ReaderWriter/MachO/ExecutableAtoms.h7
-rw-r--r--lib/ReaderWriter/MachO/File.h7
-rw-r--r--lib/ReaderWriter/MachO/FlatNamespaceFile.h7
-rw-r--r--lib/ReaderWriter/MachO/GOTPass.cpp7
-rw-r--r--lib/ReaderWriter/MachO/LayoutPass.cpp7
-rw-r--r--lib/ReaderWriter/MachO/LayoutPass.h7
-rw-r--r--lib/ReaderWriter/MachO/MachOLinkingContext.cpp7
-rw-r--r--lib/ReaderWriter/MachO/MachONormalizedFile.h7
-rw-r--r--lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp7
-rw-r--r--lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h7
-rw-r--r--lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp7
-rw-r--r--lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp7
-rw-r--r--lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp7
-rw-r--r--lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp7
-rw-r--r--lib/ReaderWriter/MachO/MachOPasses.h7
-rw-r--r--lib/ReaderWriter/MachO/ObjCPass.cpp7
-rw-r--r--lib/ReaderWriter/MachO/SectCreateFile.h7
-rw-r--r--lib/ReaderWriter/MachO/ShimPass.cpp7
-rw-r--r--lib/ReaderWriter/MachO/StubsPass.cpp7
-rw-r--r--lib/ReaderWriter/MachO/TLVPass.cpp7
-rw-r--r--lib/ReaderWriter/MachO/WriterMachO.cpp7
-rw-r--r--lib/ReaderWriter/YAML/ReaderWriterYAML.cpp7
-rw-r--r--test/CMakeLists.txt4
-rw-r--r--test/COFF/arm-thumb-thunks-pdb.s18
-rw-r--r--test/COFF/arm64-branch-range.test16
-rw-r--r--test/COFF/arm64-relocs-imports.test19
-rw-r--r--test/COFF/arm64-thunks.s27
-rw-r--r--test/COFF/armnt-rel32.yaml47
-rw-r--r--test/COFF/associative-comdat-empty.test56
-rw-r--r--test/COFF/associative-comdat-order.test97
-rw-r--r--test/COFF/color-diagnostics.test18
-rw-r--r--test/COFF/comdat-selection-associative-largest.s45
-rw-r--r--test/COFF/comdat-selection.s98
-rw-r--r--test/COFF/crt-dyn-initializer-order.test200
-rw-r--r--test/COFF/ignore-many.test16
-rw-r--r--test/COFF/imports.test13
-rw-r--r--test/COFF/line-error.yaml160
-rw-r--r--test/COFF/lto-lazy-reference.ll4
-rw-r--r--test/COFF/lto-new-symbol.ll4
-rw-r--r--test/COFF/pdb-relative-source-lines.test60
-rw-r--r--test/COFF/pdb-tpi-hash-size.test10
-rw-r--r--test/COFF/pdb-type-server-missing.yaml19
-rw-r--r--test/COFF/pdb.test34
-rw-r--r--test/COFF/precomp-link.test84
-rw-r--r--test/COFF/s_udt.s884
-rw-r--r--test/ELF/Inputs/gdb-index-invalid-ranges.obj.s2
-rw-r--r--test/ELF/Inputs/gnu-ifunc-canon-ro-abs.s2
-rw-r--r--test/ELF/Inputs/gnu-ifunc-canon-ro-pcrel.s2
-rw-r--r--test/ELF/Inputs/gnu-ifunc-canon-rw-addend.s2
-rw-r--r--test/ELF/Inputs/i386-static-tls-model1.s9
-rw-r--r--test/ELF/Inputs/i386-static-tls-model2.s9
-rw-r--r--test/ELF/Inputs/i386-static-tls-model3.s9
-rw-r--r--test/ELF/Inputs/i386-static-tls-model4.s9
-rw-r--r--test/ELF/Inputs/ppc64-sort-small-cm-relocs-input2.s23
-rw-r--r--test/ELF/Inputs/ppc64-sort-small-cm-relocs-input3.s41
-rw-r--r--test/ELF/Inputs/ppc64-sort-small-cm-relocs-input4.s18
-rw-r--r--test/ELF/Inputs/print-icf.s18
-rw-r--r--test/ELF/Inputs/wrap-with-archive.s5
-rw-r--r--test/ELF/Inputs/x86-64-pcrel.s8
-rw-r--r--test/ELF/aarch64-cortex-a53-843419-tlsrelax.s4
-rw-r--r--test/ELF/aarch64-gnu-ifunc-address-pie.s47
-rw-r--r--test/ELF/aarch64-gnu-ifunc-address.s37
-rw-r--r--test/ELF/aarch64-gnu-ifunc2.s9
-rw-r--r--test/ELF/aarch64-gnu-ifunc3.s7
-rw-r--r--test/ELF/aarch64-tls-gdle.s6
-rw-r--r--test/ELF/aarch64-tls-iele.s6
-rw-r--r--test/ELF/aarch64-tls-le.s10
-rw-r--r--test/ELF/aarch64-tlsld-ldst.s50
-rw-r--r--test/ELF/allow-shlib-undefined.s36
-rw-r--r--test/ELF/archive-thin-missing-member.s24
-rw-r--r--test/ELF/arm-extreme-range-pi-thunk.s82
-rw-r--r--test/ELF/arm-force-pi-thunk.s87
-rw-r--r--test/ELF/arm-gnu-ifunc.s5
-rw-r--r--test/ELF/arm-thunk-multipass-plt.s94
-rw-r--r--test/ELF/arm-tls-le32.s12
-rw-r--r--test/ELF/arm-tls-norelax-ie-le.s4
-rw-r--r--test/ELF/as-needed-in-regular.s24
-rw-r--r--test/ELF/as-needed-not-in-regular.s32
-rw-r--r--test/ELF/as-needed-weak.s7
-rw-r--r--test/ELF/bss-start-common.s2
-rw-r--r--test/ELF/bsymbolic-undef.s4
-rw-r--r--test/ELF/comdat-linkonce.s7
-rw-r--r--test/ELF/common-gc2.s4
-rw-r--r--test/ELF/dont-export-hidden.s2
-rw-r--r--test/ELF/driver.test1
-rw-r--r--test/ELF/dynamic-list-preempt.s8
-rw-r--r--test/ELF/dynamic-list-wildcard.s6
-rw-r--r--test/ELF/dynamic-list.s22
-rw-r--r--test/ELF/dynsym-no-rosegment.s4
-rw-r--r--test/ELF/dynsym-pie.s2
-rw-r--r--test/ELF/edata-etext.s3
-rw-r--r--test/ELF/empty-ver.s2
-rw-r--r--test/ELF/empty-ver2.s4
-rw-r--r--test/ELF/emulation-aarch64.s23
-rw-r--r--test/ELF/emulation-mips.s3
-rw-r--r--test/ELF/emulation-ppc.s69
-rw-r--r--test/ELF/emulation-x86.s10
-rw-r--r--test/ELF/gc-sections-linker-defined-symbol.s2
-rw-r--r--test/ELF/gdb-index-dwarf5-low-high.s49
-rw-r--r--test/ELF/gdb-index-invalid-ranges.s42
-rw-r--r--test/ELF/gnu-hash-table-copy.s8
-rw-r--r--test/ELF/gnu-hash-table-rwsegment.s4
-rw-r--r--test/ELF/gnu-hash-table.s52
-rw-r--r--test/ELF/gnu-ifunc-canon.s92
-rw-r--r--test/ELF/gnu-ifunc-dyntags.s2
-rw-r--r--test/ELF/gnu-ifunc-empty.s16
-rw-r--r--test/ELF/gnu-ifunc-i386.s35
-rw-r--r--test/ELF/gnu-unique.s4
-rw-r--r--test/ELF/got32-i386.s2
-rw-r--r--test/ELF/got32x-i386.s2
-rw-r--r--test/ELF/i386-static-tls-model.s20
-rw-r--r--test/ELF/i386-tls-ie-shared.s52
-rw-r--r--test/ELF/icf-symbol-type.s2
-rw-r--r--test/ELF/invalid/invalid-soname.test5
-rw-r--r--test/ELF/linkerscript/addr.test2
-rw-r--r--test/ELF/linkerscript/align-empty.test2
-rw-r--r--test/ELF/linkerscript/align1.test4
-rw-r--r--test/ELF/linkerscript/align2.test2
-rw-r--r--test/ELF/linkerscript/align3.test2
-rw-r--r--test/ELF/linkerscript/align4.test1
-rw-r--r--test/ELF/linkerscript/at2.test2
-rw-r--r--test/ELF/linkerscript/insert-after.test2
-rw-r--r--test/ELF/linkerscript/insert-before.test2
-rw-r--r--test/ELF/linkerscript/linkerscript.s2
-rw-r--r--test/ELF/linkerscript/locationcountererr2.s2
-rw-r--r--test/ELF/linkerscript/memory3.s2
-rw-r--r--test/ELF/linkerscript/multi-sections-constraint.s4
-rw-r--r--test/ELF/linkerscript/non-absolute2.test2
-rw-r--r--test/ELF/linkerscript/numbers.s4
-rw-r--r--test/ELF/linkerscript/out-of-order.s2
-rw-r--r--test/ELF/linkerscript/provide-shared2.s2
-rw-r--r--test/ELF/linkerscript/repsection-va.s2
-rw-r--r--test/ELF/linkerscript/sections-gc2.s2
-rw-r--r--test/ELF/linkerscript/segment-none.s2
-rw-r--r--test/ELF/linkerscript/sizeof.s1
-rw-r--r--test/ELF/linkerscript/sizeofheaders.s1
-rw-r--r--test/ELF/linkerscript/symbol-assignexpr.s1
-rw-r--r--test/ELF/linkerscript/symbol-location.s15
-rw-r--r--test/ELF/linkerscript/symbol-memoryexpr.s1
-rw-r--r--test/ELF/linkerscript/symbol-only.test2
-rw-r--r--test/ELF/linkerscript/va.s2
-rw-r--r--test/ELF/linkerscript/version-script.s6
-rw-r--r--test/ELF/local-dynamic.s4
-rw-r--r--test/ELF/local-ver-preemptible.s4
-rw-r--r--test/ELF/lto/dynamic-list.ll2
-rw-r--r--test/ELF/lto/shlib-undefined.ll2
-rw-r--r--test/ELF/lto/undefined-puts.ll2
-rw-r--r--test/ELF/lto/version-script.ll2
-rw-r--r--test/ELF/mips-dynamic.s6
-rw-r--r--test/ELF/mips-dynsym-sort.s6
-rw-r--r--test/ELF/mips-got-and-copy.s4
-rw-r--r--test/ELF/mips-got-extsym.s2
-rw-r--r--test/ELF/mips-got16.s2
-rw-r--r--test/ELF/mips-micro-jal.s12
-rw-r--r--test/ELF/mips-micro-plt.s2
-rw-r--r--test/ELF/mips-sto-plt.s4
-rw-r--r--test/ELF/msp430.s43
-rw-r--r--test/ELF/no-discard-this_module.s41
-rw-r--r--test/ELF/ppc64-bsymbolic-toc-restore.s2
-rw-r--r--test/ELF/ppc64-call-reach.s4
-rw-r--r--test/ELF/ppc64-dynamic-relocations.s2
-rw-r--r--test/ELF/ppc64-error-missaligned-dq.s2
-rw-r--r--test/ELF/ppc64-error-missaligned-ds.s2
-rw-r--r--test/ELF/ppc64-gd-to-ie.s4
-rw-r--r--test/ELF/ppc64-got-off.s17
-rw-r--r--test/ELF/ppc64-ifunc.s4
-rw-r--r--test/ELF/ppc64-local-dynamic.s2
-rw-r--r--test/ELF/ppc64-plt-stub.s2
-rw-r--r--test/ELF/ppc64-rel-calls.s5
-rw-r--r--test/ELF/ppc64-sort-small-cm-relocs.s108
-rw-r--r--test/ELF/ppc64-split-stack-adjust-overflow.s2
-rw-r--r--test/ELF/ppc64-tls-gd-le.s4
-rw-r--r--test/ELF/ppc64-tls-ld-le.s4
-rw-r--r--test/ELF/ppc64-toc-restore-recursive-call.s2
-rw-r--r--test/ELF/ppc64-toc-restore.s6
-rw-r--r--test/ELF/pr34872.s2
-rw-r--r--test/ELF/progname.s2
-rw-r--r--test/ELF/protected-shared.s4
-rw-r--r--test/ELF/relative-dynamic-reloc-ppc64.s4
-rw-r--r--test/ELF/relative-dynamic-reloc.s4
-rw-r--r--test/ELF/relocatable.s2
-rw-r--r--test/ELF/relocation-size-shared.s15
-rw-r--r--test/ELF/relocation-size.s13
-rw-r--r--test/ELF/relro-omagic.s2
-rw-r--r--test/ELF/retain-symbols-file.s2
-rw-r--r--test/ELF/sectionstart-noallochdr.s2
-rw-r--r--test/ELF/sectionstart.s2
-rw-r--r--test/ELF/shared.s14
-rw-r--r--test/ELF/sht-group-empty.test55
-rw-r--r--test/ELF/stdout.s18
-rw-r--r--test/ELF/tls-dynamic-i686.s46
-rw-r--r--test/ELF/tls-dynamic.s26
-rw-r--r--test/ELF/tls-got.s26
-rw-r--r--test/ELF/tls-initial-exec-local.s14
-rw-r--r--test/ELF/tls-opt-iele-i686-nopic.s44
-rw-r--r--test/ELF/tls-opt-x86_64-noplt.s88
-rw-r--r--test/ELF/trace.s2
-rw-r--r--test/ELF/undef-version-script.s6
-rw-r--r--test/ELF/undef.s4
-rw-r--r--test/ELF/undefined-opt.s2
-rw-r--r--test/ELF/unresolved-symbols.s6
-rw-r--r--test/ELF/verdef-defaultver.s8
-rw-r--r--test/ELF/verdef.s4
-rw-r--r--test/ELF/verneed.s4
-rw-r--r--test/ELF/version-script-complex-wildcards.s8
-rw-r--r--test/ELF/version-script-extern-undefined.s4
-rw-r--r--test/ELF/version-script-extern-wildcards.s2
-rw-r--r--test/ELF/version-script-extern.s4
-rw-r--r--test/ELF/version-script-extern2.s2
-rw-r--r--test/ELF/version-script-hide-so-symbol.s2
-rw-r--r--test/ELF/version-script-locals-extern.s8
-rw-r--r--test/ELF/version-script-symver2.s2
-rw-r--r--test/ELF/version-script-weak.s2
-rw-r--r--test/ELF/version-script.s28
-rw-r--r--test/ELF/version-wildcard.test4
-rw-r--r--test/ELF/visibility.s2
-rw-r--r--test/ELF/weak-undef-export.s4
-rw-r--r--test/ELF/weak-undef.s4
-rw-r--r--test/ELF/wrap-no-real.s3
-rw-r--r--test/ELF/wrap-with-archive.s13
-rw-r--r--test/ELF/x86-64-pcrel.s23
-rw-r--r--test/ELF/x86-64-reloc-error2.s2
-rw-r--r--test/ELF/x86-64-reloc-range-debug-loc.s2
-rw-r--r--test/ELF/x86-64-retpoline-znow-static-iplt.s2
-rw-r--r--test/ELF/x86-64-static-tls-model.s18
-rw-r--r--test/MinGW/driver.test6
-rw-r--r--test/lit.cfg.py14
-rw-r--r--test/lit.site.cfg.py.in2
-rw-r--r--test/wasm/Inputs/globals.yaml4
-rw-r--r--test/wasm/Inputs/undefined-globals.yaml4
-rw-r--r--test/wasm/alias.ll2
-rw-r--r--test/wasm/archive-weak-undefined.ll19
-rw-r--r--test/wasm/archive.ll6
-rw-r--r--test/wasm/call-indirect.ll2
-rw-r--r--test/wasm/cxx-mangling.ll4
-rw-r--r--test/wasm/data-layout.ll10
-rw-r--r--test/wasm/export-table.test2
-rw-r--r--test/wasm/export.ll23
-rw-r--r--test/wasm/fatal-warnings.ll4
-rw-r--r--test/wasm/import-module.ll21
-rw-r--r--test/wasm/import-names.ll27
-rw-r--r--test/wasm/import-table.test2
-rw-r--r--test/wasm/init-fini.ll86
-rw-r--r--test/wasm/local-symbols.ll2
-rw-r--r--test/wasm/locals-duplicate.test182
-rw-r--r--test/wasm/lto/opt-level.ll4
-rw-r--r--test/wasm/lto/relocatable-undefined.ll36
-rw-r--r--test/wasm/lto/weak-undefined.ll20
-rw-r--r--test/wasm/lto/weak.ll5
-rw-r--r--test/wasm/many-functions.ll266
-rw-r--r--test/wasm/reloc-addend.ll2
-rw-r--r--test/wasm/relocatable.ll34
-rw-r--r--test/wasm/shared.ll6
-rw-r--r--test/wasm/stack-pointer.ll6
-rw-r--r--test/wasm/trace-symbol.ll23
-rw-r--r--test/wasm/trace.test8
-rw-r--r--test/wasm/undefined-weak-call.ll8
-rw-r--r--test/wasm/weak-alias-overide.ll2
-rw-r--r--test/wasm/weak-alias.ll60
-rw-r--r--test/wasm/weak-symbols.ll2
-rw-r--r--test/wasm/weak-undefined.ll2
-rw-r--r--tools/lld/lld.cpp7
-rw-r--r--unittests/DriverTests/DarwinLdDriverTest.cpp7
-rw-r--r--unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp7
-rw-r--r--unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp7
-rw-r--r--unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp7
-rw-r--r--unittests/MachOTests/MachONormalizedFileYAMLTests.cpp7
-rwxr-xr-xutils/benchmark.py7
-rw-r--r--wasm/Config.h8
-rw-r--r--wasm/Driver.cpp62
-rw-r--r--wasm/InputChunks.cpp95
-rw-r--r--wasm/InputChunks.h7
-rw-r--r--wasm/InputEvent.h7
-rw-r--r--wasm/InputFiles.cpp76
-rw-r--r--wasm/InputFiles.h10
-rw-r--r--wasm/InputGlobal.h7
-rw-r--r--wasm/LTO.cpp18
-rw-r--r--wasm/LTO.h8
-rw-r--r--wasm/MarkLive.cpp15
-rw-r--r--wasm/MarkLive.h7
-rw-r--r--wasm/Options.td6
-rw-r--r--wasm/OutputSections.cpp9
-rw-r--r--wasm/OutputSections.h7
-rw-r--r--wasm/OutputSegment.h9
-rw-r--r--wasm/SymbolTable.cpp158
-rw-r--r--wasm/SymbolTable.h33
-rw-r--r--wasm/Symbols.cpp22
-rw-r--r--wasm/Symbols.h72
-rw-r--r--wasm/Writer.cpp177
-rw-r--r--wasm/Writer.h9
-rw-r--r--wasm/WriterUtils.cpp11
-rw-r--r--wasm/WriterUtils.h7
462 files changed, 6388 insertions, 3166 deletions
diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp
index 29131d7eb..8c73bda7c 100644
--- a/COFF/Chunks.cpp
+++ b/COFF/Chunks.cpp
@@ -1,9 +1,8 @@
//===- Chunks.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -199,6 +198,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,
case IMAGE_REL_ARM_BLX23T: applyBranch24T(Off, SX - P - 4); break;
case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break;
case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break;
+ case IMAGE_REL_ARM_REL32: add32(Off, SX - P - 4); break;
default:
error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
toString(File));
@@ -310,6 +310,7 @@ void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS,
case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, Off, OS, S); break;
case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, Off, OS, S); break;
case IMAGE_REL_ARM64_SECTION: applySecIdx(Off, OS); break;
+ case IMAGE_REL_ARM64_REL32: add32(Off, S - P - 4); break;
default:
error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
toString(File));
@@ -669,18 +670,38 @@ const uint8_t ArmThunk[] = {
0xe7, 0x44, // L1: add pc, ip
};
-size_t RangeExtensionThunk::getSize() const {
+size_t RangeExtensionThunkARM::getSize() const {
assert(Config->Machine == ARMNT);
return sizeof(ArmThunk);
}
-void RangeExtensionThunk::writeTo(uint8_t *Buf) const {
+void RangeExtensionThunkARM::writeTo(uint8_t *Buf) const {
assert(Config->Machine == ARMNT);
uint64_t Offset = Target->getRVA() - RVA - 12;
memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk));
applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset));
}
+// A position independent ARM64 adrp+add thunk, with a maximum range of
+// +/- 4 GB, which is enough for any PE-COFF.
+const uint8_t Arm64Thunk[] = {
+ 0x10, 0x00, 0x00, 0x90, // adrp x16, Dest
+ 0x10, 0x02, 0x00, 0x91, // add x16, x16, :lo12:Dest
+ 0x00, 0x02, 0x1f, 0xd6, // br x16
+};
+
+size_t RangeExtensionThunkARM64::getSize() const {
+ assert(Config->Machine == ARM64);
+ return sizeof(Arm64Thunk);
+}
+
+void RangeExtensionThunkARM64::writeTo(uint8_t *Buf) const {
+ assert(Config->Machine == ARM64);
+ memcpy(Buf + OutputSectionOff, Arm64Thunk, sizeof(Arm64Thunk));
+ applyArm64Addr(Buf + OutputSectionOff + 0, Target->getRVA(), RVA, 12);
+ applyArm64Imm(Buf + OutputSectionOff + 4, Target->getRVA() & 0xfff, 0);
+}
+
void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
Res->emplace_back(getRVA());
}
diff --git a/COFF/Chunks.h b/COFF/Chunks.h
index 5f2d8067c..954c753aa 100644
--- a/COFF/Chunks.h
+++ b/COFF/Chunks.h
@@ -1,9 +1,8 @@
//===- Chunks.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -224,6 +223,9 @@ public:
// The COMDAT leader symbol if this is a COMDAT chunk.
DefinedRegular *Sym = nullptr;
+ // The COMDAT selection if this is a COMDAT chunk.
+ llvm::COFF::COMDATType Selection = (llvm::COFF::COMDATType)0;
+
ArrayRef<coff_relocation> Relocs;
// Used by the garbage collector.
@@ -311,7 +313,7 @@ static const uint8_t ImportThunkARM64[] = {
};
// Windows-specific.
-// A chunk for DLL import jump table entry. In a final output, it's
+// A chunk for DLL import jump table entry. In a final output, its
// contents will be a JMP instruction to some __imp_ symbol.
class ImportThunkChunkX64 : public Chunk {
public:
@@ -355,9 +357,18 @@ private:
Defined *ImpSymbol;
};
-class RangeExtensionThunk : public Chunk {
+class RangeExtensionThunkARM : public Chunk {
+public:
+ explicit RangeExtensionThunkARM(Defined *T) : Target(T) {}
+ size_t getSize() const override;
+ void writeTo(uint8_t *Buf) const override;
+
+ Defined *Target;
+};
+
+class RangeExtensionThunkARM64 : public Chunk {
public:
- explicit RangeExtensionThunk(Defined *T) : Target(T) {}
+ explicit RangeExtensionThunkARM64(Defined *T) : Target(T) {}
size_t getSize() const override;
void writeTo(uint8_t *Buf) const override;
diff --git a/COFF/Config.h b/COFF/Config.h
index 12b74c799..31e6afaa3 100644
--- a/COFF/Config.h
+++ b/COFF/Config.h
@@ -1,9 +1,8 @@
//===- Config.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -197,6 +196,7 @@ struct Configuration {
bool MinGW = false;
bool WarnMissingOrderSymbol = true;
bool WarnLocallyDefinedImported = true;
+ bool WarnDebugInfoUnusable = true;
bool Incremental = true;
bool IntegrityCheck = false;
bool KillAt = false;
diff --git a/COFF/DLL.cpp b/COFF/DLL.cpp
index 599cc5892..6c31b787d 100644
--- a/COFF/DLL.cpp
+++ b/COFF/DLL.cpp
@@ -1,9 +1,8 @@
//===- DLL.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -47,6 +46,7 @@ public:
}
void writeTo(uint8_t *Buf) const override {
+ memset(Buf + OutputSectionOff, 0, getSize());
write16le(Buf + OutputSectionOff, Hint);
memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size());
}
@@ -63,7 +63,10 @@ public:
size_t getSize() const override { return Config->Wordsize; }
void writeTo(uint8_t *Buf) const override {
- write32le(Buf + OutputSectionOff, HintName->getRVA());
+ if (Config->is64())
+ write64le(Buf + OutputSectionOff, HintName->getRVA());
+ else
+ write32le(Buf + OutputSectionOff, HintName->getRVA());
}
Chunk *HintName;
@@ -99,6 +102,8 @@ public:
size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
void writeTo(uint8_t *Buf) const override {
+ memset(Buf + OutputSectionOff, 0, getSize());
+
auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);
E->ImportLookupTableRVA = LookupTab->getRVA();
E->NameRVA = DLLName->getRVA();
@@ -118,6 +123,10 @@ public:
bool hasData() const override { return false; }
size_t getSize() const override { return Size; }
+ void writeTo(uint8_t *Buf) const override {
+ memset(Buf + OutputSectionOff, 0, Size);
+ }
+
private:
size_t Size;
};
@@ -160,6 +169,8 @@ public:
}
void writeTo(uint8_t *Buf) const override {
+ memset(Buf + OutputSectionOff, 0, getSize());
+
auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff);
E->Attributes = 1;
E->Name = DLLName->getRVA();
@@ -392,6 +403,8 @@ public:
}
void writeTo(uint8_t *Buf) const override {
+ memset(Buf + OutputSectionOff, 0, getSize());
+
auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff);
E->NameRVA = DLLName->getRVA();
E->OrdinalBase = 0;
diff --git a/COFF/DLL.h b/COFF/DLL.h
index a298271e2..4ad029868 100644
--- a/COFF/DLL.h
+++ b/COFF/DLL.h
@@ -1,9 +1,8 @@
//===- DLL.h ----------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp
index 78b47040e..10c761db4 100644
--- a/COFF/Driver.cpp
+++ b/COFF/Driver.cpp
@@ -1,9 +1,8 @@
//===- Driver.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -225,23 +224,33 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName,
void LinkerDriver::enqueueArchiveMember(const Archive::Child &C,
StringRef SymName,
StringRef ParentName) {
+
+ auto ReportBufferError = [=](Error &&E,
+ StringRef ChildName) {
+ fatal("could not get the buffer for the member defining symbol " +
+ SymName + ": " + ParentName + "(" + ChildName + "): " +
+ toString(std::move(E)));
+ };
+
if (!C.getParent()->isThin()) {
- MemoryBufferRef MB = CHECK(
- C.getMemoryBufferRef(),
- "could not get the buffer for the member defining symbol " + SymName);
+ Expected<MemoryBufferRef> MBOrErr = C.getMemoryBufferRef();
+ if (!MBOrErr)
+ ReportBufferError(MBOrErr.takeError(), check(C.getFullName()));
+ MemoryBufferRef MB = MBOrErr.get();
enqueueTask([=]() { Driver->addArchiveBuffer(MB, SymName, ParentName); });
return;
}
- auto Future = std::make_shared<std::future<MBErrPair>>(createFutureForFile(
- CHECK(C.getFullName(),
- "could not get the filename for the member defining symbol " +
- SymName)));
+ std::string ChildName = CHECK(
+ C.getFullName(),
+ "could not get the filename for the member defining symbol " +
+ SymName);
+ auto Future = std::make_shared<std::future<MBErrPair>>(
+ createFutureForFile(ChildName));
enqueueTask([=]() {
auto MBOrErr = Future->get();
if (MBOrErr.second)
- fatal("could not get the buffer for the member defining " + SymName +
- ": " + MBOrErr.second.message());
+ ReportBufferError(errorCodeToError(MBOrErr.second), ChildName);
Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName,
ParentName);
});
@@ -986,11 +995,17 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// Handle /ignore
for (auto *Arg : Args.filtered(OPT_ignore)) {
- if (StringRef(Arg->getValue()) == "4037")
- Config->WarnMissingOrderSymbol = false;
- else if (StringRef(Arg->getValue()) == "4217")
- Config->WarnLocallyDefinedImported = false;
- // Other warning numbers are ignored.
+ SmallVector<StringRef, 8> Vec;
+ StringRef(Arg->getValue()).split(Vec, ',');
+ for (StringRef S : Vec) {
+ if (S == "4037")
+ Config->WarnMissingOrderSymbol = false;
+ else if (S == "4099")
+ Config->WarnDebugInfoUnusable = false;
+ else if (S == "4217")
+ Config->WarnLocallyDefinedImported = false;
+ // Other warning numbers are ignored.
+ }
}
// Handle /out
diff --git a/COFF/Driver.h b/COFF/Driver.h
index e779721ab..a792986a5 100644
--- a/COFF/Driver.h
+++ b/COFF/Driver.h
@@ -1,9 +1,8 @@
//===- Driver.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/COFF/DriverUtils.cpp b/COFF/DriverUtils.cpp
index 3a1189549..c022f93e6 100644
--- a/COFF/DriverUtils.cpp
+++ b/COFF/DriverUtils.cpp
@@ -1,9 +1,8 @@
//===- DriverUtils.cpp ----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/COFF/ICF.cpp b/COFF/ICF.cpp
index 34ea360fa..7684b2c80 100644
--- a/COFF/ICF.cpp
+++ b/COFF/ICF.cpp
@@ -1,9 +1,8 @@
//===- ICF.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -263,19 +262,21 @@ void ICF::run(ArrayRef<Chunk *> Vec) {
// Initially, we use hash values to partition sections.
parallelForEach(Chunks, [&](SectionChunk *SC) {
- SC->Class[1] = xxHash64(SC->getContents());
+ SC->Class[0] = xxHash64(SC->getContents());
});
// Combine the hashes of the sections referenced by each section into its
// hash.
- parallelForEach(Chunks, [&](SectionChunk *SC) {
- uint32_t Hash = SC->Class[1];
- for (Symbol *B : SC->symbols())
- if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
- Hash ^= Sym->getChunk()->Class[1];
- // Set MSB to 1 to avoid collisions with non-hash classs.
- SC->Class[0] = Hash | (1U << 31);
- });
+ for (unsigned Cnt = 0; Cnt != 2; ++Cnt) {
+ parallelForEach(Chunks, [&](SectionChunk *SC) {
+ uint32_t Hash = SC->Class[Cnt % 2];
+ for (Symbol *B : SC->symbols())
+ if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
+ Hash += Sym->getChunk()->Class[Cnt % 2];
+ // Set MSB to 1 to avoid collisions with non-hash classs.
+ SC->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
+ });
+ }
// From now on, sections in Chunks are ordered so that sections in
// the same group are consecutive in the vector.
diff --git a/COFF/ICF.h b/COFF/ICF.h
index 9c54e0c9e..f692c8af3 100644
--- a/COFF/ICF.h
+++ b/COFF/ICF.h
@@ -1,9 +1,8 @@
//===- ICF.h --------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/COFF/InputFiles.cpp b/COFF/InputFiles.cpp
index f35dcda49..ba46184a6 100644
--- a/COFF/InputFiles.cpp
+++ b/COFF/InputFiles.cpp
@@ -1,9 +1,8 @@
//===- InputFiles.cpp -----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -127,6 +126,13 @@ void ObjFile::parse() {
initializeSymbols();
}
+const coff_section* ObjFile::getSection(uint32_t I) {
+ const coff_section *Sec;
+ if (auto EC = COFFObj->getSection(I, Sec))
+ fatal("getSection failed: #" + Twine(I) + ": " + EC.message());
+ return Sec;
+}
+
// We set SectionChunk pointers in the SparseChunks vector to this value
// temporarily to mark comdat sections as having an unknown resolution. As we
// walk the object file's symbol table, once we visit either a leader symbol or
@@ -140,10 +146,7 @@ void ObjFile::initializeChunks() {
Chunks.reserve(NumSections);
SparseChunks.resize(NumSections + 1);
for (uint32_t I = 1; I < NumSections + 1; ++I) {
- const coff_section *Sec;
- if (auto EC = COFFObj->getSection(I, Sec))
- fatal("getSection failed: #" + Twine(I) + ": " + EC.message());
-
+ const coff_section *Sec = getSection(I);
if (Sec->Characteristics & IMAGE_SCN_LNK_COMDAT)
SparseChunks[I] = PendingComdat;
else
@@ -154,10 +157,9 @@ void ObjFile::initializeChunks() {
SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
const coff_aux_section_definition *Def,
StringRef LeaderName) {
- const coff_section *Sec;
+ const coff_section *Sec = getSection(SectionNumber);
+
StringRef Name;
- if (auto EC = COFFObj->getSection(SectionNumber, Sec))
- fatal("getSection failed: #" + Twine(SectionNumber) + ": " + EC.message());
if (auto EC = COFFObj->getSectionName(Sec, Name))
fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " +
EC.message());
@@ -181,8 +183,8 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
// of the linker; they are just a data section containing relocations.
// We can just link them to complete debug info.
//
- // CodeView needs a linker support. We need to interpret and debug
- // info, and then write it to a separate .pdb file.
+ // CodeView needs linker support. We need to interpret debug info,
+ // and then write it to a separate .pdb file.
// Ignore DWARF debug info unless /debug is given.
if (!Config->Debug && Name.startswith(".debug_"))
@@ -223,22 +225,38 @@ void ObjFile::readAssociativeDefinition(
void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym,
const coff_aux_section_definition *Def,
- uint32_t ParentSection) {
- SectionChunk *Parent = SparseChunks[ParentSection];
+ uint32_t ParentIndex) {
+ SectionChunk *Parent = SparseChunks[ParentIndex];
+ int32_t SectionNumber = Sym.getSectionNumber();
+
+ auto Diag = [&]() {
+ StringRef Name, ParentName;
+ COFFObj->getSymbolName(Sym, Name);
+
+ const coff_section *ParentSec = getSection(ParentIndex);
+ COFFObj->getSectionName(ParentSec, ParentName);
+ error(toString(this) + ": associative comdat " + Name + " (sec " +
+ Twine(SectionNumber) + ") has invalid reference to section " +
+ ParentName + " (sec " + Twine(ParentIndex) + ")");
+ };
- // If the parent is pending, it probably means that its section definition
- // appears after us in the symbol table. Leave the associated section as
- // pending; we will handle it during the second pass in initializeSymbols().
- if (Parent == PendingComdat)
+ if (Parent == PendingComdat) {
+ // This can happen if an associative comdat refers to another associative
+ // comdat that appears after it (invalid per COFF spec) or to a section
+ // without any symbols.
+ Diag();
return;
+ }
// Check whether the parent is prevailing. If it is, so are we, and we read
// the section; otherwise mark it as discarded.
- int32_t SectionNumber = Sym.getSectionNumber();
if (Parent) {
- SparseChunks[SectionNumber] = readSection(SectionNumber, Def, "");
- if (SparseChunks[SectionNumber])
- Parent->addAssociative(SparseChunks[SectionNumber]);
+ SectionChunk *C = readSection(SectionNumber, Def, "");
+ SparseChunks[SectionNumber] = C;
+ if (C) {
+ C->Selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE;
+ Parent->addAssociative(C);
+ }
} else {
SparseChunks[SectionNumber] = nullptr;
}
@@ -290,7 +308,7 @@ Symbol *ObjFile::createRegular(COFFSymbolRef Sym) {
return Symtab->addUndefined(Name, this, false);
}
if (SC)
- return make<DefinedRegular>(this, /*Name*/ "", false,
+ return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
/*IsExternal*/ false, Sym.getGeneric(), SC);
return nullptr;
}
@@ -326,8 +344,7 @@ void ObjFile::initializeSymbols() {
// was pending at the point when the symbol was read. This can happen in
// two cases:
// 1) section definition symbol for a comdat leader;
- // 2) symbol belongs to a comdat section associated with a section whose
- // section definition symbol appears later in the symbol table.
+ // 2) symbol belongs to a comdat section associated with another section.
// In both of these cases, we can expect the section to be resolved by
// the time we finish visiting the remaining symbols in the symbol
// table. So we postpone the handling of this symbol until that time.
@@ -338,7 +355,7 @@ void ObjFile::initializeSymbols() {
for (uint32_t I : PendingIndexes) {
COFFSymbolRef Sym = check(COFFObj->getSymbol(I));
- if (auto *Def = Sym.getSectionDefinition()) {
+ if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
readAssociativeDefinition(Sym, Def);
else if (Config->MinGW)
@@ -413,23 +430,143 @@ Optional<Symbol *> ObjFile::createDefined(
fatal(toString(this) + ": " + GetName() +
" should not refer to non-existent section " + Twine(SectionNumber));
- // Handle comdat leader symbols.
+ // Comdat handling.
+ // A comdat symbol consists of two symbol table entries.
+ // The first symbol entry has the name of the section (e.g. .text), fixed
+ // values for the other fields, and one auxilliary record.
+ // The second symbol entry has the name of the comdat symbol, called the
+ // "comdat leader".
+ // When this function is called for the first symbol entry of a comdat,
+ // it sets ComdatDefs and returns None, and when it's called for the second
+ // symbol entry it reads ComdatDefs and then sets it back to nullptr.
+
+ // Handle comdat leader.
if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) {
ComdatDefs[SectionNumber] = nullptr;
- Symbol *Leader;
+ DefinedRegular *Leader;
+
if (Sym.isExternal()) {
std::tie(Leader, Prevailing) =
Symtab->addComdat(this, GetName(), Sym.getGeneric());
} else {
- Leader = make<DefinedRegular>(this, /*Name*/ "", false,
+ Leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
/*IsExternal*/ false, Sym.getGeneric());
Prevailing = true;
}
+ if (Def->Selection < (int)IMAGE_COMDAT_SELECT_NODUPLICATES ||
+ // Intentionally ends at IMAGE_COMDAT_SELECT_LARGEST: link.exe
+ // doesn't understand IMAGE_COMDAT_SELECT_NEWEST either.
+ Def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) {
+ fatal("unknown comdat type " + std::to_string((int)Def->Selection) +
+ " for " + GetName() + " in " + toString(this));
+ }
+ COMDATType Selection = (COMDATType)Def->Selection;
+
+ if (!Prevailing && Leader->isCOMDAT()) {
+ // There's already an existing comdat for this symbol: `Leader`.
+ // Use the comdats's selection field to determine if the new
+ // symbol in `Sym` should be discarded, produce a duplicate symbol
+ // error, etc.
+
+ SectionChunk *LeaderChunk = nullptr;
+ COMDATType LeaderSelection = IMAGE_COMDAT_SELECT_ANY;
+
+ if (Leader->Data) {
+ LeaderChunk = Leader->getChunk();
+ LeaderSelection = LeaderChunk->Selection;
+ } else {
+ // FIXME: comdats from LTO files don't know their selection; treat them
+ // as "any".
+ Selection = LeaderSelection;
+ }
+
+ if ((Selection == IMAGE_COMDAT_SELECT_ANY &&
+ LeaderSelection == IMAGE_COMDAT_SELECT_LARGEST) ||
+ (Selection == IMAGE_COMDAT_SELECT_LARGEST &&
+ LeaderSelection == IMAGE_COMDAT_SELECT_ANY)) {
+ // cl.exe picks "any" for vftables when building with /GR- and
+ // "largest" when building with /GR. To be able to link object files
+ // compiled with each flag, "any" and "largest" are merged as "largest".
+ LeaderSelection = Selection = IMAGE_COMDAT_SELECT_LARGEST;
+ }
+
+ // Other than that, comdat selections must match. This is a bit more
+ // strict than link.exe which allows merging "any" and "largest" if "any"
+ // is the first symbol the linker sees, and it allows merging "largest"
+ // with everything (!) if "largest" is the first symbol the linker sees.
+ // Making this symmetric independent of which selection is seen first
+ // seems better though.
+ // (This behavior matches ModuleLinker::getComdatResult().)
+ if (Selection != LeaderSelection) {
+ std::string Msg = ("conflicting comdat type for " + toString(*Leader) +
+ ": " + Twine((int)LeaderSelection) + " in " +
+ toString(Leader->getFile()) + " and " +
+ Twine((int)Selection) + " in " + toString(this))
+ .str();
+ if (Config->ForceMultiple)
+ warn(Msg);
+ else
+ error(Msg);
+ }
+
+ switch (Selection) {
+ case IMAGE_COMDAT_SELECT_NODUPLICATES:
+ Symtab->reportDuplicate(Leader, this);
+ break;
+
+ case IMAGE_COMDAT_SELECT_ANY:
+ // Nothing to do.
+ break;
+
+ case IMAGE_COMDAT_SELECT_SAME_SIZE:
+ if (LeaderChunk->getSize() != getSection(SectionNumber)->SizeOfRawData)
+ Symtab->reportDuplicate(Leader, this);
+ break;
+
+ case IMAGE_COMDAT_SELECT_EXACT_MATCH: {
+ SectionChunk NewChunk(this, getSection(SectionNumber));
+ // link.exe only compares section contents here and doesn't complain
+ // if the two comdat sections have e.g. different alignment.
+ // Match that.
+ if (LeaderChunk->getContents() != NewChunk.getContents())
+ Symtab->reportDuplicate(Leader, this);
+ break;
+ }
+
+ case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+ // createDefined() is never called for IMAGE_COMDAT_SELECT_ASSOCIATIVE.
+ // (This means lld-link doesn't produce duplicate symbol errors for
+ // associative comdats while link.exe does, but associate comdats
+ // are never extern in practice.)
+ llvm_unreachable("createDefined not called for associative comdats");
+
+ case IMAGE_COMDAT_SELECT_LARGEST:
+ if (LeaderChunk->getSize() < getSection(SectionNumber)->SizeOfRawData) {
+ // Replace the existing comdat symbol with the new one.
+ // FIXME: This is incorrect: With /opt:noref, the previous sections
+ // make it into the final executable as well. Correct handling would
+ // be to undo reading of the whole old section that's being replaced,
+ // or doing one pass that determines what the final largest comdat
+ // is for all IMAGE_COMDAT_SELECT_LARGEST comdats and then reading
+ // only the largest one.
+ replaceSymbol<DefinedRegular>(
+ Leader, this, GetName(), /*IsCOMDAT*/ true,
+ /*IsExternal*/ true, Sym.getGeneric(), nullptr);
+ Prevailing = true;
+ }
+ break;
+
+ case IMAGE_COMDAT_SELECT_NEWEST:
+ llvm_unreachable("should have been rejected earlier");
+ }
+ }
+
if (Prevailing) {
SectionChunk *C = readSection(SectionNumber, Def, GetName());
SparseChunks[SectionNumber] = C;
C->Sym = cast<DefinedRegular>(Leader);
+ C->Selection = Selection;
cast<DefinedRegular>(Leader)->Data = &C->Repl;
} else {
SparseChunks[SectionNumber] = nullptr;
@@ -437,20 +574,16 @@ Optional<Symbol *> ObjFile::createDefined(
return Leader;
}
- // Read associative section definitions and prepare to handle the comdat
- // leader symbol by setting the section's ComdatDefs pointer if we encounter a
- // non-associative comdat.
+ // Prepare to handle the comdat leader symbol by setting the section's
+ // ComdatDefs pointer if we encounter a non-associative comdat.
if (SparseChunks[SectionNumber] == PendingComdat) {
- if (auto *Def = Sym.getSectionDefinition()) {
- if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
- readAssociativeDefinition(Sym, Def);
- else
+ if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
+ if (Def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE)
ComdatDefs[SectionNumber] = Def;
}
+ return None;
}
- if (SparseChunks[SectionNumber] == PendingComdat)
- return None;
return createRegular(Sym);
}
@@ -522,6 +655,8 @@ void BitcodeFile::parse() {
MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier()))));
std::vector<std::pair<Symbol *, bool>> Comdat(Obj->getComdatTable().size());
for (size_t I = 0; I != Obj->getComdatTable().size(); ++I)
+ // FIXME: lto::InputFile doesn't keep enough data to do correct comdat
+ // selection handling.
Comdat[I] = Symtab->addComdat(this, Saver.save(Obj->getComdatTable()[I]));
for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) {
StringRef SymName = Saver.save(ObjSym.getName());
diff --git a/COFF/InputFiles.h b/COFF/InputFiles.h
index 9e1560784..6bf0af3c4 100644
--- a/COFF/InputFiles.h
+++ b/COFF/InputFiles.h
@@ -1,9 +1,8 @@
//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -154,9 +153,11 @@ public:
// When using Microsoft precompiled headers, this is the PCH's key.
// The same key is used by both the precompiled object, and objects using the
// precompiled object. Any difference indicates out-of-date objects.
- llvm::Optional<llvm::codeview::EndPrecompRecord> EndPrecomp;
+ llvm::Optional<uint32_t> PCHSignature;
private:
+ const coff_section* getSection(uint32_t I);
+
void initializeChunks();
void initializeSymbols();
diff --git a/COFF/LTO.cpp b/COFF/LTO.cpp
index 92d9ff093..bfbfc24c7 100644
--- a/COFF/LTO.cpp
+++ b/COFF/LTO.cpp
@@ -1,9 +1,8 @@
//===- LTO.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,6 +10,7 @@
#include "Config.h"
#include "InputFiles.h"
#include "Symbols.h"
+#include "lld/Common/Args.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Strings.h"
#include "lld/Common/TargetOptionsCommandFlags.h"
@@ -43,7 +43,7 @@ using namespace lld::coff;
static std::unique_ptr<lto::LTO> createLTO() {
lto::Config C;
- C.Options = InitTargetOptionsFromCodeGenFlags();
+ C.Options = initTargetOptionsFromCodeGenFlags();
// Always emit a section per function/datum with LTO. LLVM LTO should get most
// of the benefit of linker GC, but there are still opportunities for ICF.
@@ -60,8 +60,9 @@ static std::unique_ptr<lto::LTO> createLTO() {
C.DisableVerify = true;
C.DiagHandler = diagnosticHandler;
C.OptLevel = Config->LTOO;
- C.CPU = GetCPUStr();
- C.MAttrs = GetMAttrs();
+ C.CPU = getCPUStr();
+ C.MAttrs = getMAttrs();
+ C.CGOptLevel = args::getCGOptLevel(Config->LTOO);
if (Config->SaveTemps)
checkError(C.addSaveTemps(std::string(Config->OutputFile) + ".",
diff --git a/COFF/LTO.h b/COFF/LTO.h
index f00924654..222945c81 100644
--- a/COFF/LTO.h
+++ b/COFF/LTO.h
@@ -1,9 +1,8 @@
//===- LTO.h ----------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/COFF/MapFile.cpp b/COFF/MapFile.cpp
index fd4894250..f8cdcc141 100644
--- a/COFF/MapFile.cpp
+++ b/COFF/MapFile.cpp
@@ -1,9 +1,8 @@
//===- MapFile.cpp --------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/COFF/MapFile.h b/COFF/MapFile.h
index 0d0d68ce3..f702dc668 100644
--- a/COFF/MapFile.h
+++ b/COFF/MapFile.h
@@ -1,9 +1,8 @@
//===- MapFile.h ------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/COFF/MarkLive.cpp b/COFF/MarkLive.cpp
index 18b1c9c25..e7d407ba1 100644
--- a/COFF/MarkLive.cpp
+++ b/COFF/MarkLive.cpp
@@ -1,9 +1,8 @@
//===- MarkLive.cpp -------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/COFF/MarkLive.h b/COFF/MarkLive.h
index 5b652dd48..3d7ef932e 100644
--- a/COFF/MarkLive.h
+++ b/COFF/MarkLive.h
@@ -1,9 +1,8 @@
//===- MarkLive.h -----------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/COFF/MinGW.cpp b/COFF/MinGW.cpp
index b2c8c4ead..ee9833edf 100644
--- a/COFF/MinGW.cpp
+++ b/COFF/MinGW.cpp
@@ -1,9 +1,8 @@
//===- MinGW.cpp ----------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/COFF/MinGW.h b/COFF/MinGW.h
index f9c5e3e5c..51448ddbd 100644
--- a/COFF/MinGW.h
+++ b/COFF/MinGW.h
@@ -1,9 +1,8 @@
//===- MinGW.h --------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/COFF/Options.td b/COFF/Options.td
index f5dcd2740..acf1bc5c8 100644
--- a/COFF/Options.td
+++ b/COFF/Options.td
@@ -66,13 +66,18 @@ def wholearchive_file : P<"wholearchive", "Include all object files from this ar
def disallowlib : Joined<["/", "-", "-?"], "disallowlib:">, Alias<nodefaultlib>;
-def manifest : F<"manifest">;
-def manifest_colon : P<"manifest", "Create manifest file">;
+def manifest : F<"manifest">, HelpText<"Create .manifest file">;
+def manifest_colon : P<
+ "manifest",
+ "NO disables manifest output; EMBED[,ID=#] embeds manifest as resource in the image">;
def manifestuac : P<"manifestuac", "User access control">;
-def manifestfile : P<"manifestfile", "Manifest file path">;
-def manifestdependency : P<"manifestdependency",
- "Attributes for <dependency> in manifest file">;
-def manifestinput : P<"manifestinput", "Specify manifest file">;
+def manifestfile : P<"manifestfile", "Manifest output path, with /manifest">;
+def manifestdependency : P<
+ "manifestdependency",
+ "Attributes for <dependency> element in manifest file; implies /manifest">;
+def manifestinput : P<
+ "manifestinput",
+ "Additional manifest inputs; only valid with /manifest:embed">;
// We cannot use multiclass P because class name "incl" is different
// from its command line option name. We do this because "include" is
@@ -89,10 +94,13 @@ def debug_opt : P<"debug", "Embed a symbol table in the image with option">;
def debugtype : P<"debugtype", "Debug Info Options">;
def dll : F<"dll">, HelpText<"Create a DLL">;
def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">;
-def nodefaultlib_all : F<"nodefaultlib">;
-def noentry : F<"noentry">;
+def nodefaultlib_all : F<"nodefaultlib">,
+ HelpText<"Remove all default libraries">;
+def noentry : F<"noentry">,
+ HelpText<"Don't add reference to DllMainCRTStartup; only valid with /dll">;
def profile : F<"profile">;
-def repro : F<"Brepro">, HelpText<"Use a hash of the executable as the PE header timestamp">;
+def repro : F<"Brepro">,
+ HelpText<"Use a hash of the executable as the PE header timestamp">;
def swaprun_cd : F<"swaprun:cd">;
def swaprun_net : F<"swaprun:net">;
def verbose : F<"verbose">;
diff --git a/COFF/PDB.cpp b/COFF/PDB.cpp
index 3c99d1f8d..4070ad475 100644
--- a/COFF/PDB.cpp
+++ b/COFF/PDB.cpp
@@ -1,9 +1,8 @@
//===- PDB.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -53,6 +52,7 @@
#include "llvm/Support/Errc.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/JamCRC.h"
+#include "llvm/Support/Parallel.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ScopedPrinter.h"
#include <memory>
@@ -213,7 +213,7 @@ private:
std::vector<pdb::SecMapEntry> SectionMap;
/// Type index mappings of type server PDBs that we've loaded so far.
- std::map<GUID, CVIndexMap> TypeServerIndexMappings;
+ std::map<codeview::GUID, CVIndexMap> TypeServerIndexMappings;
/// Type index mappings of precompiled objects type map that we've loaded so
/// far.
@@ -221,7 +221,7 @@ private:
/// List of TypeServer PDBs which cannot be loaded.
/// Cached to prevent repeated load attempts.
- std::map<GUID, std::string> MissingTypeServerPDBs;
+ std::map<codeview::GUID, std::string> MissingTypeServerPDBs;
};
class DebugSHandler {
@@ -287,18 +287,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);
}
@@ -493,13 +499,13 @@ PDBLinker::mergeDebugT(ObjFile *File, CVIndexMap *ObjectIndexMap) {
if (auto Err = mergeTypeAndIdRecords(GlobalIDTable, GlobalTypeTable,
ObjectIndexMap->TPIMap, Types, Hashes,
- File->EndPrecomp))
+ File->PCHSignature))
fatal("codeview::mergeTypeAndIdRecords failed: " +
toString(std::move(Err)));
} else {
if (auto Err =
mergeTypeAndIdRecords(IDTable, TypeTable, ObjectIndexMap->TPIMap,
- Types, File->EndPrecomp))
+ Types, File->PCHSignature))
fatal("codeview::mergeTypeAndIdRecords failed: " +
toString(std::move(Err)));
}
@@ -507,7 +513,7 @@ PDBLinker::mergeDebugT(ObjFile *File, CVIndexMap *ObjectIndexMap) {
}
static Expected<std::unique_ptr<pdb::NativeSession>>
-tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
+tryToLoadPDB(const codeview::GUID &GuidFromObj, StringRef TSPath) {
// Ensure the file exists before anything else. We want to return ENOENT,
// "file not found", even if the path points to a removable device (in which
// case the return message would be EAGAIN, "resource unavailable try again")
@@ -550,7 +556,7 @@ PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, const CVType &FirstType) {
TypeDeserializer::deserializeAs(const_cast<CVType &>(FirstType), TS))
fatal("error reading record: " + toString(std::move(EC)));
- const GUID &TSId = TS.getGuid();
+ const codeview::GUID &TSId = TS.getGuid();
StringRef TSPath = TS.getName();
// First, check if the PDB has previously failed to load.
@@ -631,7 +637,7 @@ PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, const CVType &FirstType) {
auto IpiHashes =
GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes);
- Optional<EndPrecompRecord> EndPrecomp;
+ Optional<uint32_t> EndPrecomp;
// Merge TPI first, because the IPI stream will reference type indices.
if (auto Err = mergeTypeRecords(GlobalTypeTable, IndexMap.TPIMap,
ExpectedTpi->typeArray(), TpiHashes, EndPrecomp))
@@ -743,10 +749,10 @@ PDBLinker::aquirePrecompObj(ObjFile *File, PrecompRecord Precomp) {
addObjFile(PrecompFile, &IndexMap);
- if (!PrecompFile->EndPrecomp)
+ if (!PrecompFile->PCHSignature)
fatal(PrecompFile->getName() + " is not a precompiled headers object");
- if (Precomp.getSignature() != PrecompFile->EndPrecomp->getSignature())
+ if (Precomp.getSignature() != PrecompFile->PCHSignature.getValueOr(0))
return createFileError(
Precomp.getPrecompFilePath().str(),
make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date));
@@ -1300,8 +1306,12 @@ void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) {
// If the .debug$T sections fail to merge, assume there is no debug info.
if (!IndexMapResult) {
- auto FileName = sys::path::filename(Path);
- warn("Cannot use debug info for '" + FileName + "'\n" +
+ if (!Config->WarnDebugInfoUnusable) {
+ consumeError(IndexMapResult.takeError());
+ return;
+ }
+ StringRef FileName = sys::path::filename(Path);
+ warn("Cannot use debug info for '" + FileName + "' [LNK4099]\n" +
">>> failed to load reference " +
StringRef(toString(IndexMapResult.takeError())));
return;
@@ -1387,10 +1397,10 @@ void PDBLinker::addObjectsToPDB() {
if (!Publics.empty()) {
// Sort the public symbols and add them to the stream.
- std::sort(Publics.begin(), Publics.end(),
- [](const PublicSym32 &L, const PublicSym32 &R) {
- return L.Name < R.Name;
- });
+ sort(parallel::par, Publics.begin(), Publics.end(),
+ [](const PublicSym32 &L, const PublicSym32 &R) {
+ return L.Name < R.Name;
+ });
for (const PublicSym32 &Pub : Publics)
GsiBuilder.addPublicSymbol(Pub);
}
@@ -1735,20 +1745,26 @@ std::pair<StringRef, uint32_t> coff::getFileLine(const SectionChunk *C,
if (!findLineTable(C, Addr, CVStrTab, Checksums, Lines, OffsetInLinetable))
return {"", 0};
- uint32_t NameIndex;
- uint32_t LineNumber;
+ Optional<uint32_t> NameIndex;
+ Optional<uint32_t> LineNumber;
for (LineColumnEntry &Entry : Lines) {
for (const LineNumberEntry &LN : Entry.LineNumbers) {
+ LineInfo LI(LN.Flags);
if (LN.Offset > OffsetInLinetable) {
+ if (!NameIndex) {
+ NameIndex = Entry.NameIndex;
+ LineNumber = LI.getStartLine();
+ }
StringRef Filename =
- ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex));
- return {Filename, LineNumber};
+ ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex));
+ return {Filename, *LineNumber};
}
- LineInfo LI(LN.Flags);
NameIndex = Entry.NameIndex;
LineNumber = LI.getStartLine();
}
}
- StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex));
- return {Filename, LineNumber};
+ if (!NameIndex)
+ return {"", 0};
+ StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex));
+ return {Filename, *LineNumber};
}
diff --git a/COFF/PDB.h b/COFF/PDB.h
index ea7a9996f..d954e09b5 100644
--- a/COFF/PDB.h
+++ b/COFF/PDB.h
@@ -1,9 +1,8 @@
//===- PDB.h ----------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/COFF/SymbolTable.cpp b/COFF/SymbolTable.cpp
index 1a9e0455d..18289292c 100644
--- a/COFF/SymbolTable.cpp
+++ b/COFF/SymbolTable.cpp
@@ -1,9 +1,8 @@
//===- SymbolTable.cpp ----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -400,7 +399,7 @@ Symbol *SymbolTable::addRegular(InputFile *F, StringRef N,
return S;
}
-std::pair<Symbol *, bool>
+std::pair<DefinedRegular *, bool>
SymbolTable::addComdat(InputFile *F, StringRef N,
const coff_symbol_generic *Sym) {
Symbol *S;
@@ -409,11 +408,12 @@ SymbolTable::addComdat(InputFile *F, StringRef N,
if (WasInserted || !isa<DefinedRegular>(S)) {
replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true,
/*IsExternal*/ true, Sym, nullptr);
- return {S, true};
+ return {cast<DefinedRegular>(S), true};
}
- if (!cast<DefinedRegular>(S)->isCOMDAT())
+ auto *ExistingSymbol = cast<DefinedRegular>(S);
+ if (!ExistingSymbol->isCOMDAT())
reportDuplicate(S, F);
- return {S, false};
+ return {ExistingSymbol, false};
}
Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
diff --git a/COFF/SymbolTable.h b/COFF/SymbolTable.h
index 00e55dbb7..7f74863bf 100644
--- a/COFF/SymbolTable.h
+++ b/COFF/SymbolTable.h
@@ -1,9 +1,8 @@
//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -28,6 +27,7 @@ class Chunk;
class CommonChunk;
class Defined;
class DefinedAbsolute;
+class DefinedRegular;
class DefinedRelative;
class Lazy;
class SectionChunk;
@@ -89,7 +89,7 @@ public:
Symbol *addRegular(InputFile *F, StringRef N,
const llvm::object::coff_symbol_generic *S = nullptr,
SectionChunk *C = nullptr);
- std::pair<Symbol *, bool>
+ std::pair<DefinedRegular *, bool>
addComdat(InputFile *F, StringRef N,
const llvm::object::coff_symbol_generic *S = nullptr);
Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size,
diff --git a/COFF/Symbols.cpp b/COFF/Symbols.cpp
index ccaf86417..781fe9fe4 100644
--- a/COFF/Symbols.cpp
+++ b/COFF/Symbols.cpp
@@ -1,9 +1,8 @@
//===- Symbols.cpp --------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/COFF/Symbols.h b/COFF/Symbols.h
index 9e9bd73a5..718acebfe 100644
--- a/COFF/Symbols.h
+++ b/COFF/Symbols.h
@@ -1,9 +1,8 @@
//===- Symbols.h ------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -39,7 +38,7 @@ class Symbol {
public:
enum Kind {
// The order of these is significant. We start with the regular defined
- // symbols as those are the most prevelant and the zero tag is the cheapest
+ // symbols as those are the most prevalent and the zero tag is the cheapest
// to set. Among the defined kinds, the lower the kind is preferred over
// the higher kind when testing whether one symbol should take precedence
// over another.
diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp
index 258796ea6..d883a4751 100644
--- a/COFF/Writer.cpp
+++ b/COFF/Writer.cpp
@@ -1,9 +1,8 @@
//===- Writer.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -157,6 +156,33 @@ public:
mutable codeview::DebugInfo *BuildId = nullptr;
};
+// PartialSection represents a group of chunks that contribute to an
+// OutputSection. Collating a collection of PartialSections of same name and
+// characteristics constitutes the OutputSection.
+class PartialSectionKey {
+public:
+ StringRef Name;
+ unsigned Characteristics;
+
+ bool operator<(const PartialSectionKey &Other) const {
+ int C = Name.compare(Other.Name);
+ if (C == 1)
+ return false;
+ if (C == 0)
+ return Characteristics < Other.Characteristics;
+ return true;
+ }
+};
+
+class PartialSection {
+public:
+ PartialSection(StringRef N, uint32_t Chars)
+ : Name(N), Characteristics(Chars) {}
+ StringRef Name;
+ unsigned Characteristics;
+ std::vector<Chunk *> Chunks;
+};
+
// The writer writes a SymbolTable result to a file.
class Writer {
public:
@@ -168,8 +194,7 @@ private:
void createMiscChunks();
void createImportTables();
void appendImportThunks();
- void locateImportTables(
- std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map);
+ void locateImportTables();
void createExportTable();
void mergeSections();
void readRelocTargets();
@@ -194,6 +219,10 @@ private:
void writeBuildId();
void sortExceptionTable();
void sortCRTSectionChunks(std::vector<Chunk *> &Chunks);
+ void addSyntheticIdata();
+ bool fixGnuImportChunks();
+ PartialSection *createPartialSection(StringRef Name, uint32_t OutChars);
+ PartialSection *findPartialSection(StringRef Name, uint32_t OutChars);
llvm::Optional<coff_symbol16> createSymbol(Defined *D);
size_t addEntryToStringTable(StringRef Str);
@@ -203,9 +232,9 @@ private:
void addBaserelBlocks(std::vector<Baserel> &V);
uint32_t getSizeOfInitializedData();
- std::map<StringRef, std::vector<DefinedImportData *>> binImports();
std::unique_ptr<FileOutputBuffer> &Buffer;
+ std::map<PartialSectionKey, PartialSection *> PartialSections;
std::vector<OutputSection *> OutputSections;
std::vector<char> Strtab;
std::vector<llvm::object::coff_symbol16> OutputSymtab;
@@ -306,16 +335,31 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) {
// Check whether the target address S is in range from a relocation
// of type RelType at address P.
static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) {
- assert(Config->Machine == ARMNT);
- int64_t Diff = AbsoluteDifference(S, P + 4) + Margin;
- switch (RelType) {
- case IMAGE_REL_ARM_BRANCH20T:
- return isInt<21>(Diff);
- case IMAGE_REL_ARM_BRANCH24T:
- case IMAGE_REL_ARM_BLX23T:
- return isInt<25>(Diff);
- default:
- return true;
+ if (Config->Machine == ARMNT) {
+ int64_t Diff = AbsoluteDifference(S, P + 4) + Margin;
+ switch (RelType) {
+ case IMAGE_REL_ARM_BRANCH20T:
+ return isInt<21>(Diff);
+ case IMAGE_REL_ARM_BRANCH24T:
+ case IMAGE_REL_ARM_BLX23T:
+ return isInt<25>(Diff);
+ default:
+ return true;
+ }
+ } else if (Config->Machine == ARM64) {
+ int64_t Diff = AbsoluteDifference(S, P) + Margin;
+ switch (RelType) {
+ case IMAGE_REL_ARM64_BRANCH26:
+ return isInt<28>(Diff);
+ case IMAGE_REL_ARM64_BRANCH19:
+ return isInt<21>(Diff);
+ case IMAGE_REL_ARM64_BRANCH14:
+ return isInt<16>(Diff);
+ default:
+ return true;
+ }
+ } else {
+ llvm_unreachable("Unexpected architecture");
}
}
@@ -327,7 +371,17 @@ getThunk(DenseMap<uint64_t, Defined *> &LastThunks, Defined *Target, uint64_t P,
Defined *&LastThunk = LastThunks[Target->getRVA()];
if (LastThunk && isInRange(Type, LastThunk->getRVA(), P, Margin))
return {LastThunk, false};
- RangeExtensionThunk *C = make<RangeExtensionThunk>(Target);
+ Chunk *C;
+ switch (Config->Machine) {
+ case ARMNT:
+ C = make<RangeExtensionThunkARM>(Target);
+ break;
+ case ARM64:
+ C = make<RangeExtensionThunkARM64>(Target);
+ break;
+ default:
+ llvm_unreachable("Unexpected architecture");
+ }
Defined *D = make<DefinedSynthetic>("", C);
LastThunk = D;
return {D, true};
@@ -344,14 +398,14 @@ getThunk(DenseMap<uint64_t, Defined *> &LastThunks, Defined *Target, uint64_t P,
// After adding thunks, we verify that all relocations are in range (with
// no extra margin requirements). If this failed, we restart (throwing away
// the previously created thunks) and retry with a wider margin.
-static bool createThunks(std::vector<Chunk *> &Chunks, int Margin) {
+static bool createThunks(OutputSection *OS, int Margin) {
bool AddressesChanged = false;
DenseMap<uint64_t, Defined *> LastThunks;
size_t ThunksSize = 0;
// Recheck Chunks.size() each iteration, since we can insert more
// elements into it.
- for (size_t I = 0; I != Chunks.size(); ++I) {
- SectionChunk *SC = dyn_cast_or_null<SectionChunk>(Chunks[I]);
+ for (size_t I = 0; I != OS->Chunks.size(); ++I) {
+ SectionChunk *SC = dyn_cast_or_null<SectionChunk>(OS->Chunks[I]);
if (!SC)
continue;
size_t ThunkInsertionSpot = I + 1;
@@ -388,7 +442,8 @@ static bool createThunks(std::vector<Chunk *> &Chunks, int Margin) {
Chunk *ThunkChunk = Thunk->getChunk();
ThunkChunk->setRVA(
ThunkInsertionRVA); // Estimate of where it will be located.
- Chunks.insert(Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
+ ThunkChunk->setOutputSection(OS);
+ OS->Chunks.insert(OS->Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
ThunkInsertionSpot++;
ThunksSize += ThunkChunk->getSize();
ThunkInsertionRVA += ThunkChunk->getSize();
@@ -428,7 +483,7 @@ static bool verifyRanges(const std::vector<Chunk *> Chunks) {
// Assign addresses and add thunks if necessary.
void Writer::finalizeAddresses() {
assignAddresses();
- if (Config->Machine != ARMNT)
+ if (Config->Machine != ARMNT && Config->Machine != ARM64)
return;
size_t OrigNumChunks = 0;
@@ -477,7 +532,7 @@ void Writer::finalizeAddresses() {
// to avoid things going out of range due to the added thunks.
bool AddressesChanged = false;
for (OutputSection *Sec : OutputSections)
- AddressesChanged |= createThunks(Sec->Chunks, Margin);
+ AddressesChanged |= createThunks(Sec, Margin);
// If the verification above thought we needed thunks, we should have
// added some.
assert(AddressesChanged);
@@ -568,34 +623,32 @@ static void sortBySectionOrder(std::vector<Chunk *> &Chunks) {
// be formed correctly, the section chunks within each .idata$* section need
// to be grouped by library, and sorted alphabetically within each library
// (which makes sure the header comes first and the trailer last).
-static bool fixGnuImportChunks(
- std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
+bool Writer::fixGnuImportChunks() {
uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
// Make sure all .idata$* section chunks are mapped as RDATA in order to
// be sorted into the same sections as our own synthesized .idata chunks.
- for (auto &Pair : Map) {
- StringRef SectionName = Pair.first.first;
- uint32_t OutChars = Pair.first.second;
- if (!SectionName.startswith(".idata"))
+ for (auto It : PartialSections) {
+ PartialSection *PSec = It.second;
+ if (!PSec->Name.startswith(".idata"))
continue;
- if (OutChars == RDATA)
+ if (PSec->Characteristics == RDATA)
continue;
- std::vector<Chunk *> &SrcVect = Pair.second;
- std::vector<Chunk *> &DestVect = Map[{SectionName, RDATA}];
- DestVect.insert(DestVect.end(), SrcVect.begin(), SrcVect.end());
- SrcVect.clear();
+ PartialSection *RDataSec = createPartialSection(PSec->Name, RDATA);
+ RDataSec->Chunks.insert(RDataSec->Chunks.end(), PSec->Chunks.begin(),
+ PSec->Chunks.end());
+ PSec->Chunks.clear();
}
bool HasIdata = false;
// Sort all .idata$* chunks, grouping chunks from the same library,
// with alphabetical ordering of the object fils within a library.
- for (auto &Pair : Map) {
- StringRef SectionName = Pair.first.first;
- if (!SectionName.startswith(".idata"))
+ for (auto It : PartialSections) {
+ PartialSection *PSec = It.second;
+ if (!PSec->Name.startswith(".idata"))
continue;
- std::vector<Chunk *> &Chunks = Pair.second;
+ std::vector<Chunk *> &Chunks = PSec->Chunks;
if (!Chunks.empty())
HasIdata = true;
std::stable_sort(Chunks.begin(), Chunks.end(), [&](Chunk *S, Chunk *T) {
@@ -621,9 +674,7 @@ static bool fixGnuImportChunks(
// Add generated idata chunks, for imported symbols and DLLs, and a
// terminator in .idata$2.
-static void addSyntheticIdata(
- IdataContents &Idata,
- std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
+void Writer::addSyntheticIdata() {
uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
Idata.create();
@@ -631,8 +682,8 @@ static void addSyntheticIdata(
// chunks from other linked in object files to be grouped together.
// See Microsoft PE/COFF spec 5.4 for details.
auto Add = [&](StringRef N, std::vector<Chunk *> &V) {
- std::vector<Chunk *> &DestVect = Map[{N, RDATA}];
- DestVect.insert(DestVect.end(), V.begin(), V.end());
+ PartialSection *PSec = createPartialSection(N, RDATA);
+ PSec->Chunks.insert(PSec->Chunks.end(), V.begin(), V.end());
};
// The loader assumes a specific order of data.
@@ -646,20 +697,22 @@ static void addSyntheticIdata(
// Locate the first Chunk and size of the import directory list and the
// IAT.
-void Writer::locateImportTables(
- std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map) {
+void Writer::locateImportTables() {
uint32_t RDATA = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
- std::vector<Chunk *> &ImportTables = Map[{".idata$2", RDATA}];
- if (!ImportTables.empty())
- ImportTableStart = ImportTables.front();
- for (Chunk *C : ImportTables)
- ImportTableSize += C->getSize();
-
- std::vector<Chunk *> &IAT = Map[{".idata$5", RDATA}];
- if (!IAT.empty())
- IATStart = IAT.front();
- for (Chunk *C : IAT)
- IATSize += C->getSize();
+
+ if (PartialSection *ImportDirs = findPartialSection(".idata$2", RDATA)) {
+ if (!ImportDirs->Chunks.empty())
+ ImportTableStart = ImportDirs->Chunks.front();
+ for (Chunk *C : ImportDirs->Chunks)
+ ImportTableSize += C->getSize();
+ }
+
+ if (PartialSection *ImportAddresses = findPartialSection(".idata$5", RDATA)) {
+ if (!ImportAddresses->Chunks.empty())
+ IATStart = ImportAddresses->Chunks.front();
+ for (Chunk *C : ImportAddresses->Chunks)
+ IATSize += C->getSize();
+ }
}
// Create output section objects and add them to OutputSections.
@@ -699,7 +752,6 @@ void Writer::createSections() {
DtorsSec = CreateSection(".dtors", DATA | R | W);
// Then bin chunks by name and output characteristics.
- std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> Map;
for (Chunk *C : Symtab->getChunks()) {
auto *SC = dyn_cast<SectionChunk>(C);
if (SC && !SC->Live) {
@@ -707,33 +759,36 @@ void Writer::createSections() {
SC->printDiscardedMessage();
continue;
}
- Map[{C->getSectionName(), C->getOutputCharacteristics()}].push_back(C);
+ PartialSection *PSec = createPartialSection(C->getSectionName(),
+ C->getOutputCharacteristics());
+ PSec->Chunks.push_back(C);
}
// Even in non MinGW cases, we might need to link against GNU import
// libraries.
- bool HasIdata = fixGnuImportChunks(Map);
+ bool HasIdata = fixGnuImportChunks();
if (!Idata.empty())
HasIdata = true;
if (HasIdata)
- addSyntheticIdata(Idata, Map);
+ addSyntheticIdata();
// Process an /order option.
if (!Config->Order.empty())
- for (auto &Pair : Map)
- sortBySectionOrder(Pair.second);
+ for (auto It : PartialSections)
+ sortBySectionOrder(It.second->Chunks);
if (HasIdata)
- locateImportTables(Map);
+ locateImportTables();
// Then create an OutputSection for each section.
// '$' and all following characters in input section names are
// discarded when determining output section. So, .text$foo
// contributes to .text, for example. See PE/COFF spec 3.2.
- for (auto &Pair : Map) {
- StringRef Name = getOutputSectionName(Pair.first.first);
- uint32_t OutChars = Pair.first.second;
+ for (auto It : PartialSections) {
+ PartialSection *PSec = It.second;
+ StringRef Name = getOutputSectionName(PSec->Name);
+ uint32_t OutChars = PSec->Characteristics;
if (Name == ".CRT") {
// In link.exe, there is a special case for the I386 target where .CRT
@@ -742,14 +797,13 @@ void Writer::createSections() {
// special case for all architectures.
OutChars = DATA | R;
- log("Processing section " + Pair.first.first + " -> " + Name);
+ log("Processing section " + PSec->Name + " -> " + Name);
- sortCRTSectionChunks(Pair.second);
+ sortCRTSectionChunks(PSec->Chunks);
}
OutputSection *Sec = CreateSection(Name, OutChars);
- std::vector<Chunk *> &Chunks = Pair.second;
- for (Chunk *C : Chunks)
+ for (Chunk *C : PSec->Chunks)
Sec->addChunk(C);
}
@@ -1717,3 +1771,19 @@ void Writer::addBaserelBlocks(std::vector<Baserel> &V) {
return;
RelocSec->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J));
}
+
+PartialSection *Writer::createPartialSection(StringRef Name,
+ uint32_t OutChars) {
+ PartialSection *&PSec = PartialSections[{Name, OutChars}];
+ if (PSec)
+ return PSec;
+ PSec = make<PartialSection>(Name, OutChars);
+ return PSec;
+}
+
+PartialSection *Writer::findPartialSection(StringRef Name, uint32_t OutChars) {
+ auto It = PartialSections.find({Name, OutChars});
+ if (It != PartialSections.end())
+ return It->second;
+ return nullptr;
+}
diff --git a/COFF/Writer.h b/COFF/Writer.h
index 727582480..c43091753 100644
--- a/COFF/Writer.h
+++ b/COFF/Writer.h
@@ -1,9 +1,8 @@
//===- Writer.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/Common/Args.cpp b/Common/Args.cpp
index 3f0671d72..b57b94097 100644
--- a/Common/Args.cpp
+++ b/Common/Args.cpp
@@ -1,9 +1,8 @@
//===- Args.cpp -----------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -18,6 +17,15 @@
using namespace llvm;
using namespace lld;
+// TODO(sbc): Remove this once CGOptLevel can be set completely based on bitcode
+// function metadata.
+CodeGenOpt::Level lld::args::getCGOptLevel(int OptLevelLTO) {
+ if (OptLevelLTO == 3)
+ return CodeGenOpt::Aggressive;
+ assert(OptLevelLTO < 3);
+ return CodeGenOpt::Default;
+}
+
int lld::args::getInteger(opt::InputArgList &Args, unsigned Key, int Default) {
auto *A = Args.getLastArg(Key);
if (!A)
diff --git a/Common/ErrorHandler.cpp b/Common/ErrorHandler.cpp
index c059516da..7c6835306 100644
--- a/Common/ErrorHandler.cpp
+++ b/Common/ErrorHandler.cpp
@@ -1,9 +1,8 @@
//===- ErrorHandler.cpp ---------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/Common/Memory.cpp b/Common/Memory.cpp
index efc5bcc22..5a6ead421 100644
--- a/Common/Memory.cpp
+++ b/Common/Memory.cpp
@@ -1,9 +1,8 @@
//===- Memory.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/Common/Reproduce.cpp b/Common/Reproduce.cpp
index 7be4ea6bb..cae85125b 100644
--- a/Common/Reproduce.cpp
+++ b/Common/Reproduce.cpp
@@ -1,9 +1,8 @@
//===- Reproduce.cpp - Utilities for creating reproducers -----------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/Common/Strings.cpp b/Common/Strings.cpp
index 6f74865b7..afd5bd39f 100644
--- a/Common/Strings.cpp
+++ b/Common/Strings.cpp
@@ -1,9 +1,8 @@
//===- Strings.cpp -------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/Common/TargetOptionsCommandFlags.cpp b/Common/TargetOptionsCommandFlags.cpp
index 7a3fc5107..d4c29d7f8 100644
--- a/Common/TargetOptionsCommandFlags.cpp
+++ b/Common/TargetOptionsCommandFlags.cpp
@@ -1,9 +1,8 @@
//===-- TargetOptionsCommandFlags.cpp ---------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -20,16 +19,17 @@
#include "llvm/Target/TargetOptions.h"
// Define an externally visible version of
-// InitTargetOptionsFromCodeGenFlags, so that its functionality can be
+// initTargetOptionsFromCodeGenFlags, so that its functionality can be
// used without having to include llvm/CodeGen/CommandFlags.inc, which
// would lead to multiple definitions of the command line flags.
-llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() {
+llvm::TargetOptions lld::initTargetOptionsFromCodeGenFlags() {
return ::InitTargetOptionsFromCodeGenFlags();
}
-llvm::Optional<llvm::CodeModel::Model> lld::GetCodeModelFromCMModel() {
+llvm::Optional<llvm::CodeModel::Model> lld::getCodeModelFromCMModel() {
return getCodeModel();
}
-std::string lld::GetCPUStr() { return ::getCPUStr(); }
-std::vector<std::string> lld::GetMAttrs() { return ::MAttrs; }
+std::string lld::getCPUStr() { return ::getCPUStr(); }
+
+std::vector<std::string> lld::getMAttrs() { return ::MAttrs; }
diff --git a/Common/Threads.cpp b/Common/Threads.cpp
index c64b8c38b..5e0af2882 100644
--- a/Common/Threads.cpp
+++ b/Common/Threads.cpp
@@ -1,9 +1,8 @@
//===- Threads.cpp --------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/Common/Timer.cpp b/Common/Timer.cpp
index 89f9829b4..30862539c 100644
--- a/Common/Timer.cpp
+++ b/Common/Timer.cpp
@@ -1,9 +1,8 @@
//===- Timer.cpp ----------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/Common/Version.cpp b/Common/Version.cpp
index 6226c9a2f..41a3236ef 100644
--- a/Common/Version.cpp
+++ b/Common/Version.cpp
@@ -1,9 +1,8 @@
//===- lib/Common/Version.cpp - LLD Version Number ---------------*- C++-=====//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/ELF/AArch64ErrataFix.cpp b/ELF/AArch64ErrataFix.cpp
index ac753cb58..a0653b96a 100644
--- a/ELF/AArch64ErrataFix.cpp
+++ b/ELF/AArch64ErrataFix.cpp
@@ -1,9 +1,8 @@
//===- AArch64ErrataFix.cpp -----------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This file implements Section Patching for the purpose of working around
diff --git a/ELF/AArch64ErrataFix.h b/ELF/AArch64ErrataFix.h
index edd154d4c..48ddb7c83 100644
--- a/ELF/AArch64ErrataFix.h
+++ b/ELF/AArch64ErrataFix.h
@@ -1,9 +1,8 @@
//===- AArch64ErrataFix.h ---------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Arch/AArch64.cpp b/ELF/Arch/AArch64.cpp
index 08ffe2a08..694da898a 100644
--- a/ELF/Arch/AArch64.cpp
+++ b/ELF/Arch/AArch64.cpp
@@ -1,9 +1,8 @@
//===- AArch64.cpp --------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Arch/AMDGPU.cpp b/ELF/Arch/AMDGPU.cpp
index a7c6c84ce..4d863fad8 100644
--- a/ELF/Arch/AMDGPU.cpp
+++ b/ELF/Arch/AMDGPU.cpp
@@ -1,9 +1,8 @@
//===- AMDGPU.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Arch/ARM.cpp b/ELF/Arch/ARM.cpp
index 5f1485f39..321b327e5 100644
--- a/ELF/Arch/ARM.cpp
+++ b/ELF/Arch/ARM.cpp
@@ -1,9 +1,8 @@
//===- ARM.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -491,14 +490,12 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
break;
case R_ARM_MOVT_ABS:
case R_ARM_MOVT_PREL:
- checkInt(Loc, Val, 32, Type);
write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
(((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
break;
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVT_PREL:
// Encoding T1: A = imm4:i:imm3:imm8
- checkInt(Loc, Val, 32, Type);
write16le(Loc,
0xf2c0 | // opcode
((Val >> 17) & 0x0400) | // i
diff --git a/ELF/Arch/AVR.cpp b/ELF/Arch/AVR.cpp
index 637da3778..9ccbd64d3 100644
--- a/ELF/Arch/AVR.cpp
+++ b/ELF/Arch/AVR.cpp
@@ -1,9 +1,8 @@
//===- AVR.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/ELF/Arch/Hexagon.cpp b/ELF/Arch/Hexagon.cpp
index b4d33be2a..580600ade 100644
--- a/ELF/Arch/Hexagon.cpp
+++ b/ELF/Arch/Hexagon.cpp
@@ -1,9 +1,8 @@
//===-- Hexagon.cpp -------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Arch/MSP430.cpp b/ELF/Arch/MSP430.cpp
new file mode 100644
index 000000000..e104c8c7f
--- /dev/null
+++ b/ELF/Arch/MSP430.cpp
@@ -0,0 +1,93 @@
+//===- MSP430.cpp ---------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The MSP430 is a 16-bit microcontroller RISC architecture. The instruction set
+// has only 27 core instructions orthogonally augmented with a variety
+// of addressing modes for source and destination operands. Entire address space
+// of MSP430 is 64KB (the extended MSP430X architecture is not considered here).
+// A typical MSP430 MCU has several kilobytes of RAM and ROM, plenty
+// of peripherals and is generally optimized for a low power consumption.
+//
+//===----------------------------------------------------------------------===//
+
+#include "InputFiles.h"
+#include "Symbols.h"
+#include "Target.h"
+#include "lld/Common/ErrorHandler.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Support/Endian.h"
+
+using namespace llvm;
+using namespace llvm::object;
+using namespace llvm::support::endian;
+using namespace llvm::ELF;
+using namespace lld;
+using namespace lld::elf;
+
+namespace {
+class MSP430 final : public TargetInfo {
+public:
+ MSP430();
+ RelExpr getRelExpr(RelType Type, const Symbol &S,
+ const uint8_t *Loc) const override;
+ void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+};
+} // namespace
+
+MSP430::MSP430() {
+ // mov.b #0, r3
+ TrapInstr = {0x43, 0x43, 0x43, 0x43};
+}
+
+RelExpr MSP430::getRelExpr(RelType Type, const Symbol &S,
+ const uint8_t *Loc) const {
+ switch (Type) {
+ case R_MSP430_10_PCREL:
+ case R_MSP430_16_PCREL:
+ case R_MSP430_16_PCREL_BYTE:
+ case R_MSP430_2X_PCREL:
+ case R_MSP430_RL_PCREL:
+ case R_MSP430_SYM_DIFF:
+ return R_PC;
+ default:
+ return R_ABS;
+ }
+}
+
+void MSP430::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
+ switch (Type) {
+ case R_MSP430_8:
+ checkIntUInt(Loc, Val, 8, Type);
+ *Loc = Val;
+ break;
+ case R_MSP430_16:
+ case R_MSP430_16_PCREL:
+ case R_MSP430_16_BYTE:
+ case R_MSP430_16_PCREL_BYTE:
+ checkIntUInt(Loc, Val, 16, Type);
+ write16le(Loc, Val);
+ break;
+ case R_MSP430_32:
+ checkIntUInt(Loc, Val, 32, Type);
+ write32le(Loc, Val);
+ break;
+ case R_MSP430_10_PCREL: {
+ int16_t Offset = ((int16_t)Val >> 1) - 1;
+ checkInt(Loc, Offset, 10, Type);
+ write16le(Loc, (read16le(Loc) & 0xFC00) | (Offset & 0x3FF));
+ break;
+ }
+ default:
+ error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));
+ }
+}
+
+TargetInfo *elf::getMSP430TargetInfo() {
+ static MSP430 Target;
+ return &Target;
+}
diff --git a/ELF/Arch/Mips.cpp b/ELF/Arch/Mips.cpp
index 23b0c1dd8..a6d7e1909 100644
--- a/ELF/Arch/Mips.cpp
+++ b/ELF/Arch/Mips.cpp
@@ -1,9 +1,8 @@
//===- MIPS.cpp -----------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Arch/MipsArchTree.cpp b/ELF/Arch/MipsArchTree.cpp
index 98ceac307..562a5fff0 100644
--- a/ELF/Arch/MipsArchTree.cpp
+++ b/ELF/Arch/MipsArchTree.cpp
@@ -1,9 +1,8 @@
//===- MipsArchTree.cpp --------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
//
diff --git a/ELF/Arch/PPC.cpp b/ELF/Arch/PPC.cpp
index 767378067..9a32e8cad 100644
--- a/ELF/Arch/PPC.cpp
+++ b/ELF/Arch/PPC.cpp
@@ -1,9 +1,8 @@
//===- PPC.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Arch/PPC64.cpp b/ELF/Arch/PPC64.cpp
index 4d42a26ee..4f5aa45aa 100644
--- a/ELF/Arch/PPC64.cpp
+++ b/ELF/Arch/PPC64.cpp
@@ -1,9 +1,8 @@
//===- PPC64.cpp ----------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -99,10 +98,16 @@ unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther) {
return 0;
}
+bool elf::isPPC64SmallCodeModelTocReloc(RelType Type) {
+ // The only small code model relocations that access the .toc section.
+ return Type == R_PPC64_TOC16 || Type == R_PPC64_TOC16_DS;
+}
+
namespace {
class PPC64 final : public TargetInfo {
public:
PPC64();
+ int getTlsGdRelaxSkip(RelType Type) const override;
uint32_t calcEFlags() const override;
RelExpr getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const override;
@@ -233,6 +238,20 @@ PPC64::PPC64() {
write32(TrapInstr.data(), 0x7fe00008);
}
+int PPC64::getTlsGdRelaxSkip(RelType Type) const {
+ // A __tls_get_addr call instruction is marked with 2 relocations:
+ //
+ // R_PPC64_TLSGD / R_PPC64_TLSLD: marker relocation
+ // R_PPC64_REL24: __tls_get_addr
+ //
+ // After the relaxation we no longer call __tls_get_addr and should skip both
+ // relocations to not create a false dependence on __tls_get_addr being
+ // defined.
+ if (Type == R_PPC64_TLSGD || Type == R_PPC64_TLSLD)
+ return 2;
+ return 1;
+}
+
static uint32_t getEFlags(InputFile *File) {
if (Config->EKind == ELF64BEKind)
return cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags;
@@ -597,17 +616,27 @@ static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
}
}
-static bool isTocRelType(RelType Type) {
- return Type == R_PPC64_TOC16_HA || Type == R_PPC64_TOC16_LO_DS ||
- Type == R_PPC64_TOC16_LO;
+static bool isTocOptType(RelType Type) {
+ switch (Type) {
+ case R_PPC64_GOT16_HA:
+ case R_PPC64_GOT16_LO_DS:
+ case R_PPC64_TOC16_HA:
+ case R_PPC64_TOC16_LO_DS:
+ case R_PPC64_TOC16_LO:
+ return true;
+ default:
+ return false;
+ }
}
void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
- // We need to save the original relocation type to determine if we should
- // toc-optimize the instructions being relocated.
- bool IsTocRelType = isTocRelType(Type);
- // For TOC-relative and GOT-indirect relocations, proceed in terms of the
- // corresponding ADDR16 relocation type.
+ // We need to save the original relocation type to use in diagnostics, and
+ // use the original type to determine if we should toc-optimize the
+ // instructions being relocated.
+ RelType OriginalType = Type;
+ bool ShouldTocOptimize = isTocOptType(Type);
+ // For dynamic thread pointer relative, toc-relative, and got-indirect
+ // relocations, proceed in terms of the corresponding ADDR16 relocation type.
std::tie(Type, Val) = toAddr16Rel(Type, Val);
switch (Type) {
@@ -620,22 +649,22 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
}
case R_PPC64_ADDR16:
case R_PPC64_TPREL16:
- checkInt(Loc, Val, 16, Type);
+ checkInt(Loc, Val, 16, OriginalType);
write16(Loc, Val);
break;
case R_PPC64_ADDR16_DS:
case R_PPC64_TPREL16_DS: {
- checkInt(Loc, Val, 16, Type);
+ checkInt(Loc, Val, 16, OriginalType);
// DQ-form instructions use bits 28-31 as part of the instruction encoding
// DS-form instructions only use bits 30-31.
uint16_t Mask = isDQFormInstruction(readInstrFromHalf16(Loc)) ? 0xF : 0x3;
- checkAlignment(Loc, lo(Val), Mask + 1, Type);
+ checkAlignment(Loc, lo(Val), Mask + 1, OriginalType);
write16(Loc, (read16(Loc) & Mask) | lo(Val));
} break;
case R_PPC64_ADDR16_HA:
case R_PPC64_REL16_HA:
case R_PPC64_TPREL16_HA:
- if (Config->TocOptimize && IsTocRelType && ha(Val) == 0)
+ if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0)
writeInstrFromHalf16(Loc, 0x60000000);
else
write16(Loc, ha(Val));
@@ -667,7 +696,7 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
// When the high-adjusted part of a toc relocation evalutes to 0, it is
// changed into a nop. The lo part then needs to be updated to use the
// toc-pointer register r2, as the base register.
- if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) {
+ if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
uint32_t Instr = readInstrFromHalf16(Loc);
if (isInstructionUpdateForm(Instr))
error(getErrorLocation(Loc) +
@@ -684,8 +713,8 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
// DS-form instructions only use bits 30-31.
uint32_t Inst = readInstrFromHalf16(Loc);
uint16_t Mask = isDQFormInstruction(Inst) ? 0xF : 0x3;
- checkAlignment(Loc, lo(Val), Mask + 1, Type);
- if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) {
+ checkAlignment(Loc, lo(Val), Mask + 1, OriginalType);
+ if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
// When the high-adjusted part of a toc relocation evalutes to 0, it is
// changed into a nop. The lo part then needs to be updated to use the toc
// pointer register r2, as the base register.
diff --git a/ELF/Arch/RISCV.cpp b/ELF/Arch/RISCV.cpp
index 461e8d35c..29a5ae622 100644
--- a/ELF/Arch/RISCV.cpp
+++ b/ELF/Arch/RISCV.cpp
@@ -1,9 +1,8 @@
//===- RISCV.cpp ----------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Arch/SPARCV9.cpp b/ELF/Arch/SPARCV9.cpp
index 831aa2028..50017d0bb 100644
--- a/ELF/Arch/SPARCV9.cpp
+++ b/ELF/Arch/SPARCV9.cpp
@@ -1,9 +1,8 @@
//===- SPARCV9.cpp --------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Arch/X86.cpp b/ELF/Arch/X86.cpp
index e910375d2..307f94fe5 100644
--- a/ELF/Arch/X86.cpp
+++ b/ELF/Arch/X86.cpp
@@ -1,9 +1,8 @@
//===- X86.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -24,6 +23,7 @@ namespace {
class X86 : public TargetInfo {
public:
X86();
+ int getTlsGdRelaxSkip(RelType Type) const override;
RelExpr getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const override;
int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
@@ -59,7 +59,6 @@ X86::X86() {
GotPltEntrySize = 4;
PltEntrySize = 16;
PltHeaderSize = 16;
- TlsGdRelaxSkip = 2;
TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
// Align to the non-PAE large page size (known as a superpage or huge page).
@@ -67,10 +66,20 @@ X86::X86() {
DefaultImageBase = 0x400000;
}
-static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }
+int X86::getTlsGdRelaxSkip(RelType Type) const {
+ return 2;
+}
RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const {
+ // There are 4 different TLS variable models with varying degrees of
+ // flexibility and performance. LocalExec and InitialExec models are fast but
+ // less-flexible models. If they are in use, we set DF_STATIC_TLS flag in the
+ // dynamic section to let runtime know about that.
+ if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 || Type == R_386_TLS_IE ||
+ Type == R_386_TLS_GOTIE)
+ Config->HasStaticTlsModel = true;
+
switch (Type) {
case R_386_8:
case R_386_16:
@@ -108,14 +117,14 @@ RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
// load an GOT address to a register, which is usually %ebx.
//
// So, there are two ways to refer to symbol foo's GOT entry: foo@GOT or
- // foo@GOT(%reg).
+ // foo@GOT(%ebx).
//
// foo@GOT is not usable in PIC. If we are creating a PIC output and if we
// find such relocation, we should report an error. foo@GOT is resolved to
// an *absolute* address of foo's GOT entry, because both GOT address and
// foo's offset are known. In other words, it's G + A.
//
- // foo@GOT(%reg) needs to be resolved to a *relative* offset from a GOT to
+ // foo@GOT(%ebx) needs to be resolved to a *relative* offset from a GOT to
// foo's GOT entry in the table, because GOT address is not known but foo's
// offset in the table is known. It's G + A - GOT.
//
@@ -123,12 +132,12 @@ RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
// different use cases. In order to distinguish them, we have to read a
// machine instruction.
//
- // The following code implements it. We assume that Loc[0] is the first
- // byte of a displacement or an immediate field of a valid machine
+ // The following code implements it. We assume that Loc[0] is the first byte
+ // of a displacement or an immediate field of a valid machine
// instruction. That means a ModRM byte is at Loc[-1]. By taking a look at
- // the byte, we can determine whether the instruction is register-relative
- // (i.e. it was generated for foo@GOT(%reg)) or absolute (i.e. foo@GOT).
- return hasBaseReg(Loc[-1]) ? R_GOT_FROM_END : R_GOT;
+ // the byte, we can determine whether the instruction uses the operand as an
+ // absolute address (R_GOT) or a register-relative address (R_GOT_FROM_END).
+ return (Loc[-1] & 0xc7) == 0x5 ? R_GOT : R_GOT_FROM_END;
case R_386_TLS_GOTIE:
return R_GOT_FROM_END;
case R_386_GOTOFF:
diff --git a/ELF/Arch/X86_64.cpp b/ELF/Arch/X86_64.cpp
index 06314155d..bfe2ba824 100644
--- a/ELF/Arch/X86_64.cpp
+++ b/ELF/Arch/X86_64.cpp
@@ -1,9 +1,8 @@
//===- X86_64.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -26,6 +25,7 @@ namespace {
template <class ELFT> class X86_64 : public TargetInfo {
public:
X86_64();
+ int getTlsGdRelaxSkip(RelType Type) const override;
RelExpr getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const override;
RelType getDynRel(RelType Type) const override;
@@ -66,7 +66,6 @@ template <class ELFT> X86_64<ELFT>::X86_64() {
GotPltEntrySize = 8;
PltEntrySize = 16;
PltHeaderSize = 16;
- TlsGdRelaxSkip = 2;
TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
// Align to the large page size (known as a superpage or huge page).
@@ -75,8 +74,16 @@ template <class ELFT> X86_64<ELFT>::X86_64() {
}
template <class ELFT>
+int X86_64<ELFT>::getTlsGdRelaxSkip(RelType Type) const {
+ return 2;
+}
+
+template <class ELFT>
RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S,
const uint8_t *Loc) const {
+ if (Type == R_X86_64_GOTTPOFF)
+ Config->HasStaticTlsModel = true;
+
switch (Type) {
case R_X86_64_8:
case R_X86_64_16:
@@ -97,6 +104,8 @@ RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S,
return R_SIZE;
case R_X86_64_PLT32:
return R_PLT_PC;
+ case R_X86_64_PC8:
+ case R_X86_64_PC16:
case R_X86_64_PC32:
case R_X86_64_PC64:
return R_PC;
@@ -264,15 +273,6 @@ void X86_64<ELFT>::relaxTlsIeToLe(uint8_t *Loc, RelType Type,
template <class ELFT>
void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
uint64_t Val) const {
- // Convert
- // leaq bar@tlsld(%rip), %rdi
- // callq __tls_get_addr@PLT
- // leaq bar@dtpoff(%rax), %rcx
- // to
- // .word 0x6666
- // .byte 0x66
- // mov %fs:0,%rax
- // leaq bar@tpoff(%rax), %rcx
if (Type == R_X86_64_DTPOFF64) {
write64le(Loc, Val);
return;
@@ -287,7 +287,37 @@ void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
0x66, // .byte 0x66
0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0,%rax
};
- memcpy(Loc - 3, Inst, sizeof(Inst));
+
+ if (Loc[4] == 0xe8) {
+ // Convert
+ // leaq bar@tlsld(%rip), %rdi # 48 8d 3d <Loc>
+ // callq __tls_get_addr@PLT # e8 <disp32>
+ // leaq bar@dtpoff(%rax), %rcx
+ // to
+ // .word 0x6666
+ // .byte 0x66
+ // mov %fs:0,%rax
+ // leaq bar@tpoff(%rax), %rcx
+ memcpy(Loc - 3, Inst, sizeof(Inst));
+ return;
+ }
+
+ if (Loc[4] == 0xff && Loc[5] == 0x15) {
+ // Convert
+ // leaq x@tlsld(%rip),%rdi # 48 8d 3d <Loc>
+ // call *__tls_get_addr@GOTPCREL(%rip) # ff 15 <disp32>
+ // to
+ // .long 0x66666666
+ // movq %fs:0,%rax
+ // See "Table 11.9: LD -> LE Code Transition (LP64)" in
+ // https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf
+ Loc[-3] = 0x66;
+ memcpy(Loc - 2, Inst, sizeof(Inst));
+ return;
+ }
+
+ error(getErrorLocation(Loc - 3) +
+ "expected R_X86_64_PLT32 or R_X86_64_GOTPCRELX after R_X86_64_TLSLD");
}
template <class ELFT>
@@ -297,10 +327,18 @@ void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
checkUInt(Loc, Val, 8, Type);
*Loc = Val;
break;
+ case R_X86_64_PC8:
+ checkInt(Loc, Val, 8, Type);
+ *Loc = Val;
+ break;
case R_X86_64_16:
checkUInt(Loc, Val, 16, Type);
write16le(Loc, Val);
break;
+ case R_X86_64_PC16:
+ checkInt(Loc, Val, 16, Type);
+ write16le(Loc, Val);
+ break;
case R_X86_64_32:
checkUInt(Loc, Val, 32, Type);
write32le(Loc, Val);
diff --git a/ELF/Bits.h b/ELF/Bits.h
deleted file mode 100644
index 13d403222..000000000
--- a/ELF/Bits.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- Bits.h ---------------------------------------------------*- C++ -*-===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_ELF_BITS_H
-#define LLD_ELF_BITS_H
-
-#include "Config.h"
-#include "llvm/Support/Endian.h"
-
-namespace lld {
-namespace elf {
-
-inline uint64_t readUint(uint8_t *Buf) {
- if (Config->Is64)
- return llvm::support::endian::read64(Buf, Config->Endianness);
- return llvm::support::endian::read32(Buf, Config->Endianness);
-}
-
-inline void writeUint(uint8_t *Buf, uint64_t Val) {
- if (Config->Is64)
- llvm::support::endian::write64(Buf, Val, Config->Endianness);
- else
- llvm::support::endian::write32(Buf, Val, Config->Endianness);
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif
diff --git a/ELF/CMakeLists.txt b/ELF/CMakeLists.txt
index 51fc1e564..a1c23b0d4 100644
--- a/ELF/CMakeLists.txt
+++ b/ELF/CMakeLists.txt
@@ -15,6 +15,7 @@ add_lld_library(lldELF
Arch/Hexagon.cpp
Arch/Mips.cpp
Arch/MipsArchTree.cpp
+ Arch/MSP430.cpp
Arch/PPC.cpp
Arch/PPC64.cpp
Arch/RISCV.cpp
diff --git a/ELF/CallGraphSort.cpp b/ELF/CallGraphSort.cpp
index 2a7d78664..2e50c5055 100644
--- a/ELF/CallGraphSort.cpp
+++ b/ELF/CallGraphSort.cpp
@@ -1,9 +1,8 @@
//===- CallGraphSort.cpp --------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/ELF/CallGraphSort.h b/ELF/CallGraphSort.h
index 3f96dc88f..5a092278a 100644
--- a/ELF/CallGraphSort.h
+++ b/ELF/CallGraphSort.h
@@ -1,9 +1,8 @@
//===- CallGraphSort.h ------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Config.h b/ELF/Config.h
index 8fb760e59..4e6c44f5d 100644
--- a/ELF/Config.h
+++ b/ELF/Config.h
@@ -1,9 +1,8 @@
//===- Config.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -18,6 +17,7 @@
#include "llvm/Support/CachePruning.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Endian.h"
+#include <atomic>
#include <vector>
namespace lld {
@@ -120,6 +120,7 @@ struct Configuration {
uint64_t>
CallGraphProfile;
bool AllowMultipleDefinition;
+ bool AllowShlibUndefined;
bool AndroidPackDynRelocs;
bool ARMHasBlx = false;
bool ARMHasMovtMovw = false;
@@ -159,6 +160,7 @@ struct Configuration {
bool OFormatBinary;
bool Omagic;
bool OptRemarksWithHotness;
+ bool PicThunk;
bool Pie;
bool PrintGcSections;
bool PrintIcfSections;
@@ -252,6 +254,20 @@ struct Configuration {
// if that's true.)
bool IsMips64EL;
+ // True if we need to set the DF_STATIC_TLS flag to an output file,
+ // which works as a hint to the dynamic loader that the file contains
+ // code compiled with the static TLS model. The thread-local variable
+ // compiled with the static TLS model is faster but less flexible, and
+ // it may not be loaded using dlopen().
+ //
+ // We set this flag to true when we see a relocation for the static TLS
+ // model. Once this becomes true, it will never become false.
+ //
+ // Since the flag is updated by multi-threaded code, we use std::atomic.
+ // (Writing to a variable is not considered thread-safe even if the
+ // variable is boolean and we always set the same value from all threads.)
+ std::atomic<bool> HasStaticTlsModel{false};
+
// Holds set of ELF header flags for the target.
uint32_t EFlags = 0;
diff --git a/ELF/DWARF.cpp b/ELF/DWARF.cpp
index 17e1a4d60..ad1363b25 100644
--- a/ELF/DWARF.cpp
+++ b/ELF/DWARF.cpp
@@ -1,9 +1,8 @@
//===- DWARF.cpp ----------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/ELF/DWARF.h b/ELF/DWARF.h
index 8ecf02c77..09796158e 100644
--- a/ELF/DWARF.h
+++ b/ELF/DWARF.h
@@ -1,9 +1,8 @@
//===- DWARF.h -----------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===-------------------------------------------------------------------===//
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index 51daa81ed..e2aa7e944 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -1,9 +1,8 @@
//===- Driver.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -130,7 +129,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})
@@ -371,6 +370,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
// Interpret this flag early because error() depends on them.
errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
+ checkZOptions(Args);
// Handle -help
if (Args.hasArg(OPT_help)) {
@@ -411,7 +411,6 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
}
readConfigs(Args);
- checkZOptions(Args);
// The behavior of -v or --version is a bit strange, but this is
// needed for compatibility with GNU linkers.
@@ -757,6 +756,9 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Args.hasFlag(OPT_allow_multiple_definition,
OPT_no_allow_multiple_definition, false) ||
hasZOption(Args, "muldefs");
+ Config->AllowShlibUndefined =
+ Args.hasFlag(OPT_allow_shlib_undefined, OPT_no_allow_shlib_undefined,
+ Args.hasArg(OPT_shared));
Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary);
Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
@@ -1006,6 +1008,7 @@ static void setConfigs(opt::InputArgList &Args) {
Config->Endianness = Config->IsLE ? endianness::little : endianness::big;
Config->IsMips64EL = (K == ELF64LEKind && M == EM_MIPS);
Config->Pic = Config->Pie || Config->Shared;
+ Config->PicThunk = Args.hasArg(OPT_pic_veneer, Config->Pic);
Config->Wordsize = Config->Is64 ? 8 : 4;
// ELF defines two different ways to store relocation addends as shown below:
@@ -1550,6 +1553,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);
+ // Create wrapped symbols for -wrap option.
+ std::vector<WrappedSymbol> Wrapped = addWrappedSymbols<ELFT>(Args);
+
// We need to create some reserved symbols such as _end. Create them.
if (!Config->Relocatable)
addReservedSymbols();
@@ -1562,9 +1568,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
if (!Config->Relocatable)
Symtab->scanVersionScript();
- // Create wrapped symbols for -wrap option.
- std::vector<WrappedSymbol> Wrapped = addWrappedSymbols<ELFT>(Args);
-
// Do link-time optimization if given files are LLVM bitcode files.
// This compiles bitcode files into real object files.
//
diff --git a/ELF/Driver.h b/ELF/Driver.h
index 81d7f608e..dd66893b2 100644
--- a/ELF/Driver.h
+++ b/ELF/Driver.h
@@ -1,9 +1,8 @@
//===- Driver.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/DriverUtils.cpp b/ELF/DriverUtils.cpp
index e51d02e38..4f2ef4d9b 100644
--- a/ELF/DriverUtils.cpp
+++ b/ELF/DriverUtils.cpp
@@ -1,9 +1,8 @@
//===- DriverUtils.cpp ----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/ELF/EhFrame.cpp b/ELF/EhFrame.cpp
index 95d444bdc..1d3745ed5 100644
--- a/ELF/EhFrame.cpp
+++ b/ELF/EhFrame.cpp
@@ -1,9 +1,8 @@
//===- EhFrame.cpp -------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/ELF/EhFrame.h b/ELF/EhFrame.h
index 5112891a9..165d72b79 100644
--- a/ELF/EhFrame.h
+++ b/ELF/EhFrame.h
@@ -1,9 +1,8 @@
//===- EhFrame.h ------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Filesystem.cpp b/ELF/Filesystem.cpp
index 5cf240eec..957534a0a 100644
--- a/ELF/Filesystem.cpp
+++ b/ELF/Filesystem.cpp
@@ -1,9 +1,8 @@
//===- Filesystem.cpp -----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/ELF/Filesystem.h b/ELF/Filesystem.h
index 987a74a6b..c92a5d204 100644
--- a/ELF/Filesystem.h
+++ b/ELF/Filesystem.h
@@ -1,9 +1,8 @@
//===- Filesystem.h ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/ICF.cpp b/ELF/ICF.cpp
index e917ae76a..7c07a42a8 100644
--- a/ELF/ICF.cpp
+++ b/ELF/ICF.cpp
@@ -1,9 +1,8 @@
//===- ICF.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -426,16 +425,17 @@ void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> Fn) {
// Combine the hashes of the sections referenced by the given section into its
// hash.
template <class ELFT, class RelTy>
-static void combineRelocHashes(InputSection *IS, ArrayRef<RelTy> Rels) {
- uint32_t Hash = IS->Class[1];
+static void combineRelocHashes(unsigned Cnt, InputSection *IS,
+ ArrayRef<RelTy> Rels) {
+ uint32_t Hash = IS->Class[Cnt % 2];
for (RelTy Rel : Rels) {
Symbol &S = IS->template getFile<ELFT>()->getRelocTargetSym(Rel);
if (auto *D = dyn_cast<Defined>(&S))
if (auto *RelSec = dyn_cast_or_null<InputSection>(D->Section))
- Hash ^= RelSec->Class[1];
+ Hash += RelSec->Class[Cnt % 2];
}
// Set MSB to 1 to avoid collisions with non-hash IDs.
- IS->Class[0] = Hash | (1U << 31);
+ IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
}
static void print(const Twine &S) {
@@ -453,15 +453,17 @@ template <class ELFT> void ICF<ELFT>::run() {
// Initially, we use hash values to partition sections.
parallelForEach(Sections, [&](InputSection *S) {
- S->Class[1] = xxHash64(S->data());
+ S->Class[0] = xxHash64(S->data());
});
- parallelForEach(Sections, [&](InputSection *S) {
- if (S->AreRelocsRela)
- combineRelocHashes<ELFT>(S, S->template relas<ELFT>());
- else
- combineRelocHashes<ELFT>(S, S->template rels<ELFT>());
- });
+ for (unsigned Cnt = 0; Cnt != 2; ++Cnt) {
+ parallelForEach(Sections, [&](InputSection *S) {
+ if (S->AreRelocsRela)
+ combineRelocHashes<ELFT>(Cnt, S, S->template relas<ELFT>());
+ else
+ combineRelocHashes<ELFT>(Cnt, S, S->template rels<ELFT>());
+ });
+ }
// From now on, sections in Sections vector are ordered so that sections
// in the same equivalence class are consecutive in the vector.
diff --git a/ELF/ICF.h b/ELF/ICF.h
index a6c8636ea..ed828fc4a 100644
--- a/ELF/ICF.h
+++ b/ELF/ICF.h
@@ -1,9 +1,8 @@
//===- ICF.h --------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index a85e5e6af..c3e5b2f48 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -1,9 +1,8 @@
//===- InputFiles.cpp -----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -320,17 +319,6 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
return Signature;
}
-template <class ELFT>
-ArrayRef<typename ObjFile<ELFT>::Elf_Word>
-ObjFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
- const ELFFile<ELFT> &Obj = this->getObj();
- ArrayRef<Elf_Word> Entries =
- CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
- if (Entries.empty() || Entries[0] != GRP_COMDAT)
- fatal(toString(this) + ": unsupported SHT_GROUP format");
- return Entries.slice(1);
-}
-
template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
// On a regular link we don't merge sections if -O0 (default is -O1). This
// sometimes makes the linker significantly faster, although the output will
@@ -413,9 +401,8 @@ void ObjFile<ELFT>::initializeSections(
const Elf_Shdr &Sec = ObjSections[I];
if (Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
- CGProfile = check(
- this->getObj().template getSectionContentsAsArray<Elf_CGProfile>(
- &Sec));
+ CGProfile =
+ check(Obj.template getSectionContentsAsArray<Elf_CGProfile>(&Sec));
// SHF_EXCLUDE'ed sections are discarded by the linker. However,
// if -r is given, we'll let the final link discard such sections.
@@ -440,18 +427,25 @@ void ObjFile<ELFT>::initializeSections(
case SHT_GROUP: {
// De-duplicate section groups by their signatures.
StringRef Signature = getShtGroupSignature(ObjSections, Sec);
- bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
this->Sections[I] = &InputSection::Discarded;
- // We only support GRP_COMDAT type of group. Get the all entries of the
- // section here to let getShtGroupEntries to check the type early for us.
- ArrayRef<Elf_Word> Entries = getShtGroupEntries(Sec);
- // If it is a new section group, we want to keep group members.
- // Group leader sections, which contain indices of group members, are
- // discarded because they are useless beyond this point. The only
- // exception is the -r option because in order to produce re-linkable
- // object files, we want to pass through basically everything.
+ ArrayRef<Elf_Word> Entries =
+ CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
+ if (Entries.empty())
+ fatal(toString(this) + ": empty SHT_GROUP");
+
+ // The first word of a SHT_GROUP section contains flags. Currently,
+ // the standard defines only "GRP_COMDAT" flag for the COMDAT group.
+ // An group with the empty flag doesn't define anything; such sections
+ // are just skipped.
+ if (Entries[0] == 0)
+ continue;
+
+ if (Entries[0] != GRP_COMDAT)
+ fatal(toString(this) + ": unsupported SHT_GROUP format");
+
+ bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
if (IsNew) {
if (Config->Relocatable)
this->Sections[I] = createInputSection(Sec);
@@ -459,7 +453,7 @@ void ObjFile<ELFT>::initializeSections(
}
// Otherwise, discard group members.
- for (uint32_t SecIndex : Entries) {
+ for (uint32_t SecIndex : Entries.slice(1)) {
if (SecIndex >= Size)
fatal(toString(this) +
": invalid section index in group: " + Twine(SecIndex));
@@ -739,7 +733,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// sections. Drop those sections to avoid duplicate symbol errors.
// FIXME: This is glibc PR20543, we should remove this hack once that has been
// fixed for a while.
- if (Name.startswith(".gnu.linkonce."))
+ if (Name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" ||
+ Name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx")
return &InputSection::Discarded;
// If we are creating a new .build-id section, strip existing .build-id
@@ -867,7 +862,7 @@ SharedFile<ELFT>::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
// Partially parse the shared object file so that we can call
// getSoName on this object.
-template <class ELFT> void SharedFile<ELFT>::parseSoName() {
+template <class ELFT> void SharedFile<ELFT>::parseDynamic() {
const Elf_Shdr *DynamicSec = nullptr;
const ELFFile<ELFT> Obj = this->getObj();
ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this);
@@ -904,12 +899,16 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() {
ArrayRef<Elf_Dyn> Arr =
CHECK(Obj.template getSectionContentsAsArray<Elf_Dyn>(DynamicSec), this);
for (const Elf_Dyn &Dyn : Arr) {
- if (Dyn.d_tag == DT_SONAME) {
+ if (Dyn.d_tag == DT_NEEDED) {
+ uint64_t Val = Dyn.getVal();
+ if (Val >= this->StringTable.size())
+ fatal(toString(this) + ": invalid DT_NEEDED entry");
+ DtNeeded.push_back(this->StringTable.data() + Val);
+ } else if (Dyn.d_tag == DT_SONAME) {
uint64_t Val = Dyn.getVal();
if (Val >= this->StringTable.size())
fatal(toString(this) + ": invalid DT_SONAME entry");
SoName = this->StringTable.data() + Val;
- return;
}
}
}
@@ -977,7 +976,7 @@ uint32_t SharedFile<ELFT>::getAlignment(ArrayRef<Elf_Shdr> Sections,
return (Ret > UINT32_MAX) ? 0 : Ret;
}
-// Fully parse the shared object file. This must be called after parseSoName().
+// Fully parse the shared object file. This must be called after parseDynamic().
//
// This function parses symbol versions. If a DSO has version information,
// the file has a ".gnu.version_d" section which contains symbol version
@@ -1081,6 +1080,8 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
case Triple::mips64:
case Triple::mips64el:
return EM_MIPS;
+ case Triple::msp430:
+ return EM_MSP430;
case Triple::ppc:
return EM_PPC;
case Triple::ppc64:
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 5094ddd80..105e5ecbd 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -1,9 +1,8 @@
//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -114,6 +113,17 @@ public:
// True if this is an argument for --just-symbols. Usually false.
bool JustSymbols = false;
+ // On PPC64 we need to keep track of which files contain small code model
+ // relocations that access the .toc section. To minimize the chance of a
+ // relocation overflow, files that do contain said relocations should have
+ // their .toc sections sorted closer to the .got section than files that do
+ // not contain any small code model relocations. Thats because the toc-pointer
+ // is defined to point at .got + 0x8000 and the instructions used with small
+ // code model relocations support immediates in the range [-0x8000, 0x7FFC],
+ // making the addressable range relative to the toc pointer
+ // [.got, .got + 0xFFFC].
+ bool PPC64SmallCodeModelTocRelocs = false;
+
// GroupId is used for --warn-backrefs which is an optional error
// checking feature. All files within the same --{start,end}-group or
// --{start,end}-lib get the same group ID. Otherwise, each file gets a new
@@ -175,7 +185,6 @@ template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
const Elf_Shdr &Sec);
- ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec);
public:
static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
@@ -324,6 +333,7 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
public:
std::vector<const Elf_Verdef *> Verdefs;
+ std::vector<StringRef> DtNeeded;
std::string SoName;
static bool classof(const InputFile *F) {
@@ -332,7 +342,7 @@ public:
SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
- void parseSoName();
+ void parseDynamic();
void parseRest();
uint32_t getAlignment(ArrayRef<Elf_Shdr> Sections, const Elf_Sym &Sym);
std::vector<const Elf_Verdef *> parseVerdefs();
@@ -350,6 +360,9 @@ public:
// data structures in the output file.
std::map<const Elf_Verdef *, NeededVer> VerdefMap;
+ // Used for --no-allow-shlib-undefined.
+ bool AllNeededIsKnown;
+
// Used for --as-needed
bool IsNeeded;
};
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp
index 30a9fc288..e70ea1563 100644
--- a/ELF/InputSection.cpp
+++ b/ELF/InputSection.cpp
@@ -1,9 +1,8 @@
//===- InputSection.cpp ---------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -288,14 +287,17 @@ Defined *InputSectionBase::getEnclosingFunction(uint64_t Offset) {
// Returns a source location string. Used to construct an error message.
template <class ELFT>
std::string InputSectionBase::getLocation(uint64_t Offset) {
+ std::string SecAndOffset = (Name + "+0x" + utohexstr(Offset)).str();
+
// We don't have file for synthetic sections.
if (getFile<ELFT>() == nullptr)
- return (Config->OutputFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")")
+ return (Config->OutputFile + ":(" + SecAndOffset + ")")
.str();
// First check if we can get desired values from debugging information.
if (Optional<DILineInfo> Info = getFile<ELFT>()->getDILineInfo(this, Offset))
- return Info->FileName + ":" + std::to_string(Info->Line);
+ return Info->FileName + ":" + std::to_string(Info->Line) + ":(" +
+ SecAndOffset + ")";
// File->SourceFile contains STT_FILE symbol that contains a
// source file name. If it's missing, we use an object file name.
@@ -304,10 +306,10 @@ std::string InputSectionBase::getLocation(uint64_t Offset) {
SrcFile = toString(File);
if (Defined *D = getEnclosingFunction<ELFT>(Offset))
- return SrcFile + ":(function " + toString(*D) + ")";
+ return SrcFile + ":(function " + toString(*D) + ": " + SecAndOffset + ")";
// If there's no symbol, print out the offset in the section.
- return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str();
+ return (SrcFile + ":(" + SecAndOffset + ")");
}
// This function is intended to be used for constructing an error message.
@@ -575,6 +577,10 @@ static int64_t getTlsTpOffset() {
// Variant 1. The thread pointer points to a TCB with a fixed 2-word size,
// followed by a variable amount of alignment padding, followed by the TLS
// segment.
+ //
+ // NB: While the ARM/AArch64 ABI formally has a 2-word TCB size, lld
+ // effectively increases the TCB size to 8 words for Android compatibility.
+ // It accomplishes this by increasing the segment's alignment.
return alignTo(Config->Wordsize * 2, Out::TlsPhdr->p_align);
case EM_386:
case EM_X86_64:
@@ -605,7 +611,6 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
case R_ARM_SBREL:
return Sym.getVA(A) - getARMStaticBase(Sym);
case R_GOT:
- case R_GOT_PLT:
case R_RELAX_TLS_GD_TO_IE_ABS:
return Sym.getGotVA() + A;
case R_GOTONLY_PC:
@@ -624,7 +629,6 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
return Sym.getGotOffset() + A;
case R_AARCH64_GOT_PAGE_PC:
- case R_AARCH64_GOT_PAGE_PC_PLT:
case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
return getAArch64Page(Sym.getGotVA() + A) - getAArch64Page(P);
case R_GOT_PC:
@@ -674,10 +678,6 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getVA(A);
return getAArch64Page(Val) - getAArch64Page(P);
}
- case R_AARCH64_PLT_PAGE_PC: {
- uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getPltVA() + A;
- return getAArch64Page(Val) - getAArch64Page(P);
- }
case R_RISCV_PC_INDIRECT: {
if (const Relocation *HiRel = getRISCVPCRelHi20(&Sym, A))
return getRelocTargetVA(File, HiRel->Type, HiRel->Addend, Sym.getVA(),
diff --git a/ELF/InputSection.h b/ELF/InputSection.h
index 34f411e87..51c186d5b 100644
--- a/ELF/InputSection.h
+++ b/ELF/InputSection.h
@@ -1,9 +1,8 @@
//===- InputSection.h -------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/LTO.cpp b/ELF/LTO.cpp
index ca4458178..6eecb7932 100644
--- a/ELF/LTO.cpp
+++ b/ELF/LTO.cpp
@@ -1,9 +1,8 @@
//===- LTO.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -13,6 +12,7 @@
#include "LinkerScript.h"
#include "SymbolTable.h"
#include "Symbols.h"
+#include "lld/Common/Args.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/TargetOptionsCommandFlags.h"
#include "llvm/ADT/STLExtras.h"
@@ -68,7 +68,7 @@ static lto::Config createConfig() {
lto::Config C;
// LLD supports the new relocations and address-significance tables.
- C.Options = InitTargetOptionsFromCodeGenFlags();
+ C.Options = initTargetOptionsFromCodeGenFlags();
C.Options.RelaxELFRelocations = true;
C.Options.EmitAddrsig = true;
@@ -83,12 +83,13 @@ static lto::Config createConfig() {
else
C.RelocModel = Reloc::Static;
- C.CodeModel = GetCodeModelFromCMModel();
+ C.CodeModel = getCodeModelFromCMModel();
C.DisableVerify = Config->DisableVerify;
C.DiagHandler = diagnosticHandler;
C.OptLevel = Config->LTOO;
- C.CPU = GetCPUStr();
- C.MAttrs = GetMAttrs();
+ C.CPU = getCPUStr();
+ C.MAttrs = getMAttrs();
+ C.CGOptLevel = args::getCGOptLevel(Config->LTOO);
// Set up a custom pipeline if we've been asked to.
C.OptPipeline = Config->LTONewPmPasses;
diff --git a/ELF/LTO.h b/ELF/LTO.h
index a190da3e5..0f0b5bce7 100644
--- a/ELF/LTO.h
+++ b/ELF/LTO.h
@@ -1,9 +1,8 @@
//===- LTO.h ----------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index fbc025416..2341938a1 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -1,9 +1,8 @@
//===- LinkerScript.cpp ---------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/ELF/LinkerScript.h b/ELF/LinkerScript.h
index 51161981e..b99381003 100644
--- a/ELF/LinkerScript.h
+++ b/ELF/LinkerScript.h
@@ -1,9 +1,8 @@
//===- LinkerScript.h -------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/MapFile.cpp b/ELF/MapFile.cpp
index b0dc62030..cc5b31de5 100644
--- a/ELF/MapFile.cpp
+++ b/ELF/MapFile.cpp
@@ -1,9 +1,8 @@
//===- MapFile.cpp --------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/ELF/MapFile.h b/ELF/MapFile.h
index 028242588..7e7938919 100644
--- a/ELF/MapFile.h
+++ b/ELF/MapFile.h
@@ -1,9 +1,8 @@
//===- MapFile.h ------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/MarkLive.cpp b/ELF/MarkLive.cpp
index 7264e1ca7..e603203db 100644
--- a/ELF/MarkLive.cpp
+++ b/ELF/MarkLive.cpp
@@ -1,9 +1,8 @@
//===- MarkLive.cpp -------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -250,9 +249,10 @@ template <class ELFT> static void doGcSections() {
if (Sec->Flags & SHF_LINK_ORDER)
continue;
- if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec))
+
+ if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec)) {
Enqueue(Sec, 0);
- else if (isValidCIdentifier(Sec->Name)) {
+ } else if (isValidCIdentifier(Sec->Name)) {
CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec);
CNamedSections[Saver.save("__stop_" + Sec->Name)].push_back(Sec);
}
@@ -267,10 +267,16 @@ template <class ELFT> static void doGcSections() {
// input sections. This function make some or all of them on
// so that they are emitted to the output file.
template <class ELFT> void elf::markLive() {
- // If -gc-sections is missing, no sections are removed.
if (!Config->GcSections) {
+ // If -gc-sections is missing, no sections are removed.
for (InputSectionBase *Sec : InputSections)
Sec->Live = true;
+
+ // If a DSO defines a symbol referenced in a regular object, it is needed.
+ for (Symbol *Sym : Symtab->getSymbols())
+ if (auto *S = dyn_cast<SharedSymbol>(Sym))
+ if (S->IsUsedInRegularObj && !S->isWeak())
+ S->getFile<ELFT>().IsNeeded = true;
return;
}
diff --git a/ELF/MarkLive.h b/ELF/MarkLive.h
index c9b99add3..63b5b2669 100644
--- a/ELF/MarkLive.h
+++ b/ELF/MarkLive.h
@@ -1,9 +1,8 @@
//===- MarkLive.h -----------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Options.td b/ELF/Options.td
index e43a21b92..1792d5ec8 100644
--- a/ELF/Options.td
+++ b/ELF/Options.td
@@ -63,6 +63,10 @@ defm allow_multiple_definition: B<"allow-multiple-definition",
"Allow multiple definitions",
"Do not allow multiple definitions (default)">;
+defm allow_shlib_undefined: B<"allow-shlib-undefined",
+ "Allow unresolved references in shared libraries (default when linking a shared library)",
+ "Do not allow unresolved references in shared libraries (default when linking an executable)">;
+
defm apply_dynamic_relocs: B<"apply-dynamic-relocs",
"Apply link-time values for dynamic relocations",
"Do not apply link-time values for dynamic relocations (default)">;
@@ -255,6 +259,9 @@ defm use_android_relr_tags: B<"use-android-relr-tags",
"Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*",
"Use SHT_RELR / DT_RELR* tags (default)">;
+def pic_veneer: F<"pic-veneer">,
+ HelpText<"Always generate position independent thunks (veneers)">;
+
defm pie: B<"pie",
"Create a position independent executable",
"Do not create a position independent executable (default)">;
@@ -489,12 +496,10 @@ def plugin_opt_thinlto: J<"plugin-opt=thinlto">;
def plugin_opt_slash: J<"plugin-opt=/">;
// Options listed below are silently ignored for now for compatibility.
-def: F<"allow-shlib-undefined">;
def: F<"detect-odr-violations">;
def: Flag<["-"], "g">;
def: F<"long-plt">;
def: F<"no-add-needed">;
-def: F<"no-allow-shlib-undefined">;
def: F<"no-copy-dt-needed-entries">;
def: F<"no-ctors-in-init-array">;
def: F<"no-keep-memory">;
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index c1442c078..6c40e45b7 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -1,9 +1,8 @@
//===- OutputSections.cpp -------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/OutputSections.h b/ELF/OutputSections.h
index 113bf6836..2ea7de6e8 100644
--- a/ELF/OutputSections.h
+++ b/ELF/OutputSections.h
@@ -1,9 +1,8 @@
//===- OutputSections.h -----------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Relocations.cpp b/ELF/Relocations.cpp
index c75ae4f82..668db477e 100644
--- a/ELF/Relocations.cpp
+++ b/ELF/Relocations.cpp
@@ -1,9 +1,8 @@
//===- Relocations.cpp ----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -66,6 +65,14 @@ using namespace llvm::support::endian;
using namespace lld;
using namespace lld::elf;
+static Optional<std::string> getLinkerScriptLocation(const Symbol &Sym) {
+ for (BaseCommand *Base : Script->SectionCommands)
+ if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
+ if (Cmd->Sym == &Sym)
+ return Cmd->Location;
+ return None;
+}
+
// Construct a message in the following format.
//
// >>> defined in /home/alice/src/foo.o
@@ -73,8 +80,13 @@ using namespace lld::elf;
// >>> /home/alice/src/bar.o:(.text+0x1)
static std::string getLocation(InputSectionBase &S, const Symbol &Sym,
uint64_t Off) {
- std::string Msg =
- "\n>>> defined in " + toString(Sym.File) + "\n>>> referenced by ";
+ std::string Msg = "\n>>> defined in ";
+ if (Sym.File)
+ Msg += toString(Sym.File);
+ else if (Optional<std::string> Loc = getLinkerScriptLocation(Sym))
+ Msg += *Loc;
+
+ Msg += "\n>>> referenced by ";
std::string Src = S.getSrcMsg(Sym, Off);
if (!Src.empty())
Msg += Src + "\n>>> ";
@@ -193,7 +205,7 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
C.Relocations.push_back(
{Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_LD_TO_LE), Type,
Offset, Addend, &Sym});
- return Target->TlsGdRelaxSkip;
+ return Target->getTlsGdRelaxSkip(Type);
}
if (Expr == R_TLSLD_HINT)
return 1;
@@ -266,7 +278,7 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
{Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type,
Offset, Addend, &Sym});
}
- return Target->TlsGdRelaxSkip;
+ return Target->getTlsGdRelaxSkip(Type);
}
// Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
@@ -324,8 +336,7 @@ static bool isAbsoluteValue(const Symbol &Sym) {
// Returns true if Expr refers a PLT entry.
static bool needsPlt(RelExpr Expr) {
- return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT, R_AARCH64_PLT_PAGE_PC,
- R_GOT_PLT, R_AARCH64_GOT_PAGE_PC_PLT>(Expr);
+ return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT>(Expr);
}
// Returns true if Expr refers a GOT entry. Note that this function
@@ -334,8 +345,7 @@ static bool needsPlt(RelExpr Expr) {
static bool needsGot(RelExpr Expr) {
return isRelExprOneOf<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE,
R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC,
- R_AARCH64_GOT_PAGE_PC_PLT, R_GOT_PC, R_GOT_FROM_END,
- R_GOT_PLT>(Expr);
+ R_GOT_PC, R_GOT_FROM_END>(Expr);
}
// True if this expression is of the form Sym - X, where X is a position in the
@@ -416,14 +426,8 @@ static RelExpr toPlt(RelExpr Expr) {
return R_PPC_CALL_PLT;
case R_PC:
return R_PLT_PC;
- case R_AARCH64_PAGE_PC:
- return R_AARCH64_PLT_PAGE_PC;
- case R_AARCH64_GOT_PAGE_PC:
- return R_AARCH64_GOT_PAGE_PC_PLT;
case R_ABS:
return R_PLT;
- case R_GOT:
- return R_GOT_PLT;
default:
return Expr;
}
@@ -650,6 +654,10 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
Msg += Src + "\n>>> ";
Msg += Sec.getObjMsg(Offset);
+ if (Sym.getName().startswith("_ZTV"))
+ Msg += "\nthe vtable symbol may be undefined because the class is missing "
+ "its key function (see https://lld.llvm.org/missingkeyfunction)";
+
if ((Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) ||
Config->NoinhibitExec) {
warn(Msg);
@@ -751,14 +759,7 @@ static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt,
template <class ELFT> static void addGotEntry(Symbol &Sym) {
In.Got->addEntry(Sym);
- RelExpr Expr;
- if (Sym.isTls())
- Expr = R_TLS;
- else if (Sym.isGnuIFunc())
- Expr = R_PLT;
- else
- Expr = R_ABS;
-
+ RelExpr Expr = Sym.isTls() ? R_TLS : R_ABS;
uint64_t Off = Sym.getGotOffset();
// If a GOT slot value can be calculated at link-time, which is now,
@@ -953,6 +954,15 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
getLocation(Sec, Sym, Offset));
}
+struct IRelativeReloc {
+ RelType Type;
+ InputSectionBase *Sec;
+ uint64_t Offset;
+ Symbol *Sym;
+};
+
+static std::vector<IRelativeReloc> IRelativeRelocs;
+
template <class ELFT, class RelTy>
static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
RelTy *End) {
@@ -984,32 +994,40 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
if (isRelExprOneOf<R_HINT, R_NONE>(Expr))
return;
- // Strenghten or relax relocations.
- //
- // GNU ifunc symbols must be accessed via PLT because their addresses
- // are determined by runtime.
+ // We can separate the small code model relocations into 2 categories:
+ // 1) Those that access the compiler generated .toc sections.
+ // 2) Those that access the linker allocated got entries.
+ // lld allocates got entries to symbols on demand. Since we don't try to sort
+ // the got entries in any way, we don't have to track which objects have
+ // got-based small code model relocs. The .toc sections get placed after the
+ // end of the linker allocated .got section and we do sort those so sections
+ // addressed with small code model relocations come first.
+ if (Config->EMachine == EM_PPC64 && isPPC64SmallCodeModelTocReloc(Type))
+ Sec.File->PPC64SmallCodeModelTocRelocs = true;
+
+ if (Sym.isGnuIFunc() && !Config->ZText && Config->WarnIfuncTextrel) {
+ warn("using ifunc symbols when text relocations are allowed may produce "
+ "a binary that will segfault, if the object file is linked with "
+ "old version of glibc (glibc 2.28 and earlier). If this applies to "
+ "you, consider recompiling the object files without -fPIC and "
+ "without -Wl,-z,notext option. Use -no-warn-ifunc-textrel to "
+ "turn off this warning." +
+ getLocation(Sec, Sym, Offset));
+ }
+
+ // Relax relocations.
//
- // On the other hand, if we know that a PLT entry will be resolved within
- // the same ELF module, we can skip PLT access and directly jump to the
- // destination function. For example, if we are linking a main exectuable,
- // all dynamic symbols that can be resolved within the executable will
- // actually be resolved that way at runtime, because the main exectuable
- // is always at the beginning of a search list. We can leverage that fact.
- if (Sym.isGnuIFunc()) {
- if (!Config->ZText && Config->WarnIfuncTextrel) {
- warn("using ifunc symbols when text relocations are allowed may produce "
- "a binary that will segfault, if the object file is linked with "
- "old version of glibc (glibc 2.28 and earlier). If this applies to "
- "you, consider recompiling the object files without -fPIC and "
- "without -Wl,-z,notext option. Use -no-warn-ifunc-textrel to "
- "turn off this warning." +
- getLocation(Sec, Sym, Offset));
- }
- Expr = toPlt(Expr);
- } else if (!Sym.IsPreemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym)) {
- Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
- } else if (!Sym.IsPreemptible) {
- Expr = fromPlt(Expr);
+ // If we know that a PLT entry will be resolved within the same ELF module, we
+ // can skip PLT access and directly jump to the destination function. For
+ // example, if we are linking a main exectuable, all dynamic symbols that can
+ // be resolved within the executable will actually be resolved that way at
+ // runtime, because the main exectuable is always at the beginning of a search
+ // list. We can leverage that fact.
+ if (!Sym.IsPreemptible && !Sym.isGnuIFunc()) {
+ if (Expr == R_GOT_PC && !isAbsoluteValue(Sym))
+ Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
+ else
+ Expr = fromPlt(Expr);
}
// This relocation does not require got entry, but it is relative to got and
@@ -1029,28 +1047,136 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
return;
}
- // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
- if (needsPlt(Expr) && !Sym.isInPlt()) {
- if (Sym.isGnuIFunc() && !Sym.IsPreemptible)
- addPltEntry<ELFT>(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel,
- Sym);
- else
+ // Non-preemptible ifuncs require special handling. First, handle the usual
+ // case where the symbol isn't one of these.
+ if (!Sym.isGnuIFunc() || Sym.IsPreemptible) {
+ // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
+ if (needsPlt(Expr) && !Sym.isInPlt())
addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
- }
- // Create a GOT slot if a relocation needs GOT.
- if (needsGot(Expr)) {
- if (Config->EMachine == EM_MIPS) {
- // MIPS ABI has special rules to process GOT entries and doesn't
- // require relocation entries for them. A special case is TLS
- // relocations. In that case dynamic loader applies dynamic
- // relocations to initialize TLS GOT entries.
- // See "Global Offset Table" in Chapter 5 in the following document
- // for detailed description:
- // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
- } else if (!Sym.isInGot()) {
- addGotEntry<ELFT>(Sym);
+ // Create a GOT slot if a relocation needs GOT.
+ if (needsGot(Expr)) {
+ if (Config->EMachine == EM_MIPS) {
+ // MIPS ABI has special rules to process GOT entries and doesn't
+ // require relocation entries for them. A special case is TLS
+ // relocations. In that case dynamic loader applies dynamic
+ // relocations to initialize TLS GOT entries.
+ // See "Global Offset Table" in Chapter 5 in the following document
+ // for detailed description:
+ // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+ In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
+ } else if (!Sym.isInGot()) {
+ addGotEntry<ELFT>(Sym);
+ }
+ }
+ } else {
+ // Handle a reference to a non-preemptible ifunc. These are special in a
+ // few ways:
+ //
+ // - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have
+ // a fixed value. But assuming that all references to the ifunc are
+ // GOT-generating or PLT-generating, the handling of an ifunc is
+ // relatively straightforward. We create a PLT entry in Iplt, which is
+ // usually at the end of .plt, which makes an indirect call using a
+ // matching GOT entry in IgotPlt, which is usually at the end of .got.plt.
+ // The GOT entry is relocated using an IRELATIVE relocation in RelaIplt,
+ // which is usually at the end of .rela.plt. Unlike most relocations in
+ // .rela.plt, which may be evaluated lazily without -z now, dynamic
+ // loaders evaluate IRELATIVE relocs eagerly, which means that for
+ // IRELATIVE relocs only, GOT-generating relocations can point directly to
+ // .got.plt without requiring a separate GOT entry.
+ //
+ // - Despite the fact that an ifunc does not have a fixed value, compilers
+ // that are not passed -fPIC will assume that they do, and will emit
+ // direct (non-GOT-generating, non-PLT-generating) relocations to the
+ // symbol. This means that if a direct relocation to the symbol is
+ // seen, the linker must set a value for the symbol, and this value must
+ // be consistent no matter what type of reference is made to the symbol.
+ // This can be done by creating a PLT entry for the symbol in the way
+ // described above and making it canonical, that is, making all references
+ // point to the PLT entry instead of the resolver. In lld we also store
+ // the address of the PLT entry in the dynamic symbol table, which means
+ // that the symbol will also have the same value in other modules.
+ // Because the value loaded from the GOT needs to be consistent with
+ // the value computed using a direct relocation, a non-preemptible ifunc
+ // may end up with two GOT entries, one in .got.plt that points to the
+ // address returned by the resolver and is used only by the PLT entry,
+ // and another in .got that points to the PLT entry and is used by
+ // GOT-generating relocations.
+ //
+ // - The fact that these symbols do not have a fixed value makes them an
+ // exception to the general rule that a statically linked executable does
+ // not require any form of dynamic relocation. To handle these relocations
+ // correctly, the IRELATIVE relocations are stored in an array which a
+ // statically linked executable's startup code must enumerate using the
+ // linker-defined symbols __rela?_iplt_{start,end}.
+ //
+ // - An absolute relocation to a non-preemptible ifunc (such as a global
+ // variable containing a pointer to the ifunc) needs to be relocated in
+ // the exact same way as a GOT entry, so we can avoid needing to make the
+ // PLT entry canonical by translating such relocations into IRELATIVE
+ // relocations in the RelaIplt.
+ if (!Sym.isInPlt()) {
+ // Create PLT and GOTPLT slots for the symbol.
+ Sym.IsInIplt = true;
+
+ // Create a copy of the symbol to use as the target of the IRELATIVE
+ // relocation in the IgotPlt. This is in case we make the PLT canonical
+ // later, which would overwrite the original symbol.
+ //
+ // FIXME: Creating a copy of the symbol here is a bit of a hack. All
+ // that's really needed to create the IRELATIVE is the section and value,
+ // so ideally we should just need to copy those.
+ auto *DirectSym = make<Defined>(cast<Defined>(Sym));
+ addPltEntry<ELFT>(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel,
+ *DirectSym);
+ Sym.PltIndex = DirectSym->PltIndex;
+ }
+ if (Expr == R_ABS && Addend == 0 && (Sec.Flags & SHF_WRITE)) {
+ // We might be able to represent this as an IRELATIVE. But we don't know
+ // yet whether some later relocation will make the symbol point to a
+ // canonical PLT, which would make this either a dynamic RELATIVE (PIC) or
+ // static (non-PIC) relocation. So we keep a record of the information
+ // required to process the relocation, and after scanRelocs() has been
+ // called on all relocations, the relocation is resolved by
+ // addIRelativeRelocs().
+ IRelativeRelocs.push_back({Type, &Sec, Offset, &Sym});
+ return;
+ }
+ if (needsGot(Expr)) {
+ // Redirect GOT accesses to point to the Igot.
+ //
+ // This field is also used to keep track of whether we ever needed a GOT
+ // entry. If we did and we make the PLT canonical later, we'll need to
+ // create a GOT entry pointing to the PLT entry for Sym.
+ Sym.GotInIgot = true;
+ } else if (!needsPlt(Expr)) {
+ // Make the ifunc's PLT entry canonical by changing the value of its
+ // symbol to redirect all references to point to it.
+ unsigned EntryOffset = Sym.PltIndex * Target->PltEntrySize;
+ if (Config->ZRetpolineplt)
+ EntryOffset += Target->PltHeaderSize;
+
+ auto &D = cast<Defined>(Sym);
+ D.Section = In.Iplt;
+ D.Value = EntryOffset;
+ D.Size = 0;
+ // It's important to set the symbol type here so that dynamic loaders
+ // don't try to call the PLT as if it were an ifunc resolver.
+ D.Type = STT_FUNC;
+
+ if (Sym.GotInIgot) {
+ // We previously encountered a GOT generating reference that we
+ // redirected to the Igot. Now that the PLT entry is canonical we must
+ // clear the redirection to the Igot and add a GOT entry. As we've
+ // changed the symbol type to STT_FUNC future GOT generating references
+ // will naturally use this GOT entry.
+ //
+ // We don't need to worry about creating a MIPS GOT here because ifuncs
+ // aren't a thing on MIPS.
+ Sym.GotInIgot = false;
+ addGotEntry<ELFT>(Sym);
+ }
}
}
@@ -1080,6 +1206,21 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {
scanRelocs<ELFT>(S, S.rels<ELFT>());
}
+// Figure out which representation to use for any absolute relocs to
+// non-preemptible ifuncs that we visited during scanRelocs().
+void elf::addIRelativeRelocs() {
+ for (IRelativeReloc &R : IRelativeRelocs) {
+ if (R.Sym->Type == STT_GNU_IFUNC)
+ In.RelaIplt->addReloc(
+ {Target->IRelativeRel, R.Sec, R.Offset, true, R.Sym, 0});
+ else if (Config->Pic)
+ addRelativeReloc(R.Sec, R.Offset, R.Sym, 0, R_ABS, R.Type);
+ else
+ R.Sec->Relocations.push_back({R_ABS, R.Type, R.Offset, 0, R.Sym});
+ }
+ IRelativeRelocs.clear();
+}
+
static bool mergeCmp(const InputSection *A, const InputSection *B) {
// std::merge requires a strict weak ordering.
if (A->OutSecOff < B->OutSecOff)
diff --git a/ELF/Relocations.h b/ELF/Relocations.h
index d00e68bd3..12a731b48 100644
--- a/ELF/Relocations.h
+++ b/ELF/Relocations.h
@@ -1,9 +1,8 @@
//===- Relocations.h -------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -34,19 +33,11 @@ enum RelExpr {
R_ABS,
R_ADDEND,
R_AARCH64_GOT_PAGE_PC,
- // The expression is used for IFUNC support. Describes PC-relative
- // address of the memory page of GOT entry. This entry is used for
- // a redirection to IPLT.
- R_AARCH64_GOT_PAGE_PC_PLT,
R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC,
R_AARCH64_PAGE_PC,
- R_AARCH64_PLT_PAGE_PC,
R_AARCH64_TLSDESC_PAGE,
R_ARM_SBREL,
R_GOT,
- // The expression is used for IFUNC support. Evaluates to GOT entry,
- // containing redirection to the IPLT.
- R_GOT_PLT,
R_GOTONLY_PC,
R_GOTONLY_PC_FROM_END,
R_GOTREL,
@@ -155,6 +146,8 @@ struct RelocationOffsetComparator {
template <class ELFT> void scanRelocations(InputSectionBase &);
+void addIRelativeRelocs();
+
class ThunkSection;
class Thunk;
struct InputSectionDescription;
diff --git a/ELF/ScriptLexer.cpp b/ELF/ScriptLexer.cpp
index 9a372c6d1..cd4873c35 100644
--- a/ELF/ScriptLexer.cpp
+++ b/ELF/ScriptLexer.cpp
@@ -1,9 +1,8 @@
//===- ScriptLexer.cpp ----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/ELF/ScriptLexer.h b/ELF/ScriptLexer.h
index fc6b5b100..19ec3a823 100644
--- a/ELF/ScriptLexer.h
+++ b/ELF/ScriptLexer.h
@@ -1,9 +1,8 @@
//===- ScriptLexer.h --------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/ScriptParser.cpp b/ELF/ScriptParser.cpp
index eee3f0e33..96ab5cc60 100644
--- a/ELF/ScriptParser.cpp
+++ b/ELF/ScriptParser.cpp
@@ -1,9 +1,8 @@
//===- ScriptParser.cpp ---------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -94,7 +93,6 @@ private:
SortSectionPolicy readSortKind();
SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
SymbolAssignment *readAssignment(StringRef Tok);
- std::tuple<ELFKind, uint16_t, bool> readBfdName();
void readSort();
Expr readAssert();
Expr readConstant();
@@ -331,7 +329,7 @@ void ScriptParser::readEntry() {
void ScriptParser::readExtern() {
expect("(");
while (!errorCount() && !consume(")"))
- Config->Undefined.push_back(next());
+ Config->Undefined.push_back(unquote(next()));
}
void ScriptParser::readGroup() {
@@ -385,39 +383,25 @@ void ScriptParser::readOutputArch() {
skip();
}
-std::tuple<ELFKind, uint16_t, bool> ScriptParser::readBfdName() {
- StringRef S = unquote(next());
- if (S == "elf32-i386")
- return std::make_tuple(ELF32LEKind, EM_386, false);
- if (S == "elf32-iamcu")
- return std::make_tuple(ELF32LEKind, EM_IAMCU, false);
- if (S == "elf32-littlearm")
- return std::make_tuple(ELF32LEKind, EM_ARM, false);
- if (S == "elf32-x86-64")
- return std::make_tuple(ELF32LEKind, EM_X86_64, false);
- if (S == "elf64-littleaarch64")
- return std::make_tuple(ELF64LEKind, EM_AARCH64, false);
- if (S == "elf64-powerpc")
- return std::make_tuple(ELF64BEKind, EM_PPC64, false);
- if (S == "elf64-powerpcle")
- return std::make_tuple(ELF64LEKind, EM_PPC64, false);
- if (S == "elf64-x86-64")
- return std::make_tuple(ELF64LEKind, EM_X86_64, false);
- if (S == "elf32-tradbigmips")
- return std::make_tuple(ELF32BEKind, EM_MIPS, false);
- if (S == "elf32-ntradbigmips")
- return std::make_tuple(ELF32BEKind, EM_MIPS, true);
- if (S == "elf32-tradlittlemips")
- return std::make_tuple(ELF32LEKind, EM_MIPS, false);
- if (S == "elf32-ntradlittlemips")
- return std::make_tuple(ELF32LEKind, EM_MIPS, true);
- if (S == "elf64-tradbigmips")
- return std::make_tuple(ELF64BEKind, EM_MIPS, false);
- if (S == "elf64-tradlittlemips")
- return std::make_tuple(ELF64LEKind, EM_MIPS, false);
-
- setError("unknown output format name: " + S);
- return std::make_tuple(ELFNoneKind, EM_NONE, false);
+static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
+ return StringSwitch<std::pair<ELFKind, uint16_t>>(S)
+ .Case("elf32-i386", {ELF32LEKind, EM_386})
+ .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
+ .Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
+ .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})
+ .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})
+ .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS})
+ .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
+ .Default({ELFNoneKind, EM_NONE});
}
// Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little).
@@ -425,9 +409,16 @@ std::tuple<ELFKind, uint16_t, bool> ScriptParser::readBfdName() {
void ScriptParser::readOutputFormat() {
expect("(");
- std::tuple<ELFKind, uint16_t, bool> BfdTuple = readBfdName();
- if (Config->EKind == ELFNoneKind)
- std::tie(Config->EKind, Config->EMachine, Config->MipsN32Abi) = BfdTuple;
+ StringRef Name = unquote(next());
+ StringRef S = Name;
+ if (S.consume_back("-freebsd"))
+ Config->OSABI = ELFOSABI_FREEBSD;
+
+ std::tie(Config->EKind, Config->EMachine) = parseBfdName(S);
+ if (Config->EMachine == EM_NONE)
+ setError("unknown output format name: " + Name);
+ if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips")
+ Config->MipsN32Abi = true;
if (consume(")"))
return;
diff --git a/ELF/ScriptParser.h b/ELF/ScriptParser.h
index d48d5aa21..bc578ac70 100644
--- a/ELF/ScriptParser.h
+++ b/ELF/ScriptParser.h
@@ -1,9 +1,8 @@
//===- ScriptParser.h -------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index e372461ee..e25682f80 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -1,9 +1,8 @@
//===- SymbolTable.cpp ----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -93,9 +92,21 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) {
// .so file
if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
// DSOs are uniquified not by filename but by soname.
- F->parseSoName();
- if (errorCount() || !SoNames.insert(F->SoName).second)
+ F->parseDynamic();
+ if (errorCount())
+ return;
+
+ // If a DSO appears more than once on the command line with and without
+ // --as-needed, --no-as-needed takes precedence over --as-needed because a
+ // user can add an extra DSO with --no-as-needed to force it to be added to
+ // the dependency list.
+ DenseMap<StringRef, InputFile *>::iterator It;
+ bool WasInserted;
+ std::tie(It, WasInserted) = SoNames.try_emplace(F->SoName, F);
+ cast<SharedFile<ELFT>>(It->second)->IsNeeded |= F->IsNeeded;
+ if (!WasInserted)
return;
+
SharedFiles.push_back(F);
F->parseRest();
return;
@@ -251,10 +262,6 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK))
S->Binding = Binding;
- if (!Config->GcSections && Binding != STB_WEAK)
- if (auto *SS = dyn_cast<SharedSymbol>(S))
- SS->getFile<ELFT>().IsNeeded = true;
-
if (S->isLazy()) {
// An undefined weak will not fetch archive members. See comment on Lazy in
// Symbols.h for the details.
@@ -319,7 +326,7 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
// We don't report backward references to weak symbols as they can be
// overridden later.
- if (Backref && S->Binding != STB_WEAK)
+ if (Backref && !S->isWeak())
warn("backward reference detected: " + Name + " in " + toString(File) +
" refers to " + toString(S->File));
}
@@ -494,19 +501,16 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
// An undefined symbol with non default visibility must be satisfied
// in the same DSO.
- if (WasInserted ||
- ((S->isUndefined() || S->isLazy()) && S->Visibility == STV_DEFAULT)) {
- uint8_t Binding = S->Binding;
- bool WasUndefined = S->isUndefined();
- replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
+ auto Replace = [&](uint8_t Binding) {
+ replaceSymbol<SharedSymbol>(S, File, Name, Binding, Sym.st_other,
Sym.getType(), Sym.st_value, Sym.st_size,
Alignment, VerdefIndex);
- if (!WasInserted) {
- S->Binding = Binding;
- if (!S->isWeak() && !Config->GcSections && WasUndefined)
- File.IsNeeded = true;
- }
- }
+ };
+
+ if (WasInserted)
+ Replace(Sym.getBinding());
+ else if (S->Visibility == STV_DEFAULT && (S->isUndefined() || S->isLazy()))
+ Replace(S->Binding);
}
Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
diff --git a/ELF/SymbolTable.h b/ELF/SymbolTable.h
index b5fd8d3b4..9822ed75c 100644
--- a/ELF/SymbolTable.h
+++ b/ELF/SymbolTable.h
@@ -1,9 +1,8 @@
//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -80,6 +79,9 @@ public:
void handleDynamicList();
+ // Set of .so files to not link the same shared object file more than once.
+ llvm::DenseMap<StringRef, InputFile *> SoNames;
+
private:
std::pair<Symbol *, bool> insertName(StringRef Name);
@@ -107,9 +109,6 @@ private:
// is used to uniquify them.
llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
- // Set of .so files to not link the same shared object file more than once.
- llvm::DenseSet<StringRef> SoNames;
-
// A map from demangled symbol names to their symbol objects.
// This mapping is 1:N because two symbols with different versions
// can have the same name. We use this map to handle "extern C++ {}"
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp
index da7fdb5dc..96e23b9d2 100644
--- a/ELF/Symbols.cpp
+++ b/ELF/Symbols.cpp
@@ -1,9 +1,8 @@
//===- Symbols.cpp --------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -38,6 +37,7 @@ Defined *ElfSym::GlobalOffsetTable;
Defined *ElfSym::MipsGp;
Defined *ElfSym::MipsGpDisp;
Defined *ElfSym::MipsLocalGp;
+Defined *ElfSym::RelaIpltStart;
Defined *ElfSym::RelaIpltEnd;
static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
@@ -120,20 +120,24 @@ uint64_t Symbol::getVA(int64_t Addend) const {
return OutVA + Addend;
}
-uint64_t Symbol::getGotVA() const { return In.Got->getVA() + getGotOffset(); }
+uint64_t Symbol::getGotVA() const {
+ if (GotInIgot)
+ return In.IgotPlt->getVA() + getGotPltOffset();
+ return In.Got->getVA() + getGotOffset();
+}
uint64_t Symbol::getGotOffset() const {
return GotIndex * Target->GotEntrySize;
}
uint64_t Symbol::getGotPltVA() const {
- if (this->IsInIgot)
+ if (IsInIplt)
return In.IgotPlt->getVA() + getGotPltOffset();
return In.GotPlt->getVA() + getGotPltOffset();
}
uint64_t Symbol::getGotPltOffset() const {
- if (IsInIgot)
+ if (IsInIplt)
return PltIndex * Target->GotPltEntrySize;
return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize;
}
diff --git a/ELF/Symbols.h b/ELF/Symbols.h
index 803cb80dd..fc48b09ba 100644
--- a/ELF/Symbols.h
+++ b/ELF/Symbols.h
@@ -1,9 +1,8 @@
//===- Symbols.h ------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -182,7 +181,7 @@ protected:
uint8_t StOther, uint8_t Type)
: File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
- IsInIplt(false), IsInIgot(false), IsPreemptible(false),
+ IsInIplt(false), GotInIgot(false), IsPreemptible(false),
Used(!Config->GcSections), NeedsTocRestore(false),
ScriptDefined(false) {}
@@ -191,11 +190,13 @@ public:
// For SharedSymbol only.
unsigned NeedsPltAddr : 1;
- // True if this symbol is in the Iplt sub-section of the Plt.
+ // True if this symbol is in the Iplt sub-section of the Plt and the Igot
+ // sub-section of the .got.plt or .got.
unsigned IsInIplt : 1;
- // True if this symbol is in the Igot sub-section of the .got.plt or .got.
- unsigned IsInIgot : 1;
+ // True if this symbol needs a GOT entry and its GOT entry is actually in
+ // Igot. This will be true only for certain non-preemptible ifuncs.
+ unsigned GotInIgot : 1;
// True if this symbol is preemptible at load time.
unsigned IsPreemptible : 1;
@@ -352,7 +353,8 @@ struct ElfSym {
static Defined *MipsGpDisp;
static Defined *MipsLocalGp;
- // __rela_iplt_end or __rel_iplt_end
+ // __rel{,a}_iplt_{start,end} symbols.
+ static Defined *RelaIpltStart;
static Defined *RelaIpltEnd;
};
diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp
index 293d8452c..e0d418ab9 100644
--- a/ELF/SyntheticSections.cpp
+++ b/ELF/SyntheticSections.cpp
@@ -1,9 +1,8 @@
//===- SyntheticSections.cpp ----------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -15,7 +14,6 @@
//===----------------------------------------------------------------------===//
#include "SyntheticSections.h"
-#include "Bits.h"
#include "Config.h"
#include "InputFiles.h"
#include "LinkerScript.h"
@@ -59,6 +57,17 @@ using llvm::support::endian::write64le;
constexpr size_t MergeNoTailSection::NumShards;
+static uint64_t readUint(uint8_t *Buf) {
+ return Config->Is64 ? read64(Buf) : read32(Buf);
+}
+
+static void writeUint(uint8_t *Buf, uint64_t Val) {
+ if (Config->Is64)
+ write64(Buf, Val);
+ else
+ write32(Buf, Val);
+}
+
// Returns an LLD version string.
static ArrayRef<uint8_t> getVersion() {
// Check LLD_VERSION first for ease of testing.
@@ -1133,7 +1142,6 @@ IgotPltSection::IgotPltSection()
Target->GotPltEntrySize, getIgotPltName()) {}
void IgotPltSection::addEntry(Symbol &Sym) {
- Sym.IsInIgot = true;
assert(Sym.PltIndex == Entries.size());
Entries.push_back(&Sym);
}
@@ -1296,6 +1304,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
}
if (!Config->ZText)
DtFlags |= DF_TEXTREL;
+ if (Config->HasStaticTlsModel)
+ DtFlags |= DF_STATIC_TLS;
if (DtFlags)
addInt(DT_FLAGS, DtFlags);
@@ -1513,8 +1523,10 @@ void RelocationBaseSection::finalizeContents() {
else
getParent()->Link = 0;
- if (In.RelaIplt == this || In.RelaPlt == this)
+ if (In.RelaPlt == this)
getParent()->Info = In.GotPlt->getParent()->SectionIndex;
+ if (In.RelaIplt == this)
+ getParent()->Info = In.IgotPlt->getParent()->SectionIndex;
}
RelrBaseSection::RelrBaseSection()
@@ -1803,7 +1815,7 @@ template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
std::vector<uint64_t> Offsets;
for (const RelativeReloc &Rel : Relocs)
Offsets.push_back(Rel.getOffset());
- llvm::sort(Offsets.begin(), Offsets.end());
+ llvm::sort(Offsets);
// For each leading relocation, find following ones that can be folded
// as a bitmap and fold them.
@@ -2176,6 +2188,8 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) {
void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) {
unsigned C = Config->Is64 ? 64 : 32;
for (const Entry &Sym : Symbols) {
+ // When C = 64, we choose a word with bits [6:...] and set 1 to two bits in
+ // the word using bits [0:5] and [26:31].
size_t I = (Sym.Hash / C) & (MaskWords - 1);
uint64_t Val = readUint(Buf + I * Config->Wordsize);
Val |= uint64_t(1) << (Sym.Hash % C);
@@ -2329,10 +2343,8 @@ void PltSection::writeTo(uint8_t *Buf) {
template <class ELFT> void PltSection::addEntry(Symbol &Sym) {
Sym.PltIndex = Entries.size();
RelocationBaseSection *PltRelocSection = In.RelaPlt;
- if (IsIplt) {
+ if (IsIplt)
PltRelocSection = In.RelaIplt;
- Sym.IsInIplt = true;
- }
unsigned RelOff =
static_cast<RelocationSection<ELFT> *>(PltRelocSection)->getRelocOffset();
Entries.push_back(std::make_pair(&Sym, RelOff));
@@ -2412,11 +2424,14 @@ readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {
uint32_t CuIdx = 0;
for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units()) {
- DWARFAddressRangesVector Ranges;
- Cu->collectAddressRanges(Ranges);
+ Expected<DWARFAddressRangesVector> Ranges = Cu->collectAddressRanges();
+ if (!Ranges) {
+ error(toString(Sec) + ": " + toString(Ranges.takeError()));
+ return {};
+ }
ArrayRef<InputSectionBase *> Sections = Sec->File->getSections();
- for (DWARFAddressRange &R : Ranges) {
+ for (DWARFAddressRange &R : *Ranges) {
InputSectionBase *S = Sections[R.SectionIndex];
if (!S || S == &InputSection::Discarded || !S->Live)
continue;
@@ -2429,6 +2444,7 @@ readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {
}
++CuIdx;
}
+
return Ret;
}
diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h
index 63d7897e1..90e1e12d9 100644
--- a/ELF/SyntheticSections.h
+++ b/ELF/SyntheticSections.h
@@ -1,9 +1,8 @@
//===- SyntheticSection.h ---------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -317,8 +316,9 @@ private:
size_t StartIndex = 0;
struct PageBlock {
- size_t FirstIndex = 0;
- size_t Count = 0;
+ size_t FirstIndex;
+ size_t Count;
+ PageBlock() : FirstIndex(0), Count(0) {}
};
// Map output sections referenced by MIPS GOT relocations
@@ -619,7 +619,8 @@ public:
void addSymbols(std::vector<SymbolTableEntry> &Symbols);
private:
- enum { Shift2 = 6 };
+ // See the comment in writeBloomFilter.
+ enum { Shift2 = 26 };
void writeBloomFilter(uint8_t *Buf);
void writeHashTable(uint8_t *Buf);
diff --git a/ELF/Target.cpp b/ELF/Target.cpp
index a6293548a..f902d678a 100644
--- a/ELF/Target.cpp
+++ b/ELF/Target.cpp
@@ -1,9 +1,8 @@
//===- Target.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -75,6 +74,8 @@ TargetInfo *elf::getTarget() {
default:
llvm_unreachable("unsupported MIPS target");
}
+ case EM_MSP430:
+ return getMSP430TargetInfo();
case EM_PPC:
return getPPCTargetInfo();
case EM_PPC64:
diff --git a/ELF/Target.h b/ELF/Target.h
index e7a31e763..c7d29b63b 100644
--- a/ELF/Target.h
+++ b/ELF/Target.h
@@ -1,9 +1,8 @@
//===- Target.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -33,6 +32,7 @@ public:
virtual void writeGotPlt(uint8_t *Buf, const Symbol &S) const {};
virtual void writeIgotPlt(uint8_t *Buf, const Symbol &S) const;
virtual int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const;
+ virtual int getTlsGdRelaxSkip(RelType Type) const { return 1; }
// If lazy binding is supported, the first entry of the PLT has code
// to call the dynamic linker to resolve PLT entries the first time
@@ -81,7 +81,6 @@ public:
virtual ~TargetInfo();
- unsigned TlsGdRelaxSkip = 1;
unsigned PageSize = 4096;
unsigned DefaultMaxPageSize = 4096;
@@ -146,6 +145,7 @@ TargetInfo *getAMDGPUTargetInfo();
TargetInfo *getARMTargetInfo();
TargetInfo *getAVRTargetInfo();
TargetInfo *getHexagonTargetInfo();
+TargetInfo *getMSP430TargetInfo();
TargetInfo *getPPC64TargetInfo();
TargetInfo *getPPCTargetInfo();
TargetInfo *getRISCVTargetInfo();
@@ -176,6 +176,10 @@ static inline std::string getErrorLocation(const uint8_t *Loc) {
// to the local entry-point.
unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther);
+// Returns true if a relocation is a small code model relocation that accesses
+// the .toc section.
+bool isPPC64SmallCodeModelTocReloc(RelType Type);
+
uint64_t getPPC64TocBase();
uint64_t getAArch64Page(uint64_t Expr);
diff --git a/ELF/Thunks.cpp b/ELF/Thunks.cpp
index 5486f23d8..d7150d4a2 100644
--- a/ELF/Thunks.cpp
+++ b/ELF/Thunks.cpp
@@ -1,9 +1,8 @@
//===- Thunks.cpp --------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
//
@@ -484,7 +483,7 @@ void ARMV7PILongThunk::writeLong(uint8_t *Buf) {
};
uint64_t S = getARMThunkDestVA(Destination);
uint64_t P = getThunkTargetSym()->getVA();
- uint64_t Offset = S - P - 16;
+ int64_t Offset = S - P - 16;
memcpy(Buf, Data, sizeof(Data));
Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset);
Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, Offset);
@@ -505,7 +504,7 @@ void ThumbV7PILongThunk::writeLong(uint8_t *Buf) {
};
uint64_t S = getARMThunkDestVA(Destination);
uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
- uint64_t Offset = S - P - 12;
+ int64_t Offset = S - P - 12;
memcpy(Buf, Data, sizeof(Data));
Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset);
Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, Offset);
@@ -722,7 +721,7 @@ Thunk::~Thunk() = default;
static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
fatal("unrecognized relocation type");
- if (Config->Pic)
+ if (Config->PicThunk)
return make<AArch64ADRPThunk>(S);
return make<AArch64ABSLongThunk>(S);
}
@@ -739,7 +738,7 @@ static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
case R_ARM_JUMP24:
case R_ARM_CALL:
case R_ARM_THM_CALL:
- if (Config->Pic)
+ if (Config->PicThunk)
return make<ARMV5PILongThunk>(S);
return make<ARMV5ABSLongThunk>(S);
}
@@ -794,13 +793,13 @@ static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
case R_ARM_PLT32:
case R_ARM_JUMP24:
case R_ARM_CALL:
- if (Config->Pic)
+ if (Config->PicThunk)
return make<ARMV7PILongThunk>(S);
return make<ARMV7ABSLongThunk>(S);
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
- if (Config->Pic)
+ if (Config->PicThunk)
return make<ThumbV7PILongThunk>(S);
return make<ThumbV7ABSLongThunk>(S);
}
@@ -820,7 +819,7 @@ static Thunk *addThunkPPC64(RelType Type, Symbol &S) {
if (S.isInPlt())
return make<PPC64PltCallStub>(S);
- if (Config->Pic)
+ if (Config->PicThunk)
return make<PPC64PILongBranchThunk>(S);
return make<PPC64PDLongBranchThunk>(S);
diff --git a/ELF/Thunks.h b/ELF/Thunks.h
index ed82b4d94..aa37227c7 100644
--- a/ELF/Thunks.h
+++ b/ELF/Thunks.h
@@ -1,9 +1,8 @@
//===- Thunks.h --------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 37a53a1e7..42c1c0bac 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -1,9 +1,8 @@
//===- Writer.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -910,12 +909,18 @@ void PhdrEntry::add(OutputSection *Sec) {
template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
if (Config->Relocatable || needsInterpSection())
return;
- StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start";
- addOptionalRegular(S, In.RelaIplt, 0, STV_HIDDEN, STB_WEAK);
- S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end";
- ElfSym::RelaIpltEnd =
- addOptionalRegular(S, In.RelaIplt, 0, STV_HIDDEN, STB_WEAK);
+ // By default, __rela_iplt_{start,end} belong to a dummy section 0
+ // because .rela.plt might be empty and thus removed from output.
+ // We'll override Out::ElfHeader with In.RelaIplt later when we are
+ // sure that .rela.plt exists in output.
+ ElfSym::RelaIpltStart = addOptionalRegular(
+ Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start",
+ Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
+
+ ElfSym::RelaIpltEnd = addOptionalRegular(
+ Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end",
+ Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
}
template <class ELFT>
@@ -949,8 +954,12 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
ElfSym::GlobalOffsetTable->Section = GotSection;
}
- if (ElfSym::RelaIpltEnd)
+ // .rela_iplt_{start,end} mark the start and the end of .rela.plt section.
+ if (ElfSym::RelaIpltStart && !In.RelaIplt->empty()) {
+ ElfSym::RelaIpltStart->Section = In.RelaIplt;
+ ElfSym::RelaIpltEnd->Section = In.RelaIplt;
ElfSym::RelaIpltEnd->Value = In.RelaIplt->getSize();
+ }
PhdrEntry *Last = nullptr;
PhdrEntry *LastRO = nullptr;
@@ -1241,6 +1250,24 @@ static void sortSection(OutputSection *Sec,
if (Name == ".init" || Name == ".fini")
return;
+ // .toc is allocated just after .got and is accessed using GOT-relative
+ // relocations. Object files compiled with small code model have an
+ // addressable range of [.got, .got + 0xFFFC] for GOT-relative relocations.
+ // To reduce the risk of relocation overflow, .toc contents are sorted so that
+ // sections having smaller relocation offsets are at beginning of .toc
+ if (Config->EMachine == EM_PPC64 && Name == ".toc") {
+ if (Script->HasSectionsCommand)
+ return;
+ assert(Sec->SectionCommands.size() == 1);
+ auto *ISD = cast<InputSectionDescription>(Sec->SectionCommands[0]);
+ std::stable_sort(ISD->Sections.begin(), ISD->Sections.end(),
+ [](const InputSection *A, const InputSection *B) -> bool {
+ return A->File->PPC64SmallCodeModelTocRelocs &&
+ !B->File->PPC64SmallCodeModelTocRelocs;
+ });
+ return;
+ }
+
// Sort input sections by priority using the list provided
// by --symbol-ordering-file.
if (!Order.empty())
@@ -1650,11 +1677,34 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (!Config->Relocatable)
forEachRelSec(scanRelocations<ELFT>);
+ addIRelativeRelocs();
+
if (In.Plt && !In.Plt->empty())
In.Plt->addSymbols();
if (In.Iplt && !In.Iplt->empty())
In.Iplt->addSymbols();
+ if (!Config->AllowShlibUndefined) {
+ // Error on undefined symbols in a shared object, if all of its DT_NEEDED
+ // entires are seen. These cases would otherwise lead to runtime errors
+ // reported by the dynamic linker.
+ //
+ // ld.bfd traces all DT_NEEDED to emulate the logic of the dynamic linker to
+ // catch more cases. That is too much for us. Our approach resembles the one
+ // used in ld.gold, achieves a good balance to be useful but not too smart.
+ for (InputFile *File : SharedFiles) {
+ SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
+ F->AllNeededIsKnown = llvm::all_of(F->DtNeeded, [&](StringRef Needed) {
+ return Symtab->SoNames.count(Needed);
+ });
+ }
+ for (Symbol *Sym : Symtab->getSymbols())
+ if (Sym->isUndefined() && !Sym->isWeak())
+ if (auto *F = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
+ if (F->AllNeededIsKnown)
+ error(toString(F) + ": undefined reference to " + toString(*Sym));
+ }
+
// Now that we have defined all possible global symbols including linker-
// synthesized ones. Visit all symbols to give the finishing touches.
for (Symbol *Sym : Symtab->getSymbols()) {
@@ -2181,11 +2231,23 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {
P->p_memsz = alignTo(P->p_memsz, Target->PageSize);
}
- // The TLS pointer goes after PT_TLS for variant 2 targets. At least glibc
- // will align it, so round up the size to make sure the offsets are
- // correct.
- if (P->p_type == PT_TLS && P->p_memsz)
+ if (P->p_type == PT_TLS && P->p_memsz) {
+ if (!Config->Shared &&
+ (Config->EMachine == EM_ARM || Config->EMachine == EM_AARCH64)) {
+ // On ARM/AArch64, reserve extra space (8 words) between the thread
+ // pointer and an executable's TLS segment by overaligning the segment.
+ // This reservation is needed for backwards compatibility with Android's
+ // TCB, which allocates several slots after the thread pointer (e.g.
+ // TLS_SLOT_STACK_GUARD==5). For simplicity, this overalignment is also
+ // done on other operating systems.
+ P->p_align = std::max<uint64_t>(P->p_align, Config->Wordsize * 8);
+ }
+
+ // The TLS pointer goes after PT_TLS for variant 2 targets. At least glibc
+ // will align it, so round up the size to make sure the offsets are
+ // correct.
P->p_memsz = alignTo(P->p_memsz, P->p_align);
+ }
}
}
diff --git a/ELF/Writer.h b/ELF/Writer.h
index 7806f824c..2ff99e6c5 100644
--- a/ELF/Writer.h
+++ b/ELF/Writer.h
@@ -1,9 +1,8 @@
//===- Writer.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/LICENSE.TXT b/LICENSE.TXT
index e05e18457..cba22f66a 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -1,10 +1,245 @@
==============================================================================
-lld License
+The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+==============================================================================
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
+==============================================================================
+Software from third parties included in the LLVM Project:
+==============================================================================
+The LLVM Project contains third party software which is under different license
+terms. All such code will be identified clearly using at least one of two
+mechanisms:
+1) It will be in a separate directory tree with its own `LICENSE.txt` or
+ `LICENSE` file at the top containing the specific license and restrictions
+ which apply to that software, or
+2) It will contain specific license and restriction terms at the top of every
+ file.
+
+==============================================================================
+Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
==============================================================================
University of Illinois/NCSA
Open Source License
-Copyright (c) 2011-2018 by the contributors listed in CREDITS.TXT
+Copyright (c) 2011-2019 by the contributors listed in CREDITS.TXT
All rights reserved.
Developed by:
@@ -41,22 +276,3 @@ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
-
-==============================================================================
-The lld software contains code written by third parties. Such software will
-have its own individual LICENSE.TXT file in the directory in which it appears.
-This file will describe the copyrights, license, and restrictions which apply
-to that code.
-
-The disclaimer of warranty in the University of Illinois Open Source License
-applies to all code in the lld Distribution, and nothing in any of the
-other licenses gives permission to use the names of the LLVM Team or the
-University of Illinois to endorse or promote products derived from this
-Software.
-
-The following pieces of software have additional or alternate copyrights,
-licenses, and/or restrictions:
-
-Program Directory
-------- ---------
-<none yet>
diff --git a/MinGW/Driver.cpp b/MinGW/Driver.cpp
index d682baf59..920afd1d6 100644
--- a/MinGW/Driver.cpp
+++ b/MinGW/Driver.cpp
@@ -1,14 +1,31 @@
//===- MinGW/Driver.cpp ---------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-///
-/// GNU ld style linker driver for COFF currently supporting mingw-w64.
-///
+//
+// MinGW is a GNU development environment for Windows. It consists of GNU
+// tools such as GCC and GNU ld. Unlike Cygwin, there's no POSIX-compatible
+// layer, as it aims to be a native development toolchain.
+//
+// lld/MinGW is a drop-in replacement for GNU ld/MinGW.
+//
+// Being a native development tool, a MinGW linker is not very different from
+// Microsoft link.exe, so a MinGW linker can be implemented as a thin wrapper
+// for lld/COFF. This driver takes Unix-ish command line options, translates
+// them to Windows-ish ones, and then passes them to lld/COFF.
+//
+// When this driver calls the lld/COFF driver, it passes a hidden option
+// "-lldmingw" along with other user-supplied options, to run the lld/COFF
+// linker in "MinGW mode".
+//
+// There are subtle differences between MS link.exe and GNU ld/MinGW, and GNU
+// ld/MinGW implements a few GNU-specific features. Such features are directly
+// implemented in lld/COFF and enabled only when the linker is running in MinGW
+// mode.
+//
//===----------------------------------------------------------------------===//
#include "lld/Common/Driver.h"
@@ -170,6 +187,9 @@ bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) {
Args.getLastArgValue(OPT_m) != "arm64pe" && !Args.hasArg(OPT_dynamicbase))
Add("-dynamicbase:no");
+ if (Args.hasFlag(OPT_no_insert_timestamp, OPT_insert_timestamp, false))
+ Add("-timestamp:0");
+
if (Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false))
Add("-opt:ref");
else
diff --git a/MinGW/Options.td b/MinGW/Options.td
index 948faa687..1eee1caf3 100644
--- a/MinGW/Options.td
+++ b/MinGW/Options.td
@@ -6,6 +6,8 @@ class S<string name>: Separate<["--", "-"], name>;
def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
HelpText<"Add a directory to the library search path">;
+def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">;
+def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">;
def dynamicbase: F<"dynamicbase">, HelpText<"Enable ASLR">;
def entry: S<"entry">, MetaVarName<"<entry>">,
HelpText<"Name of entry point symbol">;
@@ -14,12 +16,16 @@ def export_all_symbols: F<"export-all-symbols">,
def gc_sections: F<"gc-sections">, HelpText<"Remove unused sections">;
def icf: J<"icf=">, HelpText<"Identical code folding">;
def image_base: S<"image-base">, HelpText<"Base address of the program">;
+def insert_timestamp: F<"insert-timestamp">,
+ HelpText<"Include PE header timestamp">;
def kill_at: F<"kill-at">, HelpText<"Remove @n from exported symbols">;
def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">,
HelpText<"Root name of library to use">;
def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">;
def map: S<"Map">, HelpText<"Output a linker map">;
def map_eq: J<"Map=">, Alias<map>;
+def no_insert_timestamp: F<"no-insert-timestamp">,
+ HelpText<"Don't include PE header timestamp">;
def no_whole_archive: F<"no-whole-archive">,
HelpText<"No longer include all object files for following archives">;
def large_address_aware: Flag<["--"], "large-address-aware">,
@@ -52,29 +58,31 @@ def pdb: S<"pdb">, HelpText<"Specify output PDB debug information file">;
def Xlink : J<"Xlink=">, MetaVarName<"<arg>">,
HelpText<"Pass <arg> to the COFF linker">;
-// Currently stubs to avoid errors
-def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">;
-def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">;
-def O: Joined<["-"], "O">, HelpText<"Optimize output file size">;
-def build_id: F<"build-id">;
-def disable_auto_image_base: F<"disable-auto-image-base">;
-def enable_auto_image_base: F<"enable-auto-image-base">;
-def enable_auto_import: F<"enable-auto-import">;
-def end_group: F<"end-group">;
-def full_shutdown: Flag<["--"], "full-shutdown">;
-def high_entropy_va: F<"high-entropy-va">, HelpText<"Enable 64-bit ASLR">;
-def major_image_version: S<"major-image-version">;
-def minor_image_version: S<"minor-image-version">;
-def no_seh: F<"no-seh">;
-def nxcompat: F<"nxcompat">, HelpText<"Enable data execution prevention">;
-def pic_executable: F<"pic-executable">;
-def sysroot: J<"sysroot">, HelpText<"Sysroot">;
-def start_group: F<"start-group">;
-def tsaware: F<"tsaware">, HelpText<"Create Terminal Server aware executable">;
-def v: Flag<["-"], "v">, HelpText<"Display the version number">;
-def version: F<"version">, HelpText<"Display the version number and exit">;
-
// Alias
def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
def alias_strip_s: Flag<["-"], "s">, Alias<strip_all>;
def alias_strip_S: Flag<["-"], "S">, Alias<strip_debug>;
+
+// Ignored options
+def: Joined<["-"], "O">;
+def: F<"build-id">;
+def: F<"disable-auto-image-base">;
+def: F<"enable-auto-image-base">;
+def: F<"enable-auto-import">;
+def: F<"end-group">;
+def: Flag<["--"], "full-shutdown">;
+def: F<"high-entropy-va">;
+def: S<"major-image-version">;
+def: S<"minor-image-version">;
+def: F<"no-seh">;
+def: F<"nxcompat">;
+def: F<"pic-executable">;
+def: S<"plugin">;
+def: J<"plugin=">;
+def: S<"plugin-opt">;
+def: J<"plugin-opt=">;
+def: J<"sysroot">;
+def: F<"start-group">;
+def: F<"tsaware">;
+def: Flag<["-"], "v">;
+def: F<"version">;
diff --git a/docs/NewLLD.rst b/docs/NewLLD.rst
index afdb41e0a..d01fb53b9 100644
--- a/docs/NewLLD.rst
+++ b/docs/NewLLD.rst
@@ -53,7 +53,7 @@ between speed, simplicity and extensibility.
until we need them to continue linking.
When we need to do some costly operation (such as looking up
a hash table for each symbol), we do it only once.
- We obtain a handler (which is typically just a pointer to actual data)
+ We obtain a handle (which is typically just a pointer to actual data)
on the first operation and use it throughout the process.
* Efficient archive file handling
@@ -90,18 +90,18 @@ between speed, simplicity and extensibility.
`--end-group`, to let the linker loop over the files between the options until
no new symbols are added to the set.
- Visiting the same archive files multiple makes the linker slower.
+ Visiting the same archive files multiple times makes the linker slower.
Here is how LLD approaches the problem. Instead of memorizing only undefined
symbols, we program LLD so that it memorizes all symbols. When it sees an
undefined symbol that can be resolved by extracting an object file from an
- archive file it previously visited, it immediately extracts the file and link
- it. It is doable because LLD does not forget symbols it have seen in archive
+ archive file it previously visited, it immediately extracts the file and links
+ it. It is doable because LLD does not forget symbols it has seen in archive
files.
- We believe that the LLD's way is efficient and easy to justify.
+ We believe that LLD's way is efficient and easy to justify.
- The semantics of LLD's archive handling is different from the traditional
+ The semantics of LLD's archive handling are different from the traditional
Unix's. You can observe it if you carefully craft archive files to exploit
it. However, in reality, we don't know any program that cannot link with our
algorithm so far, so it's not going to cause trouble.
@@ -157,7 +157,7 @@ functions, the code of the linker should look obvious to you.
- Undefined symbols represent undefined symbols, which need to be replaced by
Defined symbols by the resolver until the link is complete.
- Lazy symbols represent symbols we found in archive file headers
- which can turn into Defined if we read archieve members.
+ which can turn into Defined if we read archive members.
There's only one Symbol instance for each unique symbol name. This uniqueness
is guaranteed by the symbol table. As the resolver reads symbols from input
@@ -307,3 +307,11 @@ Glossary
On Unix, your program is generally not guaranteed to be safe with ICF,
although large programs happen to work correctly.
LLD works fine with ICF for example.
+
+Other Info
+----------
+
+.. toctree::
+ :maxdepth: 1
+
+ missingkeyfunction
diff --git a/docs/Readers.rst b/docs/Readers.rst
index b69a0b34f..eae1717f6 100644
--- a/docs/Readers.rst
+++ b/docs/Readers.rst
@@ -74,7 +74,7 @@ files in parallel. Therefore, there should be no parsing state in you Reader
object. Any parsing state should be in ivars of your File subclass or in
some temporary object.
-The key method to implement in a reader is::
+The key function to implement in a reader is::
virtual error_code loadFile(LinkerInput &input,
std::vector<std::unique_ptr<File>> &result);
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 30c180437..0b3cee5ee 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -1,19 +1,19 @@
=======================
-lld 8.0.0 Release Notes
+lld 9.0.0 Release Notes
=======================
.. contents::
:local:
.. warning::
- These are in-progress notes for the upcoming LLVM 8.0.0 release.
+ These are in-progress notes for the upcoming LLVM 9.0.0 release.
Release notes for previous releases can be found on
`the Download Page <https://releases.llvm.org/download.html>`_.
Introduction
============
-This document contains the release notes for the lld linker, release 8.0.0.
+This document contains the release notes for the lld linker, release 9.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/>`_.
@@ -24,42 +24,17 @@ Non-comprehensive list of changes in this release
ELF Improvements
----------------
-* lld now supports RISC-V. (`r339364
- <https://reviews.llvm.org/rL339364>`_)
-
-* Default image base address has changed from 65536 to 2 MiB for i386
- and 4 MiB for AArch64 to make lld-generated executables work better
- with automatic superpage promotion. FreeBSD can promote contiguous
- non-superpages to a superpage if they are aligned to the superpage
- size. (`r342746 <https://reviews.llvm.org/rL342746>`_)
-
-* lld/Hexagon can now link Linux kernel and musl libc for Qualcomm
- Hexagon ISA.
-
-* The following flags have been added: ``-z interpose``, ``-z global``
+* ...
COFF Improvements
-----------------
-* PDB GUID is set to hash of PDB contents instead to a random byte
- sequence for build reproducibility.
-
-* 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.
+* ...
MinGW Improvements
------------------
-* lld can now automatically import data variables from DLLs without the
- use of the dllimport attribute.
-
-* lld can now use existing normal MinGW sysroots with import libraries and
- CRT startup object files for GNU binutils. lld can handle most object
- files produced by GCC, and thus works as a drop-in replacement for
- ld.bfd in such environments.
+* ...
MachO Improvements
------------------
@@ -69,7 +44,4 @@ MachO Improvements
WebAssembly Improvements
------------------------
-* Add initial support for creating shared libraries (-shared).
- Note: The shared library format is still under active development and may
- undergo significant changes in future versions.
- See: https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
+* ...
diff --git a/docs/WebAssembly.rst b/docs/WebAssembly.rst
index 424c1a10c..016fdd74e 100644
--- a/docs/WebAssembly.rst
+++ b/docs/WebAssembly.rst
@@ -11,8 +11,7 @@ Object file format
------------------
The format the input object files that lld expects is specified as part of the
-the WebAssembly tool conventions
-https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md.
+the WebAssembly tool conventions on linking_.
This is object format that the llvm will produce when run with the
``wasm32-unknown-unknown`` target. To build llvm with WebAssembly support
@@ -88,10 +87,32 @@ WebAssembly-specific options:
By default the function table is neither imported nor exported, but defined
for internal use only.
-When building shared libraries symbols are exported if they are marked
-as ``visibility=default``. When building executables only the entry point is
-exported by default. In addition any symbol included on the command line via
-``--export`` is also exported.
+Bahaviour
+---------
+
+In general, where possible, the WebAssembly linker attempts to emulate the
+behavior of a traditional ELF linker, and in particular the ELF port of lld.
+For more specific details on how this is achieved see the tool conventions on
+linking_.
+
+Imports and Exports
+~~~~~~~~~~~~~~~~~~~
+
+When building a shared library any symbols marked as ``visibility=default`` will
+be exported. When building an executable, only the entry point and symbols
+flagged as ``WASM_SYMBOL_EXPORTED`` are exported by default. In LLVM the
+``WASM_SYMBOL_EXPORTED`` flag is applied to any symbol in the ``llvm.used`` list
+which corresponds to ``__attribute__((used))`` in C/C++ sources.
+
+In addition, symbols can be exported via the linker command line using
+``--export``.
+
+Finally, just like with native ELF linker the ``--export-dynamic`` flag can be
+used to export symbol in the executable which are marked as
+``visibility=default``.
+
+Garbage Collection
+~~~~~~~~~~~~~~~~~~
Since WebAssembly is designed with size in mind the linker defaults to
``--gc-sections`` which means that all unused functions and data segments will
@@ -103,6 +124,18 @@ The symbols which are preserved by default are:
- Any symbol which is to be exported.
- Any symbol transitively referenced by the above.
+Weak Undefined Functions
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+On native platforms, calls to weak undefined functions end up as calls to the
+null function pointer. With WebAssembly, direct calls must reference a defined
+function (with the correct signature). In order to handle this case the linker
+will generate function a stub containing only the ``unreachable`` instruction
+and use this for any direct references to an undefined weak function.
+
+For example a runtime call to a weak undefined function ``foo`` will up trapping
+on ``unreachable`` inside and linker-generated function called
+``undefined:foo``.
Missing features
----------------
@@ -112,3 +145,5 @@ Missing features
- No support for creating shared libraries. The spec for shared libraries in
WebAssembly is still in flux:
https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
+
+.. _linking: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
diff --git a/docs/conf.py b/docs/conf.py
index 62404b275..dd65859fe 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -48,9 +48,9 @@ copyright = u'2011-%d, LLVM Project' % date.today().year
# built documents.
#
# The short version.
-version = '8'
+version = '9'
# The full version, including alpha/beta/rc tags.
-release = '8'
+release = '9'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
index 97c3d1bcc..a174f652e 100644
--- a/docs/getting_started.rst
+++ b/docs/getting_started.rst
@@ -28,23 +28,15 @@ On Unix-like Systems
.. _libc++: http://libcxx.llvm.org/
.. _Python 2.4: http://python.org/download/
-2. Check out LLVM::
+2. Check out LLVM and subprojects (including lld)::
- $ cd path/to/llvm-project
- $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
-
-3. Check out lld::
-
- $ cd llvm/tools
- $ svn co http://llvm.org/svn/llvm-project/lld/trunk lld
-
- * lld can also be checked out to ``path/to/llvm-project`` and built as an external
- project.
+ $ git clone https://github.com/llvm/llvm-project.git
4. Build LLVM and lld::
- $ cd path/to/llvm-build/llvm (out of source build required)
- $ cmake -G "Unix Makefiles" path/to/llvm-project/llvm
+ $ cd llvm-project
+ $ mkdir build && cd build
+ $ cmake -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS=lld ../llvm
$ make
* If you want to build with clang and it is not the default compiler or
@@ -71,23 +63,12 @@ Using Visual Studio
.. _Visual Studio 12 (2013) or later: http://www.microsoft.com/visualstudio/11/en-us
.. _Python 2.4: http://python.org/download/
-#. Check out LLVM::
-
- $ cd path/to/llvm-project
- $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
-
-#. Check out lld::
-
- $ cd llvm/tools
- $ svn co http://llvm.org/svn/llvm-project/lld/trunk lld
-
- * lld can also be checked out to ``path/to/llvm-project`` and built as an external
- project.
+#. Check out LLVM as above.
#. Generate Visual Studio project files::
- $ cd path/to/llvm-build/llvm (out of source build required)
- $ cmake -G "Visual Studio 11" path/to/llvm-project/llvm
+ $ cd llvm-project/build (out of source build required)
+ $ cmake -G "Visual Studio 11" -DLLVM_ENABLE_PROJECTS=lld ../llvm
#. Build
diff --git a/docs/index.rst b/docs/index.rst
index 2821ce4d2..8b3f70e1d 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,7 +1,7 @@
LLD - The LLVM Linker
=====================
-LLD is a linker from the LLVM project. That is a drop-in replacement
+LLD is a linker from the LLVM project that is a drop-in replacement
for system linkers and runs much faster than them. It also provides
features that are useful for toolchain developers.
@@ -17,7 +17,7 @@ read :doc:`AtomLLD`.
Features
--------
-- LLD is a drop-in replacement for the GNU linkers. That accepts the
+- LLD is a drop-in replacement for the GNU linkers that accepts the
same command line arguments and linker scripts as GNU.
We are currently working closely with the FreeBSD project to make
@@ -30,29 +30,27 @@ Features
<https://www.freebsd.org/news/status/report-2016-10-2016-12.html#Using-LLVM%27s-LLD-Linker-as-FreeBSD%27s-System-Linker>`_.
- LLD is very fast. When you link a large program on a multicore
- machine, you can expect that LLD runs more than twice as fast as GNU
+ machine, you can expect that LLD runs more than twice as fast as the GNU
gold linker. Your milage may vary, though.
- It supports various CPUs/ABIs including x86-64, x86, x32, AArch64,
ARM, MIPS 32/64 big/little-endian, PowerPC, PowerPC 64 and AMDGPU.
- Among these, x86-64 is the most well-supported target and have
- reached production quality. AArch64 and MIPS seem decent too. x86
- should be OK but not well tested yet. ARM support is being developed
- actively.
+ Among these, x86-64, AArch64, and ARM (>= v6) are production quality.
+ MIPS seems decent too. x86 should be OK but is not well tested yet.
- It is always a cross-linker, meaning that it always supports all the
above targets however it was built. In fact, we don't provide a
build-time option to enable/disable each target. This should make it
easy to use our linker as part of a cross-compile toolchain.
-- You can embed LLD to your program to eliminate dependency to
+- You can embed LLD in your program to eliminate dependencies on
external linkers. All you have to do is to construct object files
and command line arguments just like you would do to invoke an
external linker and then call the linker's main function,
``lld::elf::link``, from your code.
- It is small. We are using LLVM libObject library to read from object
- files, so it is not completely a fair comparison, but as of February
+ files, so it is not a completely fair comparison, but as of February
2017, LLD/ELF consists only of 21k lines of C++ code while GNU gold
consists of 198k lines of C++ code.
@@ -102,13 +100,13 @@ under ``tools`` directory just like you probably did for clang. For the
details, see `Getting Started with the LLVM System
<http://llvm.org/docs/GettingStarted.html>`_.
-If you haven't checkout out LLVM, the easiest way to build LLD is to
-checkout the entire LLVM projects/sub-projects from a git mirror and
+If you haven't checked out LLVM, the easiest way to build LLD is to
+check out the entire LLVM projects/sub-projects from a git mirror and
build that tree. You need `cmake` and of course a C++ compiler.
.. code-block:: console
- $ git clone https://github.com/llvm-project/llvm-project-20170507 llvm-project
+ $ git clone https://github.com/llvm/llvm-project llvm-project
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=lld -DCMAKE_INSTALL_PREFIX=/usr/local ../llvm-project/llvm
@@ -175,4 +173,5 @@ document soon.
AtomLLD
WebAssembly
windows_support
+ missingkeyfunction
ReleaseNotes
diff --git a/docs/ld.lld.1 b/docs/ld.lld.1
index d1ce4a351..591e165b5 100644
--- a/docs/ld.lld.1
+++ b/docs/ld.lld.1
@@ -1,5 +1,6 @@
-.\" This file is distributed under the University of Illinois Open Source
-.\" License. See LICENSE.TXT for details.
+.\" Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+.\" See https://llvm.org/LICENSE.txt for license information.
+.\" SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
.\"
.\" This man page documents only lld's ELF linking support, obtained originally
.\" from FreeBSD.
@@ -45,6 +46,9 @@ as a native linker as well as a cross linker.
.It Fl -allow-multiple-definition
Do not error if a symbol is defined multiple times.
The first definition will be used.
+.It Fl -allow-shlib-undefined
+Allow unresolved references in shared libraries.
+This option is enabled by default when linking a shared library.
.It Fl -apply-dynamic-relocs
Apply link-time values for dynamic relocations.
.It Fl -as-needed
@@ -241,6 +245,9 @@ Set target emulation.
.It Fl -Map Ns = Ns Ar file , Fl M Ar file
Print a link map to
.Ar file .
+.It Fl -no-allow-shlib-undefined
+Do not allow unresolved references in shared libraries.
+This option is enabled by default when linking an executable.
.It Fl -no-as-needed
Always set
.Dv DT_NEEDED
@@ -311,6 +318,8 @@ Write optimization remarks in YAML format to
.Ar file .
.It Fl -opt-remarks-with-hotness
Include hotness information in the optimization remarks file.
+.It Fl -pic-veneer
+Always generate position independent thunks.
.It Fl -pie
Create a position independent executable.
.It Fl -print-gc-sections
diff --git a/docs/missingkeyfunction.rst b/docs/missingkeyfunction.rst
new file mode 100644
index 000000000..54ad3251f
--- /dev/null
+++ b/docs/missingkeyfunction.rst
@@ -0,0 +1,84 @@
+Missing Key Function
+====================
+
+If your build failed with a linker error something like this::
+
+ foo.cc:28: error: undefined reference to 'vtable for C'
+ the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeyfunction)
+
+it's likely that your class C has a key function (defined by the ABI as the first
+non-pure, non-inline, virtual method), but you haven't actually defined it.
+
+When a class has a key function, the compiler emits the vtable (and some other
+things as well) only in the translation unit that defines that key function. Thus,
+if you're missing the key function, you'll also be missing the vtable. If no other
+function calls your missing method, you won't see any undefined reference errors
+for it, but you will see undefined references to the vtable symbol.
+
+When a class has no non-pure, non-inline, virtual methods, there is no key
+method, and the compiler is forced to emit the vtable in every translation unit
+that references the class. In this case, it is emitted in a COMDAT section,
+which allows the linker to eliminate all duplicate copies. This is still
+wasteful in terms of object file size and link time, so it's always advisable to
+ensure there is at least one eligible method that can serve as the key function.
+
+Here are the most common mistakes that lead to this error:
+
+Failing to define a virtual destructor
+--------------------------------------
+
+Say you have a base class declared in a header file::
+
+ class B {
+ public:
+ B();
+ virtual ~B();
+ ...
+ };
+
+Here, ``~B`` is the first non-pure, non-inline, virtual method, so it is the key
+method. If you forget to define ``B::~B`` in your source file, the compiler will
+not emit the vtable for ``B``, and you'll get an undefined reference to "vtable
+for B".
+
+This is just an example of the more general mistake of forgetting to define the
+key function, but it's quite common because virtual destructors are likely to be
+the first eligible key function and it's easy to forget to implement them. It's
+also more likely that you won't have any direct references to the destructor, so
+you won't see any undefined reference errors that point directly to the problem.
+
+The solution in this case is to implement the missing method.
+
+Forgetting to declare a virtual method in an abstract class as pure
+-------------------------------------------------------------------
+
+Say you have an abstract base class declared in a header file::
+
+ class A {
+ public:
+ A();
+ virtual ~A() {}
+ virtual int foo() = 0;
+ ...
+ virtual int bar();
+ ...
+ };
+
+This base class is intended to be abstract, but you forgot to mark one of the
+methods pure. Here, ``A::bar``, being non-pure, is nominated as the key function,
+and as a result, the vtable for ``A`` is not emitted, because the compiler is
+waiting for a translation unit that defines ``A::bar``.
+
+The solution in this case is to add the missing ``= 0`` to the declaration of
+``A::bar``.
+
+Key method is defined, but the linker doesn't see it
+----------------------------------------------------
+
+It's also possible that you have defined the key function somewhere, but the
+object file containing the definition of that method isn't being linked into
+your application.
+
+The solution in this case is to check your dependencies to make sure that
+the object file or the library file containing the key function is given to
+the linker.
diff --git a/docs/open_projects.rst b/docs/open_projects.rst
index eeb9f9f48..36edca4e9 100644
--- a/docs/open_projects.rst
+++ b/docs/open_projects.rst
@@ -3,8 +3,6 @@
Open Projects
=============
-.. include:: ../include/lld/Core/TODO.txt
-
Documentation TODOs
~~~~~~~~~~~~~~~~~~~
diff --git a/docs/windows_support.rst b/docs/windows_support.rst
index a0a2c4d9f..c9723c42f 100644
--- a/docs/windows_support.rst
+++ b/docs/windows_support.rst
@@ -20,8 +20,8 @@ command line options, and it drives further linking processes. LLD accepts
almost all command line options that the linker shipped with Microsoft Visual
C++ (link.exe) supports.
-The current status is that LLD can link itself on Windows x86/x64
-using Visual C++ 2013 as the compiler.
+The current status is that LLD is used to link production builds of large
+real-world binaries such as Firefox and Chromium.
Development status
==================
diff --git a/include/lld/Common/Args.h b/include/lld/Common/Args.h
index 769d4840c..d94364668 100644
--- a/include/lld/Common/Args.h
+++ b/include/lld/Common/Args.h
@@ -1,9 +1,8 @@
//===- Args.h ---------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,6 +10,7 @@
#define LLD_ARGS_H
#include "lld/Common/LLVM.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/MemoryBuffer.h"
#include <vector>
@@ -22,7 +22,11 @@ class InputArgList;
namespace lld {
namespace args {
+
+llvm::CodeGenOpt::Level getCGOptLevel(int OptLevelLTO);
+
int getInteger(llvm::opt::InputArgList &Args, unsigned Key, int Default);
+
std::vector<StringRef> getStrings(llvm::opt::InputArgList &Args, int Id);
uint64_t getZOptionValue(llvm::opt::InputArgList &Args, int Id, StringRef Key,
diff --git a/include/lld/Common/Driver.h b/include/lld/Common/Driver.h
index f6d92933a..745ef720e 100644
--- a/include/lld/Common/Driver.h
+++ b/include/lld/Common/Driver.h
@@ -1,9 +1,8 @@
//===- lld/Common/Driver.h - Linker Driver Emulator -----------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Common/ErrorHandler.h b/include/lld/Common/ErrorHandler.h
index c169f7b50..bd9c257ed 100644
--- a/include/lld/Common/ErrorHandler.h
+++ b/include/lld/Common/ErrorHandler.h
@@ -1,9 +1,8 @@
//===- ErrorHandler.h -------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/lld/Common/LLVM.h b/include/lld/Common/LLVM.h
index 95a2aa903..944bb412a 100644
--- a/include/lld/Common/LLVM.h
+++ b/include/lld/Common/LLVM.h
@@ -1,9 +1,8 @@
//===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/lld/Common/Memory.h b/include/lld/Common/Memory.h
index 699f7c165..78f6e24f9 100644
--- a/include/lld/Common/Memory.h
+++ b/include/lld/Common/Memory.h
@@ -1,9 +1,8 @@
//===- Memory.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/lld/Common/Reproduce.h b/include/lld/Common/Reproduce.h
index 0f425de26..ac7a822cf 100644
--- a/include/lld/Common/Reproduce.h
+++ b/include/lld/Common/Reproduce.h
@@ -1,9 +1,8 @@
//===- Reproduce.h - Utilities for creating reproducers ---------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Common/Strings.h b/include/lld/Common/Strings.h
index 566030e43..efc924507 100644
--- a/include/lld/Common/Strings.h
+++ b/include/lld/Common/Strings.h
@@ -1,9 +1,8 @@
//===- Strings.h ------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Common/TargetOptionsCommandFlags.h b/include/lld/Common/TargetOptionsCommandFlags.h
index 2eaecb727..9345e616f 100644
--- a/include/lld/Common/TargetOptionsCommandFlags.h
+++ b/include/lld/Common/TargetOptionsCommandFlags.h
@@ -1,9 +1,8 @@
//===-- TargetOptionsCommandFlags.h ----------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,8 +15,8 @@
#include "llvm/Target/TargetOptions.h"
namespace lld {
-llvm::TargetOptions InitTargetOptionsFromCodeGenFlags();
-llvm::Optional<llvm::CodeModel::Model> GetCodeModelFromCMModel();
-std::string GetCPUStr();
-std::vector<std::string> GetMAttrs();
+llvm::TargetOptions initTargetOptionsFromCodeGenFlags();
+llvm::Optional<llvm::CodeModel::Model> getCodeModelFromCMModel();
+std::string getCPUStr();
+std::vector<std::string> getMAttrs();
}
diff --git a/include/lld/Common/Threads.h b/include/lld/Common/Threads.h
index 1425abd12..e356fcd23 100644
--- a/include/lld/Common/Threads.h
+++ b/include/lld/Common/Threads.h
@@ -1,9 +1,8 @@
//===- Threads.h ------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/lld/Common/Timer.h b/include/lld/Common/Timer.h
index 6654af626..e2b69510a 100644
--- a/include/lld/Common/Timer.h
+++ b/include/lld/Common/Timer.h
@@ -1,9 +1,8 @@
//===- Timer.h ----------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Common/Version.h b/include/lld/Common/Version.h
index 23a10ed6d..9571aa274 100644
--- a/include/lld/Common/Version.h
+++ b/include/lld/Common/Version.h
@@ -1,9 +1,8 @@
//===- lld/Common/Version.h - LLD Version Number ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/lld/Core/AbsoluteAtom.h b/include/lld/Core/AbsoluteAtom.h
index ed25297ce..5214b418f 100644
--- a/include/lld/Core/AbsoluteAtom.h
+++ b/include/lld/Core/AbsoluteAtom.h
@@ -1,9 +1,8 @@
//===- Core/AbsoluteAtom.h - An absolute Atom -----------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/ArchiveLibraryFile.h b/include/lld/Core/ArchiveLibraryFile.h
index 2c736e7d6..0abef4044 100644
--- a/include/lld/Core/ArchiveLibraryFile.h
+++ b/include/lld/Core/ArchiveLibraryFile.h
@@ -1,9 +1,8 @@
//===- Core/ArchiveLibraryFile.h - Models static library ------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/Atom.h b/include/lld/Core/Atom.h
index 149c3d5ee..4d3d27a2a 100644
--- a/include/lld/Core/Atom.h
+++ b/include/lld/Core/Atom.h
@@ -1,9 +1,8 @@
//===- Core/Atom.h - A node in linking graph --------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/DefinedAtom.h b/include/lld/Core/DefinedAtom.h
index ba10b4541..4b1de7ffe 100644
--- a/include/lld/Core/DefinedAtom.h
+++ b/include/lld/Core/DefinedAtom.h
@@ -1,9 +1,8 @@
//===- Core/DefinedAtom.h - An Atom with content --------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/Error.h b/include/lld/Core/Error.h
index 36a367249..c18fe96d2 100644
--- a/include/lld/Core/Error.h
+++ b/include/lld/Core/Error.h
@@ -1,9 +1,8 @@
//===- Error.h - system_error extensions for lld ----------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/lld/Core/File.h b/include/lld/Core/File.h
index 54f533576..492f35989 100644
--- a/include/lld/Core/File.h
+++ b/include/lld/Core/File.h
@@ -1,9 +1,8 @@
//===- Core/File.h - A Container of Atoms ---------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/Instrumentation.h b/include/lld/Core/Instrumentation.h
index 939d64557..602a37aff 100644
--- a/include/lld/Core/Instrumentation.h
+++ b/include/lld/Core/Instrumentation.h
@@ -1,9 +1,8 @@
//===- include/Core/Instrumentation.h - Instrumentation API ---------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/lld/Core/LinkingContext.h b/include/lld/Core/LinkingContext.h
index 52ab1a248..e090ff990 100644
--- a/include/lld/Core/LinkingContext.h
+++ b/include/lld/Core/LinkingContext.h
@@ -1,9 +1,8 @@
//===- lld/Core/LinkingContext.h - Linker Target Info Interface -*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/Node.h b/include/lld/Core/Node.h
index c30482409..a224793d7 100644
--- a/include/lld/Core/Node.h
+++ b/include/lld/Core/Node.h
@@ -1,9 +1,8 @@
//===- lld/Core/Node.h - Input file class -----------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/lld/Core/Pass.h b/include/lld/Core/Pass.h
index bfe3f9b10..57d5a40e0 100644
--- a/include/lld/Core/Pass.h
+++ b/include/lld/Core/Pass.h
@@ -1,9 +1,8 @@
//===------ Core/Pass.h - Base class for linker passes ----------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/PassManager.h b/include/lld/Core/PassManager.h
index f2ef10f40..02499d09c 100644
--- a/include/lld/Core/PassManager.h
+++ b/include/lld/Core/PassManager.h
@@ -1,9 +1,8 @@
//===- lld/Core/PassManager.h - Manage linker passes ----------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/Reader.h b/include/lld/Core/Reader.h
index 6cf6282ff..a2d7912d7 100644
--- a/include/lld/Core/Reader.h
+++ b/include/lld/Core/Reader.h
@@ -1,9 +1,8 @@
//===- lld/Core/Reader.h - Abstract File Format Reading Interface ---------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/Reference.h b/include/lld/Core/Reference.h
index 1d3003c84..191e0f07e 100644
--- a/include/lld/Core/Reference.h
+++ b/include/lld/Core/Reference.h
@@ -1,9 +1,8 @@
//===- Core/References.h - A Reference to Another Atom ----------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/Resolver.h b/include/lld/Core/Resolver.h
index 5157c9fdd..9ab219509 100644
--- a/include/lld/Core/Resolver.h
+++ b/include/lld/Core/Resolver.h
@@ -1,9 +1,8 @@
//===- Core/Resolver.h - Resolves Atom References -------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/SharedLibraryAtom.h b/include/lld/Core/SharedLibraryAtom.h
index 7fec7a3e3..171d154bc 100644
--- a/include/lld/Core/SharedLibraryAtom.h
+++ b/include/lld/Core/SharedLibraryAtom.h
@@ -1,9 +1,8 @@
//===- Core/SharedLibraryAtom.h - A Shared Library Atom -------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/SharedLibraryFile.h b/include/lld/Core/SharedLibraryFile.h
index 53bf967b0..846d1f22f 100644
--- a/include/lld/Core/SharedLibraryFile.h
+++ b/include/lld/Core/SharedLibraryFile.h
@@ -1,9 +1,8 @@
//===- Core/SharedLibraryFile.h - Models shared libraries as Atoms --------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/Simple.h b/include/lld/Core/Simple.h
index feeed6ae4..f211beb99 100644
--- a/include/lld/Core/Simple.h
+++ b/include/lld/Core/Simple.h
@@ -1,9 +1,8 @@
//===- lld/Core/Simple.h - Simple implementations of Atom and File --------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/lld/Core/SymbolTable.h b/include/lld/Core/SymbolTable.h
index 156c56eaf..c7502a45d 100644
--- a/include/lld/Core/SymbolTable.h
+++ b/include/lld/Core/SymbolTable.h
@@ -1,9 +1,8 @@
//===- Core/SymbolTable.h - Main Symbol Table -----------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/TODO.txt b/include/lld/Core/TODO.txt
deleted file mode 100644
index 2aa61ff86..000000000
--- a/include/lld/Core/TODO.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-include/lld/Core
-~~~~~~~~~~~~~~~~
-
-* The yaml reader/writer interfaces should be changed to return
- an explanatory string if there is an error. The existing error_code
- abstraction only works for returning low level OS errors. It does not
- work for describing formatting issues.
-
-* We need to add more attributes to File. In particular, we need cpu
- and OS information (like target triples). We should also provide explicit
- support for `LLVM IR module flags metadata`__.
-
-.. __: http://llvm.org/docs/LangRef.html#module_flags
-.. _Clang: http://clang.llvm.org/docs/InternalsManual.html#Diagnostics
diff --git a/include/lld/Core/UndefinedAtom.h b/include/lld/Core/UndefinedAtom.h
index f45d6ecda..a40db3651 100644
--- a/include/lld/Core/UndefinedAtom.h
+++ b/include/lld/Core/UndefinedAtom.h
@@ -1,9 +1,8 @@
//===- Core/UndefinedAtom.h - An Undefined Atom ---------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/Core/Writer.h b/include/lld/Core/Writer.h
index 1cdfabefe..0de5fca32 100644
--- a/include/lld/Core/Writer.h
+++ b/include/lld/Core/Writer.h
@@ -1,9 +1,8 @@
//===- lld/Core/Writer.h - Abstract File Format Interface -----------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/ReaderWriter/MachOLinkingContext.h b/include/lld/ReaderWriter/MachOLinkingContext.h
index fde65880c..f48ad7705 100644
--- a/include/lld/ReaderWriter/MachOLinkingContext.h
+++ b/include/lld/ReaderWriter/MachOLinkingContext.h
@@ -1,9 +1,8 @@
//===- lld/ReaderWriter/MachOLinkingContext.h -----------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/lld/ReaderWriter/YamlContext.h b/include/lld/ReaderWriter/YamlContext.h
index b97d21f68..dc133e362 100644
--- a/include/lld/ReaderWriter/YamlContext.h
+++ b/include/lld/ReaderWriter/YamlContext.h
@@ -1,9 +1,8 @@
//===- lld/ReaderWriter/YamlContext.h - object used in YAML I/O context ---===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Core/DefinedAtom.cpp b/lib/Core/DefinedAtom.cpp
index 177cae7fc..3c1eece16 100644
--- a/lib/Core/DefinedAtom.cpp
+++ b/lib/Core/DefinedAtom.cpp
@@ -1,9 +1,8 @@
//===- DefinedAtom.cpp ------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Core/Error.cpp b/lib/Core/Error.cpp
index 6fc76f7ca..f138a81ef 100644
--- a/lib/Core/Error.cpp
+++ b/lib/Core/Error.cpp
@@ -1,9 +1,8 @@
//===- Error.cpp - system_error extensions for lld --------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Core/File.cpp b/lib/Core/File.cpp
index 30ded091a..ce33923c1 100644
--- a/lib/Core/File.cpp
+++ b/lib/Core/File.cpp
@@ -1,9 +1,8 @@
//===- Core/File.cpp - A Container of Atoms -------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Core/LinkingContext.cpp b/lib/Core/LinkingContext.cpp
index 0f225c322..911ae6066 100644
--- a/lib/Core/LinkingContext.cpp
+++ b/lib/Core/LinkingContext.cpp
@@ -1,9 +1,8 @@
//===- lib/Core/LinkingContext.cpp - Linker Context Object Interface ------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Core/Reader.cpp b/lib/Core/Reader.cpp
index 5d8bbbbfe..3592d87ce 100644
--- a/lib/Core/Reader.cpp
+++ b/lib/Core/Reader.cpp
@@ -1,9 +1,8 @@
//===- lib/Core/Reader.cpp ------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Core/Resolver.cpp b/lib/Core/Resolver.cpp
index 9c51c6cdb..7e6d95f82 100644
--- a/lib/Core/Resolver.cpp
+++ b/lib/Core/Resolver.cpp
@@ -1,9 +1,8 @@
//===- Core/Resolver.cpp - Resolves Atom References -----------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Core/SymbolTable.cpp b/lib/Core/SymbolTable.cpp
index 51ae8d171..55cc27c38 100644
--- a/lib/Core/SymbolTable.cpp
+++ b/lib/Core/SymbolTable.cpp
@@ -1,9 +1,8 @@
//===- Core/SymbolTable.cpp - Main Symbol Table ---------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Core/Writer.cpp b/lib/Core/Writer.cpp
index 51f95bc50..12788b187 100644
--- a/lib/Core/Writer.cpp
+++ b/lib/Core/Writer.cpp
@@ -1,9 +1,8 @@
//===- lib/Core/Writer.cpp ------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/DarwinLdDriver.cpp b/lib/Driver/DarwinLdDriver.cpp
index bbac230df..f0cb51381 100644
--- a/lib/Driver/DarwinLdDriver.cpp
+++ b/lib/Driver/DarwinLdDriver.cpp
@@ -1,9 +1,8 @@
//===- lib/Driver/DarwinLdDriver.cpp --------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/ReaderWriter/FileArchive.cpp b/lib/ReaderWriter/FileArchive.cpp
index 2f52d9d34..b09bf34dc 100644
--- a/lib/ReaderWriter/FileArchive.cpp
+++ b/lib/ReaderWriter/FileArchive.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/FileArchive.cpp -----------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/ArchHandler.cpp b/lib/ReaderWriter/MachO/ArchHandler.cpp
index cb20907b3..c101f3b15 100644
--- a/lib/ReaderWriter/MachO/ArchHandler.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler.cpp
@@ -1,9 +1,8 @@
//===- lib/FileFormat/MachO/ArchHandler.cpp -------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/ArchHandler.h b/lib/ReaderWriter/MachO/ArchHandler.h
index 80840b561..83646c09b 100644
--- a/lib/ReaderWriter/MachO/ArchHandler.h
+++ b/lib/ReaderWriter/MachO/ArchHandler.h
@@ -1,9 +1,8 @@
//===- lib/FileFormat/MachO/ArchHandler.h ---------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/ArchHandler_arm.cpp b/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
index 2f663c660..06c98ac06 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
@@ -1,9 +1,8 @@
//===- lib/FileFormat/MachO/ArchHandler_arm.cpp ---------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
index b9c815c5a..a424edf49 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
@@ -1,9 +1,8 @@
//===- lib/FileFormat/MachO/ArchHandler_arm64.cpp -------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/ArchHandler_x86.cpp b/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
index a2c680927..6ea8e8c42 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
@@ -1,9 +1,8 @@
//===- lib/FileFormat/MachO/ArchHandler_x86.cpp ---------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
index fba3d530e..316b5bbc6 100644
--- a/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
+++ b/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
@@ -1,9 +1,8 @@
//===- lib/FileFormat/MachO/ArchHandler_x86_64.cpp ------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/Atoms.h b/lib/ReaderWriter/MachO/Atoms.h
index 573efca9f..b8bca1959 100644
--- a/lib/ReaderWriter/MachO/Atoms.h
+++ b/lib/ReaderWriter/MachO/Atoms.h
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/Atoms.h ---------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/CompactUnwindPass.cpp b/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
index fa0aaa103..02eba36a0 100644
--- a/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
+++ b/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/CompactUnwindPass.cpp -------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/ReaderWriter/MachO/DebugInfo.h b/lib/ReaderWriter/MachO/DebugInfo.h
index 28e41bf42..959e10f9a 100644
--- a/lib/ReaderWriter/MachO/DebugInfo.h
+++ b/lib/ReaderWriter/MachO/DebugInfo.h
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/ExecutableAtoms.h b/lib/ReaderWriter/MachO/ExecutableAtoms.h
index ab14e6d8c..ce94be457 100644
--- a/lib/ReaderWriter/MachO/ExecutableAtoms.h
+++ b/lib/ReaderWriter/MachO/ExecutableAtoms.h
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/ExecutableAtoms.h ---------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/File.h b/lib/ReaderWriter/MachO/File.h
index 2bdd6342b..1cc1c4109 100644
--- a/lib/ReaderWriter/MachO/File.h
+++ b/lib/ReaderWriter/MachO/File.h
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/FlatNamespaceFile.h b/lib/ReaderWriter/MachO/FlatNamespaceFile.h
index 7ccd4f19f..1885effef 100644
--- a/lib/ReaderWriter/MachO/FlatNamespaceFile.h
+++ b/lib/ReaderWriter/MachO/FlatNamespaceFile.h
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/FlatNamespaceFile.h -------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/GOTPass.cpp b/lib/ReaderWriter/MachO/GOTPass.cpp
index 49e6f88d4..bc66d49ea 100644
--- a/lib/ReaderWriter/MachO/GOTPass.cpp
+++ b/lib/ReaderWriter/MachO/GOTPass.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/GOTPass.cpp -----------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/ReaderWriter/MachO/LayoutPass.cpp b/lib/ReaderWriter/MachO/LayoutPass.cpp
index 9058e4f56..2718dfcf7 100644
--- a/lib/ReaderWriter/MachO/LayoutPass.cpp
+++ b/lib/ReaderWriter/MachO/LayoutPass.cpp
@@ -1,9 +1,8 @@
//===-- ReaderWriter/MachO/LayoutPass.cpp - Layout atoms ------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/LayoutPass.h b/lib/ReaderWriter/MachO/LayoutPass.h
index c18777ede..904e16b7f 100644
--- a/lib/ReaderWriter/MachO/LayoutPass.h
+++ b/lib/ReaderWriter/MachO/LayoutPass.h
@@ -1,9 +1,8 @@
//===------ lib/ReaderWriter/MachO/LayoutPass.h - Handles Layout of atoms -===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
index 61583963d..1e8630a2d 100644
--- a/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
+++ b/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/MachOLinkingContext.cpp ---------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFile.h b/lib/ReaderWriter/MachO/MachONormalizedFile.h
index 7eeb8adbd..583c76539 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFile.h
+++ b/lib/ReaderWriter/MachO/MachONormalizedFile.h
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/MachONormalizedFile.h -----------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
index 7c2e833c0..38b365374 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp ---------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
index ee9e174b8..aeb04ef45 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h ------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
index 7ef0237e8..ed3dfd49a 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp ---------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
index e93ca86c3..0b734847e 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp ------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
index 473de8948..879f07fb4 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp --------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
index 92a646dab..7f53faaea 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp -----------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/MachOPasses.h b/lib/ReaderWriter/MachO/MachOPasses.h
index cd01d4aa2..93cd3e4df 100644
--- a/lib/ReaderWriter/MachO/MachOPasses.h
+++ b/lib/ReaderWriter/MachO/MachOPasses.h
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/MachOPasses.h -------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/ObjCPass.cpp b/lib/ReaderWriter/MachO/ObjCPass.cpp
index 23c71e0f5..df121f0e1 100644
--- a/lib/ReaderWriter/MachO/ObjCPass.cpp
+++ b/lib/ReaderWriter/MachO/ObjCPass.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/ObjCPass.cpp -------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ReaderWriter/MachO/SectCreateFile.h b/lib/ReaderWriter/MachO/SectCreateFile.h
index 49e65f631..7bb98e166 100644
--- a/lib/ReaderWriter/MachO/SectCreateFile.h
+++ b/lib/ReaderWriter/MachO/SectCreateFile.h
@@ -1,9 +1,8 @@
//===---- lib/ReaderWriter/MachO/SectCreateFile.h ---------------*- c++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/MachO/ShimPass.cpp b/lib/ReaderWriter/MachO/ShimPass.cpp
index 8a2d2e910..b0775ad5f 100644
--- a/lib/ReaderWriter/MachO/ShimPass.cpp
+++ b/lib/ReaderWriter/MachO/ShimPass.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/ShimPass.cpp -------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ReaderWriter/MachO/StubsPass.cpp b/lib/ReaderWriter/MachO/StubsPass.cpp
index 04c586df3..e8f35419a 100644
--- a/lib/ReaderWriter/MachO/StubsPass.cpp
+++ b/lib/ReaderWriter/MachO/StubsPass.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/StubsPass.cpp ---------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ReaderWriter/MachO/TLVPass.cpp b/lib/ReaderWriter/MachO/TLVPass.cpp
index e362e507e..89b655e1f 100644
--- a/lib/ReaderWriter/MachO/TLVPass.cpp
+++ b/lib/ReaderWriter/MachO/TLVPass.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/TLVPass.cpp -----------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/ReaderWriter/MachO/WriterMachO.cpp b/lib/ReaderWriter/MachO/WriterMachO.cpp
index c457e7b55..60e0e9dd9 100644
--- a/lib/ReaderWriter/MachO/WriterMachO.cpp
+++ b/lib/ReaderWriter/MachO/WriterMachO.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/MachO/WriterMachO.cpp -----------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
index 59548684e..5feff2a05 100644
--- a/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
+++ b/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
@@ -1,9 +1,8 @@
//===- lib/ReaderWriter/YAML/ReaderWriterYAML.cpp -------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 1b908335c..64aa1f7cb 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -14,7 +14,9 @@ if(LLD_BUILT_STANDALONE)
endif()
llvm_canonicalize_cmake_booleans(
- HAVE_LIBZ)
+ HAVE_LIBZ
+ LLVM_LIBXML2_ENABLED
+ )
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
diff --git a/test/COFF/arm-thumb-thunks-pdb.s b/test/COFF/arm-thumb-thunks-pdb.s
new file mode 100644
index 000000000..9e972a78d
--- /dev/null
+++ b/test/COFF/arm-thumb-thunks-pdb.s
@@ -0,0 +1,18 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -debug -pdb:%t.pdb -verbose 2>&1 | FileCheck %s --check-prefix=VERBOSE
+
+// VERBOSE: Added 1 thunks with margin {{.*}} in {{.*}} passes
+
+ .syntax unified
+ .globl main
+ .globl func1
+ .text
+main:
+ bne func1
+ bx lr
+ .section .text$a, "xr"
+ .space 0x100000
+ .section .text$b, "xr"
+func1:
+ bx lr
diff --git a/test/COFF/arm64-branch-range.test b/test/COFF/arm64-branch-range.test
deleted file mode 100644
index 0b581e9c4..000000000
--- a/test/COFF/arm64-branch-range.test
+++ /dev/null
@@ -1,16 +0,0 @@
-// REQUIRES: aarch64
-
-// RUN: echo -e '.globl _start\n _start:\n bl too_far26\n' > %t.main26.s
-// RUN: echo -e '.globl _start\n _start:\n b.ne too_far19\n' > %t.main19.s
-// RUN: echo -e '.globl _start\n _start:\n tbz x0, #0, too_far14\n' > %t.main14.s
-
-// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main26.s -o %t.main26.obj
-// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main19.s -o %t.main19.obj
-// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main14.s -o %t.main14.obj
-// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/far-arm64-abs.s -o %t.far.obj
-
-// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main26.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
-// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main19.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
-// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main14.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s
-
-// CHECK: relocation out of range
diff --git a/test/COFF/arm64-relocs-imports.test b/test/COFF/arm64-relocs-imports.test
index e2c00f189..d9799ed7c 100644
--- a/test/COFF/arm64-relocs-imports.test
+++ b/test/COFF/arm64-relocs-imports.test
@@ -45,12 +45,13 @@
# BEFORE: 90: 20 1a 09 30 adr x0, #74565
# BEFORE: 94: 01 00 00 54 b.ne #0
# BEFORE: 98: 00 00 00 36 tbz w0, #0, #0
+# BEFORE: 9c: 01 00 00 00 udf #1
# AFTER: Disassembly of section .text:
# AFTER: 140001000: fe 0f 1f f8 str x30, [sp, #-16]!
# AFTER: 140001004: 00 00 00 b0 adrp x0, #4096
# AFTER: 140001008: 00 18 00 91 add x0, x0, #6
-# AFTER: 14000100c: 24 00 00 94 bl #144
+# AFTER: 14000100c: 25 00 00 94 bl #148
# AFTER: 140001010: 00 21 40 39 ldrb w0, [x8, #8]
# AFTER: 140001014: 00 11 40 79 ldrh w0, [x8, #8]
# AFTER: 140001018: 00 09 40 b9 ldr w0, [x8, #8]
@@ -84,11 +85,12 @@
# AFTER: 140001088: 00 c4 41 f9 ldr x0, [x0, #904]
# AFTER: 14000108c: 03 00 00 00 udf #3
# AFTER: 140001090: e0 95 09 30 adr x0, #78525
-# AFTER: 140001094: 41 00 00 54 b.ne #8
-# AFTER: 140001098: 20 00 00 36 tbz w0, #0, #4
-# AFTER: 14000109c: 10 00 00 b0 adrp x16, #4096
-# AFTER: 1400010a0: 10 2a 40 f9 ldr x16, [x16, #80]
-# AFTER: 1400010a4: 00 02 1f d6 br x16
+# AFTER: 140001094: 61 00 00 54 b.ne #12
+# AFTER: 140001098: 40 00 00 36 tbz w0, #0, #8
+# AFTER: 14000109c: 61 ff ff ff <unknown>
+# AFTER: 1400010a0: 10 00 00 b0 adrp x16, #4096
+# AFTER: 1400010a4: 10 2a 40 f9 ldr x16, [x16, #80]
+# AFTER: 1400010a8: 00 02 1f d6 br x16
--- !COFF
header:
@@ -98,7 +100,7 @@ sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4
- SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD6080000000000000001000000010000000000009100004091000040f901000000201a09300100005400000036
+ SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD6080000000000000001000000010000000000009100004091000040f901000000201a0930010000540000003601000000
Relocations:
- VirtualAddress: 4
SymbolName: .Lstr
@@ -202,6 +204,9 @@ sections:
- VirtualAddress: 152
SymbolName: function
Type: IMAGE_REL_ARM64_BRANCH14
+ - VirtualAddress: 156
+ SymbolName: main
+ Type: IMAGE_REL_ARM64_REL32
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
diff --git a/test/COFF/arm64-thunks.s b/test/COFF/arm64-thunks.s
new file mode 100644
index 000000000..49004544c
--- /dev/null
+++ b/test/COFF/arm64-thunks.s
@@ -0,0 +1,27 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.obj
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
+// RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
+
+// VERBOSE: Added 1 thunks with margin {{.*}} in 1 passes
+
+ .globl main
+ .globl func1
+ .text
+main:
+ tbz w0, #0, func1
+ ret
+ .section .text$a, "xr"
+ .space 0x8000
+ .section .text$b, "xr"
+func1:
+ ret
+
+// DISASM: 0000000140001000 .text:
+// DISASM: 140001000: 40 00 00 36 tbz w0, #0, #8 <.text+0x8>
+// DISASM: 140001004: c0 03 5f d6 ret
+// DISASM: 140001008: 50 00 00 90 adrp x16, #32768
+// DISASM: 14000100c: 10 52 00 91 add x16, x16, #20
+// DISASM: 140001010: 00 02 1f d6 br x16
+
+// DISASM: 140009014: c0 03 5f d6 ret
diff --git a/test/COFF/armnt-rel32.yaml b/test/COFF/armnt-rel32.yaml
new file mode 100644
index 000000000..fa385c5fd
--- /dev/null
+++ b/test/COFF/armnt-rel32.yaml
@@ -0,0 +1,47 @@
+# REQUIRES: arm
+
+# RUN: yaml2obj < %s > %t.obj
+# RUN: llvm-objdump -s %t.obj | FileCheck %s -check-prefix BEFORE
+# RUN: lld-link /entry:function /subsystem:console /out:%t.exe %t.obj
+# RUN: llvm-objdump -s %t.exe | FileCheck %s -check-prefix AFTER
+
+# BEFORE: Contents of section .text:
+# BEFORE: 0000 704700bf 01000000 01000000
+
+# AFTER: Contents of section .text:
+# AFTER: 401000 704700bf faffffff f50f0000
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_ARMNT
+ Characteristics: []
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: 704700BF0100000001000000
+ Relocations:
+ - VirtualAddress: 4
+ SymbolName: function
+ Type: IMAGE_REL_ARM_REL32
+ - VirtualAddress: 8
+ SymbolName: data
+ Type: IMAGE_REL_ARM_REL32
+ - Name: .rdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ SectionData: 00
+symbols:
+ - Name: function
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: data
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/associative-comdat-empty.test b/test/COFF/associative-comdat-empty.test
new file mode 100644
index 000000000..c4ee8b725
--- /dev/null
+++ b/test/COFF/associative-comdat-empty.test
@@ -0,0 +1,56 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: not lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe 2>&1 | FileCheck %s
+
+# Tests an associative comdat being associated with an empty section errors.
+# CHECK: lld-link: error: {{.*}}: associative comdat .text$ac1 (sec 1) has invalid reference to section .text$nm (sec 2)
+# CHECK-NOT: lld-link: error:
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: '.text$ac1'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+ Alignment: 1
+ SectionData: '01000000'
+ - Name: '.text$nm'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+ Alignment: 1
+ SectionData: '01000000'
+symbols:
+ - Name: '.text$ac1'
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 4
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 3099354981
+ Number: 2
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+ - Name: '.text$nm'
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 0
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 3099354981
+ Number: 4
+ Selection: IMAGE_COMDAT_SELECT_ANY
+ - Name: assocsym
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+...
+
+
diff --git a/test/COFF/associative-comdat-order.test b/test/COFF/associative-comdat-order.test
new file mode 100644
index 000000000..c7756f348
--- /dev/null
+++ b/test/COFF/associative-comdat-order.test
@@ -0,0 +1,97 @@
+# Tests that an associative comdat being associated with another
+# associated comdat later in the file produces an error.
+# RUN: sed -e s/ASSOC1/2/ -e s/ASSOC2/3/ %s | yaml2obj > %t.obj
+# RUN: not lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe 2>&1 | FileCheck --check-prefix=FORWARD %s
+# FORWARD: lld-link: error: {{.*}}: associative comdat .text$ac1 (sec 1) has invalid reference to section .text$ac2 (sec 2)
+# FORWARD-NOT: lld-link: error:
+
+# Tests that an associative comdat being associated with another
+# associated comdat earlier in the file works.
+# RUN: sed -e s/ASSOC1/3/ -e s/ASSOC2/1/ %s | yaml2obj > %t.obj
+
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=BACKWARD %s
+# BACKWARD: Contents of section .text:
+# BACKWARD: 180001000 01000000 02000000 03000000 ............
+
+# RUN: lld-link /dll /noentry /nodefaultlib %t.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=BACKWARDDROP %s
+# BACKWARDDROP-NOT: Contents of section .text:
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: '.text$ac1'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+ Alignment: 1
+ SectionData: '01000000'
+ - Name: '.text$ac2'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+ Alignment: 1
+ SectionData: '02000000'
+ - Name: '.text$nm'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+ Alignment: 1
+ SectionData: '03000000'
+symbols:
+ - Name: '.text$ac1'
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 4
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 3099354981
+ Number: ASSOC1
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+ - Name: '.text$ac2'
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 4
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 3099354981
+ Number: ASSOC2
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+ - Name: '.text$nm'
+ Value: 0
+ SectionNumber: 3
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 4
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 3099354981
+ Number: 4
+ Selection: IMAGE_COMDAT_SELECT_ANY
+ - Name: symbol
+ Value: 0
+ SectionNumber: 3
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: assocsym2
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - Name: assocsym
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+...
+
diff --git a/test/COFF/color-diagnostics.test b/test/COFF/color-diagnostics.test
new file mode 100644
index 000000000..a231f1fcf
--- /dev/null
+++ b/test/COFF/color-diagnostics.test
@@ -0,0 +1,18 @@
+# Windows command prompt doesn't support ANSI escape sequences.
+# REQUIRES: shell
+
+# RUN: not lld-link -xyz --color-diagnostics /nosuchfile 2>&1 \
+# RUN: | FileCheck -check-prefix=COLOR %s
+# RUN: not lld-link -xyz --color-diagnostics=always /nosuchfile 2>&1 \
+# RUN: | FileCheck -check-prefix=COLOR %s
+
+# COLOR: {{lld-link: .\[0;1;35mwarning: .\[0mignoring unknown argument: -xyz}}
+# COLOR: {{lld-link: .\[0;1;31merror: .\[0mcould not open /nosuchfile}}
+
+# RUN: not lld-link /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s
+# RUN: not lld-link -color-diagnostics=never /nosuchfile 2>&1 \
+# RUN: | FileCheck -check-prefix=NOCOLOR %s
+# RUN: not lld-link -color-diagnostics=always -no-color-diagnostics \
+# RUN: /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s
+
+# NOCOLOR: lld-link: error: could not open /nosuchfile
diff --git a/test/COFF/comdat-selection-associative-largest.s b/test/COFF/comdat-selection-associative-largest.s
new file mode 100644
index 000000000..301aaec1f
--- /dev/null
+++ b/test/COFF/comdat-selection-associative-largest.s
@@ -0,0 +1,45 @@
+# REQUIRES: x86
+
+# Tests handling of several comdats with "largest" selection type that each
+# has an associative comdat.
+
+# Create obj files.
+# RUN: sed -e s/TYPE/.byte/ -e s/SIZE/1/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.1.obj
+# RUN: sed -e s/TYPE/.short/ -e s/SIZE/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.2.obj
+# RUN: sed -e s/TYPE/.long/ -e s/SIZE/4/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.4.obj
+
+ .section .text$ac, "", associative, symbol
+assocsym:
+ .long SIZE
+
+ .section .text$nm, "", largest, symbol
+ .globl symbol
+symbol:
+ TYPE SIZE
+
+# Pass the obj files in different orders and check that only the associative
+# comdat of the largest obj file makes it into the output, independent of
+# the order of the obj files on the command line.
+
+# FIXME: Make these pass when /opt:noref is passed.
+
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.1.obj %t.2.obj %t.4.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=ALL124 %s
+# ALL124: Contents of section .text:
+# ALL124: 180001000 04000000 04000000 ....
+
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.4.obj %t.2.obj %t.1.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=ALL421 %s
+# ALL421: Contents of section .text:
+# ALL421: 180001000 04000000 04000000 ....
+
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.2.obj %t.4.obj %t.1.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=ALL241 %s
+# ALL241: Contents of section .text:
+# ALL241: 180001000 04000000 04000000 ....
+
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.2.obj %t.1.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=JUST21 %s
+# JUST21: Contents of section .text:
+# JUST21: 180001000 02000000 0200 ....
+
diff --git a/test/COFF/comdat-selection.s b/test/COFF/comdat-selection.s
new file mode 100644
index 000000000..4926173ab
--- /dev/null
+++ b/test/COFF/comdat-selection.s
@@ -0,0 +1,98 @@
+# REQUIRES: x86
+
+# Tests handling of the comdat selection type.
+# (Except associative which is tested in associative-comdat.s and
+# comdat-selection-associate-largest.s instead.)
+
+# Create obj files with each selection type.
+# RUN: sed -e s/SEL/discard/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.discard.obj
+# RUN: sed -e s/SEL/discard/ -e s/.long/.short/ -e s/1/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.discard.short.2.obj
+# RUN: sed -e s/SEL/one_only/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.one_only.obj
+# RUN: sed -e s/SEL/same_size/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_size.obj
+# RUN: sed -e s/SEL/same_size/ -e s/.long/.short/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_size.short.obj
+# RUN: sed -e s/SEL/same_contents/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_contents.obj
+# RUN: sed -e s/SEL/same_contents/ -e s/.long/.short/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_contents.short.obj
+# RUN: sed -e s/SEL/same_contents/ -e s/1/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_contents.2.obj
+# RUN: sed -e s/SEL/largest/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.largest.obj
+# RUN: sed -e s/SEL/largest/ -e s/.long/.short/ -e s/1/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.largest.short.2.obj
+# RUN: sed -e s/SEL/newest/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.newest.obj
+
+ .section .text$nm, "", SEL, symbol
+ .globl symbol
+symbol:
+ .long 1
+
+# First, pass each selection type twice. All should link fine except for
+# one_only which should report a duplicate symbol error and newest which
+# link.exe (and hence lld-link) doesn't understand.
+
+# RUN: cp %t.discard.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.discard.obj %t.obj
+# RUN: cp %t.one_only.obj %t.obj && not lld-link /dll /noentry /nodefaultlib %t.one_only.obj %t.obj 2>&1 | FileCheck --check-prefix=ONEONE %s
+# ONEONE: lld-link: error: duplicate symbol: symbol
+# RUN: cp %t.same_size.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.same_size.obj %t.obj
+# RUN: cp %t.same_contents.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.obj
+# RUN: cp %t.largest.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.largest.obj %t.obj
+# RUN: cp %t.newest.obj %t.obj && not lld-link /dll /noentry /nodefaultlib %t.newest.obj %t.obj 2>&1 | FileCheck --check-prefix=NEWNEW %s
+# NEWNEW: lld-link: error: unknown comdat type 7 for symbol
+
+# /force doesn't affect errors about unknown comdat types.
+# RUN: cp %t.newest.obj %t.obj && not lld-link /force /dll /noentry /nodefaultlib %t.newest.obj %t.obj 2>&1 | FileCheck --check-prefix=NEWNEWFORCE %s
+# NEWNEWFORCE: lld-link: error: unknown comdat type 7 for symbol
+
+# Check that same_size, same_contents, largest do what they're supposed to.
+
+# Check that the "same_size" selection produces an error if passed two symbols
+# with different size.
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_size.obj %t.same_size.short.obj 2>&1 | FileCheck --check-prefix=SAMESIZEDUPE %s
+# SAMESIZEDUPE: lld-link: error: duplicate symbol: symbol
+
+# Check that the "same_contents" selection produces an error if passed two
+# symbols with different contents.
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.same_contents.2.obj 2>&1 | FileCheck --check-prefix=SAMECONTENTSDUPE1 %s
+# SAMECONTENTSDUPE1: lld-link: error: duplicate symbol: symbol
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.same_contents.2.obj 2>&1 | FileCheck --check-prefix=SAMECONTENTSDUPE2 %s
+# SAMECONTENTSDUPE2: lld-link: error: duplicate symbol: symbol
+
+# Check that the "largest" selection picks the larger comdat (independent of
+# the order the .obj files are passed on the commandline).
+# RUN: lld-link /opt:noref /include:symbol /dll /noentry /nodefaultlib %t.largest.obj %t.largest.short.2.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=LARGEST1 %s
+# LARGEST1: Contents of section .text:
+# LARGEST1: 180001000 01000000 ....
+
+# FIXME: Make this pass when /opt:noref is passed.
+# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.largest.short.2.obj %t.largest.obj /out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=LARGEST2 %s
+# LARGEST2: Contents of section .text:
+# LARGEST2: 180001000 01000000 ....
+
+
+# Test linking the same symbol with different comdat selection types.
+# link.exe generally rejects this, except for "largest" which is allowed to
+# combine with everything (https://bugs.llvm.org/show_bug.cgi?id=40094#c7).
+# lld-link rejects all comdat selection type mismatches. Spot-test just a few
+# combinations.
+
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.discard.obj %t.one_only.obj 2>&1 | FileCheck --check-prefix=DISCARDONE %s
+# DISCARDONE: lld-link: error: conflicting comdat type for symbol: 2 in
+# RUN: lld-link /force /dll /noentry /nodefaultlib %t.discard.obj %t.one_only.obj 2>&1 | FileCheck --check-prefix=DISCARDONEFORCE %s
+# DISCARDONEFORCE: lld-link: warning: conflicting comdat type for symbol: 2 in
+
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.same_size.obj 2>&1 | FileCheck --check-prefix=CONTENTSSIZE %s
+# CONTENTSSIZE: lld-link: error: conflicting comdat type for symbol: 4 in
+
+# Check that linking one 'discard' and one 'largest' has the effect of
+# 'largest'.
+# RUN: lld-link /dll /noentry /nodefaultlib %t.discard.short.2.obj %t.largest.obj
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=DISCARDLARGEST %s
+# DISCARDLARGEST: Contents of section .text:
+# DISCARDLARGEST: 180001000 01000000 ....
+# RUN: lld-link /dll /noentry /nodefaultlib %t.largest.obj %t.discard.short.2.obj
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=LARGESTDISCARD %s
+# LARGESTDISCARD: Contents of section .text:
+# LARGESTDISCARD: 180001000 01000000 ....
+
+
+# These cases are accepted by link.exe but not by lld-link.
+# RUN: not lld-link /dll /noentry /nodefaultlib %t.largest.obj %t.one_only.obj 2>&1 | FileCheck --check-prefix=LARGESTONE %s
+# LARGESTONE: lld-link: error: conflicting comdat type for symbol: 6 in
diff --git a/test/COFF/crt-dyn-initializer-order.test b/test/COFF/crt-dyn-initializer-order.test
index 963b06577..40f2e0ca1 100644
--- a/test/COFF/crt-dyn-initializer-order.test
+++ b/test/COFF/crt-dyn-initializer-order.test
@@ -1,100 +1,100 @@
-# // a.cpp
-# #include <iostream>
-# #include <vector>
-#
-# template <int Magic> struct TemplatedObject {
-# static std::vector<TemplatedObject<Magic> *> Instances;
-# TemplatedObject() { Instances.push_back(this); }
-# };
-#
-# using Object = TemplatedObject<0>;
-# template <> std::vector<Object *> Object::Instances{};
-# Object idle{};
-#
-# int main() {
-# if (Object::Instances.size() == 0)
-# std::cout << "It's broken" << std::endl;
-# else
-# std::cout << "It works!" << std::endl;
-# return 0;
-# }
-# // using `clang-cl /c a.cpp | lld-link a.obj` works
-# // using `cl /c a.cpp | lld-link a.obj` fails without lld/COFF/Writer.cpp/Writer::sortSectionChunks()
-
-# RUN: yaml2obj %s > %t.obj
-# RUN: yaml2obj %S/Inputs/crt-dyn-initializer-order_1.yaml > %t1.obj
-# RUN: yaml2obj %S/Inputs/crt-dyn-initializer-order_2.yaml > %t2.obj
-
-# CHECK: Name: .CRT
-# CHECK: Characteristics [
-# CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
-# CHECK-NEXT: IMAGE_SCN_MEM_READ
-# CHECK-NEXT: ]
-# CHECK-NEXT: SectionData (
-
-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj %t1.obj %t2.obj
-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE1
-# CASE1-NEXT: 01020304 55701011 1205
-
-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj %t2.obj %t1.obj
-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE2
-# CASE2-NEXT: 01020304 10111255 7005
-
-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t1.obj %t2.obj %t.obj
-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE3
-# CASE3-NEXT: 01557010 11120203 0405
-
-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t1.obj %t.obj %t2.obj
-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE4
-# CASE4-NEXT: 01557002 03041011 1205
-
-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t2.obj %t1.obj %t.obj
-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE5
-# CASE5-NEXT: 01101112 55700203 0405
-
-# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t2.obj %t.obj %t1.obj
-# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE6
-# CASE6-NEXT: 01101112 02030455 7005
-
-# CHECK-NEXT: )
-
---- !COFF
-header:
- Machine: IMAGE_FILE_MACHINE_AMD64
- Characteristics: [ ]
-sections:
- - Name: '.CRT$XCA'
- Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
- Alignment: 1
- SectionData: 01
- - Name: '.CRT$XCU'
- Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
- Alignment: 1
- SectionData: 02
- - Name: '.CRT$XCU'
- Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_LNK_COMDAT ]
- Alignment: 1
- SectionData: 03
- - Name: '.CRT$XCU'
- Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
- Alignment: 1
- SectionData: 04
- - Name: '.CRT$XCZ'
- Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
- Alignment: 1
- SectionData: 05
-symbols:
- - Name: '.CRT$XCU'
- Value: 0
- SectionNumber: 3
- SimpleType: IMAGE_SYM_TYPE_NULL
- ComplexType: IMAGE_SYM_DTYPE_NULL
- StorageClass: IMAGE_SYM_CLASS_STATIC
- SectionDefinition:
- Length: 1
- NumberOfRelocations: 0
- NumberOfLinenumbers: 0
- CheckSum: 1
- Number: 2
- Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
-...
+# // a.cpp
+# #include <iostream>
+# #include <vector>
+#
+# template <int Magic> struct TemplatedObject {
+# static std::vector<TemplatedObject<Magic> *> Instances;
+# TemplatedObject() { Instances.push_back(this); }
+# };
+#
+# using Object = TemplatedObject<0>;
+# template <> std::vector<Object *> Object::Instances{};
+# Object idle{};
+#
+# int main() {
+# if (Object::Instances.size() == 0)
+# std::cout << "It's broken" << std::endl;
+# else
+# std::cout << "It works!" << std::endl;
+# return 0;
+# }
+# // using `clang-cl /c a.cpp | lld-link a.obj` works
+# // using `cl /c a.cpp | lld-link a.obj` fails without lld/COFF/Writer.cpp/Writer::sortSectionChunks()
+
+# RUN: yaml2obj %s > %t.obj
+# RUN: yaml2obj %S/Inputs/crt-dyn-initializer-order_1.yaml > %t1.obj
+# RUN: yaml2obj %S/Inputs/crt-dyn-initializer-order_2.yaml > %t2.obj
+
+# CHECK: Name: .CRT
+# CHECK: Characteristics [
+# CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
+# CHECK-NEXT: IMAGE_SCN_MEM_READ
+# CHECK-NEXT: ]
+# CHECK-NEXT: SectionData (
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj %t1.obj %t2.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE1
+# CASE1-NEXT: 01020304 55701011 1205
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj %t2.obj %t1.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE2
+# CASE2-NEXT: 01020304 10111255 7005
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t1.obj %t2.obj %t.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE3
+# CASE3-NEXT: 01557010 11120203 0405
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t1.obj %t.obj %t2.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE4
+# CASE4-NEXT: 01557002 03041011 1205
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t2.obj %t1.obj %t.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE5
+# CASE5-NEXT: 01101112 55700203 0405
+
+# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t2.obj %t.obj %t1.obj
+# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s --check-prefixes CHECK,CASE6
+# CASE6-NEXT: 01101112 02030455 7005
+
+# CHECK-NEXT: )
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: '.CRT$XCA'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ SectionData: 01
+ - Name: '.CRT$XCU'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ SectionData: 02
+ - Name: '.CRT$XCU'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_LNK_COMDAT ]
+ Alignment: 1
+ SectionData: 03
+ - Name: '.CRT$XCU'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ SectionData: 04
+ - Name: '.CRT$XCZ'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ SectionData: 05
+symbols:
+ - Name: '.CRT$XCU'
+ Value: 0
+ SectionNumber: 3
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 1
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 1
+ Number: 2
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+...
diff --git a/test/COFF/ignore-many.test b/test/COFF/ignore-many.test
new file mode 100644
index 000000000..31398106c
--- /dev/null
+++ b/test/COFF/ignore-many.test
@@ -0,0 +1,16 @@
+Tests /ignore with more than one argument.
+
+RUN: yaml2obj %S/ignore4217.yaml > %t1.obj
+RUN: yaml2obj %S/Inputs/pdb-type-server-missing-2.yaml > %t2.obj
+RUN: echo foo > %t3.order
+
+RUN: lld-link /entry:main /out:%t.exe %t1.obj %t2.obj /order:@%t3.order /debug 2>&1 | FileCheck -check-prefix=WARNINGS %s
+RUN: lld-link /entry:main /out:%t.exe %t1.obj %t2.obj /order:@%t3.order /debug /ignore:4217,4099,4037 2>&1 | FileCheck -allow-empty -check-prefix=SUPPRESSED %s
+
+WARNINGS: locally defined symbol imported
+WARNINGS: missing symbol: foo
+WARNINGS: warning: Cannot use debug info for
+
+SUPPRESSED-NOT: locally defined symbol imported
+SUPPRESSED-NOT: missing symbol: foo
+SUPPRESSED-NOT: warning: Cannot use debug info for
diff --git a/test/COFF/imports.test b/test/COFF/imports.test
index 64f3900a1..f54bdfd88 100644
--- a/test/COFF/imports.test
+++ b/test/COFF/imports.test
@@ -34,3 +34,16 @@ IMPORT-NEXT: Symbol: ExitProcess (0)
IMPORT-NEXT: Symbol: (50)
IMPORT-NEXT: Symbol: MessageBoxA (1)
IMPORT-NEXT: }
+
+# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /merge:.rdata=.text \
+# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=MERGE %s
+
+MERGE: Import {
+MERGE-NEXT: Name: std64.dll
+MERGE-NEXT: ImportLookupTableRVA: 0x1090
+MERGE-NEXT: ImportAddressTableRVA: 0x10B0
+MERGE-NEXT: Symbol: ExitProcess (0)
+MERGE-NEXT: Symbol: (50)
+MERGE-NEXT: Symbol: MessageBoxA (1)
+MERGE-NEXT: }
diff --git a/test/COFF/line-error.yaml b/test/COFF/line-error.yaml
new file mode 100644
index 000000000..55fb723a6
--- /dev/null
+++ b/test/COFF/line-error.yaml
@@ -0,0 +1,160 @@
+# RUN: yaml2obj %s -o %t.obj
+# RUN: not lld-link %t.obj /subsystem:console 2>&1 | FileCheck %s
+
+# CHECK: lld-link: error: undefined symbol: function
+# CHECK-NEXT: >>> referenced by {{.*}}line-error.yaml.tmp.obj:(caller1)
+# CHECK-NEXT: >>> referenced by E:\file.cpp:1935
+# CHECK-NEXT: >>> {{.*}}line-error.yaml.tmp.obj:(caller22)
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 488B0500000000488B51284881C2D80000004889C148FF2500000000
+ Relocations:
+ - VirtualAddress: 3
+ SymbolName: function
+ Type: IMAGE_REL_AMD64_REL32
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 488B0500000000488B51084881C2D80000004889C148FF2500000000
+ Relocations:
+ - VirtualAddress: 3
+ SymbolName: function
+ Type: IMAGE_REL_AMD64_REL32
+ - Name: '.debug$S'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ Subsections:
+ - !FileChecksums
+ Checksums:
+ - FileName: 'E:\file.cpp'
+ Kind: MD5
+ Checksum: D72EDEF8B8E50C364A330F9CB3CD904B
+ - !StringTable
+ Strings:
+ - 'E:\file.cpp'
+ - Name: '.debug$S'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ Subsections:
+ - !Lines
+ CodeSize: 28
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks: []
+ Relocations:
+ - VirtualAddress: 12
+ SymbolName: caller1
+ Type: IMAGE_REL_AMD64_SECREL
+ - Name: '.debug$S'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ Subsections:
+ - !Lines
+ CodeSize: 28
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'E:\file.cpp'
+ Lines:
+ - Offset: 11
+ LineStart: 1935
+ IsStatement: false
+ EndDelta: 0
+ Columns: []
+ Relocations:
+ - VirtualAddress: 12
+ SymbolName: caller22
+ Type: IMAGE_REL_AMD64_SECREL
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 28
+ NumberOfRelocations: 2
+ NumberOfLinenumbers: 0
+ CheckSum: 2430089736
+ Number: 1
+ Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
+ - Name: caller1
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: .text
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 28
+ NumberOfRelocations: 2
+ NumberOfLinenumbers: 0
+ CheckSum: 3449717304
+ Number: 2
+ Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
+ - Name: caller22
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: '.debug$S'
+ Value: 0
+ SectionNumber: 3
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 767204
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 4280093374
+ Number: 3
+ - Name: '.debug$S'
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 296
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 1957793731
+ Number: 1
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+ - Name: '.debug$S'
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 276
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 1957793731
+ Number: 2
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+ - Name: function
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/lto-lazy-reference.ll b/test/COFF/lto-lazy-reference.ll
index 1e9287377..428a7b845 100644
--- a/test/COFF/lto-lazy-reference.ll
+++ b/test/COFF/lto-lazy-reference.ll
@@ -9,6 +9,10 @@
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc18.0.0"
+; Define fltused, since we don't link against the MS C runtime but are
+; using floats.
+@_fltused = dllexport global i32 0, align 4
+
define double @main(double %x) {
entry:
; When compiled, this defines the __real@40800000 symbol, which already has a
diff --git a/test/COFF/lto-new-symbol.ll b/test/COFF/lto-new-symbol.ll
index 5223f73f0..dadd49537 100644
--- a/test/COFF/lto-new-symbol.ll
+++ b/test/COFF/lto-new-symbol.ll
@@ -5,6 +5,10 @@
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
+; Define fltused, since we don't link against the MS C runtime but are
+; using floats.
+@_fltused = dllexport global i32 0, align 4
+
define void @foo(<4 x i32>* %p, <4 x float>* %q, i1 %t) nounwind {
entry:
br label %loop
diff --git a/test/COFF/pdb-relative-source-lines.test b/test/COFF/pdb-relative-source-lines.test
index 865d7a6d8..547056785 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/COFF/pdb-tpi-hash-size.test b/test/COFF/pdb-tpi-hash-size.test
new file mode 100644
index 000000000..3635a5caf
--- /dev/null
+++ b/test/COFF/pdb-tpi-hash-size.test
@@ -0,0 +1,10 @@
+# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
+# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
+# RUN: rm -f %t.dll %t.pdb
+# RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll \
+# RUN: /entry:main /nodefaultlib %t1.obj %t2.obj
+
+# RUN: llvm-pdbutil dump -types -type-extras %t.pdb | FileCheck %s
+
+CHECK: Hash Key Size: 4
+CHECK-NEXT: Num Hash Buckets: 262143
diff --git a/test/COFF/pdb-type-server-missing.yaml b/test/COFF/pdb-type-server-missing.yaml
index 7766a48c1..1a8c9a05c 100644
--- a/test/COFF/pdb-type-server-missing.yaml
+++ b/test/COFF/pdb-type-server-missing.yaml
@@ -4,13 +4,22 @@
# RUN: yaml2obj %s -o %t1.obj
# RUN: yaml2obj %p/Inputs/pdb-type-server-missing-2.yaml -o %t2.obj
-# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
+# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s -check-prefix=WARN
+# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main /ignore:4099 2>&1 | FileCheck %s -check-prefix=IGNORE -allow-empty
+# RUN: not lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main /WX 2>&1 | FileCheck %s -check-prefix=ERR
+# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main /ignore:4099 /WX 2>&1 | FileCheck %s -check-prefix=IGNORE-ERR -allow-empty
-# CHECK: warning: Cannot use debug info for {{.*}}.obj
-# CHECK-NEXT: {{N|n}}o such file or directory
+# WARN: warning: Cannot use debug info for '{{.*}}.obj' [LNK4099]
+# WARN-NEXT: {{N|n}}o such file or directory
-# CHECK: warning: Cannot use debug info for {{.*}}.obj
-# CHECK-NEXT: {{N|n}}o such file or directory
+# IGNORE-NOT: warning: Cannot use debug info for '{{.*}}.obj' [LNK4099]
+# IGNORE-NOT: {{N|n}}o such file or directory
+
+# ERR: error: Cannot use debug info for '{{.*}}.obj' [LNK4099]
+# ERR-NEXT: {{N|n}}o such file or directory
+
+# IGNORE-ERR-NOT: error: Cannot use debug info for '{{.*}}.obj' [LNK4099]
+# IGNORE-ERR-NOT: {{N|n}}o such file or directory
--- !COFF
header:
diff --git a/test/COFF/pdb.test b/test/COFF/pdb.test
index 5788b516a..745000c34 100644
--- a/test/COFF/pdb.test
+++ b/test/COFF/pdb.test
@@ -142,40 +142,40 @@ RAW-NEXT: pdb file ni: 1 `{{.*pdb.test.tmp.pdb}}`, src file ni: 0 `
RAW: Types (TPI Stream)
RAW-NEXT: ============================================================
RAW-NEXT: Showing 5 records
-RAW-NEXT: 0x1000 | LF_ARGLIST [size = 8, hash = 0xEC0]
-RAW-NEXT: 0x1001 | LF_PROCEDURE [size = 16, hash = 0x7BC]
+RAW-NEXT: 0x1000 | LF_ARGLIST [size = 8, hash = 0x32484]
+RAW-NEXT: 0x1001 | LF_PROCEDURE [size = 16, hash = 0x27EE9]
RAW-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1000
RAW-NEXT: calling conv = cdecl, options = None
-RAW-NEXT: 0x1002 | LF_POINTER [size = 12, hash = 0x884]
+RAW-NEXT: 0x1002 | LF_POINTER [size = 12, hash = 0x39732]
RAW-NEXT: referent = 0x1001, mode = pointer, opts = None, kind = ptr64
-RAW-NEXT: 0x1003 | LF_ARGLIST [size = 12, hash = 0x936]
+RAW-NEXT: 0x1003 | LF_ARGLIST [size = 12, hash = 0x1FC10]
RAW-NEXT: <no type>: ``
-RAW-NEXT: 0x1004 | LF_PROCEDURE [size = 16, hash = 0x852]
+RAW-NEXT: 0x1004 | LF_PROCEDURE [size = 16, hash = 0x1BD3]
RAW-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1003
RAW-NEXT: calling conv = cdecl, options = None
RAW: Types (IPI Stream)
RAW-NEXT: ============================================================
RAW-NEXT: Showing 12 records
-RAW-NEXT: 0x1000 | LF_FUNC_ID [size = 20, hash = 0x330]
+RAW-NEXT: 0x1000 | LF_FUNC_ID [size = 20, hash = 0x38E5A]
RAW-NEXT: name = main, type = 0x1004, parent scope = <no type>
-RAW-NEXT: 0x1001 | LF_FUNC_ID [size = 16, hash = 0x120]
+RAW-NEXT: 0x1001 | LF_FUNC_ID [size = 16, hash = 0xD08E]
RAW-NEXT: name = foo, type = 0x1001, parent scope = <no type>
-RAW-NEXT: 0x1002 | LF_STRING_ID [size = 16, hash = 0x757] ID: <no type>, String: D:\b
-RAW-NEXT: 0x1003 | LF_STRING_ID [size = 36, hash = 0xC3A] ID: <no type>, String: C:\vs14\VC\BIN\amd64\cl.exe
-RAW-NEXT: 0x1004 | LF_STRING_ID [size = 260, hash = 0x433] ID: <no type>, String: -Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"
-RAW-NEXT: 0x1005 | LF_SUBSTR_LIST [size = 12, hash = 0x759]
+RAW-NEXT: 0x1002 | LF_STRING_ID [size = 16, hash = 0x3EBD9] ID: <no type>, String: D:\b
+RAW-NEXT: 0x1003 | LF_STRING_ID [size = 36, hash = 0xD327] ID: <no type>, String: C:\vs14\VC\BIN\amd64\cl.exe
+RAW-NEXT: 0x1004 | LF_STRING_ID [size = 260, hash = 0x2FA6A] ID: <no type>, String: -Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"
+RAW-NEXT: 0x1005 | LF_SUBSTR_LIST [size = 12, hash = 0x6053]
RAW-NEXT: 0x1004: `-Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"`
-RAW-NEXT: 0x1006 | LF_STRING_ID [size = 132, hash = 0xF57] ID: 0x1005, String: -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X
-RAW-NEXT: 0x1007 | LF_STRING_ID [size = 24, hash = 0x2D1] ID: <no type>, String: ret42-main.c
-RAW-NEXT: 0x1008 | LF_STRING_ID [size = 24, hash = 0xB8B] ID: <no type>, String: D:\b\vc140.pdb
-RAW-NEXT: 0x1009 | LF_BUILDINFO [size = 28, hash = 0xA8C]
+RAW-NEXT: 0x1006 | LF_STRING_ID [size = 132, hash = 0xCAC7] ID: 0x1005, String: -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X
+RAW-NEXT: 0x1007 | LF_STRING_ID [size = 24, hash = 0x21783] ID: <no type>, String: ret42-main.c
+RAW-NEXT: 0x1008 | LF_STRING_ID [size = 24, hash = 0x1DB87] ID: <no type>, String: D:\b\vc140.pdb
+RAW-NEXT: 0x1009 | LF_BUILDINFO [size = 28, hash = 0x5E91]
RAW-NEXT: 0x1002: `D:\b`
RAW-NEXT: 0x1003: `C:\vs14\VC\BIN\amd64\cl.exe`
RAW-NEXT: 0x1007: `ret42-main.c`
RAW-NEXT: 0x1008: `D:\b\vc140.pdb`
RAW-NEXT: 0x1006: ` -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X`
-RAW-NEXT: 0x100A | LF_STRING_ID [size = 20, hash = 0x39C] ID: <no type>, String: ret42-sub.c
-RAW-NEXT: 0x100B | LF_BUILDINFO [size = 28, hash = 0xAD7]
+RAW-NEXT: 0x100A | LF_STRING_ID [size = 20, hash = 0x7C68] ID: <no type>, String: ret42-sub.c
+RAW-NEXT: 0x100B | LF_BUILDINFO [size = 28, hash = 0x254D2]
RAW-NEXT: 0x1002: `D:\b`
RAW-NEXT: 0x1003: `C:\vs14\VC\BIN\amd64\cl.exe`
RAW-NEXT: 0x100A: `ret42-sub.c`
diff --git a/test/COFF/precomp-link.test b/test/COFF/precomp-link.test
index f7be26c87..7ba747e26 100644
--- a/test/COFF/precomp-link.test
+++ b/test/COFF/precomp-link.test
@@ -1,42 +1,42 @@
-RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
-RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
-
-RUN: lld-link %S/Inputs/precomp.obj %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
-RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
-
-RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-invalid.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE
-
-RUN: not lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE-MISSING-PRECOMPOBJ
-
-FAILURE: warning: Cannot use debug info for 'precomp-invalid.obj'
-FAILURE-NEXT: failed to load reference '{{.*}}precomp.obj': The signature does not match; the file(s) might be out of date.
-
-FAILURE-MISSING-PRECOMPOBJ: warning: Cannot use debug info for 'precomp-a.obj'
-FAILURE-MISSING-PRECOMPOBJ-NEXT: failed to load reference 'precomp.obj': The path to this file must be provided on the command-line
-
-CHECK: Types (TPI Stream)
-CHECK-NOT: LF_PRECOMP
-CHECK-NOT: LF_ENDPRECOMP
-
-// precomp.h
-#pragma once
-int Function(char A);
-
-// precomp.cpp
-#include "precomp.h"
-
-// a.cpp
-#include "precomp.h"
-int main(void) {
- Function('a');
- return 0;
-}
-
-// b.cpp
-#include "precomp.h"
-int Function(char a) {
- return (int)a;
-}
-
-// cl.exe precomp.cpp /Z7 /Ycprecomp.h /c
-// cl.exe a.cpp b.cpp /Z7 /Yuprecomp.h /c
+RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
+RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
+
+RUN: lld-link %S/Inputs/precomp.obj %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
+RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
+
+RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-invalid.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE
+
+RUN: not lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE-MISSING-PRECOMPOBJ
+
+FAILURE: warning: Cannot use debug info for 'precomp-invalid.obj' [LNK4099]
+FAILURE-NEXT: failed to load reference '{{.*}}precomp.obj': The signature does not match; the file(s) might be out of date.
+
+FAILURE-MISSING-PRECOMPOBJ: warning: Cannot use debug info for 'precomp-a.obj' [LNK4099]
+FAILURE-MISSING-PRECOMPOBJ-NEXT: failed to load reference '{{.*}}precomp.obj': The path to this file must be provided on the command-line
+
+CHECK: Types (TPI Stream)
+CHECK-NOT: LF_PRECOMP
+CHECK-NOT: LF_ENDPRECOMP
+
+// precomp.h
+#pragma once
+int Function(char A);
+
+// precomp.cpp
+#include "precomp.h"
+
+// a.cpp
+#include "precomp.h"
+int main(void) {
+ Function('a');
+ return 0;
+}
+
+// b.cpp
+#include "precomp.h"
+int Function(char a) {
+ return (int)a;
+}
+
+// cl.exe precomp.cpp /Z7 /Ycprecomp.h /c
+// cl.exe a.cpp b.cpp /Z7 /Yuprecomp.h /c
diff --git a/test/COFF/s_udt.s b/test/COFF/s_udt.s
index 8ad342e4e..900948aa8 100644
--- a/test/COFF/s_udt.s
+++ b/test/COFF/s_udt.s
@@ -27,450 +27,450 @@
# CHECK-NEXT: ============================================================
# CHECK: {{.*}} | S_GPROC32 [size = 44] `main`
# CHECK-NEXT: parent = 0, end = 252, addr = 0001:0000, code size = 52
-# CHECK-NEXT: type = `0x1002 (int (int, char**))`, debug start = 0, debug end = 0, flags = none
+# CHECK-NEXT: type = `0x1002 (int (int, char**))`, debug start = 0, debug end = 0, flags = none
# CHECK-NOT: {{.*}} | S_END
# CHECK: {{.*}} | S_UDT [size = 28] `main::LocalTypedef`
# CHECK-NEXT: original type = 0x1004
-# CHECK: {{.*}} | S_END [size = 4]
-
-# source code to re-generate:
-# clang-cl /Z7 /GS- /GR- /c foo.cpp
-#
-# struct Struct {
-# int x;
-# };
-#
-# using IntTypedef = int;
-# using StructTypedef = Struct;
-# Struct S;
-# StructTypedef SS;
-# IntTypedef I;
-#
-# int main(int argc, char **argv) {
-# using LocalTypedef = Struct*;
-# LocalTypedef SPtr;
-# return I + S.x + SS.x + SPtr->x;
+# CHECK: {{.*}} | S_END [size = 4]
+
+# source code to re-generate:
+# clang-cl /Z7 /GS- /GR- /c foo.cpp
+#
+# struct Struct {
+# int x;
+# };
+#
+# using IntTypedef = int;
+# using StructTypedef = Struct;
+# Struct S;
+# StructTypedef SS;
+# IntTypedef I;
+#
+# int main(int argc, char **argv) {
+# using LocalTypedef = Struct*;
+# LocalTypedef SPtr;
+# return I + S.x + SS.x + SPtr->x;
# }
- .text
- .def @feat.00;
- .scl 3;
- .type 0;
- .endef
- .globl @feat.00
-.set @feat.00, 0
- .intel_syntax noprefix
- .def main;
- .scl 2;
- .type 32;
- .endef
- .globl main # -- Begin function main
- .p2align 4, 0x90
-main: # @main
-.Lfunc_begin0:
- .cv_func_id 0
- .cv_file 1 "D:\\src\\llvmbuild\\cl\\Debug\\x64\\foo.cpp" "2B62298EE3EEF94E1D81FDFE18BD46A6" 1
- .cv_loc 0 1 12 0 # foo.cpp:12:0
-.seh_proc main
-# %bb.0: # %entry
- sub rsp, 32
- .seh_stackalloc 32
- .seh_endprologue
- mov dword ptr [rsp + 28], 0
- mov qword ptr [rsp + 16], rdx
- mov dword ptr [rsp + 12], ecx
-.Ltmp0:
- .cv_loc 0 1 15 0 # foo.cpp:15:0
- mov ecx, dword ptr [rip + "?I@@3HA"]
- add ecx, dword ptr [rip + "?S@@3UStruct@@A"]
- add ecx, dword ptr [rip + "?SS@@3UStruct@@A"]
- mov rdx, qword ptr [rsp]
- add ecx, dword ptr [rdx]
- mov eax, ecx
- add rsp, 32
- ret
-.Ltmp1:
-.Lfunc_end0:
- .seh_handlerdata
- .text
- .seh_endproc
- # -- End function
- .bss
- .globl "?S@@3UStruct@@A" # @"?S@@3UStruct@@A"
- .p2align 2
-"?S@@3UStruct@@A":
- .zero 4
-
- .globl "?SS@@3UStruct@@A" # @"?SS@@3UStruct@@A"
- .p2align 2
-"?SS@@3UStruct@@A":
- .zero 4
-
- .globl "?I@@3HA" # @"?I@@3HA"
- .p2align 2
-"?I@@3HA":
- .long 0 # 0x0
-
- .section .drectve,"yn"
- .ascii " /DEFAULTLIB:libcmt.lib"
- .ascii " /DEFAULTLIB:oldnames.lib"
- .section .debug$S,"dr"
- .p2align 2
- .long 4 # Debug section magic
- .long 241
- .long .Ltmp3-.Ltmp2 # Subsection size
-.Ltmp2:
- .short .Ltmp5-.Ltmp4 # Record length
-.Ltmp4:
- .short 4412 # Record kind: S_COMPILE3
- .long 1 # Flags and language
- .short 208 # CPUType
- .short 8 # Frontend version
- .short 0
- .short 0
- .short 0
- .short 8000 # Backend version
- .short 0
- .short 0
- .short 0
- .asciz "clang version 8.0.0 " # Null-terminated compiler version string
-.Ltmp5:
-.Ltmp3:
- .p2align 2
- .long 241 # Symbol subsection for main
- .long .Ltmp7-.Ltmp6 # Subsection size
-.Ltmp6:
- .short .Ltmp9-.Ltmp8 # Record length
-.Ltmp8:
- .short 4423 # Record kind: S_GPROC32_ID
- .long 0 # PtrParent
- .long 0 # PtrEnd
- .long 0 # PtrNext
- .long .Lfunc_end0-main # Code size
- .long 0 # Offset after prologue
- .long 0 # Offset before epilogue
- .long 4099 # Function type index
- .secrel32 main # Function section relative address
- .secidx main # Function section index
- .byte 0 # Flags
- .asciz "main" # Function name
-.Ltmp9:
- .short .Ltmp11-.Ltmp10 # Record length
-.Ltmp10:
- .short 4114 # Record kind: S_FRAMEPROC
- .long 32 # FrameSize
- .long 0 # Padding
- .long 0 # Offset of padding
- .long 0 # Bytes of callee saved registers
- .long 0 # Exception handler offset
- .short 0 # Exception handler section
- .long 81920 # Flags (defines frame register)
-.Ltmp11:
- .short .Ltmp13-.Ltmp12 # Record length
-.Ltmp12:
- .short 4414 # Record kind: S_LOCAL
- .long 116 # TypeIndex
- .short 1 # Flags
- .asciz "argc"
-.Ltmp13:
- .cv_def_range .Ltmp0 .Ltmp1, "B\021\f\000\000\000"
- .short .Ltmp15-.Ltmp14 # Record length
-.Ltmp14:
- .short 4414 # Record kind: S_LOCAL
- .long 4096 # TypeIndex
- .short 1 # Flags
- .asciz "argv"
-.Ltmp15:
- .cv_def_range .Ltmp0 .Ltmp1, "B\021\020\000\000\000"
- .short .Ltmp17-.Ltmp16 # Record length
-.Ltmp16:
- .short 4414 # Record kind: S_LOCAL
- .long 4101 # TypeIndex
- .short 0 # Flags
- .asciz "SPtr"
-.Ltmp17:
- .cv_def_range .Ltmp0 .Ltmp1, "B\021\000\000\000\000"
- .short .Ltmp19-.Ltmp18 # Record length
-.Ltmp18:
- .short 4360 # Record kind: S_UDT
- .long 4101 # Type
- .asciz "main::LocalTypedef"
-.Ltmp19:
- .short 2 # Record length
- .short 4431 # Record kind: S_PROC_ID_END
-.Ltmp7:
- .p2align 2
- .cv_linetable 0, main, .Lfunc_end0
- .long 241 # Symbol subsection for globals
- .long .Ltmp21-.Ltmp20 # Subsection size
-.Ltmp20:
- .short .Ltmp23-.Ltmp22 # Record length
-.Ltmp22:
- .short 4365 # Record kind: S_GDATA32
- .long 4103 # Type
- .secrel32 "?S@@3UStruct@@A" # DataOffset
- .secidx "?S@@3UStruct@@A" # Segment
- .asciz "S" # Name
-.Ltmp23:
- .short .Ltmp25-.Ltmp24 # Record length
-.Ltmp24:
- .short 4365 # Record kind: S_GDATA32
- .long 4100 # Type
- .secrel32 "?SS@@3UStruct@@A" # DataOffset
- .secidx "?SS@@3UStruct@@A" # Segment
- .asciz "SS" # Name
-.Ltmp25:
- .short .Ltmp27-.Ltmp26 # Record length
-.Ltmp26:
- .short 4365 # Record kind: S_GDATA32
- .long 116 # Type
- .secrel32 "?I@@3HA" # DataOffset
- .secidx "?I@@3HA" # Segment
- .asciz "I" # Name
-.Ltmp27:
-.Ltmp21:
- .p2align 2
- .long 241
- .long .Ltmp29-.Ltmp28 # Subsection size
-.Ltmp28:
- .short .Ltmp31-.Ltmp30 # Record length
-.Ltmp30:
- .short 4360 # Record kind: S_UDT
- .long 4103 # Type
- .asciz "Struct"
-.Ltmp31:
- .short .Ltmp33-.Ltmp32 # Record length
-.Ltmp32:
- .short 4360 # Record kind: S_UDT
- .long 4100 # Type
- .asciz "StructTypedef"
-.Ltmp33:
- .short .Ltmp35-.Ltmp34 # Record length
-.Ltmp34:
- .short 4360 # Record kind: S_UDT
- .long 116 # Type
- .asciz "IntTypedef"
-.Ltmp35:
-.Ltmp29:
- .p2align 2
- .cv_filechecksums # File index to string table offset subsection
- .cv_stringtable # String table
- .long 241
- .long .Ltmp37-.Ltmp36 # Subsection size
-.Ltmp36:
- .short 6 # Record length
- .short 4428 # Record kind: S_BUILDINFO
- .long 4108 # LF_BUILDINFO index
-.Ltmp37:
- .p2align 2
- .section .debug$T,"dr"
- .p2align 2
- .long 4 # Debug section magic
- # Pointer (0x1000) {
- # TypeLeafKind: LF_POINTER (0x1002)
- # PointeeType: char* (0x670)
- # PtrType: Near64 (0xC)
- # PtrMode: Pointer (0x0)
- # IsFlat: 0
- # IsConst: 0
- # IsVolatile: 0
- # IsUnaligned: 0
- # IsRestrict: 0
- # IsThisPtr&: 0
- # IsThisPtr&&: 0
- # SizeOf: 8
- # }
- .byte 0x0a, 0x00, 0x02, 0x10
- .byte 0x70, 0x06, 0x00, 0x00
- .byte 0x0c, 0x00, 0x01, 0x00
- # ArgList (0x1001) {
- # TypeLeafKind: LF_ARGLIST (0x1201)
- # NumArgs: 2
- # Arguments [
- # ArgType: int (0x74)
- # ArgType: char** (0x1000)
- # ]
- # }
- .byte 0x0e, 0x00, 0x01, 0x12
- .byte 0x02, 0x00, 0x00, 0x00
- .byte 0x74, 0x00, 0x00, 0x00
- .byte 0x00, 0x10, 0x00, 0x00
- # Procedure (0x1002) {
- # TypeLeafKind: LF_PROCEDURE (0x1008)
- # ReturnType: int (0x74)
- # CallingConvention: NearC (0x0)
- # FunctionOptions [ (0x0)
- # ]
- # NumParameters: 2
- # ArgListType: (int, char**) (0x1001)
- # }
- .byte 0x0e, 0x00, 0x08, 0x10
- .byte 0x74, 0x00, 0x00, 0x00
- .byte 0x00, 0x00, 0x02, 0x00
- .byte 0x01, 0x10, 0x00, 0x00
- # FuncId (0x1003) {
- # TypeLeafKind: LF_FUNC_ID (0x1601)
- # ParentScope: 0x0
- # FunctionType: int (int, char**) (0x1002)
- # Name: main
- # }
- .byte 0x12, 0x00, 0x01, 0x16
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x02, 0x10, 0x00, 0x00
- .byte 0x6d, 0x61, 0x69, 0x6e
- .byte 0x00, 0xf3, 0xf2, 0xf1
- # Struct (0x1004) {
- # TypeLeafKind: LF_STRUCTURE (0x1505)
- # MemberCount: 0
- # Properties [ (0x280)
- # ForwardReference (0x80)
- # HasUniqueName (0x200)
- # ]
- # FieldList: 0x0
- # DerivedFrom: 0x0
- # VShape: 0x0
- # SizeOf: 0
- # Name: Struct
- # LinkageName: .?AUStruct@@
- # }
- .byte 0x2a, 0x00, 0x05, 0x15
- .byte 0x00, 0x00, 0x80, 0x02
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x00, 0x00, 0x53, 0x74
- .byte 0x72, 0x75, 0x63, 0x74
- .byte 0x00, 0x2e, 0x3f, 0x41
- .byte 0x55, 0x53, 0x74, 0x72
- .byte 0x75, 0x63, 0x74, 0x40
- .byte 0x40, 0x00, 0xf2, 0xf1
- # Pointer (0x1005) {
- # TypeLeafKind: LF_POINTER (0x1002)
- # PointeeType: Struct (0x1004)
- # PtrType: Near64 (0xC)
- # PtrMode: Pointer (0x0)
- # IsFlat: 0
- # IsConst: 0
- # IsVolatile: 0
- # IsUnaligned: 0
- # IsRestrict: 0
- # IsThisPtr&: 0
- # IsThisPtr&&: 0
- # SizeOf: 8
- # }
- .byte 0x0a, 0x00, 0x02, 0x10
- .byte 0x04, 0x10, 0x00, 0x00
- .byte 0x0c, 0x00, 0x01, 0x00
- # FieldList (0x1006) {
- # TypeLeafKind: LF_FIELDLIST (0x1203)
- # DataMember {
- # TypeLeafKind: LF_MEMBER (0x150D)
- # AccessSpecifier: Public (0x3)
- # Type: int (0x74)
- # FieldOffset: 0x0
- # Name: x
- # }
- # }
- .byte 0x0e, 0x00, 0x03, 0x12
- .byte 0x0d, 0x15, 0x03, 0x00
- .byte 0x74, 0x00, 0x00, 0x00
- .byte 0x00, 0x00, 0x78, 0x00
- # Struct (0x1007) {
- # TypeLeafKind: LF_STRUCTURE (0x1505)
- # MemberCount: 1
- # Properties [ (0x200)
- # HasUniqueName (0x200)
- # ]
- # FieldList: <field list> (0x1006)
- # DerivedFrom: 0x0
- # VShape: 0x0
- # SizeOf: 4
- # Name: Struct
- # LinkageName: .?AUStruct@@
- # }
- .byte 0x2a, 0x00, 0x05, 0x15
- .byte 0x01, 0x00, 0x00, 0x02
- .byte 0x06, 0x10, 0x00, 0x00
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x04, 0x00, 0x53, 0x74
- .byte 0x72, 0x75, 0x63, 0x74
- .byte 0x00, 0x2e, 0x3f, 0x41
- .byte 0x55, 0x53, 0x74, 0x72
- .byte 0x75, 0x63, 0x74, 0x40
- .byte 0x40, 0x00, 0xf2, 0xf1
- # StringId (0x1008) {
- # TypeLeafKind: LF_STRING_ID (0x1605)
- # Id: 0x0
- # StringData: D:\src\llvmbuild\cl\Debug\x64\foo.cpp
- # }
- .byte 0x2e, 0x00, 0x05, 0x16
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x44, 0x3a, 0x5c, 0x73
- .byte 0x72, 0x63, 0x5c, 0x6c
- .byte 0x6c, 0x76, 0x6d, 0x62
- .byte 0x75, 0x69, 0x6c, 0x64
- .byte 0x5c, 0x63, 0x6c, 0x5c
- .byte 0x44, 0x65, 0x62, 0x75
- .byte 0x67, 0x5c, 0x78, 0x36
- .byte 0x34, 0x5c, 0x66, 0x6f
- .byte 0x6f, 0x2e, 0x63, 0x70
- .byte 0x70, 0x00, 0xf2, 0xf1
- # UdtSourceLine (0x1009) {
- # TypeLeafKind: LF_UDT_SRC_LINE (0x1606)
- # UDT: Struct (0x1007)
- # SourceFile: D:\src\llvmbuild\cl\Debug\x64\foo.cpp (0x1008)
- # LineNumber: 1
- # }
- .byte 0x0e, 0x00, 0x06, 0x16
- .byte 0x07, 0x10, 0x00, 0x00
- .byte 0x08, 0x10, 0x00, 0x00
- .byte 0x01, 0x00, 0x00, 0x00
- # StringId (0x100A) {
- # TypeLeafKind: LF_STRING_ID (0x1605)
- # Id: 0x0
- # StringData: D:\\src\\llvmbuild\\cl\\Debug\\x64
- # }
- .byte 0x2a, 0x00, 0x05, 0x16
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x44, 0x3a, 0x5c, 0x5c
- .byte 0x73, 0x72, 0x63, 0x5c
- .byte 0x5c, 0x6c, 0x6c, 0x76
- .byte 0x6d, 0x62, 0x75, 0x69
- .byte 0x6c, 0x64, 0x5c, 0x5c
- .byte 0x63, 0x6c, 0x5c, 0x5c
- .byte 0x44, 0x65, 0x62, 0x75
- .byte 0x67, 0x5c, 0x5c, 0x78
- .byte 0x36, 0x34, 0x00, 0xf1
- # StringId (0x100B) {
- # TypeLeafKind: LF_STRING_ID (0x1605)
- # Id: 0x0
- # StringData: foo.cpp
- # }
- .byte 0x0e, 0x00, 0x05, 0x16
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x66, 0x6f, 0x6f, 0x2e
- .byte 0x63, 0x70, 0x70, 0x00
- # BuildInfo (0x100C) {
- # TypeLeafKind: LF_BUILDINFO (0x1603)
- # NumArgs: 5
- # Arguments [
- # ArgType: D:\\src\\llvmbuild\\cl\\Debug\\x64 (0x100A)
- # ArgType: 0x0
- # ArgType: foo.cpp (0x100B)
- # ArgType: 0x0
- # ArgType: 0x0
- # ]
- # }
- .byte 0x1a, 0x00, 0x03, 0x16
- .byte 0x05, 0x00, 0x0a, 0x10
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x00, 0x00, 0x0b, 0x10
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x00, 0x00, 0x00, 0x00
- .byte 0x00, 0x00, 0xf2, 0xf1
-
- .addrsig
- .addrsig_sym "?S@@3UStruct@@A"
- .addrsig_sym "?SS@@3UStruct@@A"
- .addrsig_sym "?I@@3HA"
+ .text
+ .def @feat.00;
+ .scl 3;
+ .type 0;
+ .endef
+ .globl @feat.00
+.set @feat.00, 0
+ .intel_syntax noprefix
+ .def main;
+ .scl 2;
+ .type 32;
+ .endef
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+main: # @main
+.Lfunc_begin0:
+ .cv_func_id 0
+ .cv_file 1 "D:\\src\\llvmbuild\\cl\\Debug\\x64\\foo.cpp" "2B62298EE3EEF94E1D81FDFE18BD46A6" 1
+ .cv_loc 0 1 12 0 # foo.cpp:12:0
+.seh_proc main
+# %bb.0: # %entry
+ sub rsp, 32
+ .seh_stackalloc 32
+ .seh_endprologue
+ mov dword ptr [rsp + 28], 0
+ mov qword ptr [rsp + 16], rdx
+ mov dword ptr [rsp + 12], ecx
+.Ltmp0:
+ .cv_loc 0 1 15 0 # foo.cpp:15:0
+ mov ecx, dword ptr [rip + "?I@@3HA"]
+ add ecx, dword ptr [rip + "?S@@3UStruct@@A"]
+ add ecx, dword ptr [rip + "?SS@@3UStruct@@A"]
+ mov rdx, qword ptr [rsp]
+ add ecx, dword ptr [rdx]
+ mov eax, ecx
+ add rsp, 32
+ ret
+.Ltmp1:
+.Lfunc_end0:
+ .seh_handlerdata
+ .text
+ .seh_endproc
+ # -- End function
+ .bss
+ .globl "?S@@3UStruct@@A" # @"?S@@3UStruct@@A"
+ .p2align 2
+"?S@@3UStruct@@A":
+ .zero 4
+
+ .globl "?SS@@3UStruct@@A" # @"?SS@@3UStruct@@A"
+ .p2align 2
+"?SS@@3UStruct@@A":
+ .zero 4
+
+ .globl "?I@@3HA" # @"?I@@3HA"
+ .p2align 2
+"?I@@3HA":
+ .long 0 # 0x0
+
+ .section .drectve,"yn"
+ .ascii " /DEFAULTLIB:libcmt.lib"
+ .ascii " /DEFAULTLIB:oldnames.lib"
+ .section .debug$S,"dr"
+ .p2align 2
+ .long 4 # Debug section magic
+ .long 241
+ .long .Ltmp3-.Ltmp2 # Subsection size
+.Ltmp2:
+ .short .Ltmp5-.Ltmp4 # Record length
+.Ltmp4:
+ .short 4412 # Record kind: S_COMPILE3
+ .long 1 # Flags and language
+ .short 208 # CPUType
+ .short 8 # Frontend version
+ .short 0
+ .short 0
+ .short 0
+ .short 8000 # Backend version
+ .short 0
+ .short 0
+ .short 0
+ .asciz "clang version 8.0.0 " # Null-terminated compiler version string
+.Ltmp5:
+.Ltmp3:
+ .p2align 2
+ .long 241 # Symbol subsection for main
+ .long .Ltmp7-.Ltmp6 # Subsection size
+.Ltmp6:
+ .short .Ltmp9-.Ltmp8 # Record length
+.Ltmp8:
+ .short 4423 # Record kind: S_GPROC32_ID
+ .long 0 # PtrParent
+ .long 0 # PtrEnd
+ .long 0 # PtrNext
+ .long .Lfunc_end0-main # Code size
+ .long 0 # Offset after prologue
+ .long 0 # Offset before epilogue
+ .long 4099 # Function type index
+ .secrel32 main # Function section relative address
+ .secidx main # Function section index
+ .byte 0 # Flags
+ .asciz "main" # Function name
+.Ltmp9:
+ .short .Ltmp11-.Ltmp10 # Record length
+.Ltmp10:
+ .short 4114 # Record kind: S_FRAMEPROC
+ .long 32 # FrameSize
+ .long 0 # Padding
+ .long 0 # Offset of padding
+ .long 0 # Bytes of callee saved registers
+ .long 0 # Exception handler offset
+ .short 0 # Exception handler section
+ .long 81920 # Flags (defines frame register)
+.Ltmp11:
+ .short .Ltmp13-.Ltmp12 # Record length
+.Ltmp12:
+ .short 4414 # Record kind: S_LOCAL
+ .long 116 # TypeIndex
+ .short 1 # Flags
+ .asciz "argc"
+.Ltmp13:
+ .cv_def_range .Ltmp0 .Ltmp1, "B\021\f\000\000\000"
+ .short .Ltmp15-.Ltmp14 # Record length
+.Ltmp14:
+ .short 4414 # Record kind: S_LOCAL
+ .long 4096 # TypeIndex
+ .short 1 # Flags
+ .asciz "argv"
+.Ltmp15:
+ .cv_def_range .Ltmp0 .Ltmp1, "B\021\020\000\000\000"
+ .short .Ltmp17-.Ltmp16 # Record length
+.Ltmp16:
+ .short 4414 # Record kind: S_LOCAL
+ .long 4101 # TypeIndex
+ .short 0 # Flags
+ .asciz "SPtr"
+.Ltmp17:
+ .cv_def_range .Ltmp0 .Ltmp1, "B\021\000\000\000\000"
+ .short .Ltmp19-.Ltmp18 # Record length
+.Ltmp18:
+ .short 4360 # Record kind: S_UDT
+ .long 4101 # Type
+ .asciz "main::LocalTypedef"
+.Ltmp19:
+ .short 2 # Record length
+ .short 4431 # Record kind: S_PROC_ID_END
+.Ltmp7:
+ .p2align 2
+ .cv_linetable 0, main, .Lfunc_end0
+ .long 241 # Symbol subsection for globals
+ .long .Ltmp21-.Ltmp20 # Subsection size
+.Ltmp20:
+ .short .Ltmp23-.Ltmp22 # Record length
+.Ltmp22:
+ .short 4365 # Record kind: S_GDATA32
+ .long 4103 # Type
+ .secrel32 "?S@@3UStruct@@A" # DataOffset
+ .secidx "?S@@3UStruct@@A" # Segment
+ .asciz "S" # Name
+.Ltmp23:
+ .short .Ltmp25-.Ltmp24 # Record length
+.Ltmp24:
+ .short 4365 # Record kind: S_GDATA32
+ .long 4100 # Type
+ .secrel32 "?SS@@3UStruct@@A" # DataOffset
+ .secidx "?SS@@3UStruct@@A" # Segment
+ .asciz "SS" # Name
+.Ltmp25:
+ .short .Ltmp27-.Ltmp26 # Record length
+.Ltmp26:
+ .short 4365 # Record kind: S_GDATA32
+ .long 116 # Type
+ .secrel32 "?I@@3HA" # DataOffset
+ .secidx "?I@@3HA" # Segment
+ .asciz "I" # Name
+.Ltmp27:
+.Ltmp21:
+ .p2align 2
+ .long 241
+ .long .Ltmp29-.Ltmp28 # Subsection size
+.Ltmp28:
+ .short .Ltmp31-.Ltmp30 # Record length
+.Ltmp30:
+ .short 4360 # Record kind: S_UDT
+ .long 4103 # Type
+ .asciz "Struct"
+.Ltmp31:
+ .short .Ltmp33-.Ltmp32 # Record length
+.Ltmp32:
+ .short 4360 # Record kind: S_UDT
+ .long 4100 # Type
+ .asciz "StructTypedef"
+.Ltmp33:
+ .short .Ltmp35-.Ltmp34 # Record length
+.Ltmp34:
+ .short 4360 # Record kind: S_UDT
+ .long 116 # Type
+ .asciz "IntTypedef"
+.Ltmp35:
+.Ltmp29:
+ .p2align 2
+ .cv_filechecksums # File index to string table offset subsection
+ .cv_stringtable # String table
+ .long 241
+ .long .Ltmp37-.Ltmp36 # Subsection size
+.Ltmp36:
+ .short 6 # Record length
+ .short 4428 # Record kind: S_BUILDINFO
+ .long 4108 # LF_BUILDINFO index
+.Ltmp37:
+ .p2align 2
+ .section .debug$T,"dr"
+ .p2align 2
+ .long 4 # Debug section magic
+ # Pointer (0x1000) {
+ # TypeLeafKind: LF_POINTER (0x1002)
+ # PointeeType: char* (0x670)
+ # PtrType: Near64 (0xC)
+ # PtrMode: Pointer (0x0)
+ # IsFlat: 0
+ # IsConst: 0
+ # IsVolatile: 0
+ # IsUnaligned: 0
+ # IsRestrict: 0
+ # IsThisPtr&: 0
+ # IsThisPtr&&: 0
+ # SizeOf: 8
+ # }
+ .byte 0x0a, 0x00, 0x02, 0x10
+ .byte 0x70, 0x06, 0x00, 0x00
+ .byte 0x0c, 0x00, 0x01, 0x00
+ # ArgList (0x1001) {
+ # TypeLeafKind: LF_ARGLIST (0x1201)
+ # NumArgs: 2
+ # Arguments [
+ # ArgType: int (0x74)
+ # ArgType: char** (0x1000)
+ # ]
+ # }
+ .byte 0x0e, 0x00, 0x01, 0x12
+ .byte 0x02, 0x00, 0x00, 0x00
+ .byte 0x74, 0x00, 0x00, 0x00
+ .byte 0x00, 0x10, 0x00, 0x00
+ # Procedure (0x1002) {
+ # TypeLeafKind: LF_PROCEDURE (0x1008)
+ # ReturnType: int (0x74)
+ # CallingConvention: NearC (0x0)
+ # FunctionOptions [ (0x0)
+ # ]
+ # NumParameters: 2
+ # ArgListType: (int, char**) (0x1001)
+ # }
+ .byte 0x0e, 0x00, 0x08, 0x10
+ .byte 0x74, 0x00, 0x00, 0x00
+ .byte 0x00, 0x00, 0x02, 0x00
+ .byte 0x01, 0x10, 0x00, 0x00
+ # FuncId (0x1003) {
+ # TypeLeafKind: LF_FUNC_ID (0x1601)
+ # ParentScope: 0x0
+ # FunctionType: int (int, char**) (0x1002)
+ # Name: main
+ # }
+ .byte 0x12, 0x00, 0x01, 0x16
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x02, 0x10, 0x00, 0x00
+ .byte 0x6d, 0x61, 0x69, 0x6e
+ .byte 0x00, 0xf3, 0xf2, 0xf1
+ # Struct (0x1004) {
+ # TypeLeafKind: LF_STRUCTURE (0x1505)
+ # MemberCount: 0
+ # Properties [ (0x280)
+ # ForwardReference (0x80)
+ # HasUniqueName (0x200)
+ # ]
+ # FieldList: 0x0
+ # DerivedFrom: 0x0
+ # VShape: 0x0
+ # SizeOf: 0
+ # Name: Struct
+ # LinkageName: .?AUStruct@@
+ # }
+ .byte 0x2a, 0x00, 0x05, 0x15
+ .byte 0x00, 0x00, 0x80, 0x02
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x00, 0x00, 0x53, 0x74
+ .byte 0x72, 0x75, 0x63, 0x74
+ .byte 0x00, 0x2e, 0x3f, 0x41
+ .byte 0x55, 0x53, 0x74, 0x72
+ .byte 0x75, 0x63, 0x74, 0x40
+ .byte 0x40, 0x00, 0xf2, 0xf1
+ # Pointer (0x1005) {
+ # TypeLeafKind: LF_POINTER (0x1002)
+ # PointeeType: Struct (0x1004)
+ # PtrType: Near64 (0xC)
+ # PtrMode: Pointer (0x0)
+ # IsFlat: 0
+ # IsConst: 0
+ # IsVolatile: 0
+ # IsUnaligned: 0
+ # IsRestrict: 0
+ # IsThisPtr&: 0
+ # IsThisPtr&&: 0
+ # SizeOf: 8
+ # }
+ .byte 0x0a, 0x00, 0x02, 0x10
+ .byte 0x04, 0x10, 0x00, 0x00
+ .byte 0x0c, 0x00, 0x01, 0x00
+ # FieldList (0x1006) {
+ # TypeLeafKind: LF_FIELDLIST (0x1203)
+ # DataMember {
+ # TypeLeafKind: LF_MEMBER (0x150D)
+ # AccessSpecifier: Public (0x3)
+ # Type: int (0x74)
+ # FieldOffset: 0x0
+ # Name: x
+ # }
+ # }
+ .byte 0x0e, 0x00, 0x03, 0x12
+ .byte 0x0d, 0x15, 0x03, 0x00
+ .byte 0x74, 0x00, 0x00, 0x00
+ .byte 0x00, 0x00, 0x78, 0x00
+ # Struct (0x1007) {
+ # TypeLeafKind: LF_STRUCTURE (0x1505)
+ # MemberCount: 1
+ # Properties [ (0x200)
+ # HasUniqueName (0x200)
+ # ]
+ # FieldList: <field list> (0x1006)
+ # DerivedFrom: 0x0
+ # VShape: 0x0
+ # SizeOf: 4
+ # Name: Struct
+ # LinkageName: .?AUStruct@@
+ # }
+ .byte 0x2a, 0x00, 0x05, 0x15
+ .byte 0x01, 0x00, 0x00, 0x02
+ .byte 0x06, 0x10, 0x00, 0x00
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x04, 0x00, 0x53, 0x74
+ .byte 0x72, 0x75, 0x63, 0x74
+ .byte 0x00, 0x2e, 0x3f, 0x41
+ .byte 0x55, 0x53, 0x74, 0x72
+ .byte 0x75, 0x63, 0x74, 0x40
+ .byte 0x40, 0x00, 0xf2, 0xf1
+ # StringId (0x1008) {
+ # TypeLeafKind: LF_STRING_ID (0x1605)
+ # Id: 0x0
+ # StringData: D:\src\llvmbuild\cl\Debug\x64\foo.cpp
+ # }
+ .byte 0x2e, 0x00, 0x05, 0x16
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x44, 0x3a, 0x5c, 0x73
+ .byte 0x72, 0x63, 0x5c, 0x6c
+ .byte 0x6c, 0x76, 0x6d, 0x62
+ .byte 0x75, 0x69, 0x6c, 0x64
+ .byte 0x5c, 0x63, 0x6c, 0x5c
+ .byte 0x44, 0x65, 0x62, 0x75
+ .byte 0x67, 0x5c, 0x78, 0x36
+ .byte 0x34, 0x5c, 0x66, 0x6f
+ .byte 0x6f, 0x2e, 0x63, 0x70
+ .byte 0x70, 0x00, 0xf2, 0xf1
+ # UdtSourceLine (0x1009) {
+ # TypeLeafKind: LF_UDT_SRC_LINE (0x1606)
+ # UDT: Struct (0x1007)
+ # SourceFile: D:\src\llvmbuild\cl\Debug\x64\foo.cpp (0x1008)
+ # LineNumber: 1
+ # }
+ .byte 0x0e, 0x00, 0x06, 0x16
+ .byte 0x07, 0x10, 0x00, 0x00
+ .byte 0x08, 0x10, 0x00, 0x00
+ .byte 0x01, 0x00, 0x00, 0x00
+ # StringId (0x100A) {
+ # TypeLeafKind: LF_STRING_ID (0x1605)
+ # Id: 0x0
+ # StringData: D:\\src\\llvmbuild\\cl\\Debug\\x64
+ # }
+ .byte 0x2a, 0x00, 0x05, 0x16
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x44, 0x3a, 0x5c, 0x5c
+ .byte 0x73, 0x72, 0x63, 0x5c
+ .byte 0x5c, 0x6c, 0x6c, 0x76
+ .byte 0x6d, 0x62, 0x75, 0x69
+ .byte 0x6c, 0x64, 0x5c, 0x5c
+ .byte 0x63, 0x6c, 0x5c, 0x5c
+ .byte 0x44, 0x65, 0x62, 0x75
+ .byte 0x67, 0x5c, 0x5c, 0x78
+ .byte 0x36, 0x34, 0x00, 0xf1
+ # StringId (0x100B) {
+ # TypeLeafKind: LF_STRING_ID (0x1605)
+ # Id: 0x0
+ # StringData: foo.cpp
+ # }
+ .byte 0x0e, 0x00, 0x05, 0x16
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x66, 0x6f, 0x6f, 0x2e
+ .byte 0x63, 0x70, 0x70, 0x00
+ # BuildInfo (0x100C) {
+ # TypeLeafKind: LF_BUILDINFO (0x1603)
+ # NumArgs: 5
+ # Arguments [
+ # ArgType: D:\\src\\llvmbuild\\cl\\Debug\\x64 (0x100A)
+ # ArgType: 0x0
+ # ArgType: foo.cpp (0x100B)
+ # ArgType: 0x0
+ # ArgType: 0x0
+ # ]
+ # }
+ .byte 0x1a, 0x00, 0x03, 0x16
+ .byte 0x05, 0x00, 0x0a, 0x10
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x00, 0x00, 0x0b, 0x10
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x00, 0x00, 0x00, 0x00
+ .byte 0x00, 0x00, 0xf2, 0xf1
+
+ .addrsig
+ .addrsig_sym "?S@@3UStruct@@A"
+ .addrsig_sym "?SS@@3UStruct@@A"
+ .addrsig_sym "?I@@3HA"
diff --git a/test/ELF/Inputs/gdb-index-invalid-ranges.obj.s b/test/ELF/Inputs/gdb-index-invalid-ranges.obj.s
new file mode 100644
index 000000000..d7e0bd29d
--- /dev/null
+++ b/test/ELF/Inputs/gdb-index-invalid-ranges.obj.s
@@ -0,0 +1,2 @@
+main:
+ callq f1
diff --git a/test/ELF/Inputs/gnu-ifunc-canon-ro-abs.s b/test/ELF/Inputs/gnu-ifunc-canon-ro-abs.s
new file mode 100644
index 000000000..3c09bd602
--- /dev/null
+++ b/test/ELF/Inputs/gnu-ifunc-canon-ro-abs.s
@@ -0,0 +1,2 @@
+.rodata
+.8byte ifunc
diff --git a/test/ELF/Inputs/gnu-ifunc-canon-ro-pcrel.s b/test/ELF/Inputs/gnu-ifunc-canon-ro-pcrel.s
new file mode 100644
index 000000000..c173d3d72
--- /dev/null
+++ b/test/ELF/Inputs/gnu-ifunc-canon-ro-pcrel.s
@@ -0,0 +1,2 @@
+.rodata
+.4byte ifunc - .
diff --git a/test/ELF/Inputs/gnu-ifunc-canon-rw-addend.s b/test/ELF/Inputs/gnu-ifunc-canon-rw-addend.s
new file mode 100644
index 000000000..7f369d393
--- /dev/null
+++ b/test/ELF/Inputs/gnu-ifunc-canon-rw-addend.s
@@ -0,0 +1,2 @@
+.data
+.8byte ifunc + 1
diff --git a/test/ELF/Inputs/i386-static-tls-model1.s b/test/ELF/Inputs/i386-static-tls-model1.s
new file mode 100644
index 000000000..d287fb64e
--- /dev/null
+++ b/test/ELF/Inputs/i386-static-tls-model1.s
@@ -0,0 +1,9 @@
+.section ".tdata", "awT", @progbits
+.globl var
+var:
+
+.section .foo, "aw"
+.global _start
+_start:
+ movl $var@tpoff, %edx # R_386_TLS_LE_32
+ movl %gs:0, %ecx
diff --git a/test/ELF/Inputs/i386-static-tls-model2.s b/test/ELF/Inputs/i386-static-tls-model2.s
new file mode 100644
index 000000000..2c01cee42
--- /dev/null
+++ b/test/ELF/Inputs/i386-static-tls-model2.s
@@ -0,0 +1,9 @@
+.section ".tdata", "awT", @progbits
+.globl var
+var:
+
+.section .foo, "aw"
+.global _start
+_start:
+ movl %gs:0, %eax
+ addl var@gotntpoff(%ebx), %eax # R_386_TLS_GOTIE
diff --git a/test/ELF/Inputs/i386-static-tls-model3.s b/test/ELF/Inputs/i386-static-tls-model3.s
new file mode 100644
index 000000000..fd18fceb7
--- /dev/null
+++ b/test/ELF/Inputs/i386-static-tls-model3.s
@@ -0,0 +1,9 @@
+.section ".tdata", "awT", @progbits
+.globl var
+var:
+
+.section .foo, "aw"
+.global _start
+_start:
+ movl %gs:0, %eax
+ addl var@indntpoff, %eax # R_386_TLS_IE
diff --git a/test/ELF/Inputs/i386-static-tls-model4.s b/test/ELF/Inputs/i386-static-tls-model4.s
new file mode 100644
index 000000000..6006518bf
--- /dev/null
+++ b/test/ELF/Inputs/i386-static-tls-model4.s
@@ -0,0 +1,9 @@
+.section ".tdata", "awT", @progbits
+.globl var
+var:
+
+.section .foo, "aw"
+.global _start
+_start:
+ movl %gs:0, %eax
+ leal var@ntpoff(%eax), %eax # R_386_TLS_LE
diff --git a/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input2.s b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input2.s
new file mode 100644
index 000000000..b903f9b54
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input2.s
@@ -0,0 +1,23 @@
+ .text
+
+ .global set
+ .type set,@function
+set:
+.Lgep:
+ addis 2, 12, .TOC.-.Lgep@ha
+ addi 2, 2, .TOC.-.Lgep@l
+.Llep:
+ .localentry set, .Llep-.Lgep
+ addis 5, 2, .LC0@toc@ha
+ addis 6, 2, .LC1@toc@ha
+ ld 5, .LC0@toc@l(5)
+ ld 6, .LC1@toc@l(6)
+ stw 3, 0(5)
+ stw 4, 0(6)
+ blr
+
+ .section .toc,"aw",@progbits
+.LC0:
+ .tc c[TC],c
+.LC1:
+ .tc d[TC],d
diff --git a/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input3.s b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input3.s
new file mode 100644
index 000000000..733bbb344
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input3.s
@@ -0,0 +1,41 @@
+ .text
+ .global getA
+ .type getA,@function
+getA:
+.LgepA:
+ addis 2, 12, .TOC.-.LgepA@ha
+ addi 2, 2, .TOC.-.LgepA@l
+.LlepA:
+ .localentry getA, .LlepA-.LgepA
+ ld 3, .LC0@toc(2)
+ lwa 3, 0(3)
+ blr
+
+ .global getB
+ .type getB,@function
+getB:
+.LgepB:
+ addis 2, 12, .TOC.-.LgepB@ha
+ addi 2, 2, .TOC.-.LgepB@l
+.LlepB:
+ .localentry getB, .LlepB-.LgepB
+ ld 3, .LC1@toc(2)
+ lwa 3, 0(3)
+ blr
+
+ .section .toc,"aw",@progbits
+.LC0:
+ .tc a[TC],a
+.LConst1:
+ .quad 0xa
+.LC1:
+ .tc b[TC],b
+.Lconst2:
+ .quad 0xaabbccddeeff
+
+ .type b,@object
+ .data
+ .global b
+b:
+ .long 22
+ .size b, 4
diff --git a/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input4.s b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input4.s
new file mode 100644
index 000000000..90f6e0fd6
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input4.s
@@ -0,0 +1,18 @@
+ .text
+ .global getRodata
+ .type getRodata,@function
+getRodata:
+.Lgep:
+ addis 2, 12, .TOC.-.Lgep@ha
+ addi 2, 2, .TOC.-.Lgep@l
+.Llep:
+ .localentry getRodata, .Llep-.Lgep
+ lwa 3, .LC0@toc(2)
+ blr
+
+ .section .rodata,"aMS",@progbits,8
+ .quad _start
+
+ .section .toc,"aw",@progbits
+.LC0:
+ .tc .rodata[TC], .rodata
diff --git a/test/ELF/Inputs/print-icf.s b/test/ELF/Inputs/print-icf.s
index a67bee2f1..df9bcbc09 100644
--- a/test/ELF/Inputs/print-icf.s
+++ b/test/ELF/Inputs/print-icf.s
@@ -1,9 +1,9 @@
-.section .text.f6, "ax"
-f6:
- mov $60, %rax
- mov $42, %rdi
- syscall
-
- .section .text.f7, "ax"
-f7:
- mov $0, %rax
+.section .text.f6, "ax"
+f6:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
+
+ .section .text.f7, "ax"
+f7:
+ mov $0, %rax
diff --git a/test/ELF/Inputs/wrap-with-archive.s b/test/ELF/Inputs/wrap-with-archive.s
new file mode 100644
index 000000000..93aaddc88
--- /dev/null
+++ b/test/ELF/Inputs/wrap-with-archive.s
@@ -0,0 +1,5 @@
+.global __executable_start
+.global __wrap_get_executable_start
+
+__wrap_get_executable_start:
+ movabs $__executable_start,%rdx
diff --git a/test/ELF/Inputs/x86-64-pcrel.s b/test/ELF/Inputs/x86-64-pcrel.s
new file mode 100644
index 000000000..dea824ae7
--- /dev/null
+++ b/test/ELF/Inputs/x86-64-pcrel.s
@@ -0,0 +1,8 @@
+.globl foo
+foo:
+
+.word _start - foo
+.fill 14,1,0xcc
+
+.byte _start - foo
+.fill 15,1,0xcc
diff --git a/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s b/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s
index bff72d372..2db5c7e36 100644
--- a/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s
+++ b/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s
@@ -26,9 +26,9 @@ _start:
// CHECK: _start:
// CHECK-NEXT: 210ff8: 41 d0 3b d5 mrs x1, TPIDR_EL0
// CHECK-NEXT: 210ffc: 00 00 a0 d2 movz x0, #0, lsl #16
-// CHECK-NEXT: 211000: 01 02 80 f2 movk x1, #16
+// CHECK-NEXT: 211000: 01 08 80 f2 movk x1, #64
// CHECK-NEXT: 211004: 00 00 a0 d2 movz x0, #0, lsl #16
-// CHECK-NEXT: 211008: 01 02 80 f2 movk x1, #16
+// CHECK-NEXT: 211008: 01 08 80 f2 movk x1, #64
// CHECK-NEXT: 21100c: c0 03 5f d6 ret
.type v,@object
diff --git a/test/ELF/aarch64-gnu-ifunc-address-pie.s b/test/ELF/aarch64-gnu-ifunc-address-pie.s
new file mode 100644
index 000000000..53cede9bd
--- /dev/null
+++ b/test/ELF/aarch64-gnu-ifunc-address-pie.s
@@ -0,0 +1,47 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
+# RUN: ld.lld -pie %t.o -o %tout
+# RUN: llvm-objdump -D %tout | FileCheck %s
+# RUN: llvm-readobj -r %tout | FileCheck %s -check-prefix=CHECK-RELOCS
+
+# Test that when we take the address of a preemptible ifunc using -fpie, we can
+# handle the case when the ifunc is in the same translation unit as the address
+# taker. In this case the compiler knows that ifunc is not defined in a shared
+# library so it can use a non got generating relative reference.
+.text
+.globl myfunc
+.type myfunc,@gnu_indirect_function
+myfunc:
+.globl myfunc_resolver
+.type myfunc_resolver,@function
+myfunc_resolver:
+ ret
+
+.text
+.globl main
+.type main,@function
+main:
+ adrp x8, myfunc
+ add x8, x8, :lo12: myfunc
+ ret
+
+# CHECK: 0000000000010000 myfunc_resolver:
+# CHECK-NEXT: 10000: c0 03 5f d6 ret
+# CHECK: 0000000000010004 main:
+# CHECK-NEXT: 10004: 08 00 00 90 adrp x8, #0
+# x8 = 0x10000
+# CHECK-NEXT: 10008: 08 41 00 91 add x8, x8, #16
+# x8 = 0x10010 = .plt for myfunc
+# CHECK-NEXT: 1000c: c0 03 5f d6 ret
+# CHECK-NEXT: Disassembly of section .plt:
+# CHECK-NEXT: 0000000000010010 myfunc:
+# CHECK-NEXT: 10010: 90 00 00 90 adrp x16, #65536
+# CHECK-NEXT: 10014: 11 02 40 f9 ldr x17, [x16]
+# CHECK-NEXT: 10018: 10 02 00 91 add x16, x16, #0
+# CHECK-NEXT: 1001c: 20 02 1f d6 br x17
+
+# CHECK-RELOCS: Relocations [
+# CHECK-RELOCS-NEXT: Section {{.*}} .rela.plt {
+# CHECK-RELOCS-NEXT: 0x20000 R_AARCH64_IRELATIVE - 0x10000
+# CHECK-RELOCS-NEXT: }
+# CHECK-RELOCS-NEXT: ]
diff --git a/test/ELF/aarch64-gnu-ifunc-address.s b/test/ELF/aarch64-gnu-ifunc-address.s
new file mode 100644
index 000000000..e0e4daf79
--- /dev/null
+++ b/test/ELF/aarch64-gnu-ifunc-address.s
@@ -0,0 +1,37 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %tout
+# RUN: llvm-objdump -D %tout | FileCheck %s
+# RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=CHECK-RELOCS
+
+# Test that when we take the address of a preemptible ifunc in a shared object
+# we get R_AARCH64_GLOB_DAT to the symbol as it could be defined in another
+# link unit and preempt our definition.
+.text
+.globl myfunc
+.type myfunc,@gnu_indirect_function
+myfunc:
+ ret
+
+.text
+.globl main
+.type main,@function
+main:
+ adrp x8, :got:myfunc
+ ldr x8, [x8, :got_lo12:myfunc]
+ ret
+# CHECK: 0000000000010004 main:
+# x8 = 0x20000
+# CHECK-NEXT: 10004: 88 00 00 90 adrp x8, #65536
+# x8 = 0x200a0 = .got entry for myfunc with R_AARCH64_GLOB_DAT
+# CHECK-NEXT: 10008: 08 51 40 f9 ldr x8, [x8, #160]
+# CHECK-NEXT: 1000c: c0 03 5f d6 ret
+
+# CHECK: Disassembly of section .got:
+# CHECK-NEXT: 00000000000200a0 .got:
+
+# CHECK-RELOCS: Relocations [
+# CHECK-RELOCS-NEXT: Section {{.*}} .rela.dyn {
+# CHECK-RELOCS-NEXT: 0x200A0 R_AARCH64_GLOB_DAT myfunc 0x0
+# CHECK-RELOCS-NEXT: }
+# CHECK-RELOCS-NEXT: ]
diff --git a/test/ELF/aarch64-gnu-ifunc2.s b/test/ELF/aarch64-gnu-ifunc2.s
index 2caff3f14..f83a3b388 100644
--- a/test/ELF/aarch64-gnu-ifunc2.s
+++ b/test/ELF/aarch64-gnu-ifunc2.s
@@ -9,8 +9,8 @@
# CHECK-NEXT: 210000:
# CHECK: main:
-# adrp x8, 0x230000, 0x230000 == address in .got
-# CHECK-NEXT: 210004: {{.*}} adrp x8, #131072
+# adrp x8, 0x220000, 0x220000 == address in .got.plt
+# CHECK-NEXT: 210004: {{.*}} adrp x8, #65536
# CHECK-NEXT: 210008: {{.*}} ldr x8, [x8]
# CHECK-NEXT: 21000c: {{.*}} ret
@@ -26,11 +26,6 @@
# CHECK-NEXT: .got.plt:
# CHECK-NEXT: 220000:
-# CHECK: Disassembly of section .got:
-# CHECK-NEXT: .got:
-# 0x210010 == address in .plt
-# CHECK-NEXT: 230000: 10 00 21 00
-
# RELOC: Relocations [
# RELOC-NEXT: Section {{.*}} .rela.plt {
# RELOC-NEXT: 0x220000 R_AARCH64_IRELATIVE - 0x210000
diff --git a/test/ELF/aarch64-gnu-ifunc3.s b/test/ELF/aarch64-gnu-ifunc3.s
index 11d5631b8..5d863e2f9 100644
--- a/test/ELF/aarch64-gnu-ifunc3.s
+++ b/test/ELF/aarch64-gnu-ifunc3.s
@@ -11,6 +11,9 @@
.globl myfunc
.type myfunc,@gnu_indirect_function
myfunc:
+.globl myfunc_resolver
+.type myfunc_resolver,@function
+myfunc_resolver:
ret
.text
@@ -22,7 +25,7 @@ _start:
ret
# CHECK: Disassembly of section .text:
-# CHECK-NEXT: myfunc:
+# CHECK-NEXT: myfunc_resolver:
# CHECK-NEXT: 210000: c0 03 5f d6 ret
# CHECK: _start:
# adrp x8, 0x210000 + 0x10 from add == .plt entry
@@ -30,7 +33,7 @@ _start:
# CHECK-NEXT: 210008: 08 41 00 91 add x8, x8, #16
# CHECK-NEXT: 21000c: c0 03 5f d6 ret
# CHECK-NEXT: Disassembly of section .plt:
-# CHECK-NEXT: .plt:
+# CHECK-NEXT: myfunc:
# adrp x16, 0x220000, 0x220000 == address in .got.plt
# CHECK-NEXT: 210010: 90 00 00 90 adrp x16, #65536
# CHECK-NEXT: 210014: 11 02 40 f9 ldr x17, [x16]
diff --git a/test/ELF/aarch64-tls-gdle.s b/test/ELF/aarch64-tls-gdle.s
index e91d3976d..882ec8c1a 100644
--- a/test/ELF/aarch64-tls-gdle.s
+++ b/test/ELF/aarch64-tls-gdle.s
@@ -5,15 +5,15 @@
# RUN: llvm-objdump -d %tout | FileCheck %s
# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
-#Local-Dynamic to Initial-Exec relax creates no
+#Local-Dynamic to Local-Exec relax creates no
#RELOC: Relocations [
#RELOC-NEXT: ]
-# TCB size = 0x16 and foo is first element from TLS register.
+# TCB size = 64 and foo is first element from TLS register.
# CHECK: Disassembly of section .text:
# CHECK: _start:
# CHECK: 210000: 00 00 a0 d2 movz x0, #0, lsl #16
-# CHECK: 210004: 00 02 80 f2 movk x0, #16
+# CHECK: 210004: 00 08 80 f2 movk x0, #64
# CHECK: 210008: 1f 20 03 d5 nop
# CHECK: 21000c: 1f 20 03 d5 nop
diff --git a/test/ELF/aarch64-tls-iele.s b/test/ELF/aarch64-tls-iele.s
index 9fec4ee7d..0229d6676 100644
--- a/test/ELF/aarch64-tls-iele.s
+++ b/test/ELF/aarch64-tls-iele.s
@@ -9,13 +9,13 @@
# RELOC: Relocations [
# RELOC-NEXT: ]
-# TCB size = 0x16 and foo is first element from TLS register.
+# TCB size = 64 and foo is first element from TLS register.
# CHECK: Disassembly of section .text:
# CHECK: _start:
# CHECK-NEXT: 210000: 00 00 a0 d2 movz x0, #0, lsl #16
-# CHECK-NEXT: 210004: 80 02 80 f2 movk x0, #20
+# CHECK-NEXT: 210004: 80 08 80 f2 movk x0, #68
# CHECK-NEXT: 210008: 00 00 a0 d2 movz x0, #0, lsl #16
-# CHECK-NEXT: 21000c: 00 02 80 f2 movk x0, #16
+# CHECK-NEXT: 21000c: 00 08 80 f2 movk x0, #64
.section .tdata
.align 2
diff --git a/test/ELF/aarch64-tls-le.s b/test/ELF/aarch64-tls-le.s
index 85cd3beac..49c322fac 100644
--- a/test/ELF/aarch64-tls-le.s
+++ b/test/ELF/aarch64-tls-le.s
@@ -4,7 +4,7 @@
# RUN: llvm-objdump -d %tout | FileCheck %s
# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
-#Local-Dynamic to Initial-Exec relax creates no
+#Local-Dynamic to Local-Exec relax creates no
#RELOC: Relocations [
#RELOC-NEXT: ]
@@ -17,12 +17,12 @@ _start:
add x0, x0, :tprel_hi12:v2
add x0, x0, :tprel_lo12_nc:v2
-# TCB size = 0x16 and foo is first element from TLS register.
+# TCB size = 64 and foo is first element from TLS register.
#CHECK: Disassembly of section .text:
#CHECK: _start:
#CHECK: 210000: 40 d0 3b d5 mrs x0, TPIDR_EL0
#CHECK: 210004: 00 00 40 91 add x0, x0, #0, lsl #12
-#CHECK: 210008: 00 40 00 91 add x0, x0, #16
+#CHECK: 210008: 00 00 01 91 add x0, x0, #64
#CHECK: 21000c: 40 d0 3b d5 mrs x0, TPIDR_EL0
#CHECK: 210010: 00 fc 7f 91 add x0, x0, #4095, lsl #12
#CHECK: 210014: 00 e0 3f 91 add x0, x0, #4088
@@ -36,9 +36,9 @@ v1:
.word 0
.size v1, 4
-# The current offset from the thread pointer is 20. Raise it to just below the
+# The current offset from the thread pointer is 68. Raise it to just below the
# 24-bit limit.
-.space (0xfffff8 - 20)
+.space (0xfffff8 - 68)
.type v2,@object
.globl v2
diff --git a/test/ELF/aarch64-tlsld-ldst.s b/test/ELF/aarch64-tlsld-ldst.s
index 3144ca5d9..8ebdc2f15 100644
--- a/test/ELF/aarch64-tlsld-ldst.s
+++ b/test/ELF/aarch64-tlsld-ldst.s
@@ -26,27 +26,27 @@ _start: mrs x8, TPIDR_EL0
// CHECK: _start:
// CHECK-NEXT: 210000: 48 d0 3b d5 mrs x8, TPIDR_EL0
-// 0x0 + c10 = 0xc10 = tcb (16-bytes) + var0
-// CHECK-NEXT: 210004: 08 01 40 91 add x8, x8, #0, lsl #12
-// CHECK-NEXT: 210008: 14 05 c3 3d ldr q20, [x8, #3088]
-// 0x1000 + 0x820 = 0x1820 = tcb + var1
-// CHECK-NEXT: 21000c: 08 05 40 91 add x8, x8, #1, lsl #12
-// CHECK-NEXT: 210010: 00 11 44 f9 ldr x0, [x8, #2080]
-// 0x2000 + 0x428 = 0x2428 = tcb + var2
-// CHECK-NEXT: 210014: 08 09 40 91 add x8, x8, #2, lsl #12
-// CHECK-NEXT: 210018: 00 29 44 b9 ldr w0, [x8, #1064]
-// 0x3000 + 0x2c = 0x302c = tcb + var3
-// CHECK-NEXT: 21001c: 08 0d 40 91 add x8, x8, #3, lsl #12
-// CHECK-NEXT: 210020: 00 59 40 79 ldrh w0, [x8, #44]
-// 0x3000 + 0xc2e = 0x32ce = tcb + var4
-// CHECK-NEXT: 210024: 08 0d 40 91 add x8, x8, #3, lsl #12
-// CHECK-NEXT: 210028: 00 b9 70 39 ldrb w0, [x8, #3118]
+// 0x0 + c40 = 0xc40 = tcb (64-bytes) + var0
+// CHECK-NEXT: 210004: 08 01 40 91 add x8, x8, #0, lsl #12
+// CHECK-NEXT: 210008: 14 11 c3 3d ldr q20, [x8, #3136]
+// 0x1000 + 0x850 = 0x1850 = tcb + var1
+// CHECK-NEXT: 21000c: 08 05 40 91 add x8, x8, #1, lsl #12
+// CHECK-NEXT: 210010: 00 29 44 f9 ldr x0, [x8, #2128]
+// 0x2000 + 0x458 = 0x2458 = tcb + var2
+// CHECK-NEXT: 210014: 08 09 40 91 add x8, x8, #2, lsl #12
+// CHECK-NEXT: 210018: 00 59 44 b9 ldr w0, [x8, #1112]
+// 0x3000 + 0x5c = 0x305c = tcb + var3
+// CHECK-NEXT: 21001c: 08 0d 40 91 add x8, x8, #3, lsl #12
+// CHECK-NEXT: 210020: 00 b9 40 79 ldrh w0, [x8, #92]
+// 0x3000 + 0xc5e = 0x3c5e = tcb + var4
+// CHECK-NEXT: 210024: 08 0d 40 91 add x8, x8, #3, lsl #12
+// CHECK-NEXT: 210028: 00 79 71 39 ldrb w0, [x8, #3166]
-// CHECK-SYMS: 0000000000000c00 0 TLS GLOBAL DEFAULT 2 var0
-// CHECK-SYMS-NEXT: 0000000000001810 4 TLS GLOBAL DEFAULT 2 var1
-// CHECK-SYMS-NEXT: 0000000000002418 2 TLS GLOBAL DEFAULT 2 var2
-// CHECK-SYMS-NEXT: 000000000000301c 1 TLS GLOBAL DEFAULT 2 var3
-// CHECK-SYMS-NEXT: 0000000000003c1e 0 TLS GLOBAL DEFAULT 2 var4
+// CHECK-SYMS: 0000000000000c00 16 TLS GLOBAL DEFAULT 2 var0
+// CHECK-SYMS-NEXT: 0000000000001810 8 TLS GLOBAL DEFAULT 2 var1
+// CHECK-SYMS-NEXT: 0000000000002418 4 TLS GLOBAL DEFAULT 2 var2
+// CHECK-SYMS-NEXT: 000000000000301c 2 TLS GLOBAL DEFAULT 2 var3
+// CHECK-SYMS-NEXT: 0000000000003c1e 1 TLS GLOBAL DEFAULT 2 var4
.globl var0
.globl var1
@@ -59,12 +59,12 @@ _start: mrs x8, TPIDR_EL0
.type var3,@object
.section .tbss,"awT",@nobits
- .balign 16
+ .balign 64
.space 1024 * 3
var0:
.quad 0
.quad 0
- .size var1, 16
+ .size var0, 16
.space 1024 * 3
var1:
.quad 0
@@ -72,14 +72,14 @@ var1:
.space 1024 * 3
var2:
.word 0
- .size var1, 4
+ .size var2, 4
.space 1024 * 3
var3:
.hword 0
- .size var2, 2
+ .size var3, 2
.space 1024 * 3
var4:
.byte 0
- .size var3, 1
+ .size var4, 1
.space 1024 * 3
diff --git a/test/ELF/allow-shlib-undefined.s b/test/ELF/allow-shlib-undefined.s
index abb0351db..5b09681f2 100644
--- a/test/ELF/allow-shlib-undefined.s
+++ b/test/ELF/allow-shlib-undefined.s
@@ -1,26 +1,30 @@
# REQUIRES: x86
-# --allow-shlib-undefined and --no-allow-shlib-undefined are fully
-# ignored in linker implementation.
-# --allow-shlib-undefined is set by default
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
-# RUN: %p/Inputs/allow-shlib-undefined.s -o %t
-# RUN: ld.lld -shared %t -o %t.so
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
+# RUN: %p/Inputs/allow-shlib-undefined.s -o %t1.o
+# RUN: ld.lld -shared %t1.o -o %t.so
+
+# RUN: ld.lld --allow-shlib-undefined %t.o %t.so -o /dev/null
+# RUN: not ld.lld --no-allow-shlib-undefined %t.o %t.so -o /dev/null 2>&1 | FileCheck %s
+# Executable defaults to --no-allow-shlib-undefined
+# RUN: not ld.lld %t.o %t.so -o /dev/null 2>&1 | FileCheck %s
+# -shared defaults to --allow-shlib-undefined
+# RUN: ld.lld -shared %t.o %t.so -o /dev/null
-# Executable: should link with DSO containing undefined symbols in any case.
-# RUN: ld.lld %t1 %t.so -o %t2
-# RUN: ld.lld --no-allow-shlib-undefined %t1 %t.so -o %t2
-# RUN: ld.lld --allow-shlib-undefined %t1 %t.so -o %t2
+# RUN: echo | llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %tempty.o
+# RUN: ld.lld -shared %tempty.o -o %tempty.so
+# RUN: ld.lld -shared %t1.o %tempty.so -o %t2.so
+# RUN: ld.lld --no-allow-shlib-undefined %t.o %t2.so -o /dev/null
# DSO with undefines:
# should link with or without any of these options.
-# RUN: ld.lld -shared %t -o %t.so
-# RUN: ld.lld -shared --allow-shlib-undefined %t -o %t.so
-# RUN: ld.lld -shared --no-allow-shlib-undefined %t -o %t.so
-
-# Executable still should not link when have undefines inside.
-# RUN: not ld.lld %t -o %t.so
+# RUN: ld.lld -shared %t1.o -o /dev/null
+# RUN: ld.lld -shared --allow-shlib-undefined %t1.o -o /dev/null
+# RUN: ld.lld -shared --no-allow-shlib-undefined %t1.o -o /dev/null
.globl _start
_start:
callq _shared@PLT
+
+# CHECK: undefined reference to _unresolved
diff --git a/test/ELF/archive-thin-missing-member.s b/test/ELF/archive-thin-missing-member.s
new file mode 100644
index 000000000..d96fbc454
--- /dev/null
+++ b/test/ELF/archive-thin-missing-member.s
@@ -0,0 +1,24 @@
+# REQUIRES: x86
+
+# RUN: rm -f %t-no-syms.a
+# RUN: rm -f %t-syms.a
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: llvm-ar rcTS %t-no-syms.a %t.o
+# RUN: llvm-ar rcT %t-syms.a %t.o
+# RUN: rm %t.o
+
+# Test error when loading symbols from missing thin archive member.
+# RUN: not ld.lld %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
+# ERR1: {{.*}}-no-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
+
+# Test error when thin archive has symbol table but member is missing.
+# RUN: not ld.lld -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
+# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol _start: '{{.*}}.o': {{[Nn]}}o such file or directory
+
+# Test error when thin archive is linked using --whole-archive but member is missing.
+# RUN: not ld.lld --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3
+# ERR3: {{.*}}-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
+
+.global _start
+_start:
+ nop
diff --git a/test/ELF/arm-extreme-range-pi-thunk.s b/test/ELF/arm-extreme-range-pi-thunk.s
new file mode 100644
index 000000000..5daf38807
--- /dev/null
+++ b/test/ELF/arm-extreme-range-pi-thunk.s
@@ -0,0 +1,82 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS {" > %t.script
+// RUN: echo " .text_low 0x130 : { *(.text) }" >> %t.script
+// RUN: echo " .text_high 0xf0000000 : AT(0x1000) { *(.text_high) }" >> %t.script
+// RUN: echo " } " >> %t.script
+// RUN: ld.lld --script %t.script --pie --static %t -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
+
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t3
+// RUN: ld.lld --script %t.script --pie %t3 -o %t4 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-THUMB %s
+
+// Check that we can create Arm and Thumb v7a Position Independent Thunks that
+// can span the address space without triggering overflow errors. We use an
+// AT(0x1000) for .text_high to avoid creating an almost 4Gb size file.
+ .syntax unified
+ .text
+ .global _start
+ .type _start, %function
+_start:
+ bl high
+ bx lr
+
+ .section .text_high, "ax", %progbits
+ .global high
+ .type high, %function
+high:
+ bl _start
+ bx lr
+
+// ARMv7a instructions and relocations.
+
+// CHECK: Disassembly of section .text_low:
+// CHECK-NEXT: _start:
+// CHECK-NEXT: 130: 00 00 00 eb bl #0 <__ARMV7PILongThunk_high>
+// CHECK-NEXT: 134: 1e ff 2f e1 bx lr
+
+// CHECK: __ARMV7PILongThunk_high:
+// CHECK-NEXT: 138: b8 ce 0f e3 movw r12, #65208
+// CHECK-NEXT: 13c: ff cf 4e e3 movt r12, #61439
+// 0x140 + 0xEFFF0000 + 0x0000FEB8 + 8 = 0xf0000000 = high
+// CHECK-NEXT: 140: 0f c0 8c e0 add r12, r12, pc
+// CHECK-NEXT: 144: 1c ff 2f e1 bx r12
+
+// CHECK: Disassembly of section .text_high:
+// CHECK-NEXT: high:
+// CHECK-NEXT: f0000000: 00 00 00 eb bl #0 <__ARMV7PILongThunk__start>
+// CHECK-NEXT: f0000004: 1e ff 2f e1 bx lr
+
+// CHECK: __ARMV7PILongThunk__start:
+// CHECK-NEXT: f0000008: 18 c1 00 e3 movw r12, #280
+// CHECK-NEXT: f000000c: 00 c0 41 e3 movt r12, #4096
+// 0xf0000010 + 0x10000000 + 0x0000118 + 8 = bits32(0x100000130),0x130 = _start
+// CHECK-NEXT: f0000010: 0f c0 8c e0 add r12, r12, pc
+// CHECK-NEXT: f0000014: 1c ff 2f e1 bx r12
+
+// Thumbv7a instructions and relocations
+// CHECK-THUMB: Disassembly of section .text_low:
+// CHECK-THUMB-NEXT: _start:
+// CHECK-THUMB-NEXT: 130: 00 f0 02 f8 bl #4
+// CHECK-THUMB-NEXT: 134: 70 47 bx lr
+// CHECK-THUMB-NEXT: 136: d4 d4 bmi #-88
+
+// CHECK-THUMB: __ThumbV7PILongThunk_high:
+// CHECK-THUMB-NEXT: 138: 4f f6 bd 6c movw r12, #65213
+// CHECK-THUMB-NEXT: 13c: ce f6 ff 7c movt r12, #61439
+// 0x140 + 0xEFFF0000 + 0x0000FEBD + 4 = 0xf0000001 = high
+// CHECK-THUMB-NEXT: 140: fc 44 add r12, pc
+// CHECK-THUMB-NEXT: 142: 60 47 bx r12
+
+// CHECK-THUMB: Disassembly of section .text_high:
+// CHECK-THUMB-NEXT: high:
+// CHECK-THUMB-NEXT: f0000000: 00 f0 02 f8 bl #4
+// CHECK-THUMB-NEXT: f0000004: 70 47 bx lr
+
+// CHECK-THUMB: __ThumbV7PILongThunk__start:
+// CHECK-THUMB-NEXT: f0000008: 40 f2 1d 1c movw r12, #285
+// CHECK-THUMB-NEXT: f000000c: c1 f2 00 0c movt r12, #4096
+// 0xf0000010 + 0x10000000 + 0x000011d +4 = bits32(0x100000131),0x131 = _start
+// CHECK-THUMB-NEXT: f0000010: fc 44 add r12, pc
+// CHECK-THUMB-NEXT: f0000012: 60 47 bx r12
diff --git a/test/ELF/arm-force-pi-thunk.s b/test/ELF/arm-force-pi-thunk.s
new file mode 100644
index 000000000..2c88de042
--- /dev/null
+++ b/test/ELF/arm-force-pi-thunk.s
@@ -0,0 +1,87 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN: . = SIZEOF_HEADERS; \
+// RUN: .text_low : { *(.text_low) *(.text_low2) } \
+// RUN: .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \
+// RUN: } " > %t.script
+// RUN: ld.lld --pic-veneer --script %t.script %t -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s
+
+// Test that we can force generation of position independent thunks even when
+// inputs are not pic.
+
+ .syntax unified
+ .section .text_low, "ax", %progbits
+ .thumb
+ .globl _start
+_start: bx lr
+ .globl low_target
+ .type low_target, %function
+low_target:
+ bl high_target
+ bl high_target2
+
+ .section .text_low2, "ax", %progbits
+ .thumb
+ .globl low_target2
+ .type low_target2, %function
+low_target2:
+ bl high_target
+ bl high_target2
+
+// CHECK: Disassembly of section .text_low:
+// CHECK-NEXT: _start:
+// CHECK-NEXT: 94: 70 47 bx lr
+// CHECK: low_target:
+// CHECK-NEXT: 96: 00 f0 03 f8 bl #6
+// CHECK-NEXT: 9a: 00 f0 07 f8 bl #14
+// CHECK-NEXT: 9e: d4 d4 bmi #-88
+// CHECK: __ThumbV7PILongThunk_high_target:
+// CHECK-NEXT: a0: 4f f6 55 7c movw r12, #65365
+// CHECK-NEXT: a4: c0 f2 ff 1c movt r12, #511
+// CHECK-NEXT: a8: fc 44 add r12, pc
+// CHECK-NEXT: aa: 60 47 bx r12
+// CHECK: __ThumbV7PILongThunk_high_target2:
+// CHECK-NEXT: ac: 4f f6 69 7c movw r12, #65385
+// CHECK-NEXT: b0: c0 f2 ff 1c movt r12, #511
+// CHECK-NEXT: b4: fc 44 add r12, pc
+// CHECK-NEXT: b6: 60 47 bx r12
+// CHECK: low_target2:
+// CHECK-NEXT: b8: ff f7 f2 ff bl #-28
+// CHECK-NEXT: bc: ff f7 f6 ff bl #-20
+
+
+ .section .text_high, "ax", %progbits
+ .thumb
+ .globl high_target
+ .type high_target, %function
+high_target:
+ bl low_target
+ bl low_target2
+
+ .section .text_high2, "ax", %progbits
+ .thumb
+ .globl high_target2
+ .type high_target2, %function
+high_target2:
+ bl low_target
+ bl low_target2
+
+// CHECK: Disassembly of section .text_high:
+// CHECK-NEXT: high_target:
+// CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4
+// CHECK-NEXT: 2000004: 00 f0 06 f8 bl #12
+// CHECK: __ThumbV7PILongThunk_low_target:
+// CHECK-NEXT: 2000008: 40 f2 83 0c movw r12, #131
+// CHECK-NEXT: 200000c: cf f6 00 6c movt r12, #65024
+// CHECK-NEXT: 2000010: fc 44 add r12, pc
+// CHECK-NEXT: 2000012: 60 47 bx r12
+// CHECK: __ThumbV7PILongThunk_low_target2:
+// CHECK-NEXT: 2000014: 40 f2 99 0c movw r12, #153
+// CHECK-NEXT: 2000018: cf f6 00 6c movt r12, #65024
+// CHECK-NEXT: 200001c: fc 44 add r12, pc
+// CHECK-NEXT: 200001e: 60 47 bx r12
+// CHECK: high_target2:
+// CHECK-NEXT: 2000020: ff f7 f2 ff bl #-28
+// CHECK-NEXT: 2000024: ff f7 f6 ff bl #-20
diff --git a/test/ELF/arm-gnu-ifunc.s b/test/ELF/arm-gnu-ifunc.s
index 8a7cb0ae2..92f87b5d5 100644
--- a/test/ELF/arm-gnu-ifunc.s
+++ b/test/ELF/arm-gnu-ifunc.s
@@ -35,6 +35,8 @@ _start:
// CHECK-NEXT: Address: 0x100F4
// CHECK-NEXT: Offset: 0xF4
// CHECK-NEXT: Size: 16
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info: 4
// CHECK: Name: .plt
// CHECK-NEXT: Type: SHT_PROGBITS
// CHECK-NEXT: Flags [
@@ -44,7 +46,8 @@ _start:
// CHECK-NEXT: Address: 0x11020
// CHECK-NEXT: Offset: 0x1020
// CHECK-NEXT: Size: 32
-// CHECK: Name: .got
+// CHECK: Index: 4
+// CHECK-NEXT: Name: .got
// CHECK-NEXT: Type: SHT_PROGBITS
// CHECK-NEXT: Flags [
// CHECK-NEXT: SHF_ALLOC
diff --git a/test/ELF/arm-thunk-multipass-plt.s b/test/ELF/arm-thunk-multipass-plt.s
new file mode 100644
index 000000000..90ec3a52e
--- /dev/null
+++ b/test/ELF/arm-thunk-multipass-plt.s
@@ -0,0 +1,94 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv5-none-linux-gnueabi %s -o %t
+// RUN: ld.lld %t -o %t2 --shared 2>&1
+// RUN: llvm-objdump --start-address=7340044 --stop-address=7340048 --triple=armv5-none-linux-gnueabi -d %t2 | FileCheck %s
+// RUN: llvm-objdump --start-address=8388620 --stop-address=8388624 --triple=thumbv5-none-linux-gnueabi -d %t2 | FileCheck %s -check-prefix=CHECK-CALL
+// RUN: llvm-objdump --start-address=13631520 --stop-address=13631584 --triple=armv5-none-linux-gnueabi -d %t2 | FileCheck %s -check-prefix=CHECK-PLT
+// When we create a thunk to a PLT entry the relocation is redirected to the
+// Thunk, changing its expression to a non-PLT equivalent. If the thunk
+// becomes unusable we need to restore the relocation expression to the PLT
+// form so that when we create a new thunk it targets the PLT.
+
+// Test case that checks the case:
+// - Thunk is created on pass 1 to a PLT entry for preemptible
+// - Some other Thunk added in the same pass moves the thunk to
+// preemptible out of range of its caller.
+// - New Thunk is created on pass 2 to PLT entry for preemptible
+
+ .globl preemptible
+ .globl preemptible2
+.section .text.01, "ax", %progbits
+.balign 0x100000
+ .thumb
+ .globl needsplt
+ .type needsplt, %function
+needsplt:
+ bl preemptible
+ .section .text.02, "ax", %progbits
+ .space (1024 * 1024)
+
+ .section .text.03, "ax", %progbits
+ .space (1024 * 1024)
+
+ .section .text.04, "ax", %progbits
+ .space (1024 * 1024)
+
+ .section .text.05, "ax", %progbits
+ .space (1024 * 1024)
+
+ .section .text.06, "ax", %progbits
+ .space (1024 * 1024)
+
+ .section .text.07, "ax", %progbits
+ .space (1024 * 1024)
+// 0x70000c + 8 + 0x60002c = 0xd00040 = preemptible@plt
+// CHECK: 000000000070000c __ARMV5PILongThunk_preemptible:
+// CHECK-NEXT: 70000c: 0b 00 18 ea b #6291500
+
+ .section .text.08, "ax", %progbits
+ .space (1024 * 1024) - 4
+
+ .section .text.10, "ax", %progbits
+ .balign 2
+ bl preemptible
+ bl preemptible2
+// 0x80000c + 4 - 100004 = 0x70000c = __ARMv5PILongThunk_preemptible
+// CHECK-CALL: 80000c: ff f6 fe ef blx #-1048580
+ .balign 2
+ .globl preemptible
+ .type preemptible, %function
+preemptible:
+ bx lr
+ .globl preemptible2
+ .type preemptible2, %function
+preemptible2:
+ bx lr
+
+
+ .section .text.11, "ax", %progbits
+ .space (5 * 1024 * 1024)
+
+
+// CHECK-PLT: Disassembly of section .plt:
+// CHECK-PLT-NEXT: 0000000000d00020 $a:
+// CHECK-PLT-NEXT: d00020: 04 e0 2d e5 str lr, [sp, #-4]!
+// CHECK-PLT-NEXT: d00024: 00 e6 8f e2 add lr, pc, #0, #12
+// CHECK-PLT-NEXT: d00028: 00 ea 8e e2 add lr, lr, #0, #20
+// CHECK-PLT-NEXT: d0002c: dc ff be e5 ldr pc, [lr, #4060]!
+// CHECK-PLT: 0000000000d00030 $d:
+// CHECK-PLT-NEXT: d00030: d4 d4 d4 d4 .word 0xd4d4d4d4
+// CHECK-PLT-NEXT: d00034: d4 d4 d4 d4 .word 0xd4d4d4d4
+// CHECK-PLT-NEXT: d00038: d4 d4 d4 d4 .word 0xd4d4d4d4
+// CHECK-PLT-NEXT: d0003c: d4 d4 d4 d4 .word 0xd4d4d4d4
+// CHECK-PLT: 0000000000d00040 $a:
+// CHECK-PLT-NEXT: d00040: 00 c6 8f e2 add r12, pc, #0, #12
+// CHECK-PLT-NEXT: d00044: 00 ca 8c e2 add r12, r12, #0, #20
+// CHECK-PLT-NEXT: d00048: c4 ff bc e5 ldr pc, [r12, #4036]!
+// CHECK-PLT: 0000000000d0004c $d:
+// CHECK-PLT-NEXT: d0004c: d4 d4 d4 d4 .word 0xd4d4d4d4
+// CHECK-PLT: 0000000000d00050 $a:
+// CHECK-PLT-NEXT: d00050: 00 c6 8f e2 add r12, pc, #0, #12
+// CHECK-PLT-NEXT: d00054: 00 ca 8c e2 add r12, r12, #0, #20
+// CHECK-PLT-NEXT: d00058: b8 ff bc e5 ldr pc, [r12, #4024]!
+// CHECK-PLT: 0000000000d0005c $d:
+// CHECK-PLT-NEXT: d0005c: d4 d4 d4 d4 .word 0xd4d4d4d4
diff --git a/test/ELF/arm-tls-le32.s b/test/ELF/arm-tls-le32.s
index 7834dedf1..f9a5fa9b2 100644
--- a/test/ELF/arm-tls-le32.s
+++ b/test/ELF/arm-tls-le32.s
@@ -69,9 +69,9 @@ x:
// CHECK: Disassembly of section .text:
// CHECK-NEXT: _start:
-// offset of x from Thread pointer = (TcbSize + 0x0 = 0x8)
-// CHECK-NEXT: 11000: 08 00 00 00
-// offset of z from Thread pointer = (TcbSize + 0x8 = 0x10)
-// CHECK-NEXT: 11004: 10 00 00 00
-// offset of y from Thread pointer = (TcbSize + 0x4 = 0xc)
-// CHECK-NEXT: 11008: 0c 00 00 00
+// offset of x from Thread pointer = (TcbSize + 0x0 = 0x20)
+// CHECK-NEXT: 11000: 20 00 00 00
+// offset of z from Thread pointer = (TcbSize + 0x8 = 0x28)
+// CHECK-NEXT: 11004: 28 00 00 00
+// offset of y from Thread pointer = (TcbSize + 0x4 = 0x24)
+// CHECK-NEXT: 11008: 24 00 00 00
diff --git a/test/ELF/arm-tls-norelax-ie-le.s b/test/ELF/arm-tls-norelax-ie-le.s
index be8af9760..11c3e4f5d 100644
--- a/test/ELF/arm-tls-norelax-ie-le.s
+++ b/test/ELF/arm-tls-norelax-ie-le.s
@@ -37,5 +37,5 @@ x2:
.type x2, %object
// CHECK: Contents of section .got:
-// x1 at offset 8 from TP, x2 at offset c from TP. Offsets include TCB size of 8
-// CHECK-NEXT: 13064 08000000 0c000000
+// x1 at offset 0x20 from TP, x2 at offset 0x24 from TP. Offsets include TCB size of 0x20
+// CHECK-NEXT: 13064 20000000 24000000
diff --git a/test/ELF/as-needed-in-regular.s b/test/ELF/as-needed-in-regular.s
new file mode 100644
index 000000000..2ba646f85
--- /dev/null
+++ b/test/ELF/as-needed-in-regular.s
@@ -0,0 +1,24 @@
+# REQUIRES: x86
+
+# RUN: echo '.globl a; .type a, @function; .type a, @function; a: ret' | \
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %ta.o
+# RUN: ld.lld %ta.o --shared --soname=a.so -o %ta.so
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o --as-needed %ta.so -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+# RUN: ld.lld %t.o --as-needed %ta.so --gc-sections -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+
+# The order of %ta.so and %t.o does not matter.
+
+# RUN: ld.lld --as-needed %ta.so %t.o -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+# RUN: ld.lld --as-needed %ta.so %t.o --gc-sections -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+
+# CHECK: a.so
+
+.global _start
+_start:
+ jmp a@PLT
diff --git a/test/ELF/as-needed-not-in-regular.s b/test/ELF/as-needed-not-in-regular.s
new file mode 100644
index 000000000..cd7efa6d2
--- /dev/null
+++ b/test/ELF/as-needed-not-in-regular.s
@@ -0,0 +1,32 @@
+# REQUIRES: x86
+
+# RUN: echo '.globl a1, a2; .type a1, @function; .type a2, @function; a1: a2: ret' | \
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %ta.o
+# RUN: ld.lld %ta.o --shared --soname=a.so -o %ta.so
+
+# RUN: echo '.globl b; .type b, @function; b: jmp a1@PLT' | \
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tb.o
+# RUN: ld.lld %tb.o %ta.so --shared --soname=b.so -o %tb.so
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o %tb.so --as-needed %ta.so -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+
+# RUN: ld.lld %t.o %tb.so --as-needed %ta.so --gc-sections -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s
+
+# The symbol a1 (defined in a.so) is not referenced by a regular object,
+# the reference to a2 is weak, don't add a DT_NEEDED entry for a.so.
+# CHECK-NOT: a.so
+
+# RUN: ld.lld %t.o %tb.so --as-needed %ta.so --no-as-needed %ta.so -o %t
+# RUN: llvm-readelf -d %t | FileCheck %s -check-prefix=NEEDED
+
+# a.so is needed because one of its occurrences is needed.
+# NEEDED: a.so
+
+.global _start
+.weak a2
+_start:
+ jmp b@PLT
+ jmp a2
diff --git a/test/ELF/as-needed-weak.s b/test/ELF/as-needed-weak.s
index f009c72d6..1c38fd2ab 100644
--- a/test/ELF/as-needed-weak.s
+++ b/test/ELF/as-needed-weak.s
@@ -10,9 +10,10 @@
# CHECK-NOT: libfoo
-# CHECK: Symbol table of .hash for image:
-# CHECK-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
-# CHECK-NEXT: 1 1: 0000000000000000 0 FUNC WEAK DEFAULT UND foo@
+# CHECK: Symbol table '.dynsym' contains 2 entries:
+# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
+# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+# CHECK-NEXT: 1: 0000000000000000 0 FUNC WEAK DEFAULT UND foo
.globl _start
.weak foo
diff --git a/test/ELF/bss-start-common.s b/test/ELF/bss-start-common.s
index cedf6a866..3a32f8589 100644
--- a/test/ELF/bss-start-common.s
+++ b/test/ELF/bss-start-common.s
@@ -4,7 +4,7 @@
# RUN: llvm-objdump -t -section-headers %t2 | FileCheck %s
# CHECK: Sections:
-# CHECK: Idx Name Size Address Type
+# CHECK: Idx Name Size VMA Type
# CHECK: 2 .bss 00000004 0000000000201000 BSS
# CHECK: SYMBOL TABLE:
# CHECK: 0000000000201000 .bss 00000000 __bss_start
diff --git a/test/ELF/bsymbolic-undef.s b/test/ELF/bsymbolic-undef.s
index 1269cb456..97080273c 100644
--- a/test/ELF/bsymbolic-undef.s
+++ b/test/ELF/bsymbolic-undef.s
@@ -5,7 +5,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local (0x0)
@@ -14,7 +14,7 @@
# CHECK-NEXT: Section: Undefined (0x0)
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: undef@
+# CHECK-NEXT: Name: undef
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global (0x1)
diff --git a/test/ELF/comdat-linkonce.s b/test/ELF/comdat-linkonce.s
index 8721f58bb..8b1d4b362 100644
--- a/test/ELF/comdat-linkonce.s
+++ b/test/ELF/comdat-linkonce.s
@@ -4,7 +4,12 @@
// RUN: ld.lld -shared %t.o %t2.o -o %t
// RUN: ld.lld -shared %t2.o %t.o -o %t
-.section .gnu.linkonce.t.zed
+.section .gnu.linkonce.t.__x86.get_pc_thunk.bx
.globl abc
abc:
nop
+
+.section .gnu.linkonce.t.__i686.get_pc_thunk.bx
+.globl def
+def:
+nop
diff --git a/test/ELF/common-gc2.s b/test/ELF/common-gc2.s
index 165bf6253..21bff88b6 100644
--- a/test/ELF/common-gc2.s
+++ b/test/ELF/common-gc2.s
@@ -3,8 +3,8 @@
# RUN: ld.lld -gc-sections -export-dynamic %t -o %t1
# RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s
-# CHECK: Name: bar@
-# CHECK: Name: foo@
+# CHECK: Name: bar
+# CHECK: Name: foo
.comm foo,4,4
.comm bar,4,4
diff --git a/test/ELF/dont-export-hidden.s b/test/ELF/dont-export-hidden.s
index 161e342be..651c024a0 100644
--- a/test/ELF/dont-export-hidden.s
+++ b/test/ELF/dont-export-hidden.s
@@ -19,7 +19,7 @@ foo:
// CHECK: DynamicSymbols [
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: @
+// CHECK-NEXT: Name:
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
diff --git a/test/ELF/driver.test b/test/ELF/driver.test
index 585800a3b..cc3e7898f 100644
--- a/test/ELF/driver.test
+++ b/test/ELF/driver.test
@@ -60,6 +60,7 @@
# ERR9: cannot open output file utput=/no/such/file
# RUN: not ld.lld %t -z foo 2>&1 | FileCheck -check-prefix=ERR10 %s
+# RUN: not ld.lld %t -z foo --version 2>&1 | FileCheck -check-prefix=ERR10 %s
# ERR10: unknown -z value: foo
## Check we report "unknown -z value" error even with -v.
diff --git a/test/ELF/dynamic-list-preempt.s b/test/ELF/dynamic-list-preempt.s
index 2bb10a3ed..daed27a08 100644
--- a/test/ELF/dynamic-list-preempt.s
+++ b/test/ELF/dynamic-list-preempt.s
@@ -16,7 +16,7 @@
# DYNSYMS: DynamicSymbols [
# DYNSYMS-NEXT: Symbol {
-# DYNSYMS-NEXT: Name: @ (0)
+# DYNSYMS-NEXT: Name:
# DYNSYMS-NEXT: Value: 0x0
# DYNSYMS-NEXT: Size: 0
# DYNSYMS-NEXT: Binding: Local
@@ -25,7 +25,7 @@
# DYNSYMS-NEXT: Section: Undefined
# DYNSYMS-NEXT: }
# DYNSYMS-NEXT: Symbol {
-# DYNSYMS-NEXT: Name: bar@
+# DYNSYMS-NEXT: Name: bar
# DYNSYMS-NEXT: Value:
# DYNSYMS-NEXT: Size:
# DYNSYMS-NEXT: Binding: Global
@@ -34,7 +34,7 @@
# DYNSYMS-NEXT: Section:
# DYNSYMS-NEXT: }
# DYNSYMS-NEXT: Symbol {
-# DYNSYMS-NEXT: Name: ext@
+# DYNSYMS-NEXT: Name: ext
# DYNSYMS-NEXT: Value:
# DYNSYMS-NEXT: Size:
# DYNSYMS-NEXT: Binding: Global
@@ -43,7 +43,7 @@
# DYNSYMS-NEXT: Section:
# DYNSYMS-NEXT: }
# DYNSYMS-NEXT: Symbol {
-# DYNSYMS-NEXT: Name: foo@
+# DYNSYMS-NEXT: Name: foo
# DYNSYMS-NEXT: Value:
# DYNSYMS-NEXT: Size:
# DYNSYMS-NEXT: Binding: Global
diff --git a/test/ELF/dynamic-list-wildcard.s b/test/ELF/dynamic-list-wildcard.s
index cd7ed7177..09a78af01 100644
--- a/test/ELF/dynamic-list-wildcard.s
+++ b/test/ELF/dynamic-list-wildcard.s
@@ -8,7 +8,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @ (0)
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local (0x0)
@@ -17,7 +17,7 @@
# CHECK-NEXT: Section: Undefined (0x0)
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: foo1@ (1)
+# CHECK-NEXT: Name: foo1
# CHECK-NEXT: Value: 0x1000
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global (0x1)
@@ -26,7 +26,7 @@
# CHECK-NEXT: Section: .text (0x4)
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: foo11@ (6)
+# CHECK-NEXT: Name: foo11
# CHECK-NEXT: Value: 0x1001
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global (0x1)
diff --git a/test/ELF/dynamic-list.s b/test/ELF/dynamic-list.s
index 888508e27..f6addcb9b 100644
--- a/test/ELF/dynamic-list.s
+++ b/test/ELF/dynamic-list.s
@@ -23,7 +23,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local
@@ -32,7 +32,7 @@
# CHECK-NEXT: Section: Undefined
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: foo1@
+# CHECK-NEXT: Name: foo1
# CHECK-NEXT: Value: 0x201000
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global (0x1)
@@ -54,7 +54,7 @@
# CHECK2: DynamicSymbols [
# CHECK2-NEXT: Symbol {
-# CHECK2-NEXT: Name: @
+# CHECK2-NEXT: Name:
# CHECK2-NEXT: Value: 0x0
# CHECK2-NEXT: Size: 0
# CHECK2-NEXT: Binding: Local
@@ -63,7 +63,7 @@
# CHECK2-NEXT: Section: Undefined
# CHECK2-NEXT: }
# CHECK2-NEXT: Symbol {
-# CHECK2-NEXT: Name: foo1@
+# CHECK2-NEXT: Name: foo1
# CHECK2-NEXT: Value: 0x201000
# CHECK2-NEXT: Size: 0
# CHECK2-NEXT: Binding: Global (0x1)
@@ -72,7 +72,7 @@
# CHECK2-NEXT: Section: .text (0x4)
# CHECK2-NEXT: }
# CHECK2-NEXT: Symbol {
-# CHECK2-NEXT: Name: foo2@
+# CHECK2-NEXT: Name: foo2
# CHECK2-NEXT: Value: 0x201001
# CHECK2-NEXT: Size: 0
# CHECK2-NEXT: Binding: Global (0x1)
@@ -81,7 +81,7 @@
# CHECK2-NEXT: Section: .text (0x4)
# CHECK2-NEXT: }
# CHECK2-NEXT: Symbol {
-# CHECK2-NEXT: Name: foo31@
+# CHECK2-NEXT: Name: foo31
# CHECK2-NEXT: Value: 0x201002
# CHECK2-NEXT: Size: 0
# CHECK2-NEXT: Binding: Global (0x1)
@@ -104,7 +104,7 @@
# CHECK3: DynamicSymbols [
# CHECK3-NEXT: Symbol {
-# CHECK3-NEXT: Name: @
+# CHECK3-NEXT: Name:
# CHECK3-NEXT: Value: 0x0
# CHECK3-NEXT: Size: 0
# CHECK3-NEXT: Binding: Local
@@ -113,7 +113,7 @@
# CHECK3-NEXT: Section: Undefined
# CHECK3-NEXT: }
# CHECK3-NEXT: Symbol {
-# CHECK3-NEXT: Name: _start@
+# CHECK3-NEXT: Name: _start
# CHECK3-NEXT: Value: 0x201003
# CHECK3-NEXT: Size: 0
# CHECK3-NEXT: Binding: Global (0x1)
@@ -122,7 +122,7 @@
# CHECK3-NEXT: Section: .text (0x4)
# CHECK3-NEXT: }
# CHECK3-NEXT: Symbol {
-# CHECK3-NEXT: Name: foo1@
+# CHECK3-NEXT: Name: foo1
# CHECK3-NEXT: Value: 0x201000
# CHECK3-NEXT: Size: 0
# CHECK3-NEXT: Binding: Global (0x1)
@@ -131,7 +131,7 @@
# CHECK3-NEXT: Section: .text (0x4)
# CHECK3-NEXT: }
# CHECK3-NEXT: Symbol {
-# CHECK3-NEXT: Name: foo2@
+# CHECK3-NEXT: Name: foo2
# CHECK3-NEXT: Value: 0x201001
# CHECK3-NEXT: Size: 0
# CHECK3-NEXT: Binding: Global (0x1)
@@ -140,7 +140,7 @@
# CHECK3-NEXT: Section: .text (0x4)
# CHECK3-NEXT: }
# CHECK3-NEXT: Symbol {
-# CHECK3-NEXT: Name: foo31@
+# CHECK3-NEXT: Name: foo31
# CHECK3-NEXT: Value: 0x201002
# CHECK3-NEXT: Size: 0
# CHECK3-NEXT: Binding: Global (0x1)
diff --git a/test/ELF/dynsym-no-rosegment.s b/test/ELF/dynsym-no-rosegment.s
index 947f526e0..c378bbce4 100644
--- a/test/ELF/dynsym-no-rosegment.s
+++ b/test/ELF/dynsym-no-rosegment.s
@@ -5,7 +5,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @ (0)
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local
@@ -14,7 +14,7 @@
# CHECK-NEXT: Section: Undefined
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: undef@
+# CHECK-NEXT: Name: undef
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global
diff --git a/test/ELF/dynsym-pie.s b/test/ELF/dynsym-pie.s
index b162d2733..6a7f4f1f0 100644
--- a/test/ELF/dynsym-pie.s
+++ b/test/ELF/dynsym-pie.s
@@ -50,7 +50,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local
diff --git a/test/ELF/edata-etext.s b/test/ELF/edata-etext.s
index 52070cbc4..5c83256bf 100644
--- a/test/ELF/edata-etext.s
+++ b/test/ELF/edata-etext.s
@@ -12,13 +12,12 @@
## 3) Address of _end is different from _edata because of 2.
## 4) Addresses of _edata == edata, _end == end and _etext == etext.
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .text 00000001 0000000000201000 TEXT
# CHECK-NEXT: 2 .data 00000002 0000000000202000 DATA
# CHECK-NEXT: 3 .bss 00000006 0000000000202004 BSS
# CHECK: SYMBOL TABLE:
-# CHECK-NEXT: 0000000000000000 *UND* 00000000
# CHECK-NEXT: 0000000000202002 .data 00000000 _edata
# CHECK-NEXT: 000000000020200a .bss 00000000 _end
# CHECK-NEXT: 0000000000201001 .text 00000000 _etext
diff --git a/test/ELF/empty-ver.s b/test/ELF/empty-ver.s
index 3412f3134..d923607bf 100644
--- a/test/ELF/empty-ver.s
+++ b/test/ELF/empty-ver.s
@@ -29,7 +29,7 @@
// CHECK-NEXT: Symbols [
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Version: 0
-// CHECK-NEXT: Name: @
+// CHECK-NEXT: Name:
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Version: 2
diff --git a/test/ELF/empty-ver2.s b/test/ELF/empty-ver2.s
index 2aceee128..f4b288eb5 100644
--- a/test/ELF/empty-ver2.s
+++ b/test/ELF/empty-ver2.s
@@ -8,11 +8,11 @@
# CHECK: Symbols [
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 0
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 1
-# CHECK-NEXT: Name: bar@@
+# CHECK-NEXT: Name: bar@
# CHECK-NEXT: }
# CHECK-NEXT: ]
diff --git a/test/ELF/emulation-aarch64.s b/test/ELF/emulation-aarch64.s
index b9a6428fa..c0edc9a69 100644
--- a/test/ELF/emulation-aarch64.s
+++ b/test/ELF/emulation-aarch64.s
@@ -30,5 +30,28 @@
# AARCH64-NEXT: Flags [ (0x0)
# AARCH64-NEXT: ]
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %taarch64fbsd
+# RUN: echo 'OUTPUT_FORMAT(elf64-aarch64-freebsd)' > %taarch64fbsd.script
+# RUN: ld.lld %taarch64fbsd.script %taarch64fbsd -o %t2aarch64fbsd
+# RUN: llvm-readobj -file-headers %t2aarch64fbsd | FileCheck --check-prefix=AARCH64-FBSD %s
+# AARCH64-FBSD: ElfHeader {
+# AARCH64-FBSD-NEXT: Ident {
+# AARCH64-FBSD-NEXT: Magic: (7F 45 4C 46)
+# AARCH64-FBSD-NEXT: Class: 64-bit (0x2)
+# AARCH64-FBSD-NEXT: DataEncoding: LittleEndian (0x1)
+# AARCH64-FBSD-NEXT: FileVersion: 1
+# AARCH64-FBSD-NEXT: OS/ABI: FreeBSD (0x9)
+# AARCH64-FBSD-NEXT: ABIVersion: 0
+# AARCH64-FBSD-NEXT: Unused: (00 00 00 00 00 00 00)
+# AARCH64-FBSD-NEXT: }
+# AARCH64-FBSD-NEXT: Type: Executable (0x2)
+# AARCH64-FBSD-NEXT: Machine: EM_AARCH64 (0xB7)
+# AARCH64-FBSD-NEXT: Version: 1
+# AARCH64-FBSD-NEXT: Entry:
+# AARCH64-FBSD-NEXT: ProgramHeaderOffset: 0x40
+# AARCH64-FBSD-NEXT: SectionHeaderOffset:
+# AARCH64-FBSD-NEXT: Flags [ (0x0)
+# AARCH64-FBSD-NEXT: ]
+
.globl _start
_start:
diff --git a/test/ELF/emulation-mips.s b/test/ELF/emulation-mips.s
index 42d0dd973..6d7a1198b 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 12e847822..4c8beb101 100644
--- a/test/ELF/emulation-ppc.s
+++ b/test/ELF/emulation-ppc.s
@@ -35,6 +35,38 @@
# PPC64-NEXT: StringTableSectionIndex:
# PPC64-NEXT: }
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd %s -o %tppc64fbsd
+# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc-freebsd)' > %tppc64fbsd.script
+# RUN: ld.lld %tppc64fbsd.script %tppc64fbsd -o %t2ppc64fbsd
+# RUN: llvm-readobj -file-headers %t2ppc64fbsd | FileCheck --check-prefix=PPC64-FBSD %s
+
+# PPC64-FBSD: ElfHeader {
+# PPC64-FBSD-NEXT: Ident {
+# PPC64-FBSD-NEXT: Magic: (7F 45 4C 46)
+# PPC64-FBSD-NEXT: Class: 64-bit (0x2)
+# PPC64-FBSD-NEXT: DataEncoding: BigEndian (0x2)
+# PPC64-FBSD-NEXT: FileVersion: 1
+# PPC64-FBSD-NEXT: OS/ABI: FreeBSD (0x9)
+# PPC64-FBSD-NEXT: ABIVersion: 0
+# PPC64-FBSD-NEXT: Unused: (00 00 00 00 00 00 00)
+# PPC64-FBSD-NEXT: }
+# PPC64-FBSD-NEXT: Type: Executable (0x2)
+# PPC64-FBSD-NEXT: Machine: EM_PPC64 (0x15)
+# PPC64-FBSD-NEXT: Version: 1
+# PPC64-FBSD-NEXT: Entry:
+# PPC64-FBSD-NEXT: ProgramHeaderOffset: 0x40
+# PPC64-FBSD-NEXT: SectionHeaderOffset:
+# PPC64-FBSD-NEXT: Flags [ (0x2)
+# PPC64-FBSD-NEXT: 0x2
+# PPC64-FBSD-NEXT: ]
+# PPC64-FBSD-NEXT: HeaderSize: 64
+# PPC64-FBSD-NEXT: ProgramHeaderEntrySize: 56
+# PPC64-FBSD-NEXT: ProgramHeaderCount:
+# PPC64-FBSD-NEXT: SectionHeaderEntrySize: 64
+# PPC64-FBSD-NEXT: SectionHeaderCount:
+# PPC64-FBSD-NEXT: StringTableSectionIndex:
+# PPC64-FBSD-NEXT: }
+
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le
# RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le
# RUN: llvm-readobj -file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s
@@ -71,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/ELF/emulation-x86.s b/test/ELF/emulation-x86.s
index 65d807c67..02b894356 100644
--- a/test/ELF/emulation-x86.s
+++ b/test/ELF/emulation-x86.s
@@ -7,6 +7,9 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv
# RUN: ld.lld -m elf_amd64_fbsd %t.sysv -o %t.freebsd
# RUN: llvm-readobj -file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s
+# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64-freebsd)' > %t4x64.script
+# RUN: ld.lld %t4x64.script %tx64 -o %t4x64
+# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=AMD64 %s
# AMD64: ElfHeader {
# AMD64-NEXT: Ident {
# AMD64-NEXT: Magic: (7F 45 4C 46)
@@ -137,10 +140,13 @@
# X86-NEXT: }
# RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd
-# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86_fbsd
-# RUN: llvm-readobj -file-headers %t2x86_fbsd | FileCheck --check-prefix=X86FBSD %s
+# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86fbsd
+# RUN: llvm-readobj -file-headers %t2x86fbsd | FileCheck --check-prefix=X86FBSD %s
# RUN: ld.lld %tx86fbsd -o %t3x86fbsd
# RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-i386-freebsd)' > %t4x86fbsd.script
+# RUN: ld.lld %t4x86fbsd.script %tx86fbsd -o %t4x86fbsd
+# RUN: llvm-readobj -file-headers %t4x86fbsd | FileCheck --check-prefix=X86FBSD %s
# X86FBSD: ElfHeader {
# X86FBSD-NEXT: Ident {
# X86FBSD-NEXT: Magic: (7F 45 4C 46)
diff --git a/test/ELF/gc-sections-linker-defined-symbol.s b/test/ELF/gc-sections-linker-defined-symbol.s
index 796f7b363..e570116e3 100644
--- a/test/ELF/gc-sections-linker-defined-symbol.s
+++ b/test/ELF/gc-sections-linker-defined-symbol.s
@@ -4,7 +4,7 @@
# RUN: ld.lld %t.o -o %t.so --gc-sections -shared
# RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s
-# CHECK: Name: _end@
+# CHECK: Name: _end
# CHECK-NEXT: Value:
# CHECK-NEXT: Size:
# CHECK-NEXT: Binding: Global
diff --git a/test/ELF/gdb-index-dwarf5-low-high.s b/test/ELF/gdb-index-dwarf5-low-high.s
new file mode 100644
index 000000000..94b713c6d
--- /dev/null
+++ b/test/ELF/gdb-index-dwarf5-low-high.s
@@ -0,0 +1,49 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld --gdb-index %t.o -o %t
+# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
+
+# CHECK: Address area offset = 0x28, has 1 entries:
+# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
+
+ .text
+ .globl main
+main: # @main
+.Lfunc_begin0:
+ retq
+.Lfunc_end0:
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] 0xc:0x2b DW_TAG_compile_unit
+ .long .Laddr_table_base0 # DW_AT_addr_base
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+.Ldebug_info_end0:
+
+ .section .debug_addr,"",@progbits
+ .long 12
+ .short 5
+ .byte 8
+ .byte 0
+.Laddr_table_base0:
+ .quad .Lfunc_begin0
diff --git a/test/ELF/gdb-index-invalid-ranges.s b/test/ELF/gdb-index-invalid-ranges.s
new file mode 100644
index 000000000..1aac98d87
--- /dev/null
+++ b/test/ELF/gdb-index-invalid-ranges.s
@@ -0,0 +1,42 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: not ld.lld --gdb-index -e main %t.o -o %t 2>&1 | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gdb-index-invalid-ranges.obj.s -o %t2.o
+# RUN: llvm-ar rc %t.a %t.o
+# RUN: not ld.lld --gdb-index -e main %t2.o %t.a -o %t 2>&1 | FileCheck --check-prefix=ARCHIVE %s
+
+# CHECK: ld.lld: error: {{.*}}gdb-index-invalid-ranges.s.tmp.o:(.debug_info): decoding address ranges: invalid range list entry at offset 0x10
+# ARCHIVE: ld.lld: error: {{.*}}gdb-index-invalid-ranges.s.tmp.a(gdb-index-invalid-ranges.s.tmp.o):(.debug_info): decoding address ranges: invalid range list entry at offset 0x10
+
+.section .text.foo1,"ax",@progbits
+.globl f1
+.Lfunc_begin0:
+f1:
+ nop
+.Lfunc_end0:
+
+.section .debug_abbrev,"",@progbits
+.byte 1 # Abbreviation Code
+.byte 17 # DW_TAG_compile_unit
+.byte 0 # DW_CHILDREN_no
+.byte 85 # DW_AT_ranges
+.byte 23 # DW_FORM_sec_offset
+.byte 0 # EOM(1)
+.byte 0 # EOM(2)
+.byte 0 # EOM(3)
+
+.section .debug_info,"",@progbits
+.Lcu_begin0:
+.long .Lunit_end0-.Lunit_begin0 # Length of Unit
+.Lunit_begin0:
+.short 4 # DWARF version number
+.long .debug_abbrev # Offset Into Abbrev. Section
+.byte 8 # Address Size (in bytes)
+.byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
+.long .Ldebug_ranges0 # DW_AT_ranges
+.Lunit_end0:
+
+.section .debug_ranges,"",@progbits
+.Ldebug_ranges0:
+.quad .Lfunc_begin0
+.quad .Lfunc_end0
diff --git a/test/ELF/gnu-hash-table-copy.s b/test/ELF/gnu-hash-table-copy.s
index 9d9116325..cdd96e3df 100644
--- a/test/ELF/gnu-hash-table-copy.s
+++ b/test/ELF/gnu-hash-table-copy.s
@@ -13,10 +13,10 @@
# CHECK: Symbol table '.dynsym' contains 4 entries:
# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
-# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND @
-# CHECK-NEXT: 1: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND foo@
-# CHECK-DAG: : {{.*}} 4 OBJECT GLOBAL DEFAULT {{.*}} bar@
-# CHECK-DAG: : {{.*}} 0 FUNC GLOBAL DEFAULT UND zed@
+# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+# CHECK-NEXT: 1: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND foo
+# CHECK-DAG: : {{.*}} 4 OBJECT GLOBAL DEFAULT {{.*}} bar
+# CHECK-DAG: : {{.*}} 0 FUNC GLOBAL DEFAULT UND zed
# CHECK: First Hashed Symbol Index: 2
diff --git a/test/ELF/gnu-hash-table-rwsegment.s b/test/ELF/gnu-hash-table-rwsegment.s
index b1a50fbde..ab1b252bc 100644
--- a/test/ELF/gnu-hash-table-rwsegment.s
+++ b/test/ELF/gnu-hash-table-rwsegment.s
@@ -8,8 +8,8 @@
# CHECK-NEXT: Num Buckets: 1
# CHECK-NEXT: First Hashed Symbol Index: 1
# CHECK-NEXT: Num Mask Words: 1
-# CHECK-NEXT: Shift Count: 6
-# CHECK-NEXT: Bloom Filter: [0x400000000004204]
+# CHECK-NEXT: Shift Count: 26
+# CHECK-NEXT: Bloom Filter: [0x400000000000204]
# CHECK-NEXT: Buckets: [1]
# CHECK-NEXT: Values: [0xB8860BA, 0xB887389]
# CHECK-NEXT: }
diff --git a/test/ELF/gnu-hash-table.s b/test/ELF/gnu-hash-table.s
index 642b445ec..052a5bb20 100644
--- a/test/ELF/gnu-hash-table.s
+++ b/test/ELF/gnu-hash-table.s
@@ -49,7 +49,7 @@
# EMPTY: DynamicSymbols [
# EMPTY: Symbol {
-# EMPTY: Name: foo@
+# EMPTY: Name: foo
# EMPTY-NEXT: Value: 0x0
# EMPTY-NEXT: Size: 0
# EMPTY-NEXT: Binding: Global
@@ -62,7 +62,7 @@
# EMPTY-NEXT: Num Buckets: 1
# EMPTY-NEXT: First Hashed Symbol Index: 2
# EMPTY-NEXT: Num Mask Words: 1
-# EMPTY-NEXT: Shift Count: 6
+# EMPTY-NEXT: Shift Count: 26
# EMPTY-NEXT: Bloom Filter: [0x0]
# EMPTY-NEXT: Buckets: [0]
# EMPTY-NEXT: Values: []
@@ -87,32 +87,32 @@
# I386: ]
# I386: DynamicSymbols [
# I386: Symbol {
-# I386: Name: @
+# I386: Name:
# I386: Binding: Local
# I386: Section: Undefined
# I386: }
# I386: Symbol {
-# I386: Name: baz@
+# I386: Name: baz
# I386: Binding: Global
# I386: Section: Undefined
# I386: }
# I386: Symbol {
-# I386: Name: xyz@
+# I386: Name: xyz
# I386: Binding: Global
# I386: Section: Undefined
# I386: }
# I386: Symbol {
-# I386: Name: zed@
+# I386: Name: zed
# I386: Binding: Weak
# I386: Section: Undefined
# I386: }
# I386: Symbol {
-# I386: Name: bar@
+# I386: Name: bar
# I386: Binding: Global
# I386: Section: .text
# I386: }
# I386: Symbol {
-# I386: Name: foo@
+# I386: Name: foo
# I386: Binding: Global
# I386: Section: .text
# I386: }
@@ -121,8 +121,8 @@
# I386-NEXT: Num Buckets: 1
# I386-NEXT: First Hashed Symbol Index: 4
# I386-NEXT: Num Mask Words: 1
-# I386-NEXT: Shift Count: 6
-# I386-NEXT: Bloom Filter: [0x4004204]
+# I386-NEXT: Shift Count: 26
+# I386-NEXT: Bloom Filter: [0x4000204]
# I386-NEXT: Buckets: [4]
# I386-NEXT: Values: [0xB8860BA, 0xB887389]
# I386-NEXT: }
@@ -147,32 +147,32 @@
# X86_64: ]
# X86_64: DynamicSymbols [
# X86_64: Symbol {
-# X86_64: Name: @
+# X86_64: Name:
# X86_64: Binding: Local
# X86_64: Section: Undefined
# X86_64: }
# X86_64: Symbol {
-# X86_64: Name: baz@
+# X86_64: Name: baz
# X86_64: Binding: Global
# X86_64: Section: Undefined
# X86_64: }
# X86_64: Symbol {
-# X86_64: Name: xyz@
+# X86_64: Name: xyz
# X86_64: Binding: Global
# X86_64: Section: Undefined
# X86_64: }
# X86_64: Symbol {
-# X86_64: Name: zed@
+# X86_64: Name: zed
# X86_64: Binding: Weak
# X86_64: Section: Undefined
# X86_64: }
# X86_64: Symbol {
-# X86_64: Name: bar@
+# X86_64: Name: bar
# X86_64: Binding: Global
# X86_64: Section: .text
# X86_64: }
# X86_64: Symbol {
-# X86_64: Name: foo@
+# X86_64: Name: foo
# X86_64: Binding: Global
# X86_64: Section: .text
# X86_64: }
@@ -181,8 +181,8 @@
# X86_64-NEXT: Num Buckets: 1
# X86_64-NEXT: First Hashed Symbol Index: 4
# X86_64-NEXT: Num Mask Words: 1
-# X86_64-NEXT: Shift Count: 6
-# X86_64-NEXT: Bloom Filter: [0x400000000004204]
+# X86_64-NEXT: Shift Count: 26
+# X86_64-NEXT: Bloom Filter: [0x400000000000204]
# X86_64-NEXT: Buckets: [4]
# X86_64-NEXT: Values: [0xB8860BA, 0xB887389]
# X86_64-NEXT: }
@@ -207,32 +207,32 @@
# PPC64: ]
# PPC64: DynamicSymbols [
# PPC64: Symbol {
-# PPC64: Name: @
+# PPC64: Name:
# PPC64: Binding: Local
# PPC64: Section: Undefined
# PPC64: }
# PPC64: Symbol {
-# PPC64: Name: baz@
+# PPC64: Name: baz
# PPC64: Binding: Global
# PPC64: Section: Undefined
# PPC64: }
# PPC64: Symbol {
-# PPC64: Name: xyz@
+# PPC64: Name: xyz
# PPC64: Binding: Global
# PPC64: Section: Undefined
# PPC64: }
# PPC64: Symbol {
-# PPC64: Name: zed@
+# PPC64: Name: zed
# PPC64: Binding: Weak
# PPC64: Section: Undefined
# PPC64: }
# PPC64: Symbol {
-# PPC64: Name: bar@
+# PPC64: Name: bar
# PPC64: Binding: Global
# PPC64: Section: .text
# PPC64: }
# PPC64: Symbol {
-# PPC64: Name: foo@
+# PPC64: Name: foo
# PPC64: Binding: Global
# PPC64: Section: .text
# PPC64: }
@@ -241,8 +241,8 @@
# PPC64-NEXT: Num Buckets: 1
# PPC64-NEXT: First Hashed Symbol Index: 4
# PPC64-NEXT: Num Mask Words: 1
-# PPC64-NEXT: Shift Count: 6
-# PPC64-NEXT: Bloom Filter: [0x400000000004204]
+# PPC64-NEXT: Shift Count: 26
+# PPC64-NEXT: Bloom Filter: [0x400000000000204]
# PPC64-NEXT: Buckets: [4]
# PPC64-NEXT: Values: [0xB8860BA, 0xB887389]
# PPC64-NEXT: }
diff --git a/test/ELF/gnu-ifunc-canon.s b/test/ELF/gnu-ifunc-canon.s
new file mode 100644
index 000000000..c14e137cc
--- /dev/null
+++ b/test/ELF/gnu-ifunc-canon.s
@@ -0,0 +1,92 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-canon-ro-pcrel.s -o %t-ro-pcrel.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-canon-ro-abs.s -o %t-ro-abs.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-canon-rw-addend.s -o %t-rw-addend.o
+// RUN: ld.lld %t.o -o %t1
+// RUN: llvm-readobj -relocs %t1 | FileCheck --check-prefix=IREL2 %s
+// RUN: ld.lld %t.o %t-ro-pcrel.o -o %t2
+// RUN: llvm-readobj -relocs %t2 | FileCheck --check-prefix=IREL1 %s
+// RUN: ld.lld %t.o %t-ro-abs.o -o %t3
+// RUN: llvm-readobj -relocs %t3 | FileCheck --check-prefix=IREL1 %s
+// RUN: ld.lld %t.o %t-rw-addend.o -o %t4
+// RUN: llvm-readobj -relocs %t4 | FileCheck --check-prefix=IREL1 %s
+// RUN: llvm-objdump -s %t4 | FileCheck --check-prefix=DUMP %s
+// RUN: ld.lld %t.o %t-rw-addend.o -o %t4a -z retpolineplt
+// RUN: llvm-readobj -relocs %t4a | FileCheck --check-prefix=IREL1 %s
+// RUN: llvm-objdump -s %t4a | FileCheck --check-prefix=DUMP2 %s
+// RUN: ld.lld %t-ro-pcrel.o %t.o -o %t5
+// RUN: llvm-readobj -relocs %t5 | FileCheck --check-prefix=IREL1 %s
+// RUN: ld.lld %t-ro-abs.o %t.o -o %t6
+// RUN: llvm-readobj -relocs %t6 | FileCheck --check-prefix=IREL1 %s
+// RUN: ld.lld %t-rw-addend.o %t.o -o %t7
+// RUN: llvm-readobj -relocs %t7 | FileCheck --check-prefix=IREL1 %s
+// RUN: ld.lld %t.o -o %t8 -pie
+// RUN: llvm-readobj -relocs %t8 | FileCheck --check-prefix=IREL2 %s
+// RUN: ld.lld %t.o %t-ro-pcrel.o -o %t9 -pie
+// RUN: llvm-readobj -relocs %t9 | FileCheck --check-prefix=IREL1-REL2 %s
+// RUN: ld.lld %t.o %t-rw-addend.o -o %t10 -pie
+// RUN: llvm-readobj -relocs %t10 | FileCheck --check-prefix=IREL1-REL3 %s
+// RUN: ld.lld %t-ro-pcrel.o %t.o -o %t11 -pie
+// RUN: llvm-readobj -relocs %t11 | FileCheck --check-prefix=IREL1-REL2 %s
+// RUN: ld.lld %t-rw-addend.o %t.o -o %t12 -pie
+// RUN: llvm-readobj -relocs %t12 | FileCheck --check-prefix=IREL1-REL3 %s
+
+// Two relocs, one for the GOT and the other for .data.
+// IREL2-NOT: R_X86_64_
+// IREL2: .rela.plt
+// IREL2-NEXT: R_X86_64_IRELATIVE
+// IREL2-NEXT: R_X86_64_IRELATIVE
+// IREL2-NOT: R_X86_64_
+
+// One reloc for the canonical PLT.
+// IREL1-NOT: R_X86_64_
+// IREL1: .rela.plt
+// IREL1-NEXT: R_X86_64_IRELATIVE
+// IREL1-NOT: R_X86_64_
+
+// One reloc for the canonical PLT and two RELATIVE relocations pointing to it,
+// one in the GOT and one in .data.
+// IREL1-REL2-NOT: R_X86_64_
+// IREL1-REL2: .rela.dyn
+// IREL1-REL2-NEXT: R_X86_64_RELATIVE
+// IREL1-REL2-NEXT: R_X86_64_RELATIVE
+// IREL1-REL2: .rela.plt
+// IREL1-REL2-NEXT: R_X86_64_IRELATIVE
+// IREL1-REL2-NOT: R_X86_64_
+
+// One reloc for the canonical PLT and three RELATIVE relocations pointing to it,
+// one in the GOT and two in .data.
+// IREL1-REL3-NOT: R_X86_64_
+// IREL1-REL3: .rela.dyn
+// IREL1-REL3-NEXT: R_X86_64_RELATIVE
+// IREL1-REL3-NEXT: R_X86_64_RELATIVE
+// IREL1-REL3-NEXT: R_X86_64_RELATIVE
+// IREL1-REL3: .rela.plt
+// IREL1-REL3-NEXT: R_X86_64_IRELATIVE
+// IREL1-REL3-NOT: R_X86_64_
+
+// Make sure the static relocations look right, both with and without headers.
+// DUMP: Contents of section .plt:
+// DUMP-NEXT: 201010
+// DUMP: Contents of section .data:
+// DUMP-NEXT: 202000 10102000 00000000 11102000 00000000
+// DUMP: Contents of section .got:
+// DUMP-NEXT: 203000 10102000 00000000
+
+// DUMP2: Contents of section .plt:
+// DUMP2-NEXT: 201010
+// DUMP2: Contents of section .data:
+// DUMP2-NEXT: 202000 40102000 00000000 41102000 00000000
+// DUMP2: Contents of section .got:
+// DUMP2-NEXT: 203000 40102000 00000000
+
+lea ifunc@gotpcrel(%rip), %rbx
+
+.type ifunc STT_GNU_IFUNC
+.globl ifunc
+ifunc:
+ret
+
+.data
+.8byte ifunc
diff --git a/test/ELF/gnu-ifunc-dyntags.s b/test/ELF/gnu-ifunc-dyntags.s
index 81bd338d0..79a4a890b 100644
--- a/test/ELF/gnu-ifunc-dyntags.s
+++ b/test/ELF/gnu-ifunc-dyntags.s
@@ -7,7 +7,7 @@
## Check we produce DT_PLTREL/DT_JMPREL/DT_PLTGOT and DT_PLTRELSZ tags
## when there are no other relocations except R_*_IRELATIVE.
-# CHECK: Name Size Address
+# CHECK: Name Size VMA
# CHECK: .rela.plt 00000030 0000000000000210
# CHECK: .got.plt 00000010 0000000000002000
diff --git a/test/ELF/gnu-ifunc-empty.s b/test/ELF/gnu-ifunc-empty.s
new file mode 100644
index 000000000..90798532f
--- /dev/null
+++ b/test/ELF/gnu-ifunc-empty.s
@@ -0,0 +1,16 @@
+// REQUIRES: x86
+
+// Verifies that .rela_iplt_{start,end} point to a dummy section
+// if .rela.iplt does not exist.
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld -static %t.o -o %t.exe
+// RUN: llvm-objdump -syms %t.exe | FileCheck %s
+
+// CHECK: 0000000000200000 .text 00000000 .hidden __rela_iplt_end
+// CHECK: 0000000000200000 .text 00000000 .hidden __rela_iplt_start
+
+.globl _start
+_start:
+ movl $__rela_iplt_start, %edx
+ movl $__rela_iplt_end, %edx
diff --git a/test/ELF/gnu-ifunc-i386.s b/test/ELF/gnu-ifunc-i386.s
index bfc1587f0..ac41dbdd5 100644
--- a/test/ELF/gnu-ifunc-i386.s
+++ b/test/ELF/gnu-ifunc-i386.s
@@ -70,28 +70,46 @@
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar
+// CHECK-NEXT: Value: 0x401030
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Function
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .plt
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: bar_resolver
// CHECK-NEXT: Value: 0x401001
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
-// CHECK-NEXT: Type: GNU_IFunc
+// CHECK-NEXT: Type: Function
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo
+// CHECK-NEXT: Value: 0x401020
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Function
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .plt
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo_resolver
// CHECK-NEXT: Value: 0x401000
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
-// CHECK-NEXT: Type: GNU_IFunc
+// CHECK-NEXT: Type: Function
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT:]
// DISASM: Disassembly of section .text:
-// DISASM-NEXT: foo:
+// DISASM-NEXT: foo_resolver:
// DISASM-NEXT: 401000: c3 retl
-// DISASM: bar:
+// DISASM: bar_resolver:
// DISASM-NEXT: 401001: c3 retl
// DISASM: _start:
// DISASM-NEXT: 401002: e8 19 00 00 00 calll 25
@@ -99,10 +117,11 @@
// DISASM-NEXT: 40100c: ba d4 00 40 00 movl $4194516, %edx
// DISASM-NEXT: 401011: ba e4 00 40 00 movl $4194532, %edx
// DISASM-NEXT: Disassembly of section .plt:
-// DISASM-NEXT: .plt:
+// DISASM-NEXT: foo:
// DISASM-NEXT: 401020: ff 25 00 20 40 00 jmpl *4202496
// DISASM-NEXT: 401026: 68 10 00 00 00 pushl $16
// DISASM-NEXT: 40102b: e9 e0 ff ff ff jmp -32 <_start+0xe>
+// DISASM: bar:
// DISASM-NEXT: 401030: ff 25 04 20 40 00 jmpl *4202500
// DISASM-NEXT: 401036: 68 18 00 00 00 pushl $24
// DISASM-NEXT: 40103b: e9 d0 ff ff ff jmp -48 <_start+0xe>
@@ -111,11 +130,17 @@
.type foo STT_GNU_IFUNC
.globl foo
foo:
+.type foo_resolver STT_FUNC
+.globl foo_resolver
+foo_resolver:
ret
.type bar STT_GNU_IFUNC
.globl bar
bar:
+.type bar_resolver STT_FUNC
+.globl bar_resolver
+bar_resolver:
ret
.globl _start
diff --git a/test/ELF/gnu-unique.s b/test/ELF/gnu-unique.s
index 06f370434..83f0f233f 100644
--- a/test/ELF/gnu-unique.s
+++ b/test/ELF/gnu-unique.s
@@ -20,7 +20,7 @@ _start:
.type symb, @gnu_unique_object
symb:
-# GNU: Name: symb@
+# GNU: Name: symb
# GNU-NEXT: Value:
# GNU-NEXT: Size: 0
# GNU-NEXT: Binding: Unique
@@ -29,7 +29,7 @@ symb:
# GNU-NEXT: Section: .data
# GNU-NEXT: }
-# NO: Name: symb@
+# NO: Name: symb
# NO-NEXT: Value:
# NO-NEXT: Size: 0
# NO-NEXT: Binding: Global
diff --git a/test/ELF/got32-i386.s b/test/ELF/got32-i386.s
index ff67a4bbe..0080e1be1 100644
--- a/test/ELF/got32-i386.s
+++ b/test/ELF/got32-i386.s
@@ -16,7 +16,7 @@ _start:
# CHECK: _start:
# CHECK-NEXT: 401001: 8b 1d {{.*}} movl 4202496, %ebx
# CHECK: Sections:
-# CHECK: Name Size Address
+# CHECK: Name Size VMA
# CHECK: .got 00000004 0000000000402000
# RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR
diff --git a/test/ELF/got32x-i386.s b/test/ELF/got32x-i386.s
index 88e7e31ee..7d3a1fc1e 100644
--- a/test/ELF/got32x-i386.s
+++ b/test/ELF/got32x-i386.s
@@ -38,7 +38,7 @@
# CHECK-NEXT: 40100d: 8b 80 {{.*}} movl -4(%eax), %eax
# CHECK-NEXT: 401013: 8b 83 {{.*}} movl -4(%ebx), %eax
# CHECK: Sections:
-# CHECK: Name Size Address
+# CHECK: Name Size VMA
# CHECK: .got 00000004 0000000000403000
# RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \
diff --git a/test/ELF/i386-static-tls-model.s b/test/ELF/i386-static-tls-model.s
new file mode 100644
index 000000000..a6dbc6db9
--- /dev/null
+++ b/test/ELF/i386-static-tls-model.s
@@ -0,0 +1,20 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model1.s -o %t.o
+# RUN: ld.lld %t.o -o %t1 -shared
+# RUN: llvm-readobj -dynamic-table %t1 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model2.s -o %t.o
+# RUN: ld.lld %t.o -o %t2 -shared
+# RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model3.s -o %t.o
+# RUN: ld.lld %t.o -o %t3 -shared
+# RUN: llvm-readobj -dynamic-table %t3 | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model4.s -o %t.o
+# RUN: ld.lld %t.o -o %t4 -shared
+# RUN: llvm-readobj -dynamic-table %t4 | FileCheck %s
+
+# CHECK: DynamicSection [
+# CHECK: FLAGS STATIC_TLS
diff --git a/test/ELF/i386-tls-ie-shared.s b/test/ELF/i386-tls-ie-shared.s
index 9e5ed1bcc..0e9694fd5 100644
--- a/test/ELF/i386-tls-ie-shared.s
+++ b/test/ELF/i386-tls-ie-shared.s
@@ -14,8 +14,8 @@
// GOTRELSHARED-NEXT: SHF_ALLOC
// GOTRELSHARED-NEXT: SHF_WRITE
// GOTRELSHARED-NEXT: ]
-// GOTRELSHARED-NEXT: Address: 0x2058
-// GOTRELSHARED-NEXT: Offset: 0x2058
+// GOTRELSHARED-NEXT: Address: 0x2060
+// GOTRELSHARED-NEXT: Offset: 0x2060
// GOTRELSHARED-NEXT: Size: 16
// GOTRELSHARED-NEXT: Link: 0
// GOTRELSHARED-NEXT: Info: 0
@@ -32,36 +32,36 @@
// GOTRELSHARED-NEXT: 0x102D R_386_RELATIVE - 0x0
// GOTRELSHARED-NEXT: 0x1036 R_386_RELATIVE - 0x0
// GOTRELSHARED-NEXT: 0x103F R_386_RELATIVE - 0x0
-// GOTRELSHARED-NEXT: 0x2058 R_386_TLS_TPOFF tlslocal0 0x0
-// GOTRELSHARED-NEXT: 0x205C R_386_TLS_TPOFF tlslocal1 0x0
-// GOTRELSHARED-NEXT: 0x2060 R_386_TLS_TPOFF tlsshared0 0x0
-// GOTRELSHARED-NEXT: 0x2064 R_386_TLS_TPOFF tlsshared1 0x0
+// GOTRELSHARED-NEXT: 0x2060 R_386_TLS_TPOFF tlslocal0 0x0
+// GOTRELSHARED-NEXT: 0x2064 R_386_TLS_TPOFF tlslocal1 0x0
+// GOTRELSHARED-NEXT: 0x2068 R_386_TLS_TPOFF tlsshared0 0x0
+// GOTRELSHARED-NEXT: 0x206C R_386_TLS_TPOFF tlsshared1 0x0
// GOTRELSHARED-NEXT: }
// GOTRELSHARED-NEXT: ]
// GOTRELSHARED: 0x6FFFFFFA RELCOUNT 8
// DISASMSHARED: Disassembly of section test:
// DISASMSHARED-NEXT: _start:
-// (.got)[0] = 0x2058 = 8280
-// (.got)[1] = 0x205C = 8284
-// (.got)[2] = 0x2060 = 8288
-// (.got)[3] = 0x2064 = 8292
-// DISASMSHARED-NEXT: 1000: 8b 0d 58 20 00 00 movl 8280, %ecx
-// DISASMSHARED-NEXT: 1006: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASMSHARED-NEXT: 1009: a1 58 20 00 00 movl 8280, %eax
-// DISASMSHARED-NEXT: 100e: 65 8b 00 movl %gs:(%eax), %eax
-// DISASMSHARED-NEXT: 1011: 03 0d 58 20 00 00 addl 8280, %ecx
-// DISASMSHARED-NEXT: 1017: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASMSHARED-NEXT: 101a: 8b 0d 5c 20 00 00 movl 8284, %ecx
-// DISASMSHARED-NEXT: 1020: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASMSHARED-NEXT: 1023: a1 5c 20 00 00 movl 8284, %eax
-// DISASMSHARED-NEXT: 1028: 65 8b 00 movl %gs:(%eax), %eax
-// DISASMSHARED-NEXT: 102b: 03 0d 5c 20 00 00 addl 8284, %ecx
-// DISASMSHARED-NEXT: 1031: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASMSHARED-NEXT: 1034: 8b 0d 60 20 00 00 movl 8288, %ecx
-// DISASMSHARED-NEXT: 103a: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASMSHARED-NEXT: 103d: 03 0d 64 20 00 00 addl 8292, %ecx
-// DISASMSHARED-NEXT: 1043: 65 8b 01 movl %gs:(%ecx), %eax
+// (.got)[0] = 0x2060 = 8288
+// (.got)[1] = 0x2064 = 8292
+// (.got)[2] = 0x2068 = 8296
+// (.got)[3] = 0x206C = 8300
+// DISASMSHARED-NEXT: 1000: {{.*}} movl 8288, %ecx
+// DISASMSHARED-NEXT: 1006: {{.*}} movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 1009: {{.*}} movl 8288, %eax
+// DISASMSHARED-NEXT: 100e: {{.*}} movl %gs:(%eax), %eax
+// DISASMSHARED-NEXT: 1011: {{.*}} addl 8288, %ecx
+// DISASMSHARED-NEXT: 1017: {{.*}} movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 101a: {{.*}} movl 8292, %ecx
+// DISASMSHARED-NEXT: 1020: {{.*}} movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 1023: {{.*}} movl 8292, %eax
+// DISASMSHARED-NEXT: 1028: {{.*}} movl %gs:(%eax), %eax
+// DISASMSHARED-NEXT: 102b: {{.*}} addl 8292, %ecx
+// DISASMSHARED-NEXT: 1031: {{.*}} movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 1034: {{.*}} movl 8296, %ecx
+// DISASMSHARED-NEXT: 103a: {{.*}} movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 103d: {{.*}} addl 8300, %ecx
+// DISASMSHARED-NEXT: 1043: {{.*}} movl %gs:(%ecx), %eax
.type tlslocal0,@object
.section .tbss,"awT",@nobits
diff --git a/test/ELF/icf-symbol-type.s b/test/ELF/icf-symbol-type.s
index 9cc1c5096..350f20371 100644
--- a/test/ELF/icf-symbol-type.s
+++ b/test/ELF/icf-symbol-type.s
@@ -7,8 +7,8 @@
# We used to mark bar as absolute.
# CHECK: .text PROGBITS 0000000000001000
-# CHECK: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 4 foo
# CHECK: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 4 bar
+# CHECK: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 4 foo
# The nop makes the test more interesting by making the offset of
# text.f non zero.
diff --git a/test/ELF/invalid/invalid-soname.test b/test/ELF/invalid/invalid-soname.test
index 8641465ac..bf4b33c87 100644
--- a/test/ELF/invalid/invalid-soname.test
+++ b/test/ELF/invalid/invalid-soname.test
@@ -14,5 +14,8 @@ Sections:
- Name: .test
Type: SHT_DYNAMIC
Flags: [ SHF_ALLOC ]
- Content: "0e000000000000000000000000000001"
Link: .strtab
+ EntSize: 0x0000000000000010
+ Entries:
+ - Tag: DT_SONAME
+ Value: 0x0100000000000000
diff --git a/test/ELF/linkerscript/addr.test b/test/ELF/linkerscript/addr.test
index db0568e56..2e68cc271 100644
--- a/test/ELF/linkerscript/addr.test
+++ b/test/ELF/linkerscript/addr.test
@@ -4,7 +4,7 @@
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .text 00000000 0000000000001000 TEXT
# CHECK-NEXT: 2 .foo.1 00000008 0000000000001000 DATA
diff --git a/test/ELF/linkerscript/align-empty.test b/test/ELF/linkerscript/align-empty.test
index 63fe32882..06d3945dd 100644
--- a/test/ELF/linkerscript/align-empty.test
+++ b/test/ELF/linkerscript/align-empty.test
@@ -13,7 +13,7 @@ SECTIONS {
}
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address
+# CHECK-NEXT: Idx Name Size VMA
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .dynsym 00000018 0000000000000190
# CHECK-NEXT: 2 .gnu.hash 0000001c 00000000000001a8
diff --git a/test/ELF/linkerscript/align1.test b/test/ELF/linkerscript/align1.test
index 5804bf933..70d114102 100644
--- a/test/ELF/linkerscript/align1.test
+++ b/test/ELF/linkerscript/align1.test
@@ -13,7 +13,7 @@ SECTIONS {
}
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA
# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA
@@ -25,7 +25,7 @@ SECTIONS {
# RUN: llvm-objdump -section-headers %t4 | FileCheck %s -check-prefix=ZERO
# ZERO: Sections:
-# ZERO-NEXT: Idx Name Size Address Type
+# ZERO-NEXT: Idx Name Size VMA Type
# ZERO-NEXT: 0 00000000 0000000000000000
# ZERO-NEXT: 1 .aaa 00000008 0000000000000123 DATA
diff --git a/test/ELF/linkerscript/align2.test b/test/ELF/linkerscript/align2.test
index a9003a403..56aba4738 100644
--- a/test/ELF/linkerscript/align2.test
+++ b/test/ELF/linkerscript/align2.test
@@ -13,7 +13,7 @@ SECTIONS {
}
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA
# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA
diff --git a/test/ELF/linkerscript/align3.test b/test/ELF/linkerscript/align3.test
index 2a091fcbd..8c9146e01 100644
--- a/test/ELF/linkerscript/align3.test
+++ b/test/ELF/linkerscript/align3.test
@@ -11,7 +11,7 @@ SECTIONS {
}
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA
# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA
diff --git a/test/ELF/linkerscript/align4.test b/test/ELF/linkerscript/align4.test
index 9440d60f6..834e843da 100644
--- a/test/ELF/linkerscript/align4.test
+++ b/test/ELF/linkerscript/align4.test
@@ -4,7 +4,6 @@
# RUN: llvm-objdump -t %t | FileCheck %s
# CHECK-LABEL: SYMBOL TABLE:
-# CHECK-NEXT: 0000000000000000 *UND* 00000000
# CHECK-NEXT: 0000000000014008 .text 00000000 _start
# CHECK-NEXT: 0000000000010000 *ABS* 00000000 __code_base__
# CHECK-NEXT: 0000000000001000 *ABS* 00000000 VAR
diff --git a/test/ELF/linkerscript/at2.test b/test/ELF/linkerscript/at2.test
index 82c9ae1d2..e45a716bd 100644
--- a/test/ELF/linkerscript/at2.test
+++ b/test/ELF/linkerscript/at2.test
@@ -48,7 +48,7 @@ SECTIONS {
# CHECK-NEXT: }
# SECTIONS: Sections:
-# SECTIONS-NEXT: Idx Name Size Address
+# SECTIONS-NEXT: Idx Name Size VMA
# SECTIONS-NEXT: 0 00000000 0000000000000000
# SECTIONS-NEXT: 1 .foo1 00000008 0000000000002000
# SECTIONS-NEXT: 2 .foo2 00000008 0000000000002008
diff --git a/test/ELF/linkerscript/insert-after.test b/test/ELF/linkerscript/insert-after.test
index 4260cd77f..005c1500b 100644
--- a/test/ELF/linkerscript/insert-after.test
+++ b/test/ELF/linkerscript/insert-after.test
@@ -16,7 +16,7 @@ SECTIONS {
# RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .text 00000008 0000000000000000 TEXT
# CHECK-NEXT: 2 .foo.text 00000008 0000000000000008 TEXT
diff --git a/test/ELF/linkerscript/insert-before.test b/test/ELF/linkerscript/insert-before.test
index 52317bef6..24fdd69a8 100644
--- a/test/ELF/linkerscript/insert-before.test
+++ b/test/ELF/linkerscript/insert-before.test
@@ -16,7 +16,7 @@ SECTIONS {
# RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .foo.text 00000008 0000000000000000 TEXT
# CHECK-NEXT: 2 .text 00000008 0000000000000008 TEXT
diff --git a/test/ELF/linkerscript/linkerscript.s b/test/ELF/linkerscript/linkerscript.s
index 39d2d4620..5e1cf27f0 100644
--- a/test/ELF/linkerscript/linkerscript.s
+++ b/test/ELF/linkerscript/linkerscript.s
@@ -3,7 +3,7 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
# RUN: %p/Inputs/libsearch-st.s -o %t2.o
-# RUN: echo "EXTERN( undef undef2 )" > %t.script
+# RUN: echo "EXTERN( undef undef2 \"undef3\" \"undef4@@other\")" > %t.script
# RUN: ld.lld %t -o %t2 %t.script
# RUN: llvm-readobj %t2 > /dev/null
diff --git a/test/ELF/linkerscript/locationcountererr2.s b/test/ELF/linkerscript/locationcountererr2.s
index 9efe86a72..3a0c7692c 100644
--- a/test/ELF/linkerscript/locationcountererr2.s
+++ b/test/ELF/linkerscript/locationcountererr2.s
@@ -4,7 +4,7 @@
# RUN: echo ". = 0x150; . = 0x10; .text : {} }" >> %t.script
# RUN: ld.lld %t.o --script %t.script -o %t -shared
# RUN: llvm-objdump -section-headers %t | FileCheck %s
-# CHECK: Name Size Address
+# CHECK: Name Size VMA
# CHECK: .text 00000000 0000000000000010
# RUN: echo "SECTIONS { . = 0x20; . = ASSERT(0x1, "foo"); }" > %t2.script
diff --git a/test/ELF/linkerscript/memory3.s b/test/ELF/linkerscript/memory3.s
index 6a24313f0..3a4913724 100644
--- a/test/ELF/linkerscript/memory3.s
+++ b/test/ELF/linkerscript/memory3.s
@@ -14,7 +14,7 @@
## Check we place .text into first defined memory region with appropriate flags.
# CHECK: Sections:
-# CHECK: Idx Name Size Address
+# CHECK: Idx Name Size VMA
# CHECK: 0 00000000 0000000000000000
# CHECK: 1 .text 00000001 0000000000001000
diff --git a/test/ELF/linkerscript/multi-sections-constraint.s b/test/ELF/linkerscript/multi-sections-constraint.s
index bfedd10fc..c1a253a69 100644
--- a/test/ELF/linkerscript/multi-sections-constraint.s
+++ b/test/ELF/linkerscript/multi-sections-constraint.s
@@ -8,7 +8,7 @@
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK: .aaa 00000010 0000000000002000 DATA
@@ -20,7 +20,7 @@
# RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=REV
# REV: Sections:
-# REV-NEXT: Idx Name Size Address Type
+# REV-NEXT: Idx Name Size VMA Type
# REV: .aaa 00000010 0000000000001000 DATA
.global _start
diff --git a/test/ELF/linkerscript/non-absolute2.test b/test/ELF/linkerscript/non-absolute2.test
index b60666412..2d08354a0 100644
--- a/test/ELF/linkerscript/non-absolute2.test
+++ b/test/ELF/linkerscript/non-absolute2.test
@@ -9,7 +9,7 @@ SECTIONS {
}
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address
+# CHECK-NEXT: Idx Name Size VMA
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .dynsym 00000030 0000000000001000
# CHECK: 5 .text 00000000 000000000000106c
diff --git a/test/ELF/linkerscript/numbers.s b/test/ELF/linkerscript/numbers.s
index 98d7e3361..ceb85fd68 100644
--- a/test/ELF/linkerscript/numbers.s
+++ b/test/ELF/linkerscript/numbers.s
@@ -18,7 +18,7 @@
# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address
+# CHECK-NEXT: Idx Name Size VMA
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .hex1 00000008 0000000000001000
# CHECK-NEXT: 2 .hex2 00000008 0000000000001010
@@ -67,7 +67,7 @@
# RUN: ld.lld %t --script %t8.script -o %t6
# RUN: llvm-objdump -section-headers %t6 | FileCheck -check-prefix=SECADDR %s
# SECADDR: Sections:
-# SECADDR-NEXT: Idx Name Size Address
+# SECADDR-NEXT: Idx Name Size VMA
# SECADDR-NEXT: 0 00000000 0000000000000000
# SECADDR-NEXT: 1 .hex1 00000008 0000000000000400
# SECADDR-NEXT: 2 .hex2 00000008 0000000000000500
diff --git a/test/ELF/linkerscript/out-of-order.s b/test/ELF/linkerscript/out-of-order.s
index da8c103bb..fbab435f7 100644
--- a/test/ELF/linkerscript/out-of-order.s
+++ b/test/ELF/linkerscript/out-of-order.s
@@ -22,7 +22,7 @@
# must take responsibility to make sure this does not happen.
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .data 00000008 0000000000004000
# CHECK-NEXT: 2 .dynamic 00000060 0000000000004008
diff --git a/test/ELF/linkerscript/provide-shared2.s b/test/ELF/linkerscript/provide-shared2.s
index 8a3200b6f..3c55d2fa6 100644
--- a/test/ELF/linkerscript/provide-shared2.s
+++ b/test/ELF/linkerscript/provide-shared2.s
@@ -6,7 +6,7 @@
# RUN: ld.lld -o %t --script %t.script %t.o %t2.so
# RUN: llvm-readelf --dyn-symbols %t | FileCheck %s
-# CHECK: 1 1: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo@
+# CHECK: 1: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo
.global _start
_start:
diff --git a/test/ELF/linkerscript/repsection-va.s b/test/ELF/linkerscript/repsection-va.s
index 8a50fc099..5da94d020 100644
--- a/test/ELF/linkerscript/repsection-va.s
+++ b/test/ELF/linkerscript/repsection-va.s
@@ -5,7 +5,7 @@
# RUN: ld.lld -o %t1 --script %t.script %t
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NOT: .foo
# CHECK: .foo 00000008 {{.*}} DATA
# CHECK-NOT: .foo
diff --git a/test/ELF/linkerscript/sections-gc2.s b/test/ELF/linkerscript/sections-gc2.s
index e2941aa57..7b1fa8dac 100644
--- a/test/ELF/linkerscript/sections-gc2.s
+++ b/test/ELF/linkerscript/sections-gc2.s
@@ -8,7 +8,7 @@
# RUN: ld.lld -T %t.script -o %t.so %t.o --gc-sections
# RUN: llvm-objdump -h %t.so | FileCheck %s
-# CHECK: Idx Name Size Address Type
+# CHECK: Idx Name Size VMA Type
# CHECK-NEXT: 0
# CHECK-NEXT: used_in_reloc
# CHECK-NEXT: .text
diff --git a/test/ELF/linkerscript/segment-none.s b/test/ELF/linkerscript/segment-none.s
index 36d09e776..85739747a 100644
--- a/test/ELF/linkerscript/segment-none.s
+++ b/test/ELF/linkerscript/segment-none.s
@@ -23,7 +23,7 @@
# CHECK: Section to Segment mapping:
# CHECK-NEXT: Segment Sections...
-# CHECK-NOT: .foo
+# CHECK: None {{.*}}.foo
# DEFINED: Section to Segment mapping:
# DEFINED-NEXT: Segment Sections...
diff --git a/test/ELF/linkerscript/sizeof.s b/test/ELF/linkerscript/sizeof.s
index 4618f79d3..0d7106fc8 100644
--- a/test/ELF/linkerscript/sizeof.s
+++ b/test/ELF/linkerscript/sizeof.s
@@ -18,7 +18,6 @@
# CHECK-NEXT: 2 .bbb 00000010
# CHECK-NEXT: 3 .ccc 00000018
# CHECK: SYMBOL TABLE:
-# CHECK-NEXT: 0000000000000000 *UND* 00000000
# CHECK-NEXT: .text 00000000 _start
# CHECK-NEXT: 0000000000000008 *ABS* 00000000 _aaa
# CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb
diff --git a/test/ELF/linkerscript/sizeofheaders.s b/test/ELF/linkerscript/sizeofheaders.s
index 3cc707472..6a82442bc 100644
--- a/test/ELF/linkerscript/sizeofheaders.s
+++ b/test/ELF/linkerscript/sizeofheaders.s
@@ -9,7 +9,6 @@
# RUN: llvm-objdump -t %t1 | FileCheck %s
#CHECK: SYMBOL TABLE:
-#CHECK-NEXT: 0000000000000000 *UND* 00000000
#CHECK-NEXT: 00000000000000e8 .text 00000000 _start
#CHECK-NEXT: 00000000000000e8 *ABS* 00000000 _size
diff --git a/test/ELF/linkerscript/symbol-assignexpr.s b/test/ELF/linkerscript/symbol-assignexpr.s
index 3be7d0593..56e0827ca 100644
--- a/test/ELF/linkerscript/symbol-assignexpr.s
+++ b/test/ELF/linkerscript/symbol-assignexpr.s
@@ -25,7 +25,6 @@
# RUN: llvm-objdump -t %t1 | FileCheck %s
# CHECK: SYMBOL TABLE:
-# CHECK-NEXT: 0000000000000000 *UND* 00000000
# CHECK-NEXT: 0000000000000000 .text 00000000 _start
# CHECK-NEXT: 0000000000005678 *ABS* 00000000 bar
# CHECK-NEXT: 0000000000009abc *ABS* 00000000 baz
diff --git a/test/ELF/linkerscript/symbol-location.s b/test/ELF/linkerscript/symbol-location.s
new file mode 100644
index 000000000..323d237e1
--- /dev/null
+++ b/test/ELF/linkerscript/symbol-location.s
@@ -0,0 +1,15 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "foo = 1;" > %t.script
+# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | FileCheck %s
+
+## Here we check that symbol 'foo' location is reported properly.
+
+# CHECK: error: relocation R_X86_64_PLT32 cannot refer to absolute symbol: foo
+# CHECK: >>> defined in {{.*}}.script:1
+# CHECK: >>> referenced by {{.*}}.o:(.text+0x1)
+
+.text
+.globl _start
+_start:
+ call foo@PLT
diff --git a/test/ELF/linkerscript/symbol-memoryexpr.s b/test/ELF/linkerscript/symbol-memoryexpr.s
index cdd821dc5..9214ba83e 100644
--- a/test/ELF/linkerscript/symbol-memoryexpr.s
+++ b/test/ELF/linkerscript/symbol-memoryexpr.s
@@ -13,7 +13,6 @@
# RUN: llvm-objdump -t %t1 | FileCheck %s
# CHECK: SYMBOL TABLE:
-# CHECK-NEXT: 0000000000000000 *UND* 00000000
# CHECK-NEXT: 0000000000008000 .text 00000000 _start
# CHECK-NEXT: 0000000000008000 *ABS* 00000000 origin
# CHECK-NEXT: 0000000000040000 *ABS* 00000000 length
diff --git a/test/ELF/linkerscript/symbol-only.test b/test/ELF/linkerscript/symbol-only.test
index f2fefdc04..9951e9c88 100644
--- a/test/ELF/linkerscript/symbol-only.test
+++ b/test/ELF/linkerscript/symbol-only.test
@@ -12,7 +12,7 @@ SECTIONS {
}
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address
+# CHECK-NEXT: Idx Name Size VMA
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]]
# CHECK: bar 00000000 0000000000001000
diff --git a/test/ELF/linkerscript/va.s b/test/ELF/linkerscript/va.s
index c305f0689..bbf55cb45 100644
--- a/test/ELF/linkerscript/va.s
+++ b/test/ELF/linkerscript/va.s
@@ -5,7 +5,7 @@
# RUN: ld.lld -o %t1 --script %t.script %t
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address
+# CHECK-NEXT: Idx Name Size VMA
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .foo 00000004 0000000000000000
# CHECK-NEXT: 2 .boo 00000004 0000000000000004
diff --git a/test/ELF/linkerscript/version-script.s b/test/ELF/linkerscript/version-script.s
index df666e1b3..67a0fd68c 100644
--- a/test/ELF/linkerscript/version-script.s
+++ b/test/ELF/linkerscript/version-script.s
@@ -14,11 +14,11 @@
# CHECK: Symbols [
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 0
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 0
-# CHECK-NEXT: Name: und@
+# CHECK-NEXT: Name: und
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 2
@@ -41,7 +41,7 @@
# UNDEF: Symbols [
# UNDEF-NEXT: Symbol {
# UNDEF-NEXT: Version: 0
-# UNDEF-NEXT: Name: @
+# UNDEF-NEXT: Name:
# UNDEF-NEXT: }
# UNDEF-NEXT: Symbol {
# UNDEF-NEXT: Version: 2
diff --git a/test/ELF/local-dynamic.s b/test/ELF/local-dynamic.s
index c122074fd..0adad2bf4 100644
--- a/test/ELF/local-dynamic.s
+++ b/test/ELF/local-dynamic.s
@@ -65,7 +65,7 @@
// CHECK: DynamicSymbols [
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: @
+// CHECK-NEXT: Name:
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
@@ -74,7 +74,7 @@
// CHECK-NEXT: Section: Undefined
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: _start@
+// CHECK-NEXT: Name: _start
// CHECK-NEXT: Value:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
diff --git a/test/ELF/local-ver-preemptible.s b/test/ELF/local-ver-preemptible.s
index b99f700fb..80d78c4a8 100644
--- a/test/ELF/local-ver-preemptible.s
+++ b/test/ELF/local-ver-preemptible.s
@@ -14,8 +14,8 @@
# CHECK: Symbol table '.dynsym' contains 2 entries:
# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
-# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND @
-# CHECK-NEXT: 1: 0000000000201020 0 FUNC GLOBAL DEFAULT UND foo@
+# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+# CHECK-NEXT: 1: 0000000000201020 0 FUNC GLOBAL DEFAULT UND foo
.globl _start
_start:
diff --git a/test/ELF/lto/dynamic-list.ll b/test/ELF/lto/dynamic-list.ll
index c5473d833..84b667b0e 100644
--- a/test/ELF/lto/dynamic-list.ll
+++ b/test/ELF/lto/dynamic-list.ll
@@ -4,7 +4,7 @@
; RUN: ld.lld -o %t --dynamic-list %t.list -pie %t.o
; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
-; CHECK: Name: foo@
+; CHECK: Name: foo
; CHECK-NEXT: Value: 0x1010
; CHECK-NEXT: Size: 1
; CHECK-NEXT: Binding: Global (0x1)
diff --git a/test/ELF/lto/shlib-undefined.ll b/test/ELF/lto/shlib-undefined.ll
index 6d37bfa6b..eec40cc27 100644
--- a/test/ELF/lto/shlib-undefined.ll
+++ b/test/ELF/lto/shlib-undefined.ll
@@ -6,7 +6,7 @@
; RUN: ld.lld -o %t %t.o %t2.so
; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
-; CHECK: Name: __progname@
+; CHECK: Name: __progname
; CHECK-NEXT: Value: 0x201010
; CHECK-NEXT: Size: 1
; CHECK-NEXT: Binding: Global (0x1)
diff --git a/test/ELF/lto/undefined-puts.ll b/test/ELF/lto/undefined-puts.ll
index 6c3dc76be..f34abe682 100644
--- a/test/ELF/lto/undefined-puts.ll
+++ b/test/ELF/lto/undefined-puts.ll
@@ -25,4 +25,4 @@ declare i32 @printf(i8*, ...)
; CHECK: DynamicSymbols [
; CHECK: Symbol {
-; CHECK: Name: puts@
+; CHECK: Name: puts
diff --git a/test/ELF/lto/version-script.ll b/test/ELF/lto/version-script.ll
index 35a36b5a8..eae5a35a6 100644
--- a/test/ELF/lto/version-script.ll
+++ b/test/ELF/lto/version-script.ll
@@ -21,7 +21,7 @@ define void @bar() {
; DSO: DynamicSymbols [
; DSO: Symbol {
-; DSO: Name: @ (0)
+; DSO: Name:
; DSO: Value: 0x0
; DSO: Size: 0
; DSO: Binding: Local
diff --git a/test/ELF/mips-dynamic.s b/test/ELF/mips-dynamic.s
index ebc262597..2852b5088 100644
--- a/test/ELF/mips-dynamic.s
+++ b/test/ELF/mips-dynamic.s
@@ -97,9 +97,9 @@
# DSO-NEXT: Size: 8
# DSO: ]
# DSO: DynamicSymbols [
-# DSO: Name: @
-# DSO: Name: __start@
-# DSO: Name: _foo@
+# DSO: Name:
+# DSO: Name: __start
+# DSO: Name: _foo
# DSO: ]
# DSO: DynamicSection [
# DSO-NEXT: Tag Type Name/Value
diff --git a/test/ELF/mips-dynsym-sort.s b/test/ELF/mips-dynsym-sort.s
index d1b935b63..3f98b7cd7 100644
--- a/test/ELF/mips-dynsym-sort.s
+++ b/test/ELF/mips-dynsym-sort.s
@@ -36,7 +36,7 @@ __start:
# the MIPS rules. v2 comes first as it is not in the GOT.
# v1 and v3 are sorted according to their order in the GOT.
# CHECK: DynamicSymbols [
-# CHECK: Name: v2@
-# CHECK: Name: v3@
-# CHECK: Name: v1@
+# CHECK: Name: v2
+# CHECK: Name: v3
+# CHECK: Name: v1
# CHECK: ]
diff --git a/test/ELF/mips-got-and-copy.s b/test/ELF/mips-got-and-copy.s
index f4640bf30..fed23d1eb 100644
--- a/test/ELF/mips-got-and-copy.s
+++ b/test/ELF/mips-got-and-copy.s
@@ -32,7 +32,7 @@
# CHECK-NEXT: Value: 0x[[DATA0]]
# CHECK-NEXT: Type: Object
# CHECK-NEXT: Section: .bss
-# CHECK-NEXT: Name: data0@
+# CHECK-NEXT: Name: data0
# CHECK-NEXT: }
# CHECK-NEXT: Entry {
# CHECK-NEXT: Address:
@@ -41,7 +41,7 @@
# CHECK-NEXT: Value: 0x[[DATA1]]
# CHECK-NEXT: Type: Object
# CHECK-NEXT: Section: .bss
-# CHECK-NEXT: Name: data1@
+# CHECK-NEXT: Name: data1
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: Number of TLS and multi-GOT entries: 0
diff --git a/test/ELF/mips-got-extsym.s b/test/ELF/mips-got-extsym.s
index ea57d77a0..b5063a855 100644
--- a/test/ELF/mips-got-extsym.s
+++ b/test/ELF/mips-got-extsym.s
@@ -43,7 +43,7 @@
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Type: None
# CHECK-NEXT: Section: Undefined
-# CHECK-NEXT: Name: _foo@
+# CHECK-NEXT: Name: _foo
# CHECK-NEXT: }
# CHECK-NEXT: ]
diff --git a/test/ELF/mips-got16.s b/test/ELF/mips-got16.s
index cf0847da5..53734ed31 100644
--- a/test/ELF/mips-got16.s
+++ b/test/ELF/mips-got16.s
@@ -96,7 +96,7 @@
# GOT-NEXT: Value: 0x0
# GOT-NEXT: Type: None
# GOT-NEXT: Section: Undefined
-# GOT-NEXT: Name: foo@
+# GOT-NEXT: Name: foo
# GOT-NEXT: }
# GOT-NEXT: ]
# GOT-NEXT: Number of TLS and multi-GOT entries: 0
diff --git a/test/ELF/mips-micro-jal.s b/test/ELF/mips-micro-jal.s
index 18d41cf13..f41d7dc3a 100644
--- a/test/ELF/mips-micro-jal.s
+++ b/test/ELF/mips-micro-jal.s
@@ -57,9 +57,7 @@
# EB-NEXT: 20022: 45 f9 jalrs16 $25
# EB-NEXT: 20024: 0f 83 move $gp, $3
# EB-NEXT: 20026: 0c 00 nop
-# EB-NEXT: 20028: 00 00 00 00 nop
-# EB-NEXT: 2002c: 00 00 00 00 nop
-
+# EB-NEXT: ...
# EB-NEXT: 20030: 79 00 3f f7 addiupc $2, 65500
# EB-NEXT: 20034: ff 22 00 00 lw $25, 0($2)
# EB-NEXT: 20038: 45 99 jr16 $25
@@ -76,9 +74,7 @@
# EL-NEXT: 20022: f9 45 jalrs16 $25
# EL-NEXT: 20024: 83 0f move $gp, $3
# EL-NEXT: 20026: 00 0c nop
-# EL-NEXT: 20028: 00 00 00 00 nop
-# EL-NEXT: 2002c: 00 00 00 00 nop
-
+# EL-NEXT: ...
# EL-NEXT: 20030: 00 79 f7 3f addiupc $2, 65500
# EL-NEXT: 20034: 22 ff 00 00 lw $25, 0($2)
# EL-NEXT: 20038: 99 45 jr16 $25
@@ -127,9 +123,7 @@
# MIXED-NEXT: 20032: 45 f9 jalrs16 $25
# MIXED-NEXT: 20034: 0f 83 move $gp, $3
# MIXED-NEXT: 20036: 0c 00 nop
-# MIXED-NEXT: 20038: 00 00 00 00 nop
-# MIXED-NEXT: 2003c: 00 00 00 00 nop
-
+# MIXED-NEXT: ...
# MIXED-NEXT: 20040: 79 00 3f f3 addiupc $2, 65484
# MIXED-NEXT: 20044: ff 22 00 00 lw $25, 0($2)
# MIXED-NEXT: 20048: 45 99 jr16 $25
diff --git a/test/ELF/mips-micro-plt.s b/test/ELF/mips-micro-plt.s
index 6dcd6fbee..24e90ae49 100644
--- a/test/ELF/mips-micro-plt.s
+++ b/test/ELF/mips-micro-plt.s
@@ -80,7 +80,7 @@
# CHECK-NEXT: Value: 0x20041
# CHECK-NEXT: Type: Function
# CHECK-NEXT: Section: Undefined
-# CHECK-NEXT: Name: foo0@
+# CHECK-NEXT: Name: foo0
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: }
diff --git a/test/ELF/mips-sto-plt.s b/test/ELF/mips-sto-plt.s
index b4d3ee391..4bd0d9e7b 100644
--- a/test/ELF/mips-sto-plt.s
+++ b/test/ELF/mips-sto-plt.s
@@ -9,7 +9,7 @@
# RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s
# CHECK: Symbol {
-# CHECK: Name: foo0@
+# CHECK: Name: foo0
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global
@@ -18,7 +18,7 @@
# CHECK-NEXT: Section: Undefined
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: foo1@
+# CHECK-NEXT: Name: foo1
# CHECK-NEXT: Value: 0x[[FOO1:[0-9A-F]+]]
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global
diff --git a/test/ELF/msp430.s b/test/ELF/msp430.s
new file mode 100644
index 000000000..96820acbc
--- /dev/null
+++ b/test/ELF/msp430.s
@@ -0,0 +1,43 @@
+; REQUIRES: msp430
+; RUN: llvm-mc -filetype=obj -triple=msp430-elf -o %t1.o %s
+; RUN: echo -e '.global _start\n _start: nop' | llvm-mc -filetype=obj -triple=msp430-elf -o %t2.o -
+; RUN: ld.lld -o %t.exe --Tdata=0x2000 --Ttext=0x8000 --defsym=_byte=0x21 %t2.o %t1.o
+; RUN: llvm-objdump -s -d %t.exe | FileCheck %s
+
+;; Check handling of basic msp430 relocation types.
+
+ .text
+ .global foo
+foo:
+;; R_MSP430_10_PCREL
+ jmp _start
+
+; CHECK: Disassembly of section .text:
+; CHECK-NEXT: _start:
+; CHECK-NEXT: 8000: {{.*}} nop
+; CHECK: foo:
+; CHECK-NEXT: 8004: {{.*}} jmp $-4
+
+;; R_MSP430_16_BYTE
+ call #_start
+
+; CHECK: call #32768
+
+;; R_MSP430_16_PCREL_BYTE
+ mov #-1, _start
+
+; CHECK: 800a: {{.*}} mov #-1, -12
+
+ .data
+;; R_MSP430_8
+ .byte _byte
+;; R_MSP430_16
+ .word _start
+;; R_MSP430_32
+ .long _start
+
+; CHECK: Contents of section .data:
+; CHECK-NEXT: 2000 21008000 800000
+
+; RUN: od -x %t.exe | FileCheck -check-prefix=TRAP %s
+; TRAP: 4343 4343 4343 4343 4343 4343 4343 4343
diff --git a/test/ELF/no-discard-this_module.s b/test/ELF/no-discard-this_module.s
new file mode 100644
index 000000000..3ce56d165
--- /dev/null
+++ b/test/ELF/no-discard-this_module.s
@@ -0,0 +1,41 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -save-temp-labels %s -o %t
+// RUN: ld.lld %t -o %t2
+// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
+
+.global _start
+_start:
+
+// This section and symbol is used by Linux kernel modules. Ensure it's not
+// accidentally discarded.
+.section .gnu.linkonce.this_module:
+__this_module:
+.byte 0x00
+
+// CHECK: Section {
+// CHECK: Index:
+// CHECK: Name: .gnu.linkonce.this_module
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment:
+// CHECK-NEXT: EntrySize:
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 00 |.|
+// CHECK-NEXT: )
+// CHECK-NEXT: }
+
+// CHECK: Symbol {
+// CHECK: Name: __this_module
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other:
+// CHECK-NEXT: Section: .gnu.linkonce.this_module:
+// CHECK-NEXT: }
diff --git a/test/ELF/ppc64-bsymbolic-toc-restore.s b/test/ELF/ppc64-bsymbolic-toc-restore.s
index 49d347c48..b7d9edd45 100644
--- a/test/ELF/ppc64-bsymbolic-toc-restore.s
+++ b/test/ELF/ppc64-bsymbolic-toc-restore.s
@@ -53,7 +53,7 @@ caller:
# CHECK-LABEL: caller
# CHECK: bl .+44
# CHECK-NEXT: mr 31, 3
-# CHECK-NEXT: bl .+67108816
+# CHECK-NEXT: bl .-48
# CHECK-NEXT: ld 2, 24(1)
# CHECK-NEXT: add 3, 3, 31
# CHECK-NEXT: addi 1, 1, 32
diff --git a/test/ELF/ppc64-call-reach.s b/test/ELF/ppc64-call-reach.s
index a02bfa829..e32497b35 100644
--- a/test/ELF/ppc64-call-reach.s
+++ b/test/ELF/ppc64-call-reach.s
@@ -62,7 +62,7 @@ test:
# CHECK: 10010024: {{.*}} b .+33554428
# NEGOFFSET-LABEL: test
-# NEGOFFSET: 10010014: {{.*}} bl .+33554432
+# NEGOFFSET: 10010014: {{.*}} bl .-33554432
# NEGOFFSET: 10010024: {{.*}} b .+33554432
# .branch_lt[0]
@@ -83,7 +83,7 @@ test:
# the offset is interpreted as a signed 26 bit value so 67108812 is actually
# -52.
# THUNK-LABEL: test:
-# THUNK: 10010034: {{.*}} bl .+67108812
+# THUNK: 10010034: {{.*}} bl .-52
# THUNK: 10010044: {{.*}} b .+67108812
# The offset from the TOC to the .branch_lt section is (-1 << 16) - 32768.
diff --git a/test/ELF/ppc64-dynamic-relocations.s b/test/ELF/ppc64-dynamic-relocations.s
index 2d9dfc6f8..a0484d413 100644
--- a/test/ELF/ppc64-dynamic-relocations.s
+++ b/test/ELF/ppc64-dynamic-relocations.s
@@ -25,7 +25,7 @@
// There should be 2 reserved doublewords before the first entry. The dynamic
// linker will fill those in with the address of the resolver entry point and
// the dynamic object identifier.
-// DIS: Idx Name Size Address Type
+// DIS: Idx Name Size VMA Type
// DIS: .plt 00000018 0000000010030000 BSS
// DT_PLTGOT should point to the start of the .plt section.
diff --git a/test/ELF/ppc64-error-missaligned-dq.s b/test/ELF/ppc64-error-missaligned-dq.s
index ea30ab88f..68ad2e5c4 100644
--- a/test/ELF/ppc64-error-missaligned-dq.s
+++ b/test/ELF/ppc64-error-missaligned-dq.s
@@ -6,7 +6,7 @@
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
-# CHECK: improper alignment for relocation R_PPC64_ADDR16_LO_DS: 0x8001 is not aligned to 16 bytes
+# CHECK: improper alignment for relocation R_PPC64_TOC16_LO_DS: 0x8001 is not aligned to 16 bytes
.global test
.p2align 4
diff --git a/test/ELF/ppc64-error-missaligned-ds.s b/test/ELF/ppc64-error-missaligned-ds.s
index 99a2c08bc..deee8f9ca 100644
--- a/test/ELF/ppc64-error-missaligned-ds.s
+++ b/test/ELF/ppc64-error-missaligned-ds.s
@@ -6,7 +6,7 @@
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
-# CHECK: improper alignment for relocation R_PPC64_ADDR16_LO_DS: 0x8001 is not aligned to 4 bytes
+# CHECK: improper alignment for relocation R_PPC64_TOC16_LO_DS: 0x8001 is not aligned to 4 bytes
.global test
.p2align 4
diff --git a/test/ELF/ppc64-gd-to-ie.s b/test/ELF/ppc64-gd-to-ie.s
index 121032caf..a11024a58 100644
--- a/test/ELF/ppc64-gd-to-ie.s
+++ b/test/ELF/ppc64-gd-to-ie.s
@@ -69,10 +69,6 @@ other_reg:
mtlr 0
blr
- .globl __tls_get_addr
- .type __tls_get_addr,@function
-__tls_get_addr:
-
# CheckGot: .got 00000018 00000000100200c0 DATA
# .got is at 0x100200c0 so the toc-base is 100280c0.
diff --git a/test/ELF/ppc64-got-off.s b/test/ELF/ppc64-got-off.s
index 0a1a09e1c..d3dff2262 100644
--- a/test/ELF/ppc64-got-off.s
+++ b/test/ELF/ppc64-got-off.s
@@ -8,6 +8,14 @@
# RUN: ld.lld -shared --no-toc-optimize %t.o -o %t
# RUN: llvm-objdump -d %t | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=OPT %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=OPT %s
+
.abiversion 2
.section ".text"
@@ -38,6 +46,15 @@ func:
# CHECK-NEXT: li 6, 0
# CHECK-NEXT: ori 6, 6, 32776
+# OPT-LABEL: func
+# OPT: nop
+# OPT-NEXT: ld 3, -32760(2)
+# OPT-NEXT: ld 4, -32760(2)
+# OPT-NEXT: lis 5, -1
+# OPT-NEXT: ori 5, 5, 32776
+# OPT-NEXT: li 6, 0
+# OPT-NEXT: ori 6, 6, 32776
+
# Since the got entry for a is .got[1] and the TOC base points to
# .got + 0x8000, the offset for a@got is -0x7FF8 --> -32760
diff --git a/test/ELF/ppc64-ifunc.s b/test/ELF/ppc64-ifunc.s
index 6f2d3318b..bd7f76197 100644
--- a/test/ELF/ppc64-ifunc.s
+++ b/test/ELF/ppc64-ifunc.s
@@ -42,9 +42,9 @@
# CHECK: _start:
# CHECK-NEXT: addis 2, 12, 2
# CHECK-NEXT: addi 2, 2, -32588
-# CHECK-NEXT: bl .+67108812
+# CHECK-NEXT: bl .-52
# CHECK-NEXT: ld 2, 24(1)
-# CHECK-NEXT: bl .+67108824
+# CHECK-NEXT: bl .-40
# CHECK-NEXT: ld 2, 24(1)
# Check tocbase
diff --git a/test/ELF/ppc64-local-dynamic.s b/test/ELF/ppc64-local-dynamic.s
index 6ed3b0fd8..8a23863f6 100644
--- a/test/ELF/ppc64-local-dynamic.s
+++ b/test/ELF/ppc64-local-dynamic.s
@@ -113,7 +113,7 @@ k:
// Dis: test:
// Dis: addis 3, 2, 0
// Dis-NEXT: addi 3, 3, -32760
-// Dis-NEXT: bl .+67108804
+// Dis-NEXT: bl .-60
// Dis-NEXT: ld 2, 24(1)
// Dis-NEXT: addis 3, 3, 0
// Dis-NEXT: lwa 3, -32768(3)
diff --git a/test/ELF/ppc64-plt-stub.s b/test/ELF/ppc64-plt-stub.s
index a644f487b..95e28a585 100644
--- a/test/ELF/ppc64-plt-stub.s
+++ b/test/ELF/ppc64-plt-stub.s
@@ -22,7 +22,7 @@
// CHECK: _start:
-// CHECK: bl .+67108824
+// CHECK: bl .-40
.text
.abiversion 2
.globl _start
diff --git a/test/ELF/ppc64-rel-calls.s b/test/ELF/ppc64-rel-calls.s
index 4c79498dc..8423eb43f 100644
--- a/test/ELF/ppc64-rel-calls.s
+++ b/test/ELF/ppc64-rel-calls.s
@@ -30,9 +30,8 @@ bar:
nop
blr
-# FIXME: The printing here is misleading, the branch offset here is negative.
-# CHECK: 1001000c: {{.*}} bl .+67108852
+# CHECK: 1001000c: {{.*}} bl .-12
# CHECK: 10010010: {{.*}} nop
-# CHECK: 10010014: {{.*}} bl .+67108844
+# CHECK: 10010014: {{.*}} bl .-20
# CHECK: 10010018: {{.*}} nop
# CHECK: 1001001c: {{.*}} blr
diff --git a/test/ELF/ppc64-sort-small-cm-relocs.s b/test/ELF/ppc64-sort-small-cm-relocs.s
new file mode 100644
index 000000000..fbbecc77a
--- /dev/null
+++ b/test/ELF/ppc64-sort-small-cm-relocs.s
@@ -0,0 +1,108 @@
+# REQUIRES: ppc
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-sort-small-cm-relocs-input2.s -o %t2.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-sort-small-cm-relocs-input3.s -o %t3.o
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-sort-small-cm-relocs-input4.s -o %t4.o
+
+# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -Map=%t.map
+# RUN: FileCheck %s < %t.map
+
+# Test an alternate link order.
+# RUN: ld.lld %t2.o %t3.o %t4.o %t1.o -o %t -Map=%t.map
+# RUN: FileCheck %s -check-prefix=ALTERNATE < %t.map
+
+# If a linker script has a sections command then allow that to override the
+# default sorting behavior.
+# RUN: echo "SECTIONS { \
+# RUN: .toc : { \
+# RUN: *ppc64-sort-small-cm-relocs.s.tmp4.o(.toc*) \
+# RUN: *ppc64-sort-small-cm-relocs.s.tmp1.o(.toc*) \
+# RUN: *(.toc*) \
+# RUN: } \
+# RUN: } " > %t.script
+# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -script %t.script -Map=%t.map
+# RUN: FileCheck %s -check-prefix=SEC-CMD < %t.map
+
+# RUN: echo "SECTIONS { .text : {*(.text*)} } " > %t.script
+# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -script %t.script -Map=%t.map
+# RUN: FileCheck %s -check-prefix=SEC-CMD2 < %t.map
+
+# Default sort if the linker script does not have a sections command.
+# RUN: echo "" > %t.script
+# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -script %t.script -Map=%t.map
+# RUN: FileCheck %s -check-prefix=NOSEC < %t.map
+ .text
+
+ .global _start
+ .type _start,@function
+_start:
+ li 3, 55
+ blr
+
+ .type a,@object
+ .data
+ .global a
+a:
+ .long 10
+ .size a, 4
+
+ .type c,@object
+ .data
+ .global c
+c:
+ .long 55
+ .size c, 4
+
+ .type d,@object
+ .global d
+d:
+ .long 33
+ .size d, 4
+
+ # .toc section contains only some constants.
+ .section .toc,"aw",@progbits
+ .quad 0xa1a1a1a1a1a1a1a1
+ .quad 0xb2b2b2b2b2b2b2b2
+
+# Input files tmp3.o and tmp4.o contain small code model relocs.
+
+# CHECK: .got
+# CHECK-NEXT: <internal>:(.got)
+# CHECK-NEXT: .toc
+# CHECK-NEXT: {{.*}}3.o:(.toc)
+# CHECK-NEXT: {{.*}}4.o:(.toc)
+# CHECK-NEXT: {{.*}}1.o:(.toc)
+# CHECK-NEXT: {{.*}}2.o:(.toc)
+
+# ALTERNATE: .got
+# ALTERNATE-NEXT: <internal>:(.got)
+# ALTERNATE-NEXT: .toc
+# ALTERNATE-NEXT: {{.*}}3.o:(.toc)
+# ALTERNATE-NEXT: {{.*}}4.o:(.toc)
+# ALTERNATE-NEXT: {{.*}}2.o:(.toc)
+# ALTERNATE-NEXT: {{.*}}1.o:(.toc)
+
+# SEC-CMD: .got
+# SEC-CMD-NEXT: <internal>:(.got)
+# SEC-CMD-NEXT: .toc
+# SEC-CMD-NEXT: {{.*}}4.o:(.toc)
+# SEC-CMD-NEXT: {{.*}}1.o:(.toc)
+# SEC-CMD-NEXT: {{.*}}2.o:(.toc)
+# SEC-CMD-NEXT: {{.*}}3.o:(.toc)
+
+# SEC-CMD2: .got
+# SEC-CMD2-NEXT: <internal>:(.got)
+# SEC-CMD2-NEXT: .toc
+# SEC-CMD2-NEXT: {{.*}}1.o:(.toc)
+# SEC-CMD2-NEXT: {{.*}}2.o:(.toc)
+# SEC-CMD2-NEXT: {{.*}}3.o:(.toc)
+# SEC-CMD2-NEXT: {{.*}}4.o:(.toc)
+
+# NOSEC: .got
+# NOSEC-NEXT: <internal>:(.got)
+# NOSEC-NEXT: .toc
+# NOSEC-NEXT: {{.*}}3.o:(.toc)
+# NOSEC-NEXT: {{.*}}4.o:(.toc)
+# NOSEC-NEXT: {{.*}}1.o:(.toc)
+# NOSEC-NEXT: {{.*}}2.o:(.toc)
+
diff --git a/test/ELF/ppc64-split-stack-adjust-overflow.s b/test/ELF/ppc64-split-stack-adjust-overflow.s
index bc958c752..874f45cd0 100644
--- a/test/ELF/ppc64-split-stack-adjust-overflow.s
+++ b/test/ELF/ppc64-split-stack-adjust-overflow.s
@@ -20,7 +20,7 @@
# RUN: ld.lld %t1.o %t2.o -o %t --defsym __morestack=0x10010000 -split-stack-adjust-size 4096
# RUN: llvm-objdump -d %t | FileCheck %s
-# OVERFLOW: error: {{.*}}.o:(function caller): split-stack prologue adjustment overflows
+# OVERFLOW: error: {{.*}}.o:(function caller: .text+0x8): split-stack prologue adjustment overflows
.p2align 2
.global caller
diff --git a/test/ELF/ppc64-tls-gd-le.s b/test/ELF/ppc64-tls-gd-le.s
index 7907d1104..78bffb2c4 100644
--- a/test/ELF/ppc64-tls-gd-le.s
+++ b/test/ELF/ppc64-tls-gd-le.s
@@ -50,10 +50,6 @@ _start: # @_start
.Lfunc_end0:
.size _start, .Lfunc_end0-.Lfunc_begin0
-.globl __tls_get_addr
-.type __tls_get_addr,@function
-__tls_get_addr:
-
# -- End function
.type a,@object # @a
.section .tdata,"awT",@progbits
diff --git a/test/ELF/ppc64-tls-ld-le.s b/test/ELF/ppc64-tls-ld-le.s
index b684515e8..572de0832 100644
--- a/test/ELF/ppc64-tls-ld-le.s
+++ b/test/ELF/ppc64-tls-ld-le.s
@@ -52,9 +52,7 @@ _start: # @_start
.Lfunc_end0:
.size _start, .Lfunc_end0-.Lfunc_begin0
# -- End function
-.globl __tls_get_addr
-.type __tls_get_addr,@function
-__tls_get_addr:
+
.type a,@object # @a
.section .tdata,"awT",@progbits
.p2align 2
diff --git a/test/ELF/ppc64-toc-restore-recursive-call.s b/test/ELF/ppc64-toc-restore-recursive-call.s
index 4bedcfecf..d194ada84 100644
--- a/test/ELF/ppc64-toc-restore-recursive-call.s
+++ b/test/ELF/ppc64-toc-restore-recursive-call.s
@@ -18,7 +18,7 @@
# CHECK-NEXT: 10000:
# CHECK-LABEL: recursive_func
# CHECK-NEXT: 10014:
-# CHECK: 1003c: {{[0-9a-fA-F ]+}} bl .+67108804
+# CHECK: 1003c: {{.*}} bl .-60
# CHECK-NEXT: ld 2, 24(1)
.abiversion 2
diff --git a/test/ELF/ppc64-toc-restore.s b/test/ELF/ppc64-toc-restore.s
index d9e06ca6e..8c262076b 100644
--- a/test/ELF/ppc64-toc-restore.s
+++ b/test/ELF/ppc64-toc-restore.s
@@ -32,10 +32,10 @@ _start:
// CHECK: Disassembly of section .text:
// CHECK: _start:
-// CHECK: 1001001c: {{.*}} bl .+67108836
+// CHECK: 1001001c: {{.*}} bl .-28
// CHECK-NOT: 10010020: {{.*}} nop
// CHECK: 10010020: {{.*}} ld 2, 24(1)
-// CHECK: 10010024: {{.*}} bl .+67108848
+// CHECK: 10010024: {{.*}} bl .-16
// CHECK-NOT: 10010028: {{.*}} nop
// CHECK-NOT: 10010028: {{.*}} ld 2, 24(1)
@@ -68,5 +68,5 @@ last:
bl foo
nop
// CHECK: last:
-// CHECK: 10010038: {{.*}} bl .+67108808
+// CHECK: 10010038: {{.*}} bl .-56
// CHECK-NEXT: 1001003c: {{.*}} ld 2, 24(1)
diff --git a/test/ELF/pr34872.s b/test/ELF/pr34872.s
index c6ca81972..2991e94ca 100644
--- a/test/ELF/pr34872.s
+++ b/test/ELF/pr34872.s
@@ -3,7 +3,7 @@
# RUN: llvm-mc %p/Inputs/undefined-error.s -filetype=obj \
# RUN: -triple=x86_64-pc-linux -o %t2.o
# RUN: ld.lld -shared %t2.o -o %t2.so
-# RUN: not ld.lld %t2.so %t.o -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld --allow-shlib-undefined %t2.so %t.o -o /dev/null 2>&1 | FileCheck %s
# CHECK: undefined symbol: fmod
# Check we're not emitting other diagnostics for this symbol.
diff --git a/test/ELF/progname.s b/test/ELF/progname.s
index ecd0fd872..228e3f61e 100644
--- a/test/ELF/progname.s
+++ b/test/ELF/progname.s
@@ -17,7 +17,7 @@
// RUN: ld.lld -dynamic-list %t.dynlist -o %t %t.o %t.so
// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
-// CHECK: Name: __progname@
+// CHECK: Name: __progname
// CHECK-NEXT: Value: 0x201000
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1)
diff --git a/test/ELF/protected-shared.s b/test/ELF/protected-shared.s
index e69b10899..3501162e6 100644
--- a/test/ELF/protected-shared.s
+++ b/test/ELF/protected-shared.s
@@ -32,7 +32,7 @@ bar:
// CHECK: DynamicSymbols [
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: @
+// CHECK-NEXT: Name:
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local (0x0)
@@ -41,7 +41,7 @@ bar:
// CHECK-NEXT: Section: Undefined (0x0)
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: foo@
+// CHECK-NEXT: Name: foo
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
diff --git a/test/ELF/relative-dynamic-reloc-ppc64.s b/test/ELF/relative-dynamic-reloc-ppc64.s
index 83190a270..d65ea2754 100644
--- a/test/ELF/relative-dynamic-reloc-ppc64.s
+++ b/test/ELF/relative-dynamic-reloc-ppc64.s
@@ -32,7 +32,7 @@
// CHECK: DynamicSymbols [
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: @
+// CHECK-NEXT: Name:
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
@@ -41,7 +41,7 @@
// CHECK-NEXT: Section: Undefined
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: external@
+// CHECK-NEXT: Name: external
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
diff --git a/test/ELF/relative-dynamic-reloc.s b/test/ELF/relative-dynamic-reloc.s
index 0ed7e40f7..24d03f28a 100644
--- a/test/ELF/relative-dynamic-reloc.s
+++ b/test/ELF/relative-dynamic-reloc.s
@@ -28,7 +28,7 @@
// CHECK: DynamicSymbols [
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: @
+// CHECK-NEXT: Name:
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
@@ -37,7 +37,7 @@
// CHECK-NEXT: Section: Undefined
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: external@
+// CHECK-NEXT: Name: external
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
diff --git a/test/ELF/relocatable.s b/test/ELF/relocatable.s
index 7235ea03c..74ed920fc 100644
--- a/test/ELF/relocatable.s
+++ b/test/ELF/relocatable.s
@@ -53,7 +53,7 @@
# CHECK-NEXT: }
# SECTION: Sections:
-# SECTION: Idx Name Size Address Type
+# SECTION: Idx Name Size VMA Type
# SECTION: 0 00000000 0000000000000000
# SECTION: 1 .text 00000056 0000000000000000 TEXT
# SECTION: 2 .rela.text 00000090 0000000000000000
diff --git a/test/ELF/relocation-size-shared.s b/test/ELF/relocation-size-shared.s
index f60f0929e..1aa2222d9 100644
--- a/test/ELF/relocation-size-shared.s
+++ b/test/ELF/relocation-size-shared.s
@@ -28,20 +28,7 @@
// DISASM-NEXT: 20100c: 00 00
// DISASM-NEXT: 20100e: 00 00
// DISASM-NEXT: 201010: 1b 00
-// DISASM-NEXT: 201012: 00 00
-// DISASM-NEXT: 201014: 00 00
-// DISASM-NEXT: 201016: 00 00
-// DISASM-NEXT: 201018: 00 00
-// DISASM-NEXT: 20101a: 00 00
-// DISASM-NEXT: 20101c: 00 00
-// DISASM-NEXT: 20101e: 00 00
-// DISASM-NEXT: 201020: 00 00
-// DISASM-NEXT: 201022: 00 00
-// DISASM-NEXT: 201024: 00 00
-// DISASM-NEXT: 201026: 00 00
-// DISASM-NEXT: 201028: 00 00
-// DISASM-NEXT: 20102a: 00 00
-// DISASM-NEXT: 20102c: 00 00
+// DISASM-NEXT: ...
// DISASM-NEXT: 20102e: 00 00
// DISASM: _start:
// DISASM-NEXT: 201030: 8b 04 25 19 00 00 00 movl 25, %eax
diff --git a/test/ELF/relocation-size.s b/test/ELF/relocation-size.s
index 525b1e1d1..c2554a4e4 100644
--- a/test/ELF/relocation-size.s
+++ b/test/ELF/relocation-size.s
@@ -57,18 +57,7 @@
// DISASMSHARED: Disassembly of section test:
// DISASMSHARED-NEXT: _data:
-// DISASMSHARED-NEXT: 1000: 00 00
-// DISASMSHARED-NEXT: 1002: 00 00
-// DISASMSHARED-NEXT: 1004: 00 00
-// DISASMSHARED-NEXT: 1006: 00 00
-// DISASMSHARED-NEXT: 1008: 00 00
-// DISASMSHARED-NEXT: 100a: 00 00
-// DISASMSHARED-NEXT: 100c: 00 00
-// DISASMSHARED-NEXT: 100e: 00 00
-// DISASMSHARED-NEXT: 1010: 00 00
-// DISASMSHARED-NEXT: 1012: 00 00
-// DISASMSHARED-NEXT: 1014: 00 00
-// DISASMSHARED-NEXT: 1016: 00 00
+// DISASMSHARED-NEXT: ...
// DISASMSHARED-NEXT: 1018: 19 00
// DISASMSHARED-NEXT: 101a: 00 00
// DISASMSHARED-NEXT: 101c: 00 00
diff --git a/test/ELF/relro-omagic.s b/test/ELF/relro-omagic.s
index ba0ca72e2..3f6b42557 100644
--- a/test/ELF/relro-omagic.s
+++ b/test/ELF/relro-omagic.s
@@ -7,7 +7,7 @@
# RUN: llvm-readobj --program-headers %t | FileCheck --check-prefix=NOPHDRS %s
# NORELRO: Sections:
-# NORELRO-NEXT: Idx Name Size Address Type
+# NORELRO-NEXT: Idx Name Size VMA Type
# NORELRO-NEXT: 0 00000000 0000000000000000
# NORELRO-NEXT: 1 .dynsym 00000048 0000000000200120
# NORELRO-NEXT: 2 .hash 00000020 0000000000200168
diff --git a/test/ELF/retain-symbols-file.s b/test/ELF/retain-symbols-file.s
index 79d569d69..0ab19774b 100644
--- a/test/ELF/retain-symbols-file.s
+++ b/test/ELF/retain-symbols-file.s
@@ -11,7 +11,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value:
# CHECK-NEXT: Size:
# CHECK-NEXT: Binding:
diff --git a/test/ELF/sectionstart-noallochdr.s b/test/ELF/sectionstart-noallochdr.s
index be8e0c568..b32d67c7b 100644
--- a/test/ELF/sectionstart-noallochdr.s
+++ b/test/ELF/sectionstart-noallochdr.s
@@ -5,7 +5,7 @@
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .text 00000001 0000000000000010 TEXT
# CHECK-NEXT: 2 .data 00000004 0000000000000020 DATA
diff --git a/test/ELF/sectionstart.s b/test/ELF/sectionstart.s
index be8b5f0cf..519831daa 100644
--- a/test/ELF/sectionstart.s
+++ b/test/ELF/sectionstart.s
@@ -5,7 +5,7 @@
# RUN: llvm-objdump -section-headers %t | FileCheck %s
# CHECK: Sections:
-# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: Idx Name Size VMA Type
# CHECK-NEXT: 0 00000000 0000000000000000
# CHECK-NEXT: 1 .text 00000001 0000000000100000 TEXT
# CHECK-NEXT: 2 .data 00000004 0000000000110000 DATA
diff --git a/test/ELF/shared.s b/test/ELF/shared.s
index 1b93fef8b..e00dd9937 100644
--- a/test/ELF/shared.s
+++ b/test/ELF/shared.s
@@ -181,7 +181,7 @@
// CHECK: DynamicSymbols [
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: @
+// CHECK-NEXT: Name:
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
@@ -190,7 +190,7 @@
// CHECK-NEXT: Section: Undefined
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: _start@
+// CHECK-NEXT: Name: _start
// CHECK-NEXT: Value: 0x401000
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
@@ -199,7 +199,7 @@
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: bar@
+// CHECK-NEXT: Name: bar
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
@@ -208,7 +208,7 @@
// CHECK-NEXT: Section: Undefined
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: zed@
+// CHECK-NEXT: Name: zed
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
@@ -220,7 +220,7 @@
// DONT_EXPORT: DynamicSymbols [
// DONT_EXPORT-NEXT: Symbol {
-// DONT_EXPORT-NEXT: Name: @
+// DONT_EXPORT-NEXT: Name:
// DONT_EXPORT-NEXT: Value: 0x0
// DONT_EXPORT-NEXT: Size: 0
// DONT_EXPORT-NEXT: Binding: Local (0x0)
@@ -229,7 +229,7 @@
// DONT_EXPORT-NEXT: Section: Undefined (0x0)
// DONT_EXPORT-NEXT: }
// DONT_EXPORT-NEXT: Symbol {
-// DONT_EXPORT-NEXT: Name: bar@
+// DONT_EXPORT-NEXT: Name: bar
// DONT_EXPORT-NEXT: Value: 0x0
// DONT_EXPORT-NEXT: Size: 0
// DONT_EXPORT-NEXT: Binding: Global
@@ -238,7 +238,7 @@
// DONT_EXPORT-NEXT: Section: Undefined
// DONT_EXPORT-NEXT: }
// DONT_EXPORT-NEXT: Symbol {
-// DONT_EXPORT-NEXT: Name: zed@
+// DONT_EXPORT-NEXT: Name: zed
// DONT_EXPORT-NEXT: Value: 0x0
// DONT_EXPORT-NEXT: Size: 0
// DONT_EXPORT-NEXT: Binding: Global
diff --git a/test/ELF/sht-group-empty.test b/test/ELF/sht-group-empty.test
new file mode 100644
index 000000000..46c77f332
--- /dev/null
+++ b/test/ELF/sht-group-empty.test
@@ -0,0 +1,55 @@
+# RUN: yaml2obj %s -o %t.o
+# RUN: ld.lld %t.o %t.o -o %t -r
+# RUN: llvm-readobj -s %t | FileCheck %s
+
+# CHECK: Name: .text.foo
+# CHECK: Name: .rela.text.foo
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ Info: foo
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .text.foo
+ - SectionOrType: .text.bar
+ - SectionOrType: .note
+ - Name: .note
+ Type: SHT_NOTE
+ Flags: [ SHF_GROUP ]
+ - Name: .text.foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ - Name: .text.bar
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ - Name: .rela.text.foo
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK, SHF_GROUP ]
+ Link: .symtab
+ Info: .text.foo
+ Relocations:
+ - Offset: 0x0000000000000000
+ Symbol: foo
+ Type: R_X86_64_64
+ - Name: .rela.text.bar
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK, SHF_GROUP ]
+ Link: .symtab
+ Info: .text.bar
+ Relocations:
+ - Offset: 0x0000000000000000
+ Symbol: bar
+ Type: R_X86_64_64
+Symbols:
+ Global:
+ - Name: foo
+ - Name: bar
+
diff --git a/test/ELF/stdout.s b/test/ELF/stdout.s
new file mode 100644
index 000000000..fcce79f90
--- /dev/null
+++ b/test/ELF/stdout.s
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o - > %t1
+# RUN: llvm-objdump -d %t1 | FileCheck %s
+
+# CHECK: 0000000000201000 _start:
+# CHECK: 201000: 90 nop
+
+# RUN: ld.lld %t.o -o %t2
+
+# FIXME: Add "RUN" in front of this line once the test passes on Windows
+# with it.
+# diff %t1 %t2
+
+.globl _start
+_start:
+ nop
diff --git a/test/ELF/tls-dynamic-i686.s b/test/ELF/tls-dynamic-i686.s
index 1b13f26cc..dc651d09b 100644
--- a/test/ELF/tls-dynamic-i686.s
+++ b/test/ELF/tls-dynamic-i686.s
@@ -56,8 +56,8 @@ addl tls1@gotntpoff(%ebx),%eax
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x3068
-// CHECK-NEXT: Offset: 0x3068
+// CHECK-NEXT: Address: 0x3070
+// CHECK-NEXT: Offset: 0x3070
// CHECK-NEXT: Size: 32
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
@@ -66,13 +66,13 @@ addl tls1@gotntpoff(%ebx),%eax
// CHECK: Relocations [
// CHECK: Section ({{.+}}) .rel.dyn {
-// CHECK-NEXT: 0x3078 R_386_TLS_DTPMOD32 - 0x0
-// CHECK-NEXT: 0x3068 R_386_TLS_DTPMOD32 tls0 0x0
-// CHECK-NEXT: 0x306C R_386_TLS_DTPOFF32 tls0 0x0
-// CHECK-NEXT: 0x3080 R_386_TLS_TPOFF tls0 0x0
-// CHECK-NEXT: 0x3070 R_386_TLS_DTPMOD32 tls1 0x0
-// CHECK-NEXT: 0x3074 R_386_TLS_DTPOFF32 tls1 0x0
-// CHECK-NEXT: 0x3084 R_386_TLS_TPOFF tls1 0x0
+// CHECK-NEXT: 0x3080 R_386_TLS_DTPMOD32 - 0x0
+// CHECK-NEXT: 0x3070 R_386_TLS_DTPMOD32 tls0 0x0
+// CHECK-NEXT: 0x3074 R_386_TLS_DTPOFF32 tls0 0x0
+// CHECK-NEXT: 0x3088 R_386_TLS_TPOFF tls0 0x0
+// CHECK-NEXT: 0x3078 R_386_TLS_DTPMOD32 tls1 0x0
+// CHECK-NEXT: 0x307C R_386_TLS_DTPOFF32 tls1 0x0
+// CHECK-NEXT: 0x308C R_386_TLS_TPOFF tls1 0x0
// CHECK-NEXT: }
// DIS: Disassembly of section .text:
@@ -80,20 +80,20 @@ addl tls1@gotntpoff(%ebx),%eax
// General dynamic model:
// -32 and -24 are first and second GOT entries offsets.
// Each one is a pair of records.
-// DIS-NEXT: 1000: 8d 04 1d e0 ff ff ff leal -32(,%ebx), %eax
-// DIS-NEXT: 1007: e8 64 00 00 00 calll 100
-// DIS-NEXT: 100c: 8d 04 1d e8 ff ff ff leal -24(,%ebx), %eax
-// DIS-NEXT: 1013: e8 58 00 00 00 calll 88
+// DIS-NEXT: 1000: {{.*}} leal -32(,%ebx), %eax
+// DIS-NEXT: 1007: {{.*}} calll 100
+// DIS-NEXT: 100c: {{.*}} leal -24(,%ebx), %eax
+// DIS-NEXT: 1013: {{.*}} calll 88
// Local dynamic model:
// -16 is a local module tls index offset.
-// DIS-NEXT: 1018: 8d 83 f0 ff ff ff leal -16(%ebx), %eax
-// DIS-NEXT: 101e: e8 4d 00 00 00 calll 77
-// DIS-NEXT: 1023: 8d 90 08 00 00 00 leal 8(%eax), %edx
-// DIS-NEXT: 1029: 8d 83 f0 ff ff ff leal -16(%ebx), %eax
-// DIS-NEXT: 102f: e8 3c 00 00 00 calll 60
-// DIS-NEXT: 1034: 8d 90 0c 00 00 00 leal 12(%eax), %edx
+// DIS-NEXT: 1018: {{.*}} leal -16(%ebx), %eax
+// DIS-NEXT: 101e: {{.*}} calll 77
+// DIS-NEXT: 1023: {{.*}} leal 8(%eax), %edx
+// DIS-NEXT: 1029: {{.*}} leal -16(%ebx), %eax
+// DIS-NEXT: 102f: {{.*}} calll 60
+// DIS-NEXT: 1034: {{.*}} leal 12(%eax), %edx
// Initial exec model:
-// DIS-NEXT: 103a: 65 a1 00 00 00 00 movl %gs:0, %eax
-// DIS-NEXT: 1040: 03 83 f8 ff ff ff addl -8(%ebx), %eax
-// DIS-NEXT: 1046: 65 a1 00 00 00 00 movl %gs:0, %eax
-// DIS-NEXT: 104c: 03 83 fc ff ff ff addl -4(%ebx), %eax
+// DIS-NEXT: 103a: {{.*}} movl %gs:0, %eax
+// DIS-NEXT: 1040: {{.*}} addl -8(%ebx), %eax
+// DIS-NEXT: 1046: {{.*}} movl %gs:0, %eax
+// DIS-NEXT: 104c: {{.*}} addl -4(%ebx), %eax
diff --git a/test/ELF/tls-dynamic.s b/test/ELF/tls-dynamic.s
index 167f76874..c4190a26d 100644
--- a/test/ELF/tls-dynamic.s
+++ b/test/ELF/tls-dynamic.s
@@ -48,28 +48,28 @@ c:
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x30D0
+// CHECK-NEXT: Address: 0x30E0
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 40
// CHECK: Relocations [
// CHECK: Section ({{.+}}) .rela.dyn {
-// CHECK-NEXT: 0x30D0 R_X86_64_DTPMOD64 - 0x0
-// CHECK-NEXT: 0x30E0 R_X86_64_DTPMOD64 c 0x0
-// CHECK-NEXT: 0x30E8 R_X86_64_DTPOFF64 c 0x0
-// CHECK-NEXT: 0x30F0 R_X86_64_TPOFF64 c 0x0
+// CHECK-NEXT: 0x30E0 R_X86_64_DTPMOD64 - 0x0
+// CHECK-NEXT: 0x30F0 R_X86_64_DTPMOD64 c 0x0
+// CHECK-NEXT: 0x30F8 R_X86_64_DTPOFF64 c 0x0
+// CHECK-NEXT: 0x3100 R_X86_64_TPOFF64 c 0x0
// CHECK-NEXT: }
-// 4297 = (0x20D0 + -4) - (0x1000 + 3) // PC relative offset to got entry.
-// 4285 = (0x20D0 + -4) - (0x100c + 3) // PC relative offset to got entry.
-// 4267 = (0x20E0 + -4) - (0x102e + 3) // PC relative offset to got entry.
-// 4263 = (0x20F0 + -4) - (0x1042 + 3) // PC relative offset to got entry.
+// 8409 = (0x30E0 + -4) - (0x1000 + 3) // PC relative offset to got entry.
+// 8397 = (0x30F0 + -4) - (0x100c + 3) // PC relative offset to got entry.
+// 8379 = (0x30F8 + -4) - (0x102e + 3) // PC relative offset to got entry.
+// 8375 = (0x3100 + -4) - (0x1042 + 3) // PC relative offset to got entry.
// DIS: Disassembly of section .text:
// DIS-NEXT: .text:
-// DIS-NEXT: 1000: {{.+}} leaq 8393(%rip), %rdi
+// DIS-NEXT: 1000: {{.+}} leaq 8409(%rip), %rdi
// DIS-NEXT: 1007: {{.+}} callq
-// DIS-NEXT: 100c: {{.+}} leaq 8381(%rip), %rdi
+// DIS-NEXT: 100c: {{.+}} leaq 8397(%rip), %rdi
// DIS-NEXT: 1013: {{.+}} callq
// DIS-NEXT: 1018: {{.+}} leaq (%rax), %rcx
// DIS-NEXT: 101f: {{.+}} leaq 4(%rax), %rcx
@@ -77,10 +77,10 @@ c:
// DIS-NEXT: 1028: 00 00
// DIS-NEXT: 102a: 00 00
// DIS-NEXT: 102c: 00 00
-// DIS-NEXT: 102e: {{.+}} leaq 8363(%rip), %rdi
+// DIS-NEXT: 102e: {{.+}} leaq 8379(%rip), %rdi
// DIS-NEXT: 1035: {{.+}} callq
// DIS-NEXT: 103b: {{.+}} leaq (%rax), %rcx
-// DIS-NEXT: 1042: {{.+}} movq 8359(%rip), %rax
+// DIS-NEXT: 1042: {{.+}} movq 8375(%rip), %rax
// DIS-NEXT: 1049: {{.+}} movq %fs:(%rax), %rax
// DIS-NEXT: 104d: {{.+}} movabsq $0, %rax
// DIS-NEXT: 1057: {{.+}} movabsq $4, %rax
diff --git a/test/ELF/tls-got.s b/test/ELF/tls-got.s
index bedaaebee..d9de24e39 100644
--- a/test/ELF/tls-got.s
+++ b/test/ELF/tls-got.s
@@ -15,7 +15,7 @@
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
// CHECK-NEXT: Address: [[ADDR:.*]]
-// CHECK-NEXT: Offset: 0x20B0
+// CHECK-NEXT: Offset: 0x20C0
// CHECK-NEXT: Size: 16
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
@@ -25,23 +25,23 @@
// CHECK: Relocations [
// CHECK-NEXT: Section (4) .rela.dyn {
-// CHECK-NEXT: 0x2020B8 R_X86_64_TPOFF64 tls0 0x0
-// CHECK-NEXT: 0x2020B0 R_X86_64_TPOFF64 tls1 0x0
+// CHECK-NEXT: 0x2020C8 R_X86_64_TPOFF64 tls0 0x0
+// CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0
// CHECK-NEXT: }
// CHECK-NEXT: ]
-//0x201000 + 4265 + 7 = 0x2020B0
-//0x20100A + 4263 + 7 = 0x2020B8
-//0x201014 + 4253 + 7 = 0x2020B8
+//0x201000 + 4281 + 7 = 0x2020C0
+//0x20100A + 4279 + 7 = 0x2020C8
+//0x201014 + 4269 + 7 = 0x2020C8
//DISASM: Disassembly of section .text:
//DISASM-NEXT: main:
-//DISASM-NEXT: 201000: 48 8b 05 a9 10 00 00 movq 4265(%rip), %rax
-//DISASM-NEXT: 201007: 64 8b 00 movl %fs:(%rax), %eax
-//DISASM-NEXT: 20100a: 48 8b 05 a7 10 00 00 movq 4263(%rip), %rax
-//DISASM-NEXT: 201011: 64 8b 00 movl %fs:(%rax), %eax
-//DISASM-NEXT: 201014: 48 8b 05 9d 10 00 00 movq 4253(%rip), %rax
-//DISASM-NEXT: 20101b: 64 8b 00 movl %fs:(%rax), %eax
-//DISASM-NEXT: 20101e: c3 retq
+//DISASM-NEXT: 201000: {{.*}} movq 4281(%rip), %rax
+//DISASM-NEXT: 201007: {{.*}} movl %fs:(%rax), %eax
+//DISASM-NEXT: 20100a: {{.*}} movq 4279(%rip), %rax
+//DISASM-NEXT: 201011: {{.*}} movl %fs:(%rax), %eax
+//DISASM-NEXT: 201014: {{.*}} movq 4269(%rip), %rax
+//DISASM-NEXT: 20101b: {{.*}} movl %fs:(%rax), %eax
+//DISASM-NEXT: 20101e: {{.*}} retq
.section .tdata,"awT",@progbits
diff --git a/test/ELF/tls-initial-exec-local.s b/test/ELF/tls-initial-exec-local.s
index e65fb294b..67fe9095d 100644
--- a/test/ELF/tls-initial-exec-local.s
+++ b/test/ELF/tls-initial-exec-local.s
@@ -10,21 +10,21 @@
// CHECK-NEXT: SHF_ALLOC (0x2)
// CHECK-NEXT: SHF_WRITE (0x1)
// CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x2090
+// CHECK-NEXT: Address: 0x20A0
// CHECK: Relocations [
// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
-// CHECK-NEXT: 0x2090 R_X86_64_TPOFF64 - 0x0
-// CHECK-NEXT: 0x2098 R_X86_64_TPOFF64 - 0x4
+// CHECK-NEXT: 0x20A0 R_X86_64_TPOFF64 - 0x0
+// CHECK-NEXT: 0x20A8 R_X86_64_TPOFF64 - 0x4
// CHECK-NEXT: }
// CHECK-NEXT: ]
-// 0x1007 + 4233 = 0x2090
-// 0x100e + 4234 = 0x2098
+// 0x1007 + 4249 = 0x20A0
+// 0x100e + 4250 = 0x20A8
// DISASM: Disassembly of section .text:
// DISASM-NEXT: .text:
-// DISASM-NEXT: 1000: {{.*}} addq 4233(%rip), %rax
-// DISASM-NEXT: 1007: {{.*}} addq 4234(%rip), %rax
+// DISASM-NEXT: 1000: {{.*}} addq 4249(%rip), %rax
+// DISASM-NEXT: 1007: {{.*}} addq 4250(%rip), %rax
addq foo@GOTTPOFF(%rip), %rax
addq bar@GOTTPOFF(%rip), %rax
diff --git a/test/ELF/tls-opt-iele-i686-nopic.s b/test/ELF/tls-opt-iele-i686-nopic.s
index 704928b2b..9b97264a0 100644
--- a/test/ELF/tls-opt-iele-i686-nopic.s
+++ b/test/ELF/tls-opt-iele-i686-nopic.s
@@ -14,8 +14,8 @@
// GOTREL-NEXT: SHF_ALLOC
// GOTREL-NEXT: SHF_WRITE
// GOTREL-NEXT: ]
-// GOTREL-NEXT: Address: 0x402058
-// GOTREL-NEXT: Offset: 0x2058
+// GOTREL-NEXT: Address: 0x402060
+// GOTREL-NEXT: Offset: 0x2060
// GOTREL-NEXT: Size: 8
// GOTREL-NEXT: Link: 0
// GOTREL-NEXT: Info: 0
@@ -24,8 +24,8 @@
// GOTREL-NEXT: }
// GOTREL: Relocations [
// GOTREL-NEXT: Section ({{.*}}) .rel.dyn {
-// GOTREL-NEXT: 0x402058 R_386_TLS_TPOFF tlsshared0 0x0
-// GOTREL-NEXT: 0x40205C R_386_TLS_TPOFF tlsshared1 0x0
+// GOTREL-NEXT: 0x402060 R_386_TLS_TPOFF tlsshared0 0x0
+// GOTREL-NEXT: 0x402064 R_386_TLS_TPOFF tlsshared1 0x0
// GOTREL-NEXT: }
// GOTREL-NEXT: ]
@@ -33,24 +33,24 @@
// DISASM-NEXT: _start:
// 4294967288 = 0xFFFFFFF8
// 4294967292 = 0xFFFFFFFC
-// 4202584 = (.got)[0] = 0x402058
-// 4202588 = (.got)[1] = 0x40205C
-// DISASM-NEXT: 401000: c7 c1 f8 ff ff ff movl $4294967288, %ecx
-// DISASM-NEXT: 401006: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASM-NEXT: 401009: b8 f8 ff ff ff movl $4294967288, %eax
-// DISASM-NEXT: 40100e: 65 8b 00 movl %gs:(%eax), %eax
-// DISASM-NEXT: 401011: 81 c1 f8 ff ff ff addl $4294967288, %ecx
-// DISASM-NEXT: 401017: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASM-NEXT: 40101a: c7 c1 fc ff ff ff movl $4294967292, %ecx
-// DISASM-NEXT: 401020: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASM-NEXT: 401023: b8 fc ff ff ff movl $4294967292, %eax
-// DISASM-NEXT: 401028: 65 8b 00 movl %gs:(%eax), %eax
-// DISASM-NEXT: 40102b: 81 c1 fc ff ff ff addl $4294967292, %ecx
-// DISASM-NEXT: 401031: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASM-NEXT: 401034: 8b 0d 58 20 40 00 movl 4202584, %ecx
-// DISASM-NEXT: 40103a: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASM-NEXT: 40103d: 03 0d 5c 20 40 00 addl 4202588, %ecx
-// DISASM-NEXT: 401043: 65 8b 01 movl %gs:(%ecx), %eax
+// 4202592 = (.got)[0] = 0x402060
+// 4202596 = (.got)[1] = 0x402064
+// DISASM-NEXT: 401000: {{.*}} movl $4294967288, %ecx
+// DISASM-NEXT: 401006: {{.*}} movl %gs:(%ecx), %eax
+// DISASM-NEXT: 401009: {{.*}} movl $4294967288, %eax
+// DISASM-NEXT: 40100e: {{.*}} movl %gs:(%eax), %eax
+// DISASM-NEXT: 401011: {{.*}} addl $4294967288, %ecx
+// DISASM-NEXT: 401017: {{.*}} movl %gs:(%ecx), %eax
+// DISASM-NEXT: 40101a: {{.*}} movl $4294967292, %ecx
+// DISASM-NEXT: 401020: {{.*}} movl %gs:(%ecx), %eax
+// DISASM-NEXT: 401023: {{.*}} movl $4294967292, %eax
+// DISASM-NEXT: 401028: {{.*}} movl %gs:(%eax), %eax
+// DISASM-NEXT: 40102b: {{.*}} addl $4294967292, %ecx
+// DISASM-NEXT: 401031: {{.*}} movl %gs:(%ecx), %eax
+// DISASM-NEXT: 401034: {{.*}} movl 4202592, %ecx
+// DISASM-NEXT: 40103a: {{.*}} movl %gs:(%ecx), %eax
+// DISASM-NEXT: 40103d: {{.*}} addl 4202596, %ecx
+// DISASM-NEXT: 401043: {{.*}} movl %gs:(%ecx), %eax
.type tlslocal0,@object
.section .tbss,"awT",@nobits
diff --git a/test/ELF/tls-opt-x86_64-noplt.s b/test/ELF/tls-opt-x86_64-noplt.s
new file mode 100644
index 000000000..69ec49871
--- /dev/null
+++ b/test/ELF/tls-opt-x86_64-noplt.s
@@ -0,0 +1,88 @@
+// REQUIRES: x86
+
+// Checks whether the TLS optimizations match the cases in Chapter 11 of
+// https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-opt-gdie.s -o %tso.o
+// RUN: ld.lld -shared %tso.o -o %t.so
+// RUN: ld.lld %t.o %t.so -o %t1
+// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOC %s
+// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
+
+// RELOC: Relocations [
+// RELOC-NEXT: Section {{.*}} .rela.dyn {
+// RELOC-NEXT: 0x2020C0 R_X86_64_TPOFF64 tlsshared0 0x0
+// RELOC-NEXT: 0x2020C8 R_X86_64_TPOFF64 tlsshared1 0x0
+// RELOC-NEXT: }
+// RELOC-NEXT: ]
+
+// DISASM: _start:
+
+// Table 11.5: GD -> IE Code Transition (LP64)
+// DISASM-NEXT: 201000: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
+// DISASM-NEXT: 201009: 48 03 05 b0 10 00 00 addq 4272(%rip), %rax
+// DISASM-NEXT: 201010: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
+// DISASM-NEXT: 201019: 48 03 05 a8 10 00 00 addq 4264(%rip), %rax
+
+// Table 11.7: GD -> LE Code Transition (LP64)
+// DISASM-NEXT: 201020: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
+// DISASM-NEXT: 201029: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax
+// DISASM-NEXT: 201030: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
+// DISASM-NEXT: 201039: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax
+
+
+// Table 11.9: LD -> LE Code Transition (LP64)
+// DISASM-NEXT: 201040: 66 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
+// DISASM-NEXT: 20104d: 66 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
+
+.type tls0,@object
+.section .tbss,"awT",@nobits
+.globl tls0
+.align 4
+tls0:
+ .long 0
+ .size tls0, 4
+
+.type tls1,@object
+.globl tls1
+.align 4
+tls1:
+ .long 0
+ .size tls1, 4
+
+.section .text
+.globl _start
+_start:
+ // Table 11.5: GD -> IE Code Transition (LP64)
+ .byte 0x66
+ leaq tlsshared0@tlsgd(%rip),%rdi
+ .byte 0x66
+ rex64
+ call *__tls_get_addr@GOTPCREL(%rip)
+
+ .byte 0x66
+ leaq tlsshared1@tlsgd(%rip),%rdi
+ .byte 0x66
+ rex64
+ call *__tls_get_addr@GOTPCREL(%rip)
+
+ // Table 11.7: GD -> LE Code Transition (LP64)
+ .byte 0x66
+ leaq tls0@tlsgd(%rip),%rdi
+ .byte 0x66
+ rex64
+ call *__tls_get_addr@GOTPCREL(%rip)
+
+ .byte 0x66
+ leaq tls1@tlsgd(%rip),%rdi
+ .byte 0x66
+ rex64
+ call *__tls_get_addr@GOTPCREL(%rip)
+
+ // Table 11.9: LD -> LE Code Transition (LP64)
+ leaq tls0@tlsld(%rip),%rdi
+ call *__tls_get_addr@GOTPCREL(%rip)
+
+ leaq tls1@tlsld(%rip),%rdi
+ call *__tls_get_addr@GOTPCREL(%rip)
diff --git a/test/ELF/trace.s b/test/ELF/trace.s
index 4374d93da..43876adbc 100644
--- a/test/ELF/trace.s
+++ b/test/ELF/trace.s
@@ -6,4 +6,4 @@
# CHECK: {{.*}}.foo.o
## Check --trace alias
-# RUN: ld.lld -shared %t.foo.o -o %t.so -t 2>&1 | FileCheck %s
+# RUN: ld.lld -shared %t.foo.o -o %t.so --trace 2>&1 | FileCheck %s
diff --git a/test/ELF/undef-version-script.s b/test/ELF/undef-version-script.s
index 712589e24..7ef4b7a22 100644
--- a/test/ELF/undef-version-script.s
+++ b/test/ELF/undef-version-script.s
@@ -6,7 +6,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local (0x0)
@@ -15,7 +15,7 @@
# CHECK-NEXT: Section: Undefined (0x0)
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: bar@
+# CHECK-NEXT: Name: bar
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Weak (0x2)
@@ -24,7 +24,7 @@
# CHECK-NEXT: Section: Undefined (0x0)
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: foo@
+# CHECK-NEXT: Name: foo
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global (0x1)
diff --git a/test/ELF/undef.s b/test/ELF/undef.s
index a51172339..e6277e366 100644
--- a/test/ELF/undef.s
+++ b/test/ELF/undef.s
@@ -20,6 +20,9 @@
# CHECK: >>> referenced by undef.s
# CHECK: >>> {{.*}}:(.text+0x10)
+# CHECK: error: undefined symbol: vtable for Foo
+# CHECK: the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeyfunction)
+
# CHECK: error: undefined symbol: zed2
# CHECK: >>> referenced by {{.*}}.o:(.text+0x0) in archive {{.*}}2.a
@@ -60,3 +63,4 @@ _start:
call bar
call zed1
call _Z3fooi
+ call _ZTV3Foo
diff --git a/test/ELF/undefined-opt.s b/test/ELF/undefined-opt.s
index 9e93e0fdc..268995427 100644
--- a/test/ELF/undefined-opt.s
+++ b/test/ELF/undefined-opt.s
@@ -40,7 +40,7 @@
# TWO-UNDEFINED: Name: zed
# TWO-UNDEFINED: ]
# Now the same logic but linker script is used to set undefines
-# RUN: echo "EXTERN( bar abs )" > %t.script
+# RUN: echo "EXTERN( bar \"abs\" )" > %t.script
# RUN: ld.lld -o %t3 %t.o %tar.a %t.script
# RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TWO-UNDEFINED %s
diff --git a/test/ELF/unresolved-symbols.s b/test/ELF/unresolved-symbols.s
index 69da3e63c..04159729a 100644
--- a/test/ELF/unresolved-symbols.s
+++ b/test/ELF/unresolved-symbols.s
@@ -27,21 +27,21 @@
# ERRUND: >>> referenced by {{.*}}:(.text+0x1)
## Also ignore all should not produce error for symbols from DSOs.
-# RUN: ld.lld %t1.o %t.so -o %t1_3 --unresolved-symbols=ignore-all
+# RUN: ld.lld %t1.o %t.so -o %t1_3 --allow-shlib-undefined --unresolved-symbols=ignore-all
# RUN: llvm-readobj %t1_3 > /dev/null 2>&1
## Ignoring undefines in objects should not produce error for symbol from object.
# RUN: ld.lld %t1.o %t2.o -o %t2 --unresolved-symbols=ignore-in-object-files
# RUN: llvm-readobj %t2 > /dev/null 2>&1
## And still should not should produce for undefines from DSOs.
-# RUN: ld.lld %t1.o %t.so -o /dev/null --unresolved-symbols=ignore-in-object-files
+# RUN: ld.lld %t1.o %t.so -o /dev/null --allow-shlib-undefined --unresolved-symbols=ignore-in-object-files
# RUN: llvm-readobj %t2 > /dev/null 2>&1
## Ignoring undefines in shared should produce error for symbol from object.
# RUN: not ld.lld %t2.o -o /dev/null --unresolved-symbols=ignore-in-shared-libs 2>&1 | \
# RUN: FileCheck -check-prefix=ERRUND %s
## And should not produce errors for symbols from DSO.
-# RUN: ld.lld %t1.o %t.so -o %t3_1 --unresolved-symbols=ignore-in-shared-libs
+# RUN: ld.lld %t1.o %t.so -o %t3_1 --allow-shlib-undefined --unresolved-symbols=ignore-in-shared-libs
# RUN: llvm-readobj %t3_1 > /dev/null 2>&1
## Ignoring undefines in shared libs should not produce error for symbol from object
diff --git a/test/ELF/verdef-defaultver.s b/test/ELF/verdef-defaultver.s
index c8444c4e0..db50e7c8f 100644
--- a/test/ELF/verdef-defaultver.s
+++ b/test/ELF/verdef-defaultver.s
@@ -8,7 +8,7 @@
# DSO: DynamicSymbols [
# DSO-NEXT: Symbol {
-# DSO-NEXT: Name: @
+# DSO-NEXT: Name:
# DSO-NEXT: Value: 0x0
# DSO-NEXT: Size: 0
# DSO-NEXT: Binding: Local
@@ -61,7 +61,7 @@
# DSO-NEXT: Symbols [
# DSO-NEXT: Symbol {
# DSO-NEXT: Version: 0
-# DSO-NEXT: Name: @
+# DSO-NEXT: Name:
# DSO-NEXT: }
# DSO-NEXT: Symbol {
# DSO-NEXT: Version: 2
@@ -112,7 +112,7 @@
# EXE: DynamicSymbols [
# EXE-NEXT: Symbol {
-# EXE-NEXT: Name: @
+# EXE-NEXT: Name:
# EXE-NEXT: Value: 0x0
# EXE-NEXT: Size: 0
# EXE-NEXT: Binding: Local
@@ -156,7 +156,7 @@
# EXE-NEXT: Symbols [
# EXE-NEXT: Symbol {
# EXE-NEXT: Version: 0
-# EXE-NEXT: Name: @
+# EXE-NEXT: Name:
# EXE-NEXT: }
# EXE-NEXT: Symbol {
# EXE-NEXT: Version: 2
diff --git a/test/ELF/verdef.s b/test/ELF/verdef.s
index b5d12ee38..9fc5bdd4f 100644
--- a/test/ELF/verdef.s
+++ b/test/ELF/verdef.s
@@ -14,7 +14,7 @@
# DSO-NEXT: Symbols [
# DSO-NEXT: Symbol {
# DSO-NEXT: Version: 0
-# DSO-NEXT: Name: @
+# DSO-NEXT: Name:
# DSO-NEXT: }
# DSO-NEXT: Symbol {
# DSO-NEXT: Version: 2
@@ -76,7 +76,7 @@
# MAIN-NEXT: Symbols [
# MAIN-NEXT: Symbol {
# MAIN-NEXT: Version: 0
-# MAIN-NEXT: Name: @
+# MAIN-NEXT: Name:
# MAIN-NEXT: }
# MAIN-NEXT: Symbol {
# MAIN-NEXT: Version: 2
diff --git a/test/ELF/verneed.s b/test/ELF/verneed.s
index 6e87f046e..e8b65c406 100644
--- a/test/ELF/verneed.s
+++ b/test/ELF/verneed.s
@@ -76,7 +76,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local (0x0)
@@ -125,7 +125,7 @@
# CHECK-NEXT: Symbols [
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 0
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 2
diff --git a/test/ELF/version-script-complex-wildcards.s b/test/ELF/version-script-complex-wildcards.s
index ce001d0b7..1ba347876 100644
--- a/test/ELF/version-script-complex-wildcards.s
+++ b/test/ELF/version-script-complex-wildcards.s
@@ -4,14 +4,14 @@
# RUN: echo "FOO { global: extern \"C++\" { ab[c]*; }; };" > %t.script
# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=ABC
-# ABC: Name: _Z3abbi@
+# ABC: Name: _Z3abbi
# ABC: Name: _Z3abci@@FOO
# RUN: echo "FOO { global: extern \"C++\" { ab[b]*; }; };" > %t1.script
# RUN: ld.lld --version-script %t1.script -shared %t.o -o %t1.so
# RUN: llvm-readobj -V %t1.so | FileCheck %s --check-prefix=ABB
# ABB: Name: _Z3abbi@@FOO
-# ABB: Name: _Z3abci@
+# ABB: Name: _Z3abci
# RUN: echo "FOO { global: extern \"C++\" { ab[a-b]*; }; };" > %t2.script
# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
@@ -34,8 +34,8 @@
# RUN: echo "FOO { global: extern \"C++\" { ab[^a-c]*; }; };" > %t6.script
# RUN: ld.lld --version-script %t6.script -shared %t.o -o %t6.so
# RUN: llvm-readobj -V %t6.so | FileCheck %s --check-prefix=NO
-# NO: Name: _Z3abbi@
-# NO: Name: _Z3abci@
+# NO: Name: _Z3abbi
+# NO: Name: _Z3abci
# RUN: echo "FOO { global: extern \"C++\" { ab[^c-z]*; }; };" > %t7.script
# RUN: ld.lld --version-script %t7.script -shared %t.o -o %t7.so
diff --git a/test/ELF/version-script-extern-undefined.s b/test/ELF/version-script-extern-undefined.s
index 518b122ce..8bff4050b 100644
--- a/test/ELF/version-script-extern-undefined.s
+++ b/test/ELF/version-script-extern-undefined.s
@@ -8,11 +8,11 @@
# CHECK: Symbols [
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 0
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 1
-# CHECK-NEXT: Name: _Z3abbi@
+# CHECK-NEXT: Name: _Z3abbi
# CHECK-NEXT: }
# CHECK-NEXT: ]
diff --git a/test/ELF/version-script-extern-wildcards.s b/test/ELF/version-script-extern-wildcards.s
index 472fc1f78..27660b25c 100644
--- a/test/ELF/version-script-extern-wildcards.s
+++ b/test/ELF/version-script-extern-wildcards.s
@@ -8,7 +8,7 @@
# CHECK: Version symbols {
# CHECK: Symbols [
-# CHECK: Name: _Z3bari@
+# CHECK: Name: _Z3bari
# CHECK: Name: _Z3fooi@@FOO
# CHECK: Name: _Z3zedi@@BAR
diff --git a/test/ELF/version-script-extern.s b/test/ELF/version-script-extern.s
index 16f400354..682afb09f 100644
--- a/test/ELF/version-script-extern.s
+++ b/test/ELF/version-script-extern.s
@@ -12,7 +12,7 @@
# DSO: DynamicSymbols [
# DSO-NEXT: Symbol {
-# DSO-NEXT: Name: @
+# DSO-NEXT: Name:
# DSO-NEXT: Value: 0x0
# DSO-NEXT: Size: 0
# DSO-NEXT: Binding: Local
@@ -74,7 +74,7 @@
# DSO-NEXT: Symbols [
# DSO-NEXT: Symbol {
# DSO-NEXT: Version: 0
-# DSO-NEXT: Name: @
+# DSO-NEXT: Name:
# DSO-NEXT: }
# DSO-NEXT: Symbol {
# DSO-NEXT: Version: 3
diff --git a/test/ELF/version-script-extern2.s b/test/ELF/version-script-extern2.s
index 834bbe112..245cb0076 100644
--- a/test/ELF/version-script-extern2.s
+++ b/test/ELF/version-script-extern2.s
@@ -8,7 +8,7 @@
# CHECK: Symbols [
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 0
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 2
diff --git a/test/ELF/version-script-hide-so-symbol.s b/test/ELF/version-script-hide-so-symbol.s
index b4f58be06..c84e37a5a 100644
--- a/test/ELF/version-script-hide-so-symbol.s
+++ b/test/ELF/version-script-hide-so-symbol.s
@@ -12,7 +12,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @ (0)
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local
diff --git a/test/ELF/version-script-locals-extern.s b/test/ELF/version-script-locals-extern.s
index 12e8771b8..ca1d7173e 100644
--- a/test/ELF/version-script-locals-extern.s
+++ b/test/ELF/version-script-locals-extern.s
@@ -7,11 +7,11 @@
# ABB: Symbols [
# ABB-NEXT: Symbol {
# ABB-NEXT: Version: 0
-# ABB-NEXT: Name: @
+# ABB-NEXT: Name:
# ABB-NEXT: }
# ABB-NEXT: Symbol {
# ABB-NEXT: Version: 1
-# ABB-NEXT: Name: _Z3abci@
+# ABB-NEXT: Name: _Z3abci
# ABB-NEXT: }
# ABB-NEXT: ]
@@ -26,11 +26,11 @@
# ABC: Symbols [
# ABC-NEXT: Symbol {
# ABC-NEXT: Version: 0
-# ABC-NEXT: Name: @
+# ABC-NEXT: Name:
# ABC-NEXT: }
# ABC-NEXT: Symbol {
# ABC-NEXT: Version: 1
-# ABC-NEXT: Name: _Z3abbi@
+# ABC-NEXT: Name: _Z3abbi
# ABC-NEXT: }
# ABC-NEXT: ]
diff --git a/test/ELF/version-script-symver2.s b/test/ELF/version-script-symver2.s
index 5961d9a7c..8441e1930 100644
--- a/test/ELF/version-script-symver2.s
+++ b/test/ELF/version-script-symver2.s
@@ -7,7 +7,7 @@
# CHECK: Symbols [
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 0
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Version: 3
diff --git a/test/ELF/version-script-weak.s b/test/ELF/version-script-weak.s
index cc3df8da5..887d6f94d 100644
--- a/test/ELF/version-script-weak.s
+++ b/test/ELF/version-script-weak.s
@@ -14,7 +14,7 @@
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK: Symbol {
-# CHECK: Name: foo@
+# CHECK: Name: foo
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Weak
diff --git a/test/ELF/version-script.s b/test/ELF/version-script.s
index 75083ac9a..5f2f3c44c 100644
--- a/test/ELF/version-script.s
+++ b/test/ELF/version-script.s
@@ -50,7 +50,7 @@
# DSO: DynamicSymbols [
# DSO-NEXT: Symbol {
-# DSO-NEXT: Name: @
+# DSO-NEXT: Name:
# DSO-NEXT: Value: 0x0
# DSO-NEXT: Size: 0
# DSO-NEXT: Binding: Local (0x0)
@@ -59,7 +59,7 @@
# DSO-NEXT: Section: Undefined (0x0)
# DSO-NEXT: }
# DSO-NEXT: Symbol {
-# DSO-NEXT: Name: bar@
+# DSO-NEXT: Name: bar
# DSO-NEXT: Value: 0x0
# DSO-NEXT: Size: 0
# DSO-NEXT: Binding: Global (0x1)
@@ -68,7 +68,7 @@
# DSO-NEXT: Section: Undefined (0x0)
# DSO-NEXT: }
# DSO-NEXT: Symbol {
-# DSO-NEXT: Name: foo1@
+# DSO-NEXT: Name: foo1
# DSO-NEXT: Value: 0x1000
# DSO-NEXT: Size: 0
# DSO-NEXT: Binding: Global (0x1)
@@ -77,7 +77,7 @@
# DSO-NEXT: Section: .text
# DSO-NEXT: }
# DSO-NEXT: Symbol {
-# DSO-NEXT: Name: foo3@
+# DSO-NEXT: Name: foo3
# DSO-NEXT: Value: 0x1007
# DSO-NEXT: Size: 0
# DSO-NEXT: Binding: Global (0x1)
@@ -89,7 +89,7 @@
# DSO2: DynamicSymbols [
# DSO2-NEXT: Symbol {
-# DSO2-NEXT: Name: @
+# DSO2-NEXT: Name:
# DSO2-NEXT: Value: 0x0
# DSO2-NEXT: Size: 0
# DSO2-NEXT: Binding: Local (0x0)
@@ -98,7 +98,7 @@
# DSO2-NEXT: Section: Undefined (0x0)
# DSO2-NEXT: }
# DSO2-NEXT: Symbol {
-# DSO2-NEXT: Name: bar@
+# DSO2-NEXT: Name: bar
# DSO2-NEXT: Value: 0x0
# DSO2-NEXT: Size: 0
# DSO2-NEXT: Binding: Global (0x1)
@@ -110,7 +110,7 @@
# VERDSO: DynamicSymbols [
# VERDSO-NEXT: Symbol {
-# VERDSO-NEXT: Name: @
+# VERDSO-NEXT: Name:
# VERDSO-NEXT: Value: 0x0
# VERDSO-NEXT: Size: 0
# VERDSO-NEXT: Binding: Local
@@ -119,7 +119,7 @@
# VERDSO-NEXT: Section: Undefined
# VERDSO-NEXT: }
# VERDSO-NEXT: Symbol {
-# VERDSO-NEXT: Name: bar@
+# VERDSO-NEXT: Name: bar
# VERDSO-NEXT: Value: 0x0
# VERDSO-NEXT: Size: 0
# VERDSO-NEXT: Binding: Global
@@ -158,7 +158,7 @@
# ALL: DynamicSymbols [
# ALL-NEXT: Symbol {
-# ALL-NEXT: Name: @
+# ALL-NEXT: Name:
# ALL-NEXT: Value: 0x0
# ALL-NEXT: Size: 0
# ALL-NEXT: Binding: Local
@@ -167,7 +167,7 @@
# ALL-NEXT: Section: Undefined
# ALL-NEXT: }
# ALL-NEXT: Symbol {
-# ALL-NEXT: Name: _start@
+# ALL-NEXT: Name: _start
# ALL-NEXT: Value:
# ALL-NEXT: Size: 0
# ALL-NEXT: Binding: Global
@@ -176,7 +176,7 @@
# ALL-NEXT: Section: .text
# ALL-NEXT: }
# ALL-NEXT: Symbol {
-# ALL-NEXT: Name: bar@
+# ALL-NEXT: Name: bar
# ALL-NEXT: Value:
# ALL-NEXT: Size: 0
# ALL-NEXT: Binding: Global
@@ -185,7 +185,7 @@
# ALL-NEXT: Section: Undefined
# ALL-NEXT: }
# ALL-NEXT: Symbol {
-# ALL-NEXT: Name: foo1@
+# ALL-NEXT: Name: foo1
# ALL-NEXT: Value:
# ALL-NEXT: Size: 0
# ALL-NEXT: Binding: Global
@@ -194,7 +194,7 @@
# ALL-NEXT: Section: .text
# ALL-NEXT: }
# ALL-NEXT: Symbol {
-# ALL-NEXT: Name: foo2@
+# ALL-NEXT: Name: foo2
# ALL-NEXT: Value:
# ALL-NEXT: Size: 0
# ALL-NEXT: Binding: Global
@@ -203,7 +203,7 @@
# ALL-NEXT: Section: .text
# ALL-NEXT: }
# ALL-NEXT: Symbol {
-# ALL-NEXT: Name: foo3@
+# ALL-NEXT: Name: foo3
# ALL-NEXT: Value:
# ALL-NEXT: Size: 0
# ALL-NEXT: Binding: Global
diff --git a/test/ELF/version-wildcard.test b/test/ELF/version-wildcard.test
index ac0b7edc6..f9a43319a 100644
--- a/test/ELF/version-wildcard.test
+++ b/test/ELF/version-wildcard.test
@@ -7,7 +7,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local
@@ -52,7 +52,7 @@
# MIX: DynamicSymbols [
# MIX-NEXT: Symbol {
-# MIX-NEXT: Name: @
+# MIX-NEXT: Name:
# MIX-NEXT: Value: 0x0
# MIX-NEXT: Size: 0
# MIX-NEXT: Binding: Local
diff --git a/test/ELF/visibility.s b/test/ELF/visibility.s
index 0582d718e..b9e9b5583 100644
--- a/test/ELF/visibility.s
+++ b/test/ELF/visibility.s
@@ -82,7 +82,7 @@
// CHECK: DynamicSymbols [
// CHECK-NEXT: Symbol {
-// CHECK-NEXT: Name: @
+// CHECK-NEXT: Name:
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
diff --git a/test/ELF/weak-undef-export.s b/test/ELF/weak-undef-export.s
index 164bc1730..561a0571a 100644
--- a/test/ELF/weak-undef-export.s
+++ b/test/ELF/weak-undef-export.s
@@ -8,7 +8,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @ (0)
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local (0x0)
@@ -17,7 +17,7 @@
# CHECK-NEXT: Section: Undefined (0x0)
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: foo@ (1)
+# CHECK-NEXT: Name: foo
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Weak (0x2)
diff --git a/test/ELF/weak-undef.s b/test/ELF/weak-undef.s
index 09c2a4c44..e7905c338 100644
--- a/test/ELF/weak-undef.s
+++ b/test/ELF/weak-undef.s
@@ -5,7 +5,7 @@
# CHECK: DynamicSymbols [
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: @
+# CHECK-NEXT: Name:
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Local (0x0)
@@ -14,7 +14,7 @@
# CHECK-NEXT: Section: Undefined (0x0)
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: foo@
+# CHECK-NEXT: Name: foo
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Weak
diff --git a/test/ELF/wrap-no-real.s b/test/ELF/wrap-no-real.s
index d6bda77c0..2dba291ac 100644
--- a/test/ELF/wrap-no-real.s
+++ b/test/ELF/wrap-no-real.s
@@ -18,8 +18,7 @@
// RUN: llvm-objdump -t %t | FileCheck -check-prefix=SYM %s
-// SYM: 0000000000000000 *UND* 00000000
-// SYM-NEXT: 0000000000202000 .dynamic 00000000 .hidden _DYNAMIC
+// SYM: 0000000000202000 .dynamic 00000000 .hidden _DYNAMIC
// SYM-NEXT: 0000000000011000 *ABS* 00000000 __real_foo
// SYM-NEXT: 0000000000011010 *ABS* 00000000 __wrap_foo
// SYM-NEXT: 0000000000201000 .text 00000000 _start
diff --git a/test/ELF/wrap-with-archive.s b/test/ELF/wrap-with-archive.s
new file mode 100644
index 000000000..1bfbdcef3
--- /dev/null
+++ b/test/ELF/wrap-with-archive.s
@@ -0,0 +1,13 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap-with-archive.s -o %t2
+// RUN: llvm-ar rcs %t3 %t2
+// RUN: ld.lld -o %t4 %t %t3 -wrap get_executable_start
+
+// Regression test for https://bugs.llvm.org/show_bug.cgi?id=40134
+
+.global get_executable_start
+.global _start
+
+_start:
+ jmp get_executable_start
diff --git a/test/ELF/x86-64-pcrel.s b/test/ELF/x86-64-pcrel.s
new file mode 100644
index 000000000..8129c9cab
--- /dev/null
+++ b/test/ELF/x86-64-pcrel.s
@@ -0,0 +1,23 @@
+// REQUIRES: x86
+
+// This is a test for R_X86_64_PC8 and R_X86_64_PC16.
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/x86-64-pcrel.s -o %t2.o
+// RUN: ld.lld -o %t.exe %t1.o %t2.o
+// RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+// CHECK: Contents of section .text:
+// CHECK-NEXT: 2000cccc cccccccc cccccccc cccccccc
+// CHECK-NEXT: 20cccccc cccccccc cccccccc cccccccc
+// CHECK-NEXT: e0ffcccc cccccccc cccccccc cccccccc
+// CHECK-NEXT: e0cccccc cccccccc cccccccc cccccccc
+
+.globl _start
+_start:
+
+.word foo - _start
+.fill 14,1,0xcc
+
+.byte foo - _start
+.fill 15,1,0xcc
diff --git a/test/ELF/x86-64-reloc-error2.s b/test/ELF/x86-64-reloc-error2.s
index 81f033f28..230241b2b 100644
--- a/test/ELF/x86-64-reloc-error2.s
+++ b/test/ELF/x86-64-reloc-error2.s
@@ -4,7 +4,7 @@
## Check we are able to find a function symbol that encloses
## a given location when reporting error messages.
-# CHECK: {{.*}}.o:(function func): relocation R_X86_64_32S out of range: -281474974609408 is not in [-2147483648, 2147483647]
+# CHECK: {{.*}}.o:(function func: .text.func+0x3): relocation R_X86_64_32S out of range: -281474974609408 is not in [-2147483648, 2147483647]
# This mergeable section will be garbage collected. We had a crash issue in that case. Test it.
.section .rodata.str1,"aMS",@progbits,1
diff --git a/test/ELF/x86-64-reloc-range-debug-loc.s b/test/ELF/x86-64-reloc-range-debug-loc.s
index 8be4df3c5..08a49607e 100644
--- a/test/ELF/x86-64-reloc-range-debug-loc.s
+++ b/test/ELF/x86-64-reloc-range-debug-loc.s
@@ -5,7 +5,7 @@
## Check we are able to report file and location from debug information
## when reporting such kind of errors.
-# CHECK: error: test.s:3: relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295]
+# CHECK: error: test.s:3:(.text+0x1): relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295]
.section .text,"ax",@progbits
foo:
diff --git a/test/ELF/x86-64-retpoline-znow-static-iplt.s b/test/ELF/x86-64-retpoline-znow-static-iplt.s
index 0321f6e4a..70355c05e 100644
--- a/test/ELF/x86-64-retpoline-znow-static-iplt.s
+++ b/test/ELF/x86-64-retpoline-znow-static-iplt.s
@@ -8,7 +8,7 @@
# CHECK-NEXT: 201001: callq 42
#Static IPLT header due to -z retpolineplt
-# CHECK: {{^}}.plt:
+# CHECK: 0000000000201010 .plt:
# CHECK-NEXT: 201010: callq 11 <.plt+0x10>
# CHECK-NEXT: 201015: pause
# CHECK-NEXT: 201017: lfence
diff --git a/test/ELF/x86-64-static-tls-model.s b/test/ELF/x86-64-static-tls-model.s
new file mode 100644
index 000000000..9781d795e
--- /dev/null
+++ b/test/ELF/x86-64-static-tls-model.s
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+
+## In this test R_X86_64_GOTTPOFF is a IE relocation (static TLS model),
+## test check we add STATIC_TLS flag.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t1 -shared
+# RUN: llvm-readobj -dynamic-table %t1 | FileCheck %s
+
+# CHECK: DynamicSection [
+# CHECK: FLAGS STATIC_TLS
+
+.section ".tdata", "awT", @progbits
+.globl var
+var:
+
+movq var@GOTTPOFF(%rip), %rax # R_X86_64_GOTTPOFF
+movl %fs:0(%rax), %eax
diff --git a/test/MinGW/driver.test b/test/MinGW/driver.test
index 3222bb111..f944994bb 100644
--- a/test/MinGW/driver.test
+++ b/test/MinGW/driver.test
@@ -151,3 +151,9 @@ REQUIRE-DEFINED: -include:_foo -include:_bar -include:_baz -include:_foo2
RUN: ld.lld -### -m i386pep foo.o -Llibpath | FileCheck -check-prefix LIBPATH %s
LIBPATH: -libpath:libpath
+
+RUN: ld.lld -### -m i386pep foo.o --no-insert-timestamp | FileCheck -check-prefix NOTIMESTAMP %s
+RUN: ld.lld -### -m i386pep foo.o --insert-timestamp --no-insert-timestamp | FileCheck -check-prefix NOTIMESTAMP %s
+NOTIMESTAMP: -timestamp:0
+RUN: ld.lld -### -m i386pep foo.o --no-insert-timestamp --insert-timestamp | FileCheck -check-prefix TIMESTAMP %s
+TIMESTAMP-NOT: -timestamp:0
diff --git a/test/lit.cfg.py b/test/lit.cfg.py
index 9989a1cc9..350b40a10 100644
--- a/test/lit.cfg.py
+++ b/test/lit.cfg.py
@@ -45,13 +45,18 @@ tool_patterns = [
llvm_config.add_tool_substitutions(tool_patterns)
+# LLD tests tend to be flaky on NetBSD, so add some retries.
+# We don't do this on other platforms because it's slower.
+if platform.system() in ['NetBSD']:
+ config.test_retry_attempts = 2
+
# When running under valgrind, we mangle '-vg' onto the end of the triple so we
# can check it with XFAIL and XTARGET.
if lit_config.useValgrind:
config.target_triple += '-vg'
# Running on ELF based *nix
-if platform.system() in ['FreeBSD', 'Linux']:
+if platform.system() in ['FreeBSD', 'NetBSD', 'Linux']:
config.available_features.add('system-linker-elf')
# Set if host-cxxabi's demangler can handle target's symbols.
@@ -67,6 +72,7 @@ llvm_config.feature_config(
'AVR': 'avr',
'Hexagon': 'hexagon',
'Mips': 'mips',
+ 'MSP430': 'msp430',
'PowerPC': 'ppc',
'RISCV': 'riscv',
'Sparc': 'sparc',
@@ -81,11 +87,11 @@ config.environment['LLD_IN_TEST'] = '1'
# Indirectly check if the mt.exe Microsoft utility exists by searching for
# cvtres, which always accompanies it. Alternatively, check if we can use
# libxml2 to merge manifests.
-if (lit.util.which('cvtres', config.environment['PATH'])) or \
- (config.llvm_libxml2_enabled == '1'):
+if (lit.util.which('cvtres', config.environment['PATH']) or
+ config.llvm_libxml2_enabled):
config.available_features.add('manifest_tool')
-if (config.llvm_libxml2_enabled == '1'):
+if config.llvm_libxml2_enabled:
config.available_features.add('libxml2')
if config.have_dia_sdk:
diff --git a/test/lit.site.cfg.py.in b/test/lit.site.cfg.py.in
index 7475ac7ea..07ffc2303 100644
--- a/test/lit.site.cfg.py.in
+++ b/test/lit.site.cfg.py.in
@@ -7,7 +7,7 @@ config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
-config.llvm_libxml2_enabled = "@LLVM_LIBXML2_ENABLED@"
+config.llvm_libxml2_enabled = @LLVM_LIBXML2_ENABLED@
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
config.lld_obj_root = "@LLD_BINARY_DIR@"
config.lld_libs_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@"
diff --git a/test/wasm/Inputs/globals.yaml b/test/wasm/Inputs/globals.yaml
index c08a3044e..6f6322627 100644
--- a/test/wasm/Inputs/globals.yaml
+++ b/test/wasm/Inputs/globals.yaml
@@ -29,12 +29,12 @@ Sections:
Locals:
Body: 2381808080000B
Relocations:
- - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+ - Type: R_WASM_GLOBAL_INDEX_LEB
Index: 1
Offset: 0x00000004
- Type: CUSTOM
Name: linking
- Version: 1
+ Version: 2
SymbolTable:
- Index: 0
Kind: GLOBAL
diff --git a/test/wasm/Inputs/undefined-globals.yaml b/test/wasm/Inputs/undefined-globals.yaml
index 440a538d6..fd5a2361c 100644
--- a/test/wasm/Inputs/undefined-globals.yaml
+++ b/test/wasm/Inputs/undefined-globals.yaml
@@ -27,12 +27,12 @@ Sections:
Locals:
Body: 2381808080000B
Relocations:
- - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+ - Type: R_WASM_GLOBAL_INDEX_LEB
Index: 1
Offset: 0x00000004
- Type: CUSTOM
Name: linking
- Version: 1
+ Version: 2
SymbolTable:
- Index: 0
Kind: GLOBAL
diff --git a/test/wasm/alias.ll b/test/wasm/alias.ll
index d91f4b10d..358582ea1 100644
--- a/test/wasm/alias.ll
+++ b/test/wasm/alias.ll
@@ -25,7 +25,7 @@ entry:
; CHECK-NEXT: FunctionTypes: [ 0, 0 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000001
diff --git a/test/wasm/archive-weak-undefined.ll b/test/wasm/archive-weak-undefined.ll
new file mode 100644
index 000000000..0285724e5
--- /dev/null
+++ b/test/wasm/archive-weak-undefined.ll
@@ -0,0 +1,19 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: llc -filetype=obj %S/Inputs/ret32.ll -o %t.a1.o
+; RUN: rm -f %t.a
+; RUN: llvm-ar rcs %t.a %t.a1.o
+; RUN: wasm-ld %t.o %t.a -o %t.wasm
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+declare extern_weak i32 @ret32()
+
+define void @_start() {
+entry:
+ %call1 = call i32 @ret32()
+ ret void
+}
+
+; CHECK: Name: 'undefined:ret32'
+; CHECK-NOT: Name: ret32
diff --git a/test/wasm/archive.ll b/test/wasm/archive.ll
index beea2725c..f2eee96a6 100644
--- a/test/wasm/archive.ll
+++ b/test/wasm/archive.ll
@@ -33,10 +33,10 @@ entry:
; TODO(ncw): Update LLD so that the symbol table is written out for
; non-relocatable output (with an option to strip it)
-; CHECK: 00000004 T _start
-; CHECK-NEXT: 00000002 T archive2_symbol
+; CHECK: 00000016 T _start
+; CHECK-NEXT: 0000000a T archive2_symbol
; CHECK-NEXT: 00000001 T bar
-; CHECK-NEXT: 00000003 T foo
+; CHECK-NEXT: 0000000d T foo
; CHECK-NEXT: U missing_func
; Verify that symbols from unused objects don't appear in the symbol table
diff --git a/test/wasm/call-indirect.ll b/test/wasm/call-indirect.ll
index 1b9e1723f..7f8fe474f 100644
--- a/test/wasm/call-indirect.ll
+++ b/test/wasm/call-indirect.ll
@@ -60,7 +60,7 @@ define void @call_ptr(i64 (i64)* %arg) {
; CHECK-NEXT: FunctionTypes: [ 3, 0, 3, 1, 3, 4 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000003
diff --git a/test/wasm/cxx-mangling.ll b/test/wasm/cxx-mangling.ll
index e1f4ea495..9732d21dd 100644
--- a/test/wasm/cxx-mangling.ll
+++ b/test/wasm/cxx-mangling.ll
@@ -58,8 +58,8 @@ define void @_start() {
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __wasm_call_ctors
; CHECK-NEXT: - Index: 1
-; DEMANGLE-NEXT: Name: 'undefined function bar(int)'
-; MANGLE-NEXT: Name: undefined function _Z3bari
+; DEMANGLE-NEXT: Name: 'undefined:bar(int)'
+; MANGLE-NEXT: Name: 'undefined:_Z3bari'
; CHECK-NEXT: - Index: 2
; DEMANGLE-NEXT: Name: 'foo(int)'
; MANGLE-NEXT: Name: _Z3fooi
diff --git a/test/wasm/data-layout.ll b/test/wasm/data-layout.ll
index b01c13ac9..2edbec661 100644
--- a/test/wasm/data-layout.ll
+++ b/test/wasm/data-layout.ll
@@ -84,11 +84,11 @@ 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: Offset: 0x00000018
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
+; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
; RELOC-NEXT: Index: 3
+; RELOC-NEXT: Offset: 0x00000018
+; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
+; 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/export-table.test b/test/wasm/export-table.test
index 58775b928..e2d05f00d 100644
--- a/test/wasm/export-table.test
+++ b/test/wasm/export-table.test
@@ -6,7 +6,7 @@
# CHECK: - Type: TABLE
# CHECK-NEXT: Tables:
-# CHECK-NEXT: - ElemType: ANYFUNC
+# CHECK-NEXT: - ElemType: FUNCREF
# CHECK-NEXT: Limits:
# CHECK-NEXT: Flags: [ HAS_MAX ]
# CHECK-NEXT: Initial: 0x00000001
diff --git a/test/wasm/export.ll b/test/wasm/export.ll
index 519aafebb..48b66ee10 100644
--- a/test/wasm/export.ll
+++ b/test/wasm/export.ll
@@ -3,13 +3,29 @@
; RUN: wasm-ld --export=hidden_function -o %t.wasm %t.o
; RUN: obj2yaml %t.wasm | FileCheck %s
+@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @used_function to i8*)], section "llvm.metadata"
+
target triple = "wasm32-unknown-unknown"
+; Not exported by default, but forced via commandline
define hidden i32 @hidden_function() local_unnamed_addr {
entry:
ret i32 0
}
+; Not exported by default
+define i32 @default_function() local_unnamed_addr {
+entry:
+ ret i32 0
+}
+
+; Exported because its part of llvm.used
+define i32 @used_function() local_unnamed_addr {
+entry:
+ ret i32 0
+}
+
+; Exported by default
define void @_start() local_unnamed_addr {
entry:
ret void
@@ -17,6 +33,8 @@ entry:
; CHECK-ERROR: error: symbol exported via --export not found: missing
+; CHECK-NOT: - Name: default_function
+
; CHECK: - Type: EXPORT
; CHECK-NEXT: Exports:
; CHECK-NEXT: - Name: memory
@@ -31,7 +49,10 @@ entry:
; CHECK-NEXT: - Name: hidden_function
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: _start
+; CHECK-NEXT: - Name: used_function
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 2
+; CHECK-NEXT: - Name: _start
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 3
; CHECK-NEXT: - Type: CODE
diff --git a/test/wasm/fatal-warnings.ll b/test/wasm/fatal-warnings.ll
index 0007dc203..d338420ef 100644
--- a/test/wasm/fatal-warnings.ll
+++ b/test/wasm/fatal-warnings.ll
@@ -1,7 +1,7 @@
; RUN: llc -filetype=obj %s -o %t.main.o
; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
-; RUN: lld -flavor wasm -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-WARN
-; RUN: not lld -flavor wasm --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-FATAL
+; RUN: wasm-ld -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-WARN
+; RUN: not wasm-ld --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-FATAL
; CHECK-WARN: warning: function signature mismatch: ret32
; CHECK-FATAL: error: function signature mismatch: ret32
diff --git a/test/wasm/import-module.ll b/test/wasm/import-module.ll
new file mode 100644
index 000000000..9a473194c
--- /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 000000000..a3953d335
--- /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/import-table.test b/test/wasm/import-table.test
index ae4231139..440509b34 100644
--- a/test/wasm/import-table.test
+++ b/test/wasm/import-table.test
@@ -10,7 +10,7 @@
# CHECK-NEXT: Field: __indirect_function_table
# CHECK-NEXT: Kind: TABLE
# CHECK-NEXT: Table:
-# CHECK-NEXT: ElemType: ANYFUNC
+# CHECK-NEXT: ElemType: FUNCREF
# CHECK-NEXT: Limits:
# CHECK-NEXT: Initial: 0x00000001
diff --git a/test/wasm/init-fini.ll b/test/wasm/init-fini.ll
index 9a7f5357e..b17020b17 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/local-symbols.ll b/test/wasm/local-symbols.ll
index 6d1a324b1..dd92b4ec9 100644
--- a/test/wasm/local-symbols.ll
+++ b/test/wasm/local-symbols.ll
@@ -36,7 +36,7 @@ entry:
; CHECK-NEXT: FunctionTypes: [ 0, 1, 0 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000001
diff --git a/test/wasm/locals-duplicate.test b/test/wasm/locals-duplicate.test
index 8da0b22d1..34a5cadd7 100644
--- a/test/wasm/locals-duplicate.test
+++ b/test/wasm/locals-duplicate.test
@@ -20,7 +20,7 @@
; CHECK-NEXT: 1, 1, 1 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000007
@@ -253,7 +253,7 @@
; RELOC-NEXT: 0, 0 ]
; RELOC-NEXT: - Type: TABLE
; RELOC-NEXT: Tables:
-; RELOC-NEXT: - ElemType: ANYFUNC
+; RELOC-NEXT: - ElemType: FUNCREF
; RELOC-NEXT: Limits:
; RELOC-NEXT: Flags: [ HAS_MAX ]
; RELOC-NEXT: Initial: 0x00000007
@@ -269,41 +269,41 @@
; 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: 4
+; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 18
; RELOC-NEXT: Offset: 0x00000013
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 6
+; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 3
; RELOC-NEXT: Offset: 0x0000001C
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 8
+; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 19
; RELOC-NEXT: Offset: 0x00000025
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 0
+; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 16
; RELOC-NEXT: Offset: 0x0000002E
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 1
+; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 0
; RELOC-NEXT: Offset: 0x00000037
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 2
+; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 17
; RELOC-NEXT: Offset: 0x00000040
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 16
+; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 10
; RELOC-NEXT: Offset: 0x00000058
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 18
+; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 22
; RELOC-NEXT: Offset: 0x00000061
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
-; RELOC-NEXT: Index: 20
+; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
+; RELOC-NEXT: Index: 23
; RELOC-NEXT: Offset: 0x0000006A
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 12
+; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 8
; RELOC-NEXT: Offset: 0x00000073
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 13
+; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 20
; RELOC-NEXT: Offset: 0x0000007C
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 14
+; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 21
; RELOC-NEXT: Offset: 0x00000085
; RELOC-NEXT: Functions:
; RELOC-NEXT: - Index: 0
@@ -382,149 +382,149 @@
; RELOC-NEXT: Content: '0000000000000000'
; RELOC-NEXT: - Type: CUSTOM
; RELOC-NEXT: Name: linking
-; RELOC-NEXT: Version: 1
+; RELOC-NEXT: Version: 2
; 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
-; RELOC-NEXT: Alignment: 4
+; RELOC-NEXT: Alignment: 2
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: - Index: 1
; RELOC-NEXT: Name: .bss.colliding_global2
-; RELOC-NEXT: Alignment: 4
+; RELOC-NEXT: Alignment: 2
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: - Index: 2
; RELOC-NEXT: Name: .bss.colliding_global3
-; RELOC-NEXT: Alignment: 4
+; RELOC-NEXT: Alignment: 2
; RELOC-NEXT: Flags: [ ]
; RELOC-NEXT: - Type: CUSTOM
; RELOC-NEXT: Name: name
diff --git a/test/wasm/lto/opt-level.ll b/test/wasm/lto/opt-level.ll
index b7e6a4cdc..f6156e725 100644
--- a/test/wasm/lto/opt-level.ll
+++ b/test/wasm/lto/opt-level.ll
@@ -7,11 +7,11 @@
; RUN: obj2yaml %t2a | FileCheck --check-prefix=CHECK-O2 %s
; Reject invalid optimization levels.
-; RUN: not ld.lld -o %t3 -e main --lto-O6 %t.o 2>&1 | \
+; RUN: not wasm-ld -o %t3 -e main --lto-O6 %t.o 2>&1 | \
; RUN: FileCheck --check-prefix=INVALID %s
; INVALID: invalid optimization level for LTO: 6
-; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \
+; RUN: not wasm-ld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \
; RUN: FileCheck --check-prefix=INVALIDNEGATIVE %s
; INVALIDNEGATIVE: invalid optimization level for LTO: 4294967295
diff --git a/test/wasm/lto/relocatable-undefined.ll b/test/wasm/lto/relocatable-undefined.ll
new file mode 100644
index 000000000..b9780ee03
--- /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/lto/weak-undefined.ll b/test/wasm/lto/weak-undefined.ll
new file mode 100644
index 000000000..5eb405afa
--- /dev/null
+++ b/test/wasm/lto/weak-undefined.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: wasm-ld %t.o -o %t.wasm
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; Test that undefined weak external functions are handled in the LTO case
+; We had a bug where stub function generation was failing because functions
+; that are in bitcode (pre-LTO) don't have signatures assigned.
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+declare extern_weak i32 @foo()
+
+define void @_start() #0 {
+entry:
+ %call2 = call i32 @foo()
+ ret void
+}
+
+; CHECK: Name: 'undefined:foo'
diff --git a/test/wasm/lto/weak.ll b/test/wasm/lto/weak.ll
index 03a017c1a..61705d0f4 100644
--- a/test/wasm/lto/weak.ll
+++ b/test/wasm/lto/weak.ll
@@ -12,5 +12,8 @@ define weak void @f() {
; CHECK: Symbol {
; CHECK-NEXT: Name: f
; CHECK-NEXT: Type: FUNCTION (0x0)
-; CHECK-NEXT: Flags: 0x1
+; CHECK-NEXT: Flags [ (0x1)
+; CHECK-NEXT: BINDING_WEAK (0x1)
+; CHECK-NEXT: ]
+; CHECK-NEXT: ElementIndex: 0x0
; CHECK-NEXT: }
diff --git a/test/wasm/many-functions.ll b/test/wasm/many-functions.ll
index 02ad9aab5..2e1bbafcd 100644
--- a/test/wasm/many-functions.ll
+++ b/test/wasm/many-functions.ll
@@ -18,394 +18,394 @@ entry:
; CHECK: - Type: CODE
; CHECK-NEXT: Relocations:
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000008
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000014
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000020
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000002C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000038
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000044
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000050
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000005C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000068
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000074
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000080
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000008C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000098
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000000A4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000000B0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000000BC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000000C8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000000D4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000000E0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000000EC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000000F8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000104
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000110
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000011C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000128
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000134
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000140
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000014C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000158
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000164
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000170
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000017C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000188
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000194
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000001A0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000001AC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000001B8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000001C4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000001D0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000001DC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000001E8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000001F4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000200
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000020C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000218
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000224
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000230
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000023C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000248
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000254
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000260
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000026C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000278
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000284
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000290
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000029C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000002A8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000002B4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000002C0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000002CC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000002D8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000002E4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000002F0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000002FC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000308
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000314
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000320
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000032C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000338
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000344
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000350
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000035C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000368
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000374
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000380
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000038C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000398
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000003A4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000003B0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000003BC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000003C8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000003D4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000003E0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000003EC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000003F8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000404
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000410
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000041C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000428
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000434
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000440
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000044C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000458
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000464
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000470
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000047C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000488
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000494
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000004A0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000004AC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000004B8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000004C4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000004D0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000004DC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000004E8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000004F4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000500
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000050C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000518
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000524
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000530
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000053C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000548
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000554
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000560
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000056C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000578
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000584
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000590
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x0000059C
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000005A8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000005B4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000005C0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000005CC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000005D8
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000005E4
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x000005F0
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 129
; CHECK-NEXT: Offset: 0x000005FC
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
; CHECK-NEXT: Index: 129
; CHECK-NEXT: Offset: 0x00000608
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
; CHECK-NEXT: Index: 131
; CHECK-NEXT: Offset: 0x00000611
; CHECK-NEXT: Functions:
@@ -815,7 +815,7 @@ entry:
; CHECK-NEXT: Content: '01000000'
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
-; CHECK-NEXT: Version: 1
+; CHECK-NEXT: Version: 2
; CHECK-NEXT: SymbolTable:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Kind: FUNCTION
@@ -1482,9 +1482,9 @@ entry:
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .data.g0
-; CHECK-NEXT: Alignment: 4
+; CHECK-NEXT: Alignment: 2
; CHECK-NEXT: Flags: [ ]
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Name: .data.foo
-; CHECK-NEXT: Alignment: 4
+; CHECK-NEXT: Alignment: 2
; CHECK-NEXT: Flags: [ ]
diff --git a/test/wasm/reloc-addend.ll b/test/wasm/reloc-addend.ll
index f678a3d4b..fc00b8ebc 100644
--- a/test/wasm/reloc-addend.ll
+++ b/test/wasm/reloc-addend.ll
@@ -13,7 +13,7 @@ target triple = "wasm32-unknown-unknown"
; CHECK: - Type: DATA
; CHECK-NEXT: Relocations:
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
; CHECK-NEXT: Index: 0
; CHECK-NEXT: Offset: 0x0000013D
; CHECK-NEXT: Addend: 64
diff --git a/test/wasm/relocatable.ll b/test/wasm/relocatable.ll
index 4e8a887f3..ab2d37b3c 100644
--- a/test/wasm/relocatable.ll
+++ b/test/wasm/relocatable.ll
@@ -63,7 +63,7 @@ entry:
; CHECK-NEXT: FunctionTypes: [ 2, 1, 1 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000004
@@ -79,19 +79,19 @@ entry:
; CHECK-NEXT: Functions: [ 4, 1, 2 ]
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Relocations:
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000004
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
; CHECK-NEXT: Index: 2
; CHECK-NEXT: Offset: 0x0000000A
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
; CHECK-NEXT: Index: 4
; CHECK-NEXT: Offset: 0x00000013
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
; CHECK-NEXT: Index: 5
; CHECK-NEXT: Offset: 0x0000001A
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
; CHECK-NEXT: Index: 7
; CHECK-NEXT: Offset: 0x00000026
; CHECK-NEXT: Functions:
@@ -106,16 +106,16 @@ entry:
; CHECK-NEXT: Body: 419C808080000B
; CHECK-NEXT: - Type: DATA
; CHECK-NEXT: Relocations:
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
+; CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_I32
; CHECK-NEXT: Index: 3
; CHECK-NEXT: Offset: 0x00000012
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
+; CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_I32
; CHECK-NEXT: Index: 4
; CHECK-NEXT: Offset: 0x0000001B
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
+; CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_I32
; CHECK-NEXT: Index: 5
; CHECK-NEXT: Offset: 0x00000024
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
+; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
; CHECK-NEXT: Index: 12
; CHECK-NEXT: Offset: 0x0000002D
; CHECK-NEXT: Segments:
@@ -157,7 +157,7 @@ entry:
; CHECK-NEXT: Content: '616263'
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
-; CHECK-NEXT: Version: 1
+; CHECK-NEXT: Version: 2
; CHECK-NEXT: SymbolTable:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Kind: FUNCTION
@@ -232,27 +232,27 @@ entry:
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .rodata.hello_str
-; CHECK-NEXT: Alignment: 1
+; CHECK-NEXT: Alignment: 0
; CHECK-NEXT: Flags: [ ]
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Name: .data.func_addr1
-; CHECK-NEXT: Alignment: 4
+; CHECK-NEXT: Alignment: 2
; CHECK-NEXT: Flags: [ ]
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Name: .data.func_addr2
-; CHECK-NEXT: Alignment: 4
+; CHECK-NEXT: Alignment: 2
; CHECK-NEXT: Flags: [ ]
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Name: .data.func_addr3
-; CHECK-NEXT: Alignment: 4
+; CHECK-NEXT: Alignment: 2
; CHECK-NEXT: Flags: [ ]
; CHECK-NEXT: - Index: 4
; CHECK-NEXT: Name: .data.data_addr1
-; CHECK-NEXT: Alignment: 8
+; CHECK-NEXT: Alignment: 3
; CHECK-NEXT: Flags: [ ]
; CHECK-NEXT: - Index: 5
; CHECK-NEXT: Name: .rodata.data_comdat
-; CHECK-NEXT: Alignment: 1
+; CHECK-NEXT: Alignment: 0
; CHECK-NEXT: Flags: [ ]
; CHECK-NEXT: Comdats:
; CHECK-NEXT: - Name: func_comdat
diff --git a/test/wasm/shared.ll b/test/wasm/shared.ll
index 088c65084..f3abd1172 100644
--- a/test/wasm/shared.ll
+++ b/test/wasm/shared.ll
@@ -42,7 +42,7 @@ declare void @func_external()
; CHECK-NEXT: Field: __indirect_function_table
; CHECK-NEXT: Kind: TABLE
; CHECK-NEXT: Table:
-; CHECK-NEXT: ElemType: ANYFUNC
+; CHECK-NEXT: ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Initial: 0x00000002
; CHECK-NEXT: - Module: env
@@ -66,7 +66,7 @@ declare void @func_external()
; CHECK: - Type: ELEM
; CHECK-NEXT: Segments:
; CHECK-NEXT: - Offset:
-; CHECK-NEXT: Opcode: GET_GLOBAL
+; CHECK-NEXT: Opcode: GLOBAL_GET
; CHECK-NEXT: Index: 2
; CHECK-NEXT: Functions: [ 2, 0 ]
@@ -77,6 +77,6 @@ declare void @func_external()
; CHECK-NEXT: - SectionOffset: 6
; CHECK-NEXT: MemoryIndex: 0
; CHECK-NEXT: Offset:
-; CHECK-NEXT: Opcode: GET_GLOBAL
+; CHECK-NEXT: Opcode: GLOBAL_GET
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Content: '0000000001000000'
diff --git a/test/wasm/stack-pointer.ll b/test/wasm/stack-pointer.ll
index 888c93888..30501baf8 100644
--- a/test/wasm/stack-pointer.ll
+++ b/test/wasm/stack-pointer.ll
@@ -31,7 +31,7 @@ entry:
; CHECK-NEXT: FunctionTypes: [ 0 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000001
@@ -41,7 +41,7 @@ entry:
; CHECK-NEXT: - Initial: 0x00000000
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Relocations:
-; CHECK-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; CHECK-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000004
; CHECK-NEXT: Functions:
@@ -50,7 +50,7 @@ entry:
; CHECK-NEXT: Body: 23808080800041106B1A41000B
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
-; CHECK-NEXT: Version: 1
+; CHECK-NEXT: Version: 2
; CHECK-NEXT: SymbolTable:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Kind: FUNCTION
diff --git a/test/wasm/trace-symbol.ll b/test/wasm/trace-symbol.ll
new file mode 100644
index 000000000..649b425f4
--- /dev/null
+++ b/test/wasm/trace-symbol.ll
@@ -0,0 +1,23 @@
+; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
+; RUN: llc -filetype=obj -o %t.o %s
+; RUN: wasm-ld -o %t.wasm %t.o %t.ret32.o -y ret32 -y _start 2>&1 | FileCheck %s -check-prefix=BOTH
+
+; check alias
+; RUN: wasm-ld -o %t.wasm %t.o %t.ret32.o -trace-symbol=_start 2>&1 | FileCheck %s -check-prefixes=JUST-START
+
+target triple = "wasm32-unknown-unknown"
+
+declare i32 @ret32(float %arg)
+
+define void @_start() {
+entry:
+ %call1 = call i32 @ret32(float 0.0)
+ ret void
+}
+
+; BOTH: .o: definition of _start
+; BOTH: .o: reference to ret32
+; BOTH: .ret32.o: definition of ret32
+
+; JUST-START: .o: definition of _start
+; JUST-START-NOT: ret32
diff --git a/test/wasm/trace.test b/test/wasm/trace.test
new file mode 100644
index 000000000..023a2ccb2
--- /dev/null
+++ b/test/wasm/trace.test
@@ -0,0 +1,8 @@
+RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.foo.o
+
+# Check -t
+RUN: wasm-ld %t.foo.o -o %t.t.out.wasm -t 2>&1 | FileCheck %s
+CHECK: {{.*}}.foo.o
+
+# Check --trace alias
+RUN: wasm-ld %t.foo.o -o %t.trace.out.wasm --trace 2>&1 | FileCheck %s
diff --git a/test/wasm/undefined-weak-call.ll b/test/wasm/undefined-weak-call.ll
index 920379e8d..9f1c39bc2 100644
--- a/test/wasm/undefined-weak-call.ll
+++ b/test/wasm/undefined-weak-call.ll
@@ -45,7 +45,7 @@ define i32 @callWeakFuncs() {
; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 1, 2 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000001
@@ -110,11 +110,11 @@ define i32 @callWeakFuncs() {
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: __wasm_call_ctors
; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: Name: undefined function weakFunc1
+; CHECK-NEXT: Name: 'undefined:weakFunc1'
; CHECK-NEXT: - Index: 2
-; CHECK-NEXT: Name: undefined function weakFunc2
+; CHECK-NEXT: Name: 'undefined:weakFunc2'
; CHECK-NEXT: - Index: 3
-; CHECK-NEXT: Name: undefined function weakFunc3
+; CHECK-NEXT: Name: 'undefined:weakFunc3'
; CHECK-NEXT: - Index: 4
; CHECK-NEXT: Name: callWeakFuncs
; CHECK-NEXT: ...
diff --git a/test/wasm/weak-alias-overide.ll b/test/wasm/weak-alias-overide.ll
index 496900b23..7fefad0fb 100644
--- a/test/wasm/weak-alias-overide.ll
+++ b/test/wasm/weak-alias-overide.ll
@@ -35,7 +35,7 @@ entry:
; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 1, 1, 1, 1, 1 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000003
diff --git a/test/wasm/weak-alias.ll b/test/wasm/weak-alias.ll
index 49f288503..45d529444 100644
--- a/test/wasm/weak-alias.ll
+++ b/test/wasm/weak-alias.ll
@@ -32,7 +32,7 @@ entry:
; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1, 1, 1 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000002
@@ -170,7 +170,7 @@ entry:
; RELOC-NEXT: FunctionTypes: [ 0, 1, 1, 1, 1, 1 ]
; RELOC-NEXT: - Type: TABLE
; RELOC-NEXT: Tables:
-; RELOC-NEXT: - ElemType: ANYFUNC
+; RELOC-NEXT: - ElemType: FUNCREF
; RELOC-NEXT: Limits:
; RELOC-NEXT: Flags: [ HAS_MAX ]
; RELOC-NEXT: Initial: 0x00000002
@@ -186,43 +186,43 @@ entry:
; RELOC-NEXT: Functions: [ 1 ]
; RELOC-NEXT: - Type: CODE
; RELOC-NEXT: Relocations:
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT: Index: 4
-; RELOC-NEXT: Offset: 0x00000004
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; RELOC-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
; RELOC-NEXT: Index: 1
+; RELOC-NEXT: Offset: 0x00000004
+; RELOC-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
+; RELOC-NEXT: Index: 2
; RELOC-NEXT: Offset: 0x00000013
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT: Index: 4
+; RELOC-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
+; RELOC-NEXT: Index: 1
; RELOC-NEXT: Offset: 0x0000001C
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
; RELOC-NEXT: Index: 6
; RELOC-NEXT: Offset: 0x00000027
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
; RELOC-NEXT: Index: 6
; RELOC-NEXT: Offset: 0x00000032
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 4
+; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 1
; RELOC-NEXT: Offset: 0x0000003A
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT: Index: 4
+; RELOC-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
+; RELOC-NEXT: Index: 1
; RELOC-NEXT: Offset: 0x00000043
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
; RELOC-NEXT: Index: 6
; RELOC-NEXT: Offset: 0x00000050
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
; RELOC-NEXT: Index: 6
; RELOC-NEXT: Offset: 0x0000005D
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
; RELOC-NEXT: Index: 6
; RELOC-NEXT: Offset: 0x00000068
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
-; RELOC-NEXT: Index: 1
+; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
+; RELOC-NEXT: Index: 2
; RELOC-NEXT: Offset: 0x00000070
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
-; RELOC-NEXT: Index: 1
+; RELOC-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
+; RELOC-NEXT: Index: 2
; RELOC-NEXT: Offset: 0x00000079
-; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
+; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
; RELOC-NEXT: Index: 6
; RELOC-NEXT: Offset: 0x00000086
; RELOC-NEXT: Functions:
@@ -250,7 +250,7 @@ entry:
; RELOC-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
; RELOC-NEXT: - Type: CUSTOM
; RELOC-NEXT: Name: linking
-; RELOC-NEXT: Version: 1
+; RELOC-NEXT: Version: 2
; RELOC-NEXT: SymbolTable:
; RELOC-NEXT: - Index: 0
; RELOC-NEXT: Kind: FUNCTION
@@ -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/test/wasm/weak-symbols.ll b/test/wasm/weak-symbols.ll
index 7af432347..41ade7c1a 100644
--- a/test/wasm/weak-symbols.ll
+++ b/test/wasm/weak-symbols.ll
@@ -32,7 +32,7 @@ entry:
; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000002
diff --git a/test/wasm/weak-undefined.ll b/test/wasm/weak-undefined.ll
index 2f2451add..41e992e5e 100644
--- a/test/wasm/weak-undefined.ll
+++ b/test/wasm/weak-undefined.ll
@@ -43,7 +43,7 @@ entry:
; CHECK-NEXT: FunctionTypes: [ 0, 1, 1, 0 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
+; CHECK-NEXT: - ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000001
diff --git a/tools/lld/lld.cpp b/tools/lld/lld.cpp
index c749d458a..c6be7f8f8 100644
--- a/tools/lld/lld.cpp
+++ b/tools/lld/lld.cpp
@@ -1,9 +1,8 @@
//===- tools/lld/lld.cpp - Linker Driver Dispatcher -----------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/DriverTests/DarwinLdDriverTest.cpp b/unittests/DriverTests/DarwinLdDriverTest.cpp
index e2e634a4c..806667025 100644
--- a/unittests/DriverTests/DarwinLdDriverTest.cpp
+++ b/unittests/DriverTests/DarwinLdDriverTest.cpp
@@ -1,9 +1,8 @@
//===- lld/unittest/DarwinLdDriverTest.cpp --------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp b/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
index 336bbdba6..aad5f8afc 100644
--- a/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
+++ b/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp
@@ -1,9 +1,8 @@
//===- lld/unittest/MachOTests/MachONormalizedFileBinaryReaderTests.cpp ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp b/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp
index 210fecbf0..d0cdd50de 100644
--- a/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp
+++ b/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp
@@ -1,9 +1,8 @@
//===- lld/unittest/MachOTests/MachONormalizedFileBinaryWriterTests.cpp ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp b/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp
index a0176bb67..cf9a845c4 100644
--- a/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp
+++ b/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp
@@ -1,9 +1,8 @@
//===- lld/unittest/MachOTests/MachONormalizedFileToAtomsTests.cpp --------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp b/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp
index 6bbde72d3..6ceb197b4 100644
--- a/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp
+++ b/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp
@@ -1,9 +1,8 @@
//===- lld/unittest/MachOTests/MachONormalizedFileYAMLTests.cpp -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/utils/benchmark.py b/utils/benchmark.py
index f1deb0647..8ca6cca89 100755
--- a/utils/benchmark.py
+++ b/utils/benchmark.py
@@ -1,9 +1,8 @@
#!/usr/bin/env python
#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ==------------------------------------------------------------------------==#
diff --git a/wasm/Config.h b/wasm/Config.h
index 0857a645f..c5f22eb53 100644
--- a/wasm/Config.h
+++ b/wasm/Config.h
@@ -1,9 +1,8 @@
//===- Config.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -39,6 +38,7 @@ struct Configuration {
bool StripAll;
bool StripDebug;
bool StackFirst;
+ bool Trace;
uint32_t GlobalBase;
uint32_t InitialMemory;
uint32_t MaxMemory;
diff --git a/wasm/Driver.cpp b/wasm/Driver.cpp
index fab4c0c4e..40e88f2ac 100644
--- a/wasm/Driver.cpp
+++ b/wasm/Driver.cpp
@@ -1,9 +1,8 @@
//===- Driver.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -287,44 +286,6 @@ static StringRef getEntry(opt::InputArgList &Args, StringRef Default) {
return Arg->getValue();
}
-static const uint8_t UnreachableFn[] = {
- 0x03 /* ULEB length */, 0x00 /* ULEB num locals */,
- 0x00 /* opcode unreachable */, 0x0b /* opcode end */
-};
-
-// For weak undefined functions, there may be "call" instructions that reference
-// the symbol. In this case, we need to synthesise a dummy/stub function that
-// will abort at runtime, so that relocations can still provided an operand to
-// the call instruction that passes Wasm validation.
-static void handleWeakUndefines() {
- for (Symbol *Sym : Symtab->getSymbols()) {
- if (!Sym->isUndefined() || !Sym->isWeak())
- continue;
- auto *FuncSym = dyn_cast<FunctionSymbol>(Sym);
- if (!FuncSym)
- continue;
-
- // It is possible for undefined functions not to have a signature (eg. if
- // added via "--undefined"), but weak undefined ones do have a signature.
- assert(FuncSym->Signature);
- const WasmSignature &Sig = *FuncSym->Signature;
-
- // Add a synthetic dummy for weak undefined functions. These dummies will
- // be GC'd if not used as the target of any "call" instructions.
- std::string SymName = toString(*Sym);
- StringRef DebugName = Saver.save("undefined function " + SymName);
- auto *Func = make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
- Func->setBody(UnreachableFn);
- // Ensure it compares equal to the null pointer, and so that table relocs
- // don't pull in the stub body (only call-operand relocs should do that).
- Func->setTableIndex(0);
- Symtab->SyntheticFunctions.emplace_back(Func);
- // Hide our dummy to prevent export.
- uint32_t Flags = WASM_SYMBOL_VISIBILITY_HIDDEN;
- replaceSymbol<DefinedFunction>(Sym, Sym->getName(), Flags, nullptr, Func);
- }
-}
-
// Some Config members do not directly correspond to any particular
// command line options, but computed based on other Config values.
// This function initialize such members. See Config.h for the details
@@ -363,6 +324,7 @@ static void setConfigs(opt::InputArgList &Args) {
Config->StripAll = Args.hasArg(OPT_strip_all);
Config->StripDebug = Args.hasArg(OPT_strip_debug);
Config->StackFirst = Args.hasArg(OPT_stack_first);
+ Config->Trace = Args.hasArg(OPT_trace);
Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir);
Config->ThinLTOCachePolicy = CHECK(
parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
@@ -434,7 +396,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;
@@ -548,6 +512,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Config->AllowUndefined = true;
}
+ // Handle --trace-symbol.
+ for (auto *Arg : Args.filtered(OPT_trace_symbol))
+ Symtab->trace(Arg->getValue());
+
if (!Config->Relocatable)
createSyntheticSymbols();
@@ -579,9 +547,6 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Symbol *EntrySym = nullptr;
if (!Config->Relocatable) {
- // Add synthetic dummies for weak undefined functions.
- handleWeakUndefines();
-
if (!Config->Shared && !Config->Entry.empty()) {
EntrySym = handleUndefined(Config->Entry);
if (EntrySym && EntrySym->isDefined())
@@ -605,6 +570,11 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
if (errorCount())
return;
+ // Add synthetic dummies for weak undefined functions. Must happen
+ // after LTO otherwise functions may not yet have signatures.
+ if (!Config->Relocatable)
+ Symtab->handleWeakUndefines();
+
if (EntrySym)
EntrySym->setHidden(false);
diff --git a/wasm/InputChunks.cpp b/wasm/InputChunks.cpp
index 1145c6702..238c111ea 100644
--- a/wasm/InputChunks.cpp
+++ b/wasm/InputChunks.cpp
@@ -1,9 +1,8 @@
//===- InputChunks.cpp ----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -23,7 +22,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: \
@@ -52,21 +51,21 @@ void InputChunk::verifyRelocTargets() const {
uint32_t Offset = Rel.Offset - getInputSectionOffset();
const uint8_t *Loc = data().data() + Offset;
switch (Rel.Type) {
- case R_WEBASSEMBLY_TYPE_INDEX_LEB:
- case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
- case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
- case R_WEBASSEMBLY_EVENT_INDEX_LEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
+ case R_WASM_TYPE_INDEX_LEB:
+ case R_WASM_FUNCTION_INDEX_LEB:
+ case R_WASM_GLOBAL_INDEX_LEB:
+ case R_WASM_EVENT_INDEX_LEB:
+ case R_WASM_MEMORY_ADDR_LEB:
ExistingValue = decodeULEB128(Loc, &BytesRead);
break;
- case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
+ case R_WASM_TABLE_INDEX_SLEB:
+ case R_WASM_MEMORY_ADDR_SLEB:
ExistingValue = static_cast<uint32_t>(decodeSLEB128(Loc, &BytesRead));
break;
- case R_WEBASSEMBLY_TABLE_INDEX_I32:
- case R_WEBASSEMBLY_MEMORY_ADDR_I32:
- case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
- case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+ case R_WASM_TABLE_INDEX_I32:
+ case R_WASM_MEMORY_ADDR_I32:
+ case R_WASM_FUNCTION_OFFSET_I32:
+ case R_WASM_SECTION_OFFSET_I32:
ExistingValue = static_cast<uint32_t>(read32le(Loc));
break;
default:
@@ -77,7 +76,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,27 +102,27 @@ 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");
switch (Rel.Type) {
- case R_WEBASSEMBLY_TYPE_INDEX_LEB:
- case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
- case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
- case R_WEBASSEMBLY_EVENT_INDEX_LEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
+ case R_WASM_TYPE_INDEX_LEB:
+ case R_WASM_FUNCTION_INDEX_LEB:
+ case R_WASM_GLOBAL_INDEX_LEB:
+ case R_WASM_EVENT_INDEX_LEB:
+ case R_WASM_MEMORY_ADDR_LEB:
encodeULEB128(Value, Loc, 5);
break;
- case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
+ case R_WASM_TABLE_INDEX_SLEB:
+ case R_WASM_MEMORY_ADDR_SLEB:
encodeSLEB128(static_cast<int32_t>(Value), Loc, 5);
break;
- case R_WEBASSEMBLY_TABLE_INDEX_I32:
- case R_WEBASSEMBLY_MEMORY_ADDR_I32:
- case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
- case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+ case R_WASM_TABLE_INDEX_I32:
+ case R_WASM_MEMORY_ADDR_I32:
+ case R_WASM_FUNCTION_OFFSET_I32:
+ case R_WASM_SECTION_OFFSET_I32:
write32le(Loc, Value);
break;
default:
@@ -149,11 +148,11 @@ void InputChunk::writeRelocations(raw_ostream &OS) const {
writeUleb128(OS, File->calcNewIndex(Rel), "reloc index");
switch (Rel.Type) {
- case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_I32:
- case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
- case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+ case R_WASM_MEMORY_ADDR_LEB:
+ case R_WASM_MEMORY_ADDR_SLEB:
+ case R_WASM_MEMORY_ADDR_I32:
+ case R_WASM_FUNCTION_OFFSET_I32:
+ case R_WASM_SECTION_OFFSET_I32:
writeSleb128(OS, File->calcNewAddend(Rel), "reloc addend");
break;
}
@@ -179,14 +178,14 @@ void InputFunction::setTableIndex(uint32_t Index) {
static unsigned writeCompressedReloc(uint8_t *Buf, const WasmRelocation &Rel,
uint32_t Value) {
switch (Rel.Type) {
- case R_WEBASSEMBLY_TYPE_INDEX_LEB:
- case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
- case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
- case R_WEBASSEMBLY_EVENT_INDEX_LEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
+ case R_WASM_TYPE_INDEX_LEB:
+ case R_WASM_FUNCTION_INDEX_LEB:
+ case R_WASM_GLOBAL_INDEX_LEB:
+ case R_WASM_EVENT_INDEX_LEB:
+ case R_WASM_MEMORY_ADDR_LEB:
return encodeULEB128(Value, Buf);
- case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
+ case R_WASM_TABLE_INDEX_SLEB:
+ case R_WASM_MEMORY_ADDR_SLEB:
return encodeSLEB128(static_cast<int32_t>(Value), Buf);
default:
llvm_unreachable("unexpected relocation type");
@@ -195,13 +194,13 @@ static unsigned writeCompressedReloc(uint8_t *Buf, const WasmRelocation &Rel,
static unsigned getRelocWidthPadded(const WasmRelocation &Rel) {
switch (Rel.Type) {
- case R_WEBASSEMBLY_TYPE_INDEX_LEB:
- case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
- case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
- case R_WEBASSEMBLY_EVENT_INDEX_LEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
- case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
+ case R_WASM_TYPE_INDEX_LEB:
+ case R_WASM_FUNCTION_INDEX_LEB:
+ case R_WASM_GLOBAL_INDEX_LEB:
+ case R_WASM_EVENT_INDEX_LEB:
+ case R_WASM_MEMORY_ADDR_LEB:
+ case R_WASM_TABLE_INDEX_SLEB:
+ case R_WASM_MEMORY_ADDR_SLEB:
return 5;
default:
llvm_unreachable("unexpected relocation type");
diff --git a/wasm/InputChunks.h b/wasm/InputChunks.h
index a3bcbb266..20b8f01f6 100644
--- a/wasm/InputChunks.h
+++ b/wasm/InputChunks.h
@@ -1,9 +1,8 @@
//===- InputChunks.h --------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/wasm/InputEvent.h b/wasm/InputEvent.h
index d7c12627b..52afc930f 100644
--- a/wasm/InputEvent.h
+++ b/wasm/InputEvent.h
@@ -1,9 +1,8 @@
//===- InputEvent.h ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/wasm/InputFiles.cpp b/wasm/InputFiles.cpp
index e5da23db3..2a5c10e39 100644
--- a/wasm/InputFiles.cpp
+++ b/wasm/InputFiles.cpp
@@ -1,9 +1,8 @@
//===- InputFiles.cpp -----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -66,7 +65,7 @@ void ObjFile::dumpInfo() const {
// relocation and returns relocated index (i.e. translates from the input
// symbol/type space to the output symbol/type space).
uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
- if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
+ if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) {
assert(TypeIsUsed[Reloc.Index]);
return TypeMap[Reloc.Index];
}
@@ -77,12 +76,12 @@ uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
// relocation and returns updated addend by offset in the output section.
uint32_t ObjFile::calcNewAddend(const WasmRelocation &Reloc) const {
switch (Reloc.Type) {
- case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_I32:
- case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
+ case R_WASM_MEMORY_ADDR_LEB:
+ case R_WASM_MEMORY_ADDR_SLEB:
+ case R_WASM_MEMORY_ADDR_I32:
+ case R_WASM_FUNCTION_OFFSET_I32:
return Reloc.Addend;
- case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+ case R_WASM_SECTION_OFFSET_I32:
return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend;
default:
llvm_unreachable("unexpected relocation type");
@@ -94,14 +93,14 @@ uint32_t ObjFile::calcNewAddend(const WasmRelocation &Reloc) const {
// location. It is useful for catching bugs in the compiler and linker.
uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
switch (Reloc.Type) {
- case R_WEBASSEMBLY_TABLE_INDEX_I32:
- case R_WEBASSEMBLY_TABLE_INDEX_SLEB: {
+ case R_WASM_TABLE_INDEX_I32:
+ case R_WASM_TABLE_INDEX_SLEB: {
const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
return TableEntries[Sym.Info.ElementIndex];
}
- case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_I32:
- case R_WEBASSEMBLY_MEMORY_ADDR_LEB: {
+ case R_WASM_MEMORY_ADDR_SLEB:
+ case R_WASM_MEMORY_ADDR_I32:
+ case R_WASM_MEMORY_ADDR_LEB: {
const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
if (Sym.isUndefined())
return 0;
@@ -110,19 +109,19 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset +
Reloc.Addend;
}
- case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
+ case R_WASM_FUNCTION_OFFSET_I32:
if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {
return Sym->Function->getFunctionInputOffset() +
Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
}
return 0;
- case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+ case R_WASM_SECTION_OFFSET_I32:
return Reloc.Addend;
- case R_WEBASSEMBLY_TYPE_INDEX_LEB:
+ case R_WASM_TYPE_INDEX_LEB:
return Reloc.Index;
- case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
- case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
- case R_WEBASSEMBLY_EVENT_INDEX_LEB: {
+ case R_WASM_FUNCTION_INDEX_LEB:
+ case R_WASM_GLOBAL_INDEX_LEB:
+ case R_WASM_EVENT_INDEX_LEB: {
const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
return Sym.Info.ElementIndex;
}
@@ -134,32 +133,32 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
// Translate from the relocation's index into the final linked output value.
uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
switch (Reloc.Type) {
- case R_WEBASSEMBLY_TABLE_INDEX_I32:
- case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
+ case R_WASM_TABLE_INDEX_I32:
+ case R_WASM_TABLE_INDEX_SLEB:
return getFunctionSymbol(Reloc.Index)->getTableIndex();
- case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
- case R_WEBASSEMBLY_MEMORY_ADDR_I32:
- case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
+ case R_WASM_MEMORY_ADDR_SLEB:
+ case R_WASM_MEMORY_ADDR_I32:
+ case R_WASM_MEMORY_ADDR_LEB:
if (auto *Sym = dyn_cast<DefinedData>(getDataSymbol(Reloc.Index)))
if (Sym->isLive())
return Sym->getVirtualAddress() + Reloc.Addend;
return 0;
- case R_WEBASSEMBLY_TYPE_INDEX_LEB:
+ case R_WASM_TYPE_INDEX_LEB:
return TypeMap[Reloc.Index];
- case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
+ case R_WASM_FUNCTION_INDEX_LEB:
return getFunctionSymbol(Reloc.Index)->getFunctionIndex();
- case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
+ case R_WASM_GLOBAL_INDEX_LEB:
return getGlobalSymbol(Reloc.Index)->getGlobalIndex();
- case R_WEBASSEMBLY_EVENT_INDEX_LEB:
+ case R_WASM_EVENT_INDEX_LEB:
return getEventSymbol(Reloc.Index)->getEventIndex();
- case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
+ case R_WASM_FUNCTION_OFFSET_I32:
if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {
if (Sym->isLive())
return Sym->Function->OutputOffset +
Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
}
return 0;
- case R_WEBASSEMBLY_SECTION_OFFSET_I32:
+ case R_WASM_SECTION_OFFSET_I32:
return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend;
default:
llvm_unreachable("unknown relocation type");
@@ -240,6 +239,8 @@ void ObjFile::parse() {
CustomSections.emplace_back(make<InputSection>(Section, this));
CustomSections.back()->setRelocations(Section.Relocations);
CustomSectionsByIndex[SectionIndex] = CustomSections.back();
+ if (Section.Name == "producers")
+ ProducersSection = &Section;
}
SectionIndex++;
}
@@ -377,11 +378,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 +450,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/InputFiles.h b/wasm/InputFiles.h
index bcda9cc8e..07d72de09 100644
--- a/wasm/InputFiles.h
+++ b/wasm/InputFiles.h
@@ -1,9 +1,8 @@
//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -99,6 +98,7 @@ public:
const WasmSection *CodeSection = nullptr;
const WasmSection *DataSection = nullptr;
+ const WasmSection *ProducersSection = nullptr;
// Maps input type indices to output type indices
std::vector<uint32_t> TypeMap;
@@ -139,7 +139,7 @@ public:
};
// Will report a fatal() error if the input buffer is not a valid bitcode
-// or was object file.
+// or wasm object file.
InputFile *createObjectFile(MemoryBufferRef MB);
// Opens a given file.
diff --git a/wasm/InputGlobal.h b/wasm/InputGlobal.h
index 3b20600b2..e008d2ecc 100644
--- a/wasm/InputGlobal.h
+++ b/wasm/InputGlobal.h
@@ -1,9 +1,8 @@
//===- InputGlobal.h --------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/wasm/LTO.cpp b/wasm/LTO.cpp
index 96a947e29..19b23d50c 100644
--- a/wasm/LTO.cpp
+++ b/wasm/LTO.cpp
@@ -1,9 +1,8 @@
//===- LTO.cpp ------------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,6 +10,7 @@
#include "Config.h"
#include "InputFiles.h"
#include "Symbols.h"
+#include "lld/Common/Args.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Strings.h"
#include "lld/Common/TargetOptionsCommandFlags.h"
@@ -41,7 +41,7 @@ using namespace lld::wasm;
static std::unique_ptr<lto::LTO> createLTO() {
lto::Config C;
- C.Options = InitTargetOptionsFromCodeGenFlags();
+ C.Options = initTargetOptionsFromCodeGenFlags();
// Always emit a section per function/data with LTO.
C.Options.FunctionSections = true;
@@ -53,7 +53,8 @@ static std::unique_ptr<lto::LTO> createLTO() {
C.DisableVerify = Config->DisableVerify;
C.DiagHandler = diagnosticHandler;
C.OptLevel = Config->LTOO;
- C.MAttrs = GetMAttrs();
+ C.MAttrs = getMAttrs();
+ C.CGOptLevel = args::getCGOptLevel(Config->LTOO);
if (Config->Relocatable)
C.RelocModel = None;
@@ -79,8 +80,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 cf726de56..37fea7ad6 100644
--- a/wasm/LTO.h
+++ b/wasm/LTO.h
@@ -1,9 +1,8 @@
//===- LTO.h ----------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,6 +22,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 3bbd1148f..5d4b379e2 100644
--- a/wasm/MarkLive.cpp
+++ b/wasm/MarkLive.cpp
@@ -1,9 +1,8 @@
//===- MarkLive.cpp -------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -72,7 +71,7 @@ void lld::wasm::markLive() {
InputChunk *C = Q.pop_back_val();
for (const WasmRelocation Reloc : C->getRelocations()) {
- if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB)
+ if (Reloc.Type == R_WASM_TYPE_INDEX_LEB)
continue;
Symbol *Sym = C->File->getSymbol(Reloc.Index);
@@ -83,9 +82,9 @@ void lld::wasm::markLive() {
// zero is only reachable via "call", not via "call_indirect". The stub
// functions used for weak-undefined symbols have this behaviour (compare
// 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);
+ if (Reloc.Type == R_WASM_TABLE_INDEX_SLEB ||
+ Reloc.Type == R_WASM_TABLE_INDEX_I32) {
+ auto *FuncSym = cast<FunctionSymbol>(Sym);
if (FuncSym->hasTableIndex() && FuncSym->getTableIndex() == 0)
continue;
}
diff --git a/wasm/MarkLive.h b/wasm/MarkLive.h
index 0b58f153c..7b88cb485 100644
--- a/wasm/MarkLive.h
+++ b/wasm/MarkLive.h
@@ -1,9 +1,8 @@
//===- MarkLive.h -----------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/wasm/Options.td b/wasm/Options.td
index 3ed55b4bc..591d624e6 100644
--- a/wasm/Options.td
+++ b/wasm/Options.td
@@ -93,6 +93,10 @@ def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">;
def threads: F<"threads">, HelpText<"Run the linker multi-threaded">;
+def trace: F<"trace">, HelpText<"Print the names of the input files">;
+
+defm trace_symbol: Eq<"trace-symbol", "Trace references to symbols">;
+
defm undefined: Eq<"undefined", "Force undefined symbol during linking">;
def v: Flag<["-"], "v">, HelpText<"Display the version number">;
@@ -160,6 +164,8 @@ def: Flag<["-"], "m">, Alias<max_memory>;
def: Flag<["-"], "r">, Alias<relocatable>;
def: Flag<["-"], "s">, Alias<strip_all>, HelpText<"Alias for --strip-all">;
def: Flag<["-"], "S">, Alias<strip_debug>, HelpText<"Alias for --strip-debug">;
+def: Flag<["-"], "t">, Alias<trace>, HelpText<"Alias for --trace">;
+def: JoinedOrSeparate<["-"], "y">, Alias<trace_symbol>, HelpText<"Alias for --trace-symbol">;
def: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
// LTO-related options.
diff --git a/wasm/OutputSections.cpp b/wasm/OutputSections.cpp
index 38d32d2cf..70ef9f8ca 100644
--- a/wasm/OutputSections.cpp
+++ b/wasm/OutputSections.cpp
@@ -1,9 +1,8 @@
//===- OutputSections.cpp -------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -142,7 +141,7 @@ DataSection::DataSection(ArrayRef<OutputSegment *> Segments)
if (Config->Pic) {
assert(Segments.size() <= 1 &&
"Currenly only a single data segment is supported in PIC mode");
- InitExpr.Opcode = WASM_OPCODE_GET_GLOBAL;
+ InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
InitExpr.Value.Global = WasmSym::MemoryBase->getGlobalIndex();
} else {
InitExpr.Opcode = WASM_OPCODE_I32_CONST;
diff --git a/wasm/OutputSections.h b/wasm/OutputSections.h
index 6c5baa309..a1853cb32 100644
--- a/wasm/OutputSections.h
+++ b/wasm/OutputSections.h
@@ -1,9 +1,8 @@
//===- OutputSections.h -----------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/wasm/OutputSegment.h b/wasm/OutputSegment.h
index d5c89cd19..782b43bd7 100644
--- a/wasm/OutputSegment.h
+++ b/wasm/OutputSegment.h
@@ -1,9 +1,8 @@
//===- OutputSegment.h ------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -26,7 +25,7 @@ public:
void addInputSegment(InputSegment *InSeg) {
Alignment = std::max(Alignment, InSeg->getAlignment());
InputSegments.push_back(InSeg);
- Size = llvm::alignTo(Size, InSeg->getAlignment());
+ Size = llvm::alignTo(Size, 1ULL << InSeg->getAlignment());
InSeg->OutputSeg = this;
InSeg->OutputSegmentOffset = Size;
Size += InSeg->getSize();
diff --git a/wasm/SymbolTable.cpp b/wasm/SymbolTable.cpp
index c7983196d..35ac2c5a6 100644
--- a/wasm/SymbolTable.cpp
+++ b/wasm/SymbolTable.cpp
@@ -1,9 +1,8 @@
//===- SymbolTable.cpp ----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -29,6 +28,8 @@ SymbolTable *lld::wasm::Symtab;
void SymbolTable::addFile(InputFile *File) {
log("Processing: " + toString(File));
+ if (Config->Trace)
+ message(toString(File));
File->parse();
// LLVM bitcode file
@@ -74,21 +75,43 @@ void SymbolTable::reportRemainingUndefines() {
}
Symbol *SymbolTable::find(StringRef Name) {
- return SymMap.lookup(CachedHashStringRef(Name));
+ auto It = SymMap.find(CachedHashStringRef(Name));
+ if (It == SymMap.end() || It->second == -1)
+ return nullptr;
+ return SymVector[It->second];
}
-std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
- bool Inserted = false;
- Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
- if (!Sym) {
- Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
- Sym->IsUsedInRegularObj = false;
- SymVector.emplace_back(Sym);
- Inserted = true;
+std::pair<Symbol *, bool> SymbolTable::insertName(StringRef Name) {
+ bool Trace = false;
+ auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()});
+ int &SymIndex = P.first->second;
+ bool IsNew = P.second;
+ if (SymIndex == -1) {
+ SymIndex = SymVector.size();
+ Trace = true;
+ IsNew = true;
}
+
+ if (!IsNew)
+ return {SymVector[SymIndex], false};
+
+ Symbol *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+ Sym->IsUsedInRegularObj = false;
+ Sym->Traced = Trace;
+ SymVector.emplace_back(Sym);
+ return {Sym, true};
+}
+
+std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name,
+ const InputFile *File) {
+ Symbol *S;
+ bool WasInserted;
+ std::tie(S, WasInserted) = insertName(Name);
+
if (!File || File->kind() == InputFile::ObjectKind)
- Sym->IsUsedInRegularObj = true;
- return {Sym, Inserted};
+ S->IsUsedInRegularObj = true;
+
+ return {S, WasInserted};
}
static void reportTypeError(const Symbol *Existing, const InputFile *File,
@@ -242,10 +265,12 @@ Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
if (shouldReplace(S, File, Flags)) {
// If the new defined function doesn't have signture (i.e. bitcode
- // functions) but the old symbols does then preserve the old signature
+ // functions) but the old symbol does then preserve the old signature
const WasmSignature *OldSig = nullptr;
if (auto* F = dyn_cast<FunctionSymbol>(S))
OldSig = F->Signature;
+ if (auto *L = dyn_cast<LazySymbol>(S))
+ OldSig = L->Signature;
auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
if (!NewSym->Signature)
NewSym->Signature = OldSig;
@@ -314,8 +339,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 +351,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 +378,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 +389,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())
@@ -378,17 +407,94 @@ void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) {
std::tie(S, WasInserted) = insert(Name, nullptr);
if (WasInserted) {
- replaceSymbol<LazySymbol>(S, Name, File, *Sym);
+ replaceSymbol<LazySymbol>(S, Name, 0, File, *Sym);
return;
}
- // If there is an existing undefined symbol, load a new one from the archive.
- if (S->isUndefined()) {
- LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
- File->addMember(Sym);
+ if (!S->isUndefined())
+ return;
+
+ // The existing symbol is undefined, load a new one from the archive,
+ // unless the the existing symbol is weak in which case replace the undefined
+ // symbols with a LazySymbol.
+ if (S->isWeak()) {
+ const WasmSignature *OldSig = nullptr;
+ // In the case of an UndefinedFunction we need to preserve the expected
+ // signature.
+ if (auto *F = dyn_cast<UndefinedFunction>(S))
+ OldSig = F->Signature;
+ LLVM_DEBUG(dbgs() << "replacing existing weak undefined symbol\n");
+ auto NewSym = replaceSymbol<LazySymbol>(S, Name, WASM_SYMBOL_BINDING_WEAK,
+ File, *Sym);
+ NewSym->Signature = OldSig;
+ return;
}
+
+ LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
+ File->addMember(Sym);
}
bool SymbolTable::addComdat(StringRef Name) {
return Comdats.insert(CachedHashStringRef(Name)).second;
}
+
+// Set a flag for --trace-symbol so that we can print out a log message
+// if a new symbol with the same name is inserted into the symbol table.
+void SymbolTable::trace(StringRef Name) {
+ SymMap.insert({CachedHashStringRef(Name), -1});
+}
+
+static const uint8_t UnreachableFn[] = {
+ 0x03 /* ULEB length */, 0x00 /* ULEB num locals */,
+ 0x00 /* opcode unreachable */, 0x0b /* opcode end */
+};
+
+// Replace the given symbol body with an unreachable function.
+// This is used by handleWeakUndefines in order to generate a callable
+// equivalent of an undefined function.
+InputFunction *SymbolTable::replaceWithUnreachable(Symbol *Sym,
+ const WasmSignature &Sig,
+ StringRef DebugName) {
+ auto *Func = make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
+ Func->setBody(UnreachableFn);
+ SyntheticFunctions.emplace_back(Func);
+ replaceSymbol<DefinedFunction>(Sym, Sym->getName(), Sym->getFlags(), nullptr, Func);
+ return Func;
+}
+
+// For weak undefined functions, there may be "call" instructions that reference
+// the symbol. In this case, we need to synthesise a dummy/stub function that
+// will abort at runtime, so that relocations can still provided an operand to
+// the call instruction that passes Wasm validation.
+void SymbolTable::handleWeakUndefines() {
+ for (Symbol *Sym : getSymbols()) {
+ if (!Sym->isUndefWeak())
+ continue;
+
+ const WasmSignature *Sig = nullptr;
+
+ if (auto *FuncSym = dyn_cast<FunctionSymbol>(Sym)) {
+ // It is possible for undefined functions not to have a signature (eg. if
+ // added via "--undefined"), but weak undefined ones do have a signature.
+ assert(FuncSym->Signature);
+ Sig = FuncSym->Signature;
+ } else if (auto *LazySym = dyn_cast<LazySymbol>(Sym)) {
+ // Lazy symbols may not be functions and therefore can have a null
+ // signature.
+ Sig = LazySym->Signature;
+ }
+
+ if (!Sig)
+ continue;
+
+ // Add a synthetic dummy for weak undefined functions. These dummies will
+ // be GC'd if not used as the target of any "call" instructions.
+ StringRef DebugName = Saver.save("undefined:" + toString(*Sym));
+ InputFunction* Func = replaceWithUnreachable(Sym, *Sig, DebugName);
+ // Ensure it compares equal to the null pointer, and so that table relocs
+ // don't pull in the stub body (only call-operand relocs should do that).
+ Func->setTableIndex(0);
+ // Hide our dummy to prevent export.
+ Sym->setHidden(true);
+ }
+}
diff --git a/wasm/SymbolTable.h b/wasm/SymbolTable.h
index 5e38e3069..f03980d70 100644
--- a/wasm/SymbolTable.h
+++ b/wasm/SymbolTable.h
@@ -1,9 +1,8 @@
//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -47,8 +46,11 @@ public:
void reportRemainingUndefines();
ArrayRef<Symbol *> getSymbols() const { return SymVector; }
+
Symbol *find(StringRef Name);
+ void trace(StringRef Name);
+
Symbol *addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *File,
InputFunction *Function);
Symbol *addDefinedData(StringRef Name, uint32_t Flags, InputFile *File,
@@ -59,11 +61,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);
@@ -75,10 +79,19 @@ public:
DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags,
InputFunction *Function);
+ void handleWeakUndefines();
+
private:
- std::pair<Symbol *, bool> insert(StringRef Name, InputFile *File);
+ std::pair<Symbol *, bool> insert(StringRef Name, const InputFile *File);
+ std::pair<Symbol *, bool> insertName(StringRef Name);
+
+ InputFunction *replaceWithUnreachable(Symbol *Sym, const WasmSignature &Sig,
+ StringRef DebugName);
- llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
+ // Maps symbol names to index into the SymVector. -1 means that symbols
+ // is to not yet in the vector but it should have tracing enabled if it is
+ // ever added.
+ llvm::DenseMap<llvm::CachedHashStringRef, int> SymMap;
std::vector<Symbol *> SymVector;
llvm::DenseSet<llvm::CachedHashStringRef> Comdats;
diff --git a/wasm/Symbols.cpp b/wasm/Symbols.cpp
index 4bef9761e..60030bef3 100644
--- a/wasm/Symbols.cpp
+++ b/wasm/Symbols.cpp
@@ -1,9 +1,8 @@
//===- Symbols.cpp --------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -117,7 +116,7 @@ bool Symbol::isExported() const {
if (Config->ExportDynamic && !isHidden())
return true;
- return false;
+ return Flags & WASM_SYMBOL_EXPORTED;
}
uint32_t FunctionSymbol::getFunctionIndex() const {
@@ -294,3 +293,16 @@ std::string lld::toString(wasm::Symbol::Kind Kind) {
}
llvm_unreachable("invalid symbol kind");
}
+
+// Print out a log message for --trace-symbol.
+void lld::wasm::printTraceSymbol(Symbol *Sym) {
+ std::string S;
+ if (Sym->isUndefined())
+ S = ": reference to ";
+ else if (Sym->isLazy())
+ S = ": lazy definition of ";
+ else
+ S = ": definition of ";
+
+ message(toString(Sym->getFile()) + S + Sym->getName());
+}
diff --git a/wasm/Symbols.h b/wasm/Symbols.h
index 11ee66550..fd501ed64 100644
--- a/wasm/Symbols.h
+++ b/wasm/Symbols.h
@@ -1,9 +1,8 @@
//===- Symbols.h ------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -64,12 +63,21 @@ public:
bool isWeak() const;
bool isHidden() const;
+ // True if this is an undefined weak symbol. This only works once
+ // all input files have been added.
+ bool isUndefWeak() const {
+ // See comment on lazy symbols for details.
+ return isWeak() && (isUndefined() || isLazy());
+ }
+
// Returns the symbol name.
StringRef getName() const { return Name; }
// Returns the file from which this symbol was created.
InputFile *getFile() const { return File; }
+ uint32_t getFlags() const { return Flags; }
+
InputChunk *getChunk() const;
// Indicates that the section or import for this symbol will be included in
@@ -94,10 +102,14 @@ public:
unsigned IsUsedInRegularObj : 1;
unsigned ForceExport : 1;
+ // True if this symbol is specified by --trace-symbol option.
+ unsigned Traced : 1;
+
protected:
Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
- : IsUsedInRegularObj(false), ForceExport(false), Name(Name),
- SymbolKind(K), Flags(Flags), File(F), Referenced(!Config->GcSections) {}
+ : IsUsedInRegularObj(false), ForceExport(false), Traced(false),
+ Name(Name), SymbolKind(K), Flags(Flags), File(F),
+ Referenced(!Config->GcSections) {}
StringRef Name;
Kind SymbolKind;
@@ -149,13 +161,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 +279,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
@@ -314,15 +337,31 @@ public:
InputEvent *Event;
};
+// LazySymbol represents a symbol that is not yet in the link, but we know where
+// to find it if needed. If the resolver finds both Undefined and Lazy for the
+// same name, it will ask the Lazy to load a file.
+//
+// A special complication is the handling of weak undefined symbols. They should
+// not load a file, but we have to remember we have seen both the weak undefined
+// and the lazy. We represent that with a lazy symbol with a weak binding. This
+// means that code looking for undefined symbols normally also has to take lazy
+// symbols into consideration.
class LazySymbol : public Symbol {
public:
- LazySymbol(StringRef Name, InputFile *File,
+ LazySymbol(StringRef Name, uint32_t Flags, InputFile *File,
const llvm::object::Archive::Symbol &Sym)
- : Symbol(Name, LazyKind, 0, File), ArchiveSymbol(Sym) {}
+ : Symbol(Name, LazyKind, Flags, File), ArchiveSymbol(Sym) {}
static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
void fetch();
+ // Lazy symbols can have a signature because they can replace an
+ // UndefinedFunction which which case we need to be able to preserve the
+ // signture.
+ // TODO(sbc): This repetition of the signature field is inelegant. Revisit
+ // the use of class hierarchy to represent symbol taxonomy.
+ const WasmSignature *Signature = nullptr;
+
private:
llvm::object::Archive::Symbol ArchiveSymbol;
};
@@ -376,6 +415,8 @@ union SymbolUnion {
alignas(SectionSymbol) char I[sizeof(SectionSymbol)];
};
+void printTraceSymbol(Symbol *Sym);
+
template <typename T, typename... ArgT>
T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
static_assert(std::is_trivially_destructible<T>(),
@@ -391,6 +432,13 @@ T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
S2->ForceExport = SymCopy.ForceExport;
+ S2->Traced = SymCopy.Traced;
+
+ // Print out a log message if --trace-symbol was specified.
+ // This is for debugging.
+ if (S2->Traced)
+ printTraceSymbol(S2);
+
return S2;
}
diff --git a/wasm/Writer.cpp b/wasm/Writer.cpp
index 710f9ccdf..213beca18 100644
--- a/wasm/Writer.cpp
+++ b/wasm/Writer.cpp
@@ -1,9 +1,8 @@
//===- Writer.cpp ---------------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -21,6 +20,7 @@
#include "lld/Common/Strings.h"
#include "lld/Common/Threads.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/Object/WasmTraits.h"
@@ -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 {
@@ -95,6 +96,7 @@ private:
void createRelocSections();
void createLinkingSection();
void createNameSection();
+ void createProducersSection();
void writeHeader();
void writeSections();
@@ -155,7 +157,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,18 +174,27 @@ 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_ANYFUNC;
+ Import.Table.ElemType = WASM_TYPE_FUNCREF;
Import.Table.Limits = {0, TableSize, 0};
writeImport(OS, Import);
}
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);
@@ -304,7 +315,7 @@ void Writer::createTableSection() {
writeUleb128(OS, 1, "table count");
WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};
- writeTableType(OS, WasmTable{WASM_TYPE_ANYFUNC, Limits});
+ writeTableType(OS, WasmTable{WASM_TYPE_FUNCREF, Limits});
}
void Writer::createExportSection() {
@@ -327,7 +338,8 @@ void Writer::calculateCustomSections() {
StringRef Name = Section->getName();
// These custom sections are known the linker and synthesized rather than
// blindly copied
- if (Name == "linking" || Name == "name" || Name.startswith("reloc."))
+ if (Name == "linking" || Name == "name" || Name == "producers" ||
+ Name.startswith("reloc."))
continue;
// .. or it is a debug section
if (StripDebug && Name.startswith(".debug_"))
@@ -364,7 +376,7 @@ void Writer::createElemSection() {
writeUleb128(OS, 0, "table index");
WasmInitExpr InitExpr;
if (Config->Pic) {
- InitExpr.Opcode = WASM_OPCODE_GET_GLOBAL;
+ InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex();
} else {
InitExpr.Opcode = WASM_OPCODE_I32_CONST;
@@ -441,6 +453,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;
}
@@ -477,7 +496,7 @@ void Writer::createDylinkSection() {
raw_ostream &OS = Section->getStream();
writeUleb128(OS, MemSize, "MemSize");
- writeUleb128(OS, int(log2(MemAlign)), "MemAlign");
+ writeUleb128(OS, MemAlign, "MemAlign");
writeUleb128(OS, IndirectFunctions.size(), "TableSize");
writeUleb128(OS, 0, "TableAlign");
writeUleb128(OS, 0, "Needed"); // TODO: Support "needed" shared libraries
@@ -506,15 +525,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");
@@ -633,6 +655,45 @@ void Writer::createNameSection() {
Sub.writeTo(Section->getStream());
}
+void Writer::createProducersSection() {
+ SmallVector<std::pair<std::string, std::string>, 8> Languages;
+ SmallVector<std::pair<std::string, std::string>, 8> Tools;
+ SmallVector<std::pair<std::string, std::string>, 8> SDKs;
+ for (ObjFile *File : Symtab->ObjectFiles) {
+ const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo();
+ for (auto &Producers : {std::make_pair(&Info.Languages, &Languages),
+ std::make_pair(&Info.Tools, &Tools),
+ std::make_pair(&Info.SDKs, &SDKs)})
+ for (auto &Producer : *Producers.first)
+ if (Producers.second->end() ==
+ std::find_if(Producers.second->begin(), Producers.second->end(),
+ [&](std::pair<std::string, std::string> Seen) {
+ return Seen.first == Producer.first;
+ }))
+ Producers.second->push_back(Producer);
+ }
+ int FieldCount =
+ int(!Languages.empty()) + int(!Tools.empty()) + int(!SDKs.empty());
+ if (FieldCount == 0)
+ return;
+ SyntheticSection *Section =
+ createSyntheticSection(WASM_SEC_CUSTOM, "producers");
+ auto &OS = Section->getStream();
+ writeUleb128(OS, FieldCount, "field count");
+ for (auto &Field :
+ {std::make_pair("language", Languages),
+ std::make_pair("processed-by", Tools), std::make_pair("sdk", SDKs)}) {
+ if (Field.second.empty())
+ continue;
+ writeStr(OS, Field.first, "field name");
+ writeUleb128(OS, Field.second.size(), "number of entries");
+ for (auto &Entry : Field.second) {
+ writeStr(OS, Entry.first, "producer name");
+ writeStr(OS, Entry.second, "producer version");
+ }
+ }
+}
+
void Writer::writeHeader() {
memcpy(Buffer->getBufferStart(), Header.data(), Header.size());
}
@@ -663,9 +724,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;
@@ -691,7 +752,7 @@ void Writer::layoutMemory() {
MemAlign = 0;
for (OutputSegment *Seg : Segments) {
MemAlign = std::max(MemAlign, Seg->Alignment);
- MemoryPtr = alignTo(MemoryPtr, Seg->Alignment);
+ MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment);
Seg->StartVA = MemoryPtr;
log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,
MemoryPtr, Seg->Size, Seg->Alignment));
@@ -772,9 +833,13 @@ void Writer::createSections() {
createLinkingSection();
createRelocSections();
}
+
if (!Config->StripDebug && !Config->StripAll)
createNameSection();
+ if (!Config->StripAll)
+ createProducersSection();
+
for (OutputSection *S : OutputSections) {
S->setOffset(FileSize);
S->finalizeContents();
@@ -814,7 +879,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 +923,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) {
@@ -967,14 +1034,14 @@ void Writer::assignIndexes() {
ObjFile *File = Chunk->File;
ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
- if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||
- Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) {
+ if (Reloc.Type == R_WASM_TABLE_INDEX_I32 ||
+ Reloc.Type == R_WASM_TABLE_INDEX_SLEB) {
FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
if (Sym->hasTableIndex() || !Sym->hasFunctionIndex())
continue;
Sym->setTableIndex(TableIndex++);
IndirectFunctions.emplace_back(Sym);
- } else if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
+ } else if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) {
// Mark target type as live
File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
File->TypeIsUsed[Reloc.Index] = true;
diff --git a/wasm/Writer.h b/wasm/Writer.h
index a931ba9c2..ebbd10944 100644
--- a/wasm/Writer.h
+++ b/wasm/Writer.h
@@ -1,9 +1,8 @@
//===- Writer.h -------------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -15,6 +14,8 @@ namespace wasm {
void writeResult();
+extern const char *DefaultModule;
+
} // namespace wasm
} // namespace lld
diff --git a/wasm/WriterUtils.cpp b/wasm/WriterUtils.cpp
index 6af152a36..599b42b22 100644
--- a/wasm/WriterUtils.cpp
+++ b/wasm/WriterUtils.cpp
@@ -1,9 +1,8 @@
//===- WriterUtils.cpp ----------------------------------------------------===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -83,7 +82,7 @@ void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) {
case WASM_OPCODE_I64_CONST:
writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)");
break;
- case WASM_OPCODE_GET_GLOBAL:
+ case WASM_OPCODE_GLOBAL_GET:
writeUleb128(OS, InitExpr.Value.Global, "literal (global index)");
break;
default:
@@ -120,7 +119,7 @@ void wasm::writeEvent(raw_ostream &OS, const WasmEvent &Event) {
}
void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) {
- writeU8(OS, WASM_TYPE_ANYFUNC, "table type");
+ writeU8(OS, WASM_TYPE_FUNCREF, "table type");
writeLimits(OS, Type.Limits);
}
diff --git a/wasm/WriterUtils.h b/wasm/WriterUtils.h
index 7fc4b5aa8..389f99799 100644
--- a/wasm/WriterUtils.h
+++ b/wasm/WriterUtils.h
@@ -1,9 +1,8 @@
//===- WriterUtils.h --------------------------------------------*- C++ -*-===//
//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//