aboutsummaryrefslogtreecommitdiff
path: root/test/ELF
diff options
context:
space:
mode:
Diffstat (limited to 'test/ELF')
-rw-r--r--test/ELF/Inputs/aarch64-copy2.s5
-rw-r--r--test/ELF/Inputs/aarch64-tls-gdie.s4
-rw-r--r--test/ELF/Inputs/abs-hidden.s3
-rw-r--r--test/ELF/Inputs/allow-shlib-undefined.s2
-rw-r--r--test/ELF/Inputs/archive.s4
-rw-r--r--test/ELF/Inputs/arm-plt-reloc.s14
-rw-r--r--test/ELF/Inputs/arm-thumb-blx-targets.s36
-rw-r--r--test/ELF/Inputs/arm-thumb-narrow-branch.s18
-rw-r--r--test/ELF/Inputs/conflict.s7
-rw-r--r--test/ELF/Inputs/copy-in-shared.s4
-rw-r--r--test/ELF/Inputs/copy-rel-corrupted.s4
-rw-r--r--test/ELF/Inputs/copy-rel-pie.s9
-rw-r--r--test/ELF/Inputs/ctors_dtors_priority1.s5
-rw-r--r--test/ELF/Inputs/ctors_dtors_priority2.s5
-rw-r--r--test/ELF/Inputs/ctors_dtors_priority3.s5
-rw-r--r--test/ELF/Inputs/duplicated-plt-entry.s3
-rw-r--r--test/ELF/Inputs/dynamic-reloc-weak.s11
-rw-r--r--test/ELF/Inputs/ehframe-relocation.s2
-rw-r--r--test/ELF/Inputs/empty-ver.ver2
-rw-r--r--test/ELF/Inputs/far-arm-abs.s13
-rw-r--r--test/ELF/Inputs/far-arm-thumb-abs.s24
-rw-r--r--test/ELF/Inputs/gc-sections-weak.s8
-rw-r--r--test/ELF/Inputs/gnu-ifunc-gotpcrel.s4
-rw-r--r--test/ELF/Inputs/gotpc-relax-und-dso.s4
-rw-r--r--test/ELF/Inputs/icf2.s5
-rw-r--r--test/ELF/Inputs/invalid-cie-version2.elfbin0 -> 1128 bytes
-rw-r--r--test/ELF/Inputs/libsearch-dyn.s2
-rw-r--r--test/ELF/Inputs/libsearch-st.s2
-rw-r--r--test/ELF/Inputs/mips-align-err.s2
-rw-r--r--test/ELF/Inputs/mips-dynamic.s24
-rw-r--r--test/ELF/Inputs/mips-gp-disp.sobin131832 -> 131828 bytes
-rw-r--r--test/ELF/Inputs/mips-nonalloc.s2
-rw-r--r--test/ELF/Inputs/mips-pic.s19
-rw-r--r--test/ELF/Inputs/mips-tls.s5
-rw-r--r--test/ELF/Inputs/plt-aarch64.s5
-rw-r--r--test/ELF/Inputs/ppc64-addr16-error.s3
-rw-r--r--test/ELF/Inputs/protected-shared.s10
-rw-r--r--test/ELF/Inputs/relocatable-ehframe.s14
-rw-r--r--test/ELF/Inputs/relocatable.s22
-rw-r--r--test/ELF/Inputs/relocatable2.s22
-rw-r--r--test/ELF/Inputs/relocation-copy-alias.s25
-rw-r--r--test/ELF/Inputs/relocation-copy-arm.s22
-rw-r--r--test/ELF/Inputs/resolution-shared.s2
-rw-r--r--test/ELF/Inputs/shared.s4
-rw-r--r--test/ELF/Inputs/start-lib-comdat.s5
-rw-r--r--test/ELF/Inputs/start-lib1.s3
-rw-r--r--test/ELF/Inputs/start-lib2.s2
-rw-r--r--test/ELF/Inputs/symbol-override.s16
-rw-r--r--test/ELF/Inputs/tls-got-entry.s13
-rw-r--r--test/ELF/Inputs/tls-in-archive.s3
-rw-r--r--test/ELF/Inputs/trace-ar1.s2
-rw-r--r--test/ELF/Inputs/trace-ar2.s2
-rw-r--r--test/ELF/Inputs/trace-symbols-foo-strong.s14
-rw-r--r--test/ELF/Inputs/trace-symbols-foo-weak.s12
-rw-r--r--test/ELF/Inputs/undef-with-plt-addr.s7
-rw-r--r--test/ELF/Inputs/undef.s3
-rw-r--r--test/ELF/Inputs/unresolved-symbols.s3
-rw-r--r--test/ELF/Inputs/verdef-defaultver.s22
-rw-r--r--test/ELF/Inputs/verdef.s6
-rwxr-xr-xtest/ELF/Inputs/verneed.so.sh58
-rw-r--r--test/ELF/Inputs/version-script-err.script4
-rw-r--r--test/ELF/Inputs/version-use.script6
-rw-r--r--test/ELF/Inputs/visibility.s1
-rw-r--r--test/ELF/Inputs/warn-common.s2
-rw-r--r--test/ELF/Inputs/warn-common2.s8
-rw-r--r--test/ELF/Inputs/whole-archive.s2
-rw-r--r--test/ELF/Inputs/x86-64-relax-offset.s7
-rw-r--r--test/ELF/Inputs/x86-64-reloc-error.s7
-rw-r--r--test/ELF/Inputs/x86-64-tls-gd-got.s6
-rw-r--r--test/ELF/aarch64-abs64-dyn.s27
-rw-r--r--test/ELF/aarch64-copy.s38
-rw-r--r--test/ELF/aarch64-copy2.s27
-rw-r--r--test/ELF/aarch64-fpic-abs16.s2
-rw-r--r--test/ELF/aarch64-fpic-add_abs_lo12_nc.s2
-rw-r--r--test/ELF/aarch64-fpic-adr_prel_lo21.s2
-rw-r--r--test/ELF/aarch64-fpic-adr_prel_pg_hi21.s2
-rw-r--r--test/ELF/aarch64-fpic-got.s18
-rw-r--r--test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s2
-rw-r--r--test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s2
-rw-r--r--test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s2
-rw-r--r--test/ELF/aarch64-fpic-prel16.s2
-rw-r--r--test/ELF/aarch64-fpic-prel32.s2
-rw-r--r--test/ELF/aarch64-fpic-prel64.s2
-rw-r--r--test/ELF/aarch64-gnu-ifunc-nosym.s6
-rw-r--r--test/ELF/aarch64-gnu-ifunc.s16
-rw-r--r--test/ELF/aarch64-got-relocations.s21
-rw-r--r--test/ELF/aarch64-got.s18
-rw-r--r--test/ELF/aarch64-relative.s26
-rw-r--r--test/ELF/aarch64-relocs.s30
-rw-r--r--test/ELF/aarch64-tls-gdie.s34
-rw-r--r--test/ELF/aarch64-tls-gdle.s26
-rw-r--r--test/ELF/aarch64-tls-ie.s3
-rw-r--r--test/ELF/aarch64-tls-iele.s33
-rw-r--r--test/ELF/aarch64-tls-le.s31
-rw-r--r--test/ELF/aarch64-tls-pie.s28
-rw-r--r--test/ELF/aarch64-tls-static.s37
-rw-r--r--test/ELF/aarch64-tlsdesc.s24
-rw-r--r--test/ELF/abs-hidden.s46
-rw-r--r--test/ELF/allow-shlib-undefined.s2
-rw-r--r--test/ELF/amdgpu-entry.s2
-rw-r--r--test/ELF/amdgpu-globals.s20
-rw-r--r--test/ELF/amdgpu-kernels.s10
-rw-r--r--test/ELF/amdgpu-relocs.s33
-rw-r--r--test/ELF/archive.s4
-rw-r--r--test/ELF/arm-abs32-dyn.s32
-rw-r--r--test/ELF/arm-attributes-remove.s45
-rw-r--r--test/ELF/arm-blx.s113
-rw-r--r--test/ELF/arm-branch-error.s19
-rw-r--r--test/ELF/arm-branch.s59
-rw-r--r--test/ELF/arm-copy.s81
-rw-r--r--test/ELF/arm-data-prel.s63
-rw-r--r--test/ELF/arm-data-relocs.s20
-rw-r--r--test/ELF/arm-fpic-got.s63
-rw-r--r--test/ELF/arm-gnu-ifunc-nosym.s27
-rw-r--r--test/ELF/arm-gnu-ifunc.s131
-rw-r--r--test/ELF/arm-got-relative.s53
-rw-r--r--test/ELF/arm-gotoff.s74
-rw-r--r--test/ELF/arm-mov-relocs.s94
-rw-r--r--test/ELF/arm-plt-reloc.s90
-rw-r--r--test/ELF/arm-thumb-blx.s85
-rw-r--r--test/ELF/arm-thumb-branch-error.s19
-rw-r--r--test/ELF/arm-thumb-branch.s59
-rw-r--r--test/ELF/arm-thumb-interwork-thunk.s375
-rw-r--r--test/ELF/arm-thumb-narrow-branch-check.s72
-rw-r--r--test/ELF/arm-thumb-plt-reloc.s101
-rw-r--r--test/ELF/as-needed-no-reloc.s23
-rw-r--r--test/ELF/as-needed.s5
-rw-r--r--test/ELF/avoid-empty-program-headers.s78
-rw-r--r--test/ELF/basic-aarch64.s2
-rw-r--r--test/ELF/basic-mips.s99
-rw-r--r--test/ELF/basic-ppc.s13
-rw-r--r--test/ELF/basic.s22
-rw-r--r--test/ELF/basic32.s4
-rw-r--r--test/ELF/basic64be.s76
-rw-r--r--test/ELF/bsymbolic-undef.s26
-rw-r--r--test/ELF/bsymbolic.s34
-rw-r--r--test/ELF/build-id.s38
-rw-r--r--test/ELF/combrelocs.s92
-rw-r--r--test/ELF/comdat.s11
-rw-r--r--test/ELF/common.s3
-rw-r--r--test/ELF/compressed-debug-input.s61
-rw-r--r--test/ELF/conflict.s26
-rw-r--r--test/ELF/copy-errors.s15
-rw-r--r--test/ELF/copy-in-shared.s10
-rw-r--r--test/ELF/copy-rel-corrupted.s10
-rw-r--r--test/ELF/copy-rel-pie-error.s12
-rw-r--r--test/ELF/copy-rel-pie.s44
-rw-r--r--test/ELF/ctors_dtors_priority.s41
-rw-r--r--test/ELF/default-output.s2
-rw-r--r--test/ELF/discard-merge-locals.s11
-rw-r--r--test/ELF/discard-merge-unnamed.s11
-rw-r--r--test/ELF/discard-none.s2
-rw-r--r--test/ELF/dont-export-hidden.s39
-rw-r--r--test/ELF/driver.test49
-rw-r--r--test/ELF/duplicate-internal.s2
-rw-r--r--test/ELF/duplicated-plt-entry.s17
-rw-r--r--test/ELF/dynamic-list.s110
-rw-r--r--test/ELF/dynamic-reloc-in-ro.s8
-rw-r--r--test/ELF/dynamic-reloc-weak.s14
-rw-r--r--test/ELF/dynamic-reloc.s2
-rw-r--r--test/ELF/dynamic.s44
-rw-r--r--test/ELF/dynsym-pie.s36
-rw-r--r--test/ELF/edata-etext.s117
-rw-r--r--test/ELF/eh-frame-dyn-rel.s10
-rw-r--r--test/ELF/eh-frame-gc.s20
-rw-r--r--test/ELF/eh-frame-hdr-abs-fde.s33
-rw-r--r--test/ELF/eh-frame-hdr-augmentation.s38
-rw-r--r--test/ELF/eh-frame-hdr-icf.s27
-rw-r--r--test/ELF/eh-frame-hdr-no-out.s6
-rw-r--r--test/ELF/eh-frame-hdr-no-out2.s19
-rw-r--r--test/ELF/eh-frame-hdr.s127
-rw-r--r--test/ELF/eh-frame-marker.s6
-rw-r--r--test/ELF/eh-frame-merge.s2
-rw-r--r--test/ELF/eh-frame-multilpe-cie.s12
-rw-r--r--test/ELF/eh-frame-type.test5
-rw-r--r--test/ELF/ehframe-relocation.s8
-rw-r--r--test/ELF/empty-ver.s25
-rw-r--r--test/ELF/emulation.s118
-rw-r--r--test/ELF/end.s8
-rw-r--r--test/ELF/entry.s4
-rw-r--r--test/ELF/fatal-warnings.s16
-rw-r--r--test/ELF/file-sym.s12
-rw-r--r--test/ELF/gc-merge-local-sym.s34
-rw-r--r--test/ELF/gc-sections-eh.s13
-rw-r--r--test/ELF/gc-sections-local-sym.s57
-rw-r--r--test/ELF/gc-sections-lsda.s21
-rw-r--r--test/ELF/gc-sections-merge-addend.s39
-rw-r--r--test/ELF/gc-sections-merge-implicit-addend.s39
-rw-r--r--test/ELF/gc-sections-merge.s61
-rw-r--r--test/ELF/gc-sections-protected.s18
-rw-r--r--test/ELF/gc-sections-shared.s34
-rw-r--r--test/ELF/gc-sections-weak.s24
-rw-r--r--test/ELF/global_offset_table_shared.s9
-rw-r--r--test/ELF/gnu-ifunc-gotpcrel.s14
-rw-r--r--test/ELF/gnu-ifunc-i386.s16
-rw-r--r--test/ELF/gnu-ifunc-nosym-i386.s6
-rw-r--r--test/ELF/gnu-ifunc-nosym.s6
-rw-r--r--test/ELF/gnu-ifunc-relative.s23
-rw-r--r--test/ELF/gnu-ifunc.s18
-rw-r--r--test/ELF/gnu-unique.s33
-rw-r--r--test/ELF/got-plt-header.s30
-rw-r--r--test/ELF/gotpc-relax-nopic.s81
-rw-r--r--test/ELF/gotpc-relax-und-dso.s72
-rw-r--r--test/ELF/gotpc-relax.s98
-rw-r--r--test/ELF/gotpcrelx.s30
-rw-r--r--test/ELF/i386-got-and-copy.s25
-rw-r--r--test/ELF/i386-gotpc.s20
-rw-r--r--test/ELF/i386-merge.s50
-rw-r--r--test/ELF/i386-relative.s14
-rw-r--r--test/ELF/i386-relax-reloc.s12
-rw-r--r--test/ELF/i386-tls-ie-shared.s110
-rw-r--r--test/ELF/icf1.s23
-rw-r--r--test/ELF/icf2.s17
-rw-r--r--test/ELF/icf3.s19
-rw-r--r--test/ELF/icf4.s19
-rw-r--r--test/ELF/icf5.s19
-rw-r--r--test/ELF/icf6.s23
-rw-r--r--test/ELF/icf7.s29
-rw-r--r--test/ELF/image-base.s60
-rw-r--r--test/ELF/incompatible.s1
-rw-r--r--test/ELF/init-fini.s2
-rw-r--r--test/ELF/init_fini_priority.s37
-rw-r--r--test/ELF/invalid-cie-length.s2
-rw-r--r--test/ELF/invalid-cie-length3.s2
-rw-r--r--test/ELF/invalid-cie-length4.s2
-rw-r--r--test/ELF/invalid-cie-length5.s2
-rw-r--r--test/ELF/invalid-cie-reference.s2
-rw-r--r--test/ELF/invalid-dynamic-list.test37
-rw-r--r--test/ELF/invalid-elf.test13
-rw-r--r--test/ELF/invalid-linkerscript.test54
-rw-r--r--test/ELF/invalid-relocations.test5
-rw-r--r--test/ELF/libsearch.s12
-rw-r--r--test/ELF/linkerscript-align.s41
-rw-r--r--test/ELF/linkerscript-diagnostic.s66
-rw-r--r--test/ELF/linkerscript-locationcounter.s340
-rw-r--r--test/ELF/linkerscript-orphans.s31
-rw-r--r--test/ELF/linkerscript-phdr-check.s15
-rw-r--r--test/ELF/linkerscript-repsection-va.s24
-rw-r--r--test/ELF/linkerscript-sections-keep.s80
-rw-r--r--test/ELF/linkerscript-sections-padding.s44
-rw-r--r--test/ELF/linkerscript-sections.s10
-rw-r--r--test/ELF/linkerscript-symbol-conflict.s11
-rw-r--r--test/ELF/linkerscript-symbols.s11
-rw-r--r--test/ELF/linkerscript-va.s24
-rw-r--r--test/ELF/linkerscript.s38
-rw-r--r--test/ELF/linkerscript2.s8
-rw-r--r--test/ELF/lit.local.cfg2
-rw-r--r--test/ELF/llvm33-rela-outside-group.s11
-rw-r--r--test/ELF/local-dynamic.s11
-rw-r--r--test/ELF/local-got-pie.s36
-rw-r--r--test/ELF/local-undefined-symbol.s13
-rw-r--r--test/ELF/lto/Inputs/archive-2.ll6
-rw-r--r--test/ELF/lto/Inputs/archive-3.ll5
-rw-r--r--test/ELF/lto/Inputs/archive.ll6
-rw-r--r--test/ELF/lto/Inputs/available-externally.ll6
-rw-r--r--test/ELF/lto/Inputs/comdat.s5
-rw-r--r--test/ELF/lto/Inputs/common.s1
-rw-r--r--test/ELF/lto/Inputs/drop-debug-info.bcbin0 -> 1152 bytes
-rw-r--r--test/ELF/lto/Inputs/drop-linkage.ll12
-rw-r--r--test/ELF/lto/Inputs/dynsym.s3
-rw-r--r--test/ELF/lto/Inputs/internalize-exportdyn.ll6
-rw-r--r--test/ELF/lto/Inputs/internalize-undef.ll6
-rw-r--r--test/ELF/lto/Inputs/irmover-error.ll6
-rw-r--r--test/ELF/lto/Inputs/linkonce-odr.ll6
-rw-r--r--test/ELF/lto/Inputs/linkonce.ll6
-rw-r--r--test/ELF/lto/Inputs/resolution.s4
-rw-r--r--test/ELF/lto/Inputs/save-temps.ll6
-rw-r--r--test/ELF/lto/Inputs/shared.s7
-rw-r--r--test/ELF/lto/Inputs/start-lib1.ll8
-rw-r--r--test/ELF/lto/Inputs/start-lib2.ll6
-rw-r--r--test/ELF/lto/Inputs/tls-mixed.s4
-rw-r--r--test/ELF/lto/Inputs/type-merge.ll8
-rw-r--r--test/ELF/lto/Inputs/type-merge2.ll8
-rw-r--r--test/ELF/lto/Inputs/undef-mixed.s3
-rw-r--r--test/ELF/lto/Inputs/unnamed-addr-lib.s6
-rw-r--r--test/ELF/lto/Inputs/visibility.s8
-rw-r--r--test/ELF/lto/archive-2.ll28
-rw-r--r--test/ELF/lto/archive-3.ll19
-rw-r--r--test/ELF/lto/archive.ll37
-rw-r--r--test/ELF/lto/asmundef.ll25
-rw-r--r--test/ELF/lto/available-externally.ll22
-rw-r--r--test/ELF/lto/combined-lto-object-name.ll14
-rw-r--r--test/ELF/lto/comdat.ll21
-rw-r--r--test/ELF/lto/comdat2.ll40
-rw-r--r--test/ELF/lto/common.ll31
-rw-r--r--test/ELF/lto/common2.ll24
-rw-r--r--test/ELF/lto/ctors.ll18
-rw-r--r--test/ELF/lto/discard-value-names.ll23
-rw-r--r--test/ELF/lto/drop-debug-info.ll9
-rw-r--r--test/ELF/lto/drop-linkage.ll14
-rw-r--r--test/ELF/lto/duplicated.ll10
-rw-r--r--test/ELF/lto/dynamic-list.ll25
-rw-r--r--test/ELF/lto/dynsym.ll25
-rw-r--r--test/ELF/lto/inline-asm.ll11
-rw-r--r--test/ELF/lto/internalize-basic.ll21
-rw-r--r--test/ELF/lto/internalize-exportdyn.ll47
-rw-r--r--test/ELF/lto/internalize-llvmused.ll20
-rw-r--r--test/ELF/lto/internalize-undef.ll16
-rw-r--r--test/ELF/lto/internalize-version-script.ll22
-rw-r--r--test/ELF/lto/invalid-bitcode.ll12
-rw-r--r--test/ELF/lto/irmover-error.ll12
-rw-r--r--test/ELF/lto/linkage.ll20
-rw-r--r--test/ELF/lto/linkonce-odr.ll17
-rw-r--r--test/ELF/lto/linkonce.ll17
-rw-r--r--test/ELF/lto/lto-start.ll23
-rw-r--r--test/ELF/lto/ltopasses-basic.ll18
-rw-r--r--test/ELF/lto/ltopasses-custom.ll30
-rw-r--r--test/ELF/lto/metadata.ll13
-rw-r--r--test/ELF/lto/mix-platforms.ll10
-rw-r--r--test/ELF/lto/module-asm.ll19
-rw-r--r--test/ELF/lto/opt-level.ll29
-rw-r--r--test/ELF/lto/parallel-internalize.ll57
-rw-r--r--test/ELF/lto/parallel.ll24
-rw-r--r--test/ELF/lto/pic.ll20
-rw-r--r--test/ELF/lto/relax-relocs.ll15
-rw-r--r--test/ELF/lto/resolution.ll27
-rw-r--r--test/ELF/lto/save-temps.ll20
-rw-r--r--test/ELF/lto/shlib-undefined.ll27
-rw-r--r--test/ELF/lto/start-lib.ll27
-rw-r--r--test/ELF/lto/tls-mixed.ll10
-rw-r--r--test/ELF/lto/tls-preserve.ll25
-rw-r--r--test/ELF/lto/type-merge.ll26
-rw-r--r--test/ELF/lto/type-merge2.ll27
-rw-r--r--test/ELF/lto/undef-mixed.ll22
-rw-r--r--test/ELF/lto/undef-weak.ll29
-rw-r--r--test/ELF/lto/undef.ll20
-rw-r--r--test/ELF/lto/undefined-puts.ll28
-rw-r--r--test/ELF/lto/unnamed-addr-comdat.ll11
-rw-r--r--test/ELF/lto/unnamed-addr-lib.ll21
-rw-r--r--test/ELF/lto/unnamed-addr.ll14
-rw-r--r--test/ELF/lto/verify-invalid.ll17
-rw-r--r--test/ELF/lto/version-script.ll50
-rw-r--r--test/ELF/lto/visibility.ll35
-rw-r--r--test/ELF/lto/weak.ll16
-rw-r--r--test/ELF/merge-shared-str.s28
-rw-r--r--test/ELF/merge-shared.s2
-rw-r--r--test/ELF/merge-string-align.s25
-rw-r--r--test/ELF/merge-string-error.s4
-rw-r--r--test/ELF/merge-string-no-null.s2
-rw-r--r--test/ELF/merge-string.s26
-rw-r--r--test/ELF/merge.s6
-rw-r--r--test/ELF/mips-26.s95
-rw-r--r--test/ELF/mips-32.s78
-rw-r--r--test/ELF/mips-64-disp.s89
-rw-r--r--test/ELF/mips-64-got.s87
-rw-r--r--test/ELF/mips-64-gprel-so.s23
-rw-r--r--test/ELF/mips-64-rels.s46
-rw-r--r--test/ELF/mips-64.s63
-rw-r--r--test/ELF/mips-align-err.s12
-rw-r--r--test/ELF/mips-dynamic.s19
-rw-r--r--test/ELF/mips-gnu-hash.s2
-rw-r--r--test/ELF/mips-got-and-copy.s57
-rw-r--r--test/ELF/mips-got-extsym.s59
-rw-r--r--test/ELF/mips-got-redundant.s58
-rw-r--r--test/ELF/mips-got-relocs.s5
-rw-r--r--test/ELF/mips-got-weak.s172
-rw-r--r--test/ELF/mips-got16.s120
-rw-r--r--test/ELF/mips-gp-disp.s9
-rw-r--r--test/ELF/mips-gp-local.s20
-rw-r--r--test/ELF/mips-gprel32-relocs-gp0.test31
-rw-r--r--test/ELF/mips-gprel32-relocs.s2
-rw-r--r--test/ELF/mips-hilo-gp-disp.s21
-rw-r--r--test/ELF/mips-hilo-hi-only.s2
-rw-r--r--test/ELF/mips-hilo.s10
-rw-r--r--test/ELF/mips-jalr.test7
-rw-r--r--test/ELF/mips-lo16-not-relative.s23
-rw-r--r--test/ELF/mips-nonalloc.s21
-rw-r--r--test/ELF/mips-npic-call-pic.s144
-rw-r--r--test/ELF/mips-options-r.test19
-rw-r--r--test/ELF/mips-options.s28
-rw-r--r--test/ELF/mips-pc-relocs.s15
-rw-r--r--test/ELF/mips-plt-copy.s85
-rw-r--r--test/ELF/mips-relocs.s42
-rw-r--r--test/ELF/mips-sto-plt.s66
-rw-r--r--test/ELF/mips-tls-64.s86
-rw-r--r--test/ELF/mips-tls-hilo.s52
-rw-r--r--test/ELF/mips-tls.s77
-rw-r--r--test/ELF/no-augmentation.s19
-rw-r--r--test/ELF/no-inhibit-exec.s4
-rw-r--r--test/ELF/no-plt-shared.s17
-rw-r--r--test/ELF/no-undefined.s2
-rw-r--r--test/ELF/noplt-pie.s21
-rw-r--r--test/ELF/note.s18
-rw-r--r--test/ELF/phdr-align.s82
-rw-r--r--test/ELF/pie-weak.s16
-rw-r--r--test/ELF/pie.s102
-rw-r--r--test/ELF/plt-aarch64.s2
-rw-r--r--test/ELF/plt-i686.s20
-rw-r--r--test/ELF/plt.s2
-rw-r--r--test/ELF/ppc64-addr16-error.s5
-rw-r--r--test/ELF/ppc64-relocs.s4
-rw-r--r--test/ELF/ppc64-toc-restore.s4
-rw-r--r--test/ELF/pre_init_fini_array.s24
-rw-r--r--test/ELF/progname.s21
-rw-r--r--test/ELF/protected-shared.s52
-rw-r--r--test/ELF/rel-offset.s15
-rw-r--r--test/ELF/relative-dynamic-reloc-pie.s26
-rw-r--r--test/ELF/relative-dynamic-reloc-ppc64.s7
-rw-r--r--test/ELF/relative-dynamic-reloc.s7
-rw-r--r--test/ELF/relocatable-bss.s40
-rw-r--r--test/ELF/relocatable-ehframe.s51
-rw-r--r--test/ELF/relocatable-reloc.s14
-rw-r--r--test/ELF/relocatable-symbols.s183
-rw-r--r--test/ELF/relocatable.s121
-rw-r--r--test/ELF/relocation-copy-alias.s67
-rw-r--r--test/ELF/relocation-copy-flags.s73
-rw-r--r--test/ELF/relocation-copy-i686.s2
-rw-r--r--test/ELF/relocation-copy.s2
-rw-r--r--test/ELF/relocation-i686.s24
-rw-r--r--test/ELF/relocation-in-merge.s2
-rw-r--r--test/ELF/relocation-non-alloc.s60
-rw-r--r--test/ELF/relocation-past-merge-end.s3
-rw-r--r--test/ELF/relocation-relative-absolute.s12
-rw-r--r--test/ELF/relocation-relative-synthetic.s11
-rw-r--r--test/ELF/relocation-relative-weak.s14
-rw-r--r--test/ELF/relocation-shared.s35
-rw-r--r--test/ELF/relocation-size-shared.s76
-rw-r--r--test/ELF/relocation-size.s138
-rw-r--r--test/ELF/relocation.s21
-rw-r--r--test/ELF/relro-tls.s23
-rw-r--r--test/ELF/relro.s2
-rw-r--r--test/ELF/reproduce-error.s15
-rw-r--r--test/ELF/reproduce-linkerscript.s17
-rw-r--r--test/ELF/reproduce-thin-archive.s15
-rw-r--r--test/ELF/reproduce-windows.s12
-rw-r--r--test/ELF/reproduce.s67
-rw-r--r--test/ELF/resolution-shared.s15
-rw-r--r--test/ELF/resolution.s2
-rw-r--r--test/ELF/section-align-0.test3
-rw-r--r--test/ELF/section-name.s6
-rw-r--r--test/ELF/section-symbol.s13
-rw-r--r--test/ELF/shared-be.s7
-rw-r--r--test/ELF/shared.s19
-rw-r--r--test/ELF/soname.s2
-rw-r--r--test/ELF/splitstacks.s11
-rw-r--r--test/ELF/start-lib-comdat.s23
-rw-r--r--test/ELF/start-lib.s25
-rw-r--r--test/ELF/startstop-gccollect.s32
-rw-r--r--test/ELF/startstop-shared.s20
-rw-r--r--test/ELF/startstop.s16
-rw-r--r--test/ELF/string-gc.s73
-rw-r--r--test/ELF/string-table.s5
-rw-r--r--test/ELF/strip-all.s6
-rw-r--r--test/ELF/strip-debug.s25
-rw-r--r--test/ELF/symbol-override.s46
-rw-r--r--test/ELF/symbols.s14
-rw-r--r--test/ELF/sysroot.s4
-rw-r--r--test/ELF/tail-merge-string-align.s35
-rw-r--r--test/ELF/tls-archive.s10
-rw-r--r--test/ELF/tls-dynamic-i686.s24
-rw-r--r--test/ELF/tls-dynamic.s10
-rw-r--r--test/ELF/tls-got-entry.s25
-rw-r--r--test/ELF/tls-got.s2
-rw-r--r--test/ELF/tls-i686.s54
-rw-r--r--test/ELF/tls-in-archive.s11
-rw-r--r--test/ELF/tls-initial-exec-local.s36
-rw-r--r--test/ELF/tls-offset.s56
-rw-r--r--test/ELF/tls-opt-gdie.s27
-rw-r--r--test/ELF/tls-opt-iele-i686-nopic.s59
-rw-r--r--test/ELF/tls-opt-no-plt.s34
-rw-r--r--test/ELF/tls-opt.s74
-rw-r--r--test/ELF/tls-two-relocs.s30
-rw-r--r--test/ELF/trace-ar.s21
-rw-r--r--test/ELF/trace-symbols.s78
-rw-r--r--test/ELF/trace.s9
-rw-r--r--test/ELF/undef-shared.s14
-rw-r--r--test/ELF/undef-version-script.s40
-rw-r--r--test/ELF/undef-with-plt-addr-i686.s23
-rw-r--r--test/ELF/undef-with-plt-addr.s45
-rw-r--r--test/ELF/undef.s15
-rw-r--r--test/ELF/undefined-opt.s13
-rw-r--r--test/ELF/unresolved-symbols.s63
-rw-r--r--test/ELF/user_def_init_array_start.s10
-rw-r--r--test/ELF/valid-cie-length-dw64.s13
-rw-r--r--test/ELF/verdef-defaultver.s205
-rw-r--r--test/ELF/verdef-dependency.s44
-rw-r--r--test/ELF/verdef.s117
-rw-r--r--test/ELF/verneed-as-needed-weak.s14
-rw-r--r--test/ELF/verneed-local.s8
-rw-r--r--test/ELF/verneed.s173
-rw-r--r--test/ELF/version-script-err.s10
-rw-r--r--test/ELF/version-script-extern.s97
-rw-r--r--test/ELF/version-script-noundef.s22
-rw-r--r--test/ELF/version-script.s274
-rw-r--r--test/ELF/version-undef-sym.s42
-rw-r--r--test/ELF/version-use.s9
-rw-r--r--test/ELF/version-wildcard.test114
-rw-r--r--test/ELF/visibility.s31
-rw-r--r--test/ELF/warn-common.s25
-rw-r--r--test/ELF/weak-undef-hidden.s29
-rw-r--r--test/ELF/weak-undef-shared.s19
-rw-r--r--test/ELF/weak-undef.s21
-rw-r--r--test/ELF/whole-archive.s8
-rw-r--r--test/ELF/wildcards.s80
-rw-r--r--test/ELF/writable-merge.s4
-rw-r--r--test/ELF/x86-64-dyn-rel-error.s12
-rw-r--r--test/ELF/x86-64-dyn-rel-error2.s12
-rw-r--r--test/ELF/x86-64-rela.s11
-rw-r--r--test/ELF/x86-64-relax-offset.s13
-rw-r--r--test/ELF/x86-64-reloc-32-fpic.s7
-rw-r--r--test/ELF/x86-64-reloc-32S-error.s7
-rw-r--r--test/ELF/x86-64-reloc-error.s (renamed from test/ELF/x86-64-reloc-32-error.s)6
-rw-r--r--test/ELF/x86-64-reloc-pc32-fpic.s7
-rw-r--r--test/ELF/x86-64-reloc-range.s13
-rw-r--r--test/ELF/x86-64-tls-gd-got.s19
-rw-r--r--test/ELF/x86-64-tls-gd-local.s52
-rw-r--r--test/ELF/x86-64-tls-pie.s26
-rw-r--r--test/ELF/zdefs.s7
508 files changed, 13685 insertions, 674 deletions
diff --git a/test/ELF/Inputs/aarch64-copy2.s b/test/ELF/Inputs/aarch64-copy2.s
new file mode 100644
index 000000000000..8f3f748366be
--- /dev/null
+++ b/test/ELF/Inputs/aarch64-copy2.s
@@ -0,0 +1,5 @@
+ .global foo
+ .type foo, @function
+foo:
+ .global bar
+bar:
diff --git a/test/ELF/Inputs/aarch64-tls-gdie.s b/test/ELF/Inputs/aarch64-tls-gdie.s
new file mode 100644
index 000000000000..289cae523fe8
--- /dev/null
+++ b/test/ELF/Inputs/aarch64-tls-gdie.s
@@ -0,0 +1,4 @@
+ .section .tdata,"awT",@progbits
+ .globl a
+a:
+ .word 42
diff --git a/test/ELF/Inputs/abs-hidden.s b/test/ELF/Inputs/abs-hidden.s
new file mode 100644
index 000000000000..44bff383a8e0
--- /dev/null
+++ b/test/ELF/Inputs/abs-hidden.s
@@ -0,0 +1,3 @@
+.global foo
+.hidden foo
+foo = 0x42
diff --git a/test/ELF/Inputs/allow-shlib-undefined.s b/test/ELF/Inputs/allow-shlib-undefined.s
index e2fb7de2301a..5e3a46179027 100644
--- a/test/ELF/Inputs/allow-shlib-undefined.s
+++ b/test/ELF/Inputs/allow-shlib-undefined.s
@@ -1,3 +1,3 @@
.globl _shared
_shared:
- call _unresolved
+ callq _unresolved@PLT
diff --git a/test/ELF/Inputs/archive.s b/test/ELF/Inputs/archive.s
index 42ccfd47b48b..568bc1fc0a49 100644
--- a/test/ELF/Inputs/archive.s
+++ b/test/ELF/Inputs/archive.s
@@ -1,5 +1,5 @@
-.globl _start;
+.globl _start
_start:
-.globl end;
+.globl end
end:
diff --git a/test/ELF/Inputs/arm-plt-reloc.s b/test/ELF/Inputs/arm-plt-reloc.s
new file mode 100644
index 000000000000..29f133e6eb8f
--- /dev/null
+++ b/test/ELF/Inputs/arm-plt-reloc.s
@@ -0,0 +1,14 @@
+.text
+ .align 2
+ .globl func1
+ .type func1,%function
+func1:
+ bx lr
+ .globl func2
+ .type func2,%function
+func2:
+ bx lr
+ .globl func3
+ .type func3,%function
+func3:
+ bx lr
diff --git a/test/ELF/Inputs/arm-thumb-blx-targets.s b/test/ELF/Inputs/arm-thumb-blx-targets.s
new file mode 100644
index 000000000000..4585ac4399cb
--- /dev/null
+++ b/test/ELF/Inputs/arm-thumb-blx-targets.s
@@ -0,0 +1,36 @@
+ .syntax unified
+ .arm
+ .section .R_ARM_CALL24_callee_low, "ax",%progbits
+ .align 2
+ .globl callee_low
+ .type callee_low,%function
+callee_low:
+ bx lr
+
+ .section .R_ARM_CALL24_callee_thumb_low, "ax",%progbits
+ .balign 0x100
+ .thumb
+ .type callee_thumb_low,%function
+ .globl callee_thumb_low
+callee_thumb_low:
+ bx lr
+
+ .section .R_ARM_CALL24_callee_high, "ax",%progbits
+ .balign 0x100
+ .arm
+ .globl callee_high
+ .type callee_high,%function
+callee_high:
+ bx lr
+
+ .section .R_ARM_CALL24_callee_thumb_high, "ax",%progbits
+ .balign 0x100
+ .thumb
+ .type callee_thumb_high,%function
+ .globl callee_thumb_high
+callee_thumb_high:
+ bx lr
+
+ .globl blx_far
+ .type blx_far, %function
+blx_far = 0x1010018
diff --git a/test/ELF/Inputs/arm-thumb-narrow-branch.s b/test/ELF/Inputs/arm-thumb-narrow-branch.s
new file mode 100644
index 000000000000..473a8e64ef74
--- /dev/null
+++ b/test/ELF/Inputs/arm-thumb-narrow-branch.s
@@ -0,0 +1,18 @@
+// This input must be assembled by the GNU assembler, as llvm-mc does not emit
+// the R_ARM_JUMP11 relocation for a Thumb narrow branch. This is permissible
+// by the ABI for the ARM architecture as the range of the Thumb narrow branch
+// is short enough (+- 2048 bytes) that widespread use would be impractical.
+//
+// The test case will use a pre compiled object arm-thumb-narrow-branch.o
+ .syntax unified
+ .section .caller, "ax",%progbits
+ .thumb
+ .align 2
+ .type callers,%function
+ .globl callers
+callers:
+ b.n callee_low_far
+ b.n callee_low
+ b.n callee_high
+ b.n callee_high_far
+ bx lr
diff --git a/test/ELF/Inputs/conflict.s b/test/ELF/Inputs/conflict.s
new file mode 100644
index 000000000000..545ae99c845a
--- /dev/null
+++ b/test/ELF/Inputs/conflict.s
@@ -0,0 +1,7 @@
+.globl _Z3muldd, foo, baz
+_Z3muldd:
+foo:
+baz:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
diff --git a/test/ELF/Inputs/copy-in-shared.s b/test/ELF/Inputs/copy-in-shared.s
new file mode 100644
index 000000000000..52e99c6707a7
--- /dev/null
+++ b/test/ELF/Inputs/copy-in-shared.s
@@ -0,0 +1,4 @@
+.type foo, @object
+.global foo
+foo:
+.size foo, 4
diff --git a/test/ELF/Inputs/copy-rel-corrupted.s b/test/ELF/Inputs/copy-rel-corrupted.s
new file mode 100644
index 000000000000..b8d1b1aa04c4
--- /dev/null
+++ b/test/ELF/Inputs/copy-rel-corrupted.s
@@ -0,0 +1,4 @@
+.type x,@object
+.globl x
+x:
+.size x, 0
diff --git a/test/ELF/Inputs/copy-rel-pie.s b/test/ELF/Inputs/copy-rel-pie.s
new file mode 100644
index 000000000000..6cd681fcecb4
--- /dev/null
+++ b/test/ELF/Inputs/copy-rel-pie.s
@@ -0,0 +1,9 @@
+.global foo
+.type foo, @object
+.size foo, 4
+foo:
+.long 0
+
+.global bar
+.type bar, @function
+bar:
diff --git a/test/ELF/Inputs/ctors_dtors_priority1.s b/test/ELF/Inputs/ctors_dtors_priority1.s
new file mode 100644
index 000000000000..2eb19d7edad9
--- /dev/null
+++ b/test/ELF/Inputs/ctors_dtors_priority1.s
@@ -0,0 +1,5 @@
+.section .ctors, "aw", @progbits
+ .byte 0xA1
+
+.section .dtors, "aw", @progbits
+ .byte 0xA2
diff --git a/test/ELF/Inputs/ctors_dtors_priority2.s b/test/ELF/Inputs/ctors_dtors_priority2.s
new file mode 100644
index 000000000000..fb85ce87c5c5
--- /dev/null
+++ b/test/ELF/Inputs/ctors_dtors_priority2.s
@@ -0,0 +1,5 @@
+.section .ctors, "aw", @progbits
+ .byte 0xB1
+
+.section .dtors, "aw", @progbits
+ .byte 0xB2
diff --git a/test/ELF/Inputs/ctors_dtors_priority3.s b/test/ELF/Inputs/ctors_dtors_priority3.s
new file mode 100644
index 000000000000..96418d351a85
--- /dev/null
+++ b/test/ELF/Inputs/ctors_dtors_priority3.s
@@ -0,0 +1,5 @@
+.section .ctors, "aw", @progbits
+ .byte 0xC1
+
+.section .dtors, "aw", @progbits
+ .byte 0xC2
diff --git a/test/ELF/Inputs/duplicated-plt-entry.s b/test/ELF/Inputs/duplicated-plt-entry.s
new file mode 100644
index 000000000000..689f3af0ef4a
--- /dev/null
+++ b/test/ELF/Inputs/duplicated-plt-entry.s
@@ -0,0 +1,3 @@
+.global bar
+.type bar, @gnu_indirect_function
+bar:
diff --git a/test/ELF/Inputs/dynamic-reloc-weak.s b/test/ELF/Inputs/dynamic-reloc-weak.s
new file mode 100644
index 000000000000..2310749d9f85
--- /dev/null
+++ b/test/ELF/Inputs/dynamic-reloc-weak.s
@@ -0,0 +1,11 @@
+ .type sym1,@function
+ .global sym1
+sym1:
+
+ .type sym2,@function
+ .global sym2
+sym2:
+
+ .type sym3,@function
+ .global sym3
+sym3:
diff --git a/test/ELF/Inputs/ehframe-relocation.s b/test/ELF/Inputs/ehframe-relocation.s
new file mode 100644
index 000000000000..7ba6c0510cc8
--- /dev/null
+++ b/test/ELF/Inputs/ehframe-relocation.s
@@ -0,0 +1,2 @@
+ .cfi_startproc
+ .cfi_endproc
diff --git a/test/ELF/Inputs/empty-ver.ver b/test/ELF/Inputs/empty-ver.ver
new file mode 100644
index 000000000000..7d4b4ede7675
--- /dev/null
+++ b/test/ELF/Inputs/empty-ver.ver
@@ -0,0 +1,2 @@
+ver {
+};
diff --git a/test/ELF/Inputs/far-arm-abs.s b/test/ELF/Inputs/far-arm-abs.s
new file mode 100644
index 000000000000..68d6aabe00b8
--- /dev/null
+++ b/test/ELF/Inputs/far-arm-abs.s
@@ -0,0 +1,13 @@
+.global far
+.type far,%function
+far = 0x201001c
+
+.global too_far1
+.type too_far1,%function
+too_far1 = 0x2020008
+.global too_far2
+.type too_far2,%function
+too_far2 = 0x202000c
+.global too_far3
+.type too_far3,%function
+too_far3 = 0x2020010
diff --git a/test/ELF/Inputs/far-arm-thumb-abs.s b/test/ELF/Inputs/far-arm-thumb-abs.s
new file mode 100644
index 000000000000..0eb99b8e6ee9
--- /dev/null
+++ b/test/ELF/Inputs/far-arm-thumb-abs.s
@@ -0,0 +1,24 @@
+.global far_cond
+.type far_cond,%function
+far_cond = 0x110023
+.global far_uncond
+.type far_uncond,%function
+far_uncond = 0x101001b
+
+.global too_far1
+.type too_far1,%function
+too_far1 = 0x1020005
+.global too_far2
+.type too_far1,%function
+too_far2 = 0x1020009
+.global too_far3
+.type too_far3,%function
+too_far3 = 0x12000d
+
+.global blx_far
+.type blx_far, %function
+blx_far = 0x2010025
+
+.global blx_far2
+.type blx_far2, %function
+blx_far2 = 0x2010029
diff --git a/test/ELF/Inputs/gc-sections-weak.s b/test/ELF/Inputs/gc-sections-weak.s
new file mode 100644
index 000000000000..27baa6694e3d
--- /dev/null
+++ b/test/ELF/Inputs/gc-sections-weak.s
@@ -0,0 +1,8 @@
+.weak foo
+foo:
+ nop
+
+.data
+.global bar2
+bar2:
+.quad foo
diff --git a/test/ELF/Inputs/gnu-ifunc-gotpcrel.s b/test/ELF/Inputs/gnu-ifunc-gotpcrel.s
new file mode 100644
index 000000000000..83b06e05d461
--- /dev/null
+++ b/test/ELF/Inputs/gnu-ifunc-gotpcrel.s
@@ -0,0 +1,4 @@
+.type foo STT_GNU_IFUNC
+.globl foo
+foo:
+ret
diff --git a/test/ELF/Inputs/gotpc-relax-und-dso.s b/test/ELF/Inputs/gotpc-relax-und-dso.s
new file mode 100644
index 000000000000..cbe39f38ef0b
--- /dev/null
+++ b/test/ELF/Inputs/gotpc-relax-und-dso.s
@@ -0,0 +1,4 @@
+.globl dsofoo
+.type dsofoo, @function
+dsofoo:
+ nop
diff --git a/test/ELF/Inputs/icf2.s b/test/ELF/Inputs/icf2.s
new file mode 100644
index 000000000000..d332130bc935
--- /dev/null
+++ b/test/ELF/Inputs/icf2.s
@@ -0,0 +1,5 @@
+.globl f1, f2
+.section .text.f2, "ax"
+f2:
+ mov $60, %rdi
+ call f1
diff --git a/test/ELF/Inputs/invalid-cie-version2.elf b/test/ELF/Inputs/invalid-cie-version2.elf
new file mode 100644
index 000000000000..87f8a5be76f4
--- /dev/null
+++ b/test/ELF/Inputs/invalid-cie-version2.elf
Binary files differ
diff --git a/test/ELF/Inputs/libsearch-dyn.s b/test/ELF/Inputs/libsearch-dyn.s
index c0c33f92944d..091b3b9b6ece 100644
--- a/test/ELF/Inputs/libsearch-dyn.s
+++ b/test/ELF/Inputs/libsearch-dyn.s
@@ -1,3 +1,3 @@
-.globl _bar,_dynamic;
+.globl _bar,_dynamic
_bar:
_dynamic:
diff --git a/test/ELF/Inputs/libsearch-st.s b/test/ELF/Inputs/libsearch-st.s
index c02ee741c803..6da62f79d52f 100644
--- a/test/ELF/Inputs/libsearch-st.s
+++ b/test/ELF/Inputs/libsearch-st.s
@@ -1,3 +1,3 @@
-.globl _bar,_static;
+.globl _bar,_static
_bar:
_static:
diff --git a/test/ELF/Inputs/mips-align-err.s b/test/ELF/Inputs/mips-align-err.s
new file mode 100644
index 000000000000..2d813b754a45
--- /dev/null
+++ b/test/ELF/Inputs/mips-align-err.s
@@ -0,0 +1,2 @@
+ .global _foo
+_foo:
diff --git a/test/ELF/Inputs/mips-dynamic.s b/test/ELF/Inputs/mips-dynamic.s
index eba5b7f327b4..6f15cf334d9d 100644
--- a/test/ELF/Inputs/mips-dynamic.s
+++ b/test/ELF/Inputs/mips-dynamic.s
@@ -1,4 +1,28 @@
+ .option pic2
.text
.globl _foo
_foo:
nop
+
+ .globl foo0
+ .type foo0, @function
+foo0:
+ nop
+
+ .globl foo1
+ .type foo1, @function
+foo1:
+ nop
+
+ .data
+ .globl data0
+ .type data0, @object
+ .size data0, 4
+data0:
+ .word 0
+
+ .globl data1
+ .type data1, @object
+ .size data1, 4
+data1:
+ .word 0
diff --git a/test/ELF/Inputs/mips-gp-disp.so b/test/ELF/Inputs/mips-gp-disp.so
index 9cbb43720606..150de18fcca1 100644
--- a/test/ELF/Inputs/mips-gp-disp.so
+++ b/test/ELF/Inputs/mips-gp-disp.so
Binary files differ
diff --git a/test/ELF/Inputs/mips-nonalloc.s b/test/ELF/Inputs/mips-nonalloc.s
new file mode 100644
index 000000000000..72bfd274335c
--- /dev/null
+++ b/test/ELF/Inputs/mips-nonalloc.s
@@ -0,0 +1,2 @@
+ .section .debug_info
+ .word __start
diff --git a/test/ELF/Inputs/mips-pic.s b/test/ELF/Inputs/mips-pic.s
new file mode 100644
index 000000000000..880903241d3d
--- /dev/null
+++ b/test/ELF/Inputs/mips-pic.s
@@ -0,0 +1,19 @@
+ .option pic2
+
+ .section .text.1,"ax",@progbits
+ .align 4
+ .globl foo1a
+ .type foo1a, @function
+foo1a:
+ nop
+ .globl foo1b
+ .type foo1b, @function
+foo1b:
+ nop
+
+ .section .text.2,"ax",@progbits
+ .align 4
+ .globl foo2
+ .type foo2, @function
+foo2:
+ nop
diff --git a/test/ELF/Inputs/mips-tls.s b/test/ELF/Inputs/mips-tls.s
new file mode 100644
index 000000000000..9e0a0983e1cd
--- /dev/null
+++ b/test/ELF/Inputs/mips-tls.s
@@ -0,0 +1,5 @@
+ .globl foo
+ .section .tdata,"awT",%progbits
+ .type foo, %object
+foo:
+ .word 0
diff --git a/test/ELF/Inputs/plt-aarch64.s b/test/ELF/Inputs/plt-aarch64.s
new file mode 100644
index 000000000000..0f7a4eda7be1
--- /dev/null
+++ b/test/ELF/Inputs/plt-aarch64.s
@@ -0,0 +1,5 @@
+.global bar
+bar:
+
+.global weak
+weak:
diff --git a/test/ELF/Inputs/ppc64-addr16-error.s b/test/ELF/Inputs/ppc64-addr16-error.s
new file mode 100644
index 000000000000..d83a9f929c6e
--- /dev/null
+++ b/test/ELF/Inputs/ppc64-addr16-error.s
@@ -0,0 +1,3 @@
+.global sym
+.hidden sym
+sym = 0
diff --git a/test/ELF/Inputs/protected-shared.s b/test/ELF/Inputs/protected-shared.s
new file mode 100644
index 000000000000..5f4b1daf63cc
--- /dev/null
+++ b/test/ELF/Inputs/protected-shared.s
@@ -0,0 +1,10 @@
+ .global foo
+ .protected foo
+foo:
+
+ .global bar
+ .protected bar
+bar:
+
+ .global zed
+zed:
diff --git a/test/ELF/Inputs/relocatable-ehframe.s b/test/ELF/Inputs/relocatable-ehframe.s
new file mode 100644
index 000000000000..384aac6e7ced
--- /dev/null
+++ b/test/ELF/Inputs/relocatable-ehframe.s
@@ -0,0 +1,14 @@
+.section foo1,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section bar1,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section dah1,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
diff --git a/test/ELF/Inputs/relocatable.s b/test/ELF/Inputs/relocatable.s
new file mode 100644
index 000000000000..de34a6b3bf0e
--- /dev/null
+++ b/test/ELF/Inputs/relocatable.s
@@ -0,0 +1,22 @@
+.text
+.type xx,@object
+.bss
+.globl xx
+.align 4
+xx:
+.long 0
+.size xx, 4
+.type yy,@object
+.globl yy
+.align 4
+yy:
+.long 0
+.size yy, 4
+
+.text
+.globl foo
+.align 16, 0x90
+.type foo,@function
+foo:
+movl $1, xx
+movl $2, yy
diff --git a/test/ELF/Inputs/relocatable2.s b/test/ELF/Inputs/relocatable2.s
new file mode 100644
index 000000000000..93e23bc7ae69
--- /dev/null
+++ b/test/ELF/Inputs/relocatable2.s
@@ -0,0 +1,22 @@
+.text
+.type xxx,@object
+.bss
+.globl xxx
+.align 4
+xxx:
+.long 0
+.size xxx, 4
+.type yyy,@object
+.globl yyy
+.align 4
+yyy:
+.long 0
+.size yyy, 4
+
+.text
+.globl bar
+.align 16, 0x90
+.type bar,@function
+bar:
+movl $8, xxx
+movl $9, yyy
diff --git a/test/ELF/Inputs/relocation-copy-alias.s b/test/ELF/Inputs/relocation-copy-alias.s
new file mode 100644
index 000000000000..a9bc3d76a12c
--- /dev/null
+++ b/test/ELF/Inputs/relocation-copy-alias.s
@@ -0,0 +1,25 @@
+.data
+
+.globl a1
+.type a1, @object
+.size a1, 1
+a1:
+.weak a2
+.type a2, @object
+.size a2, 1
+a2:
+.byte 1
+
+.weak b1
+.type b1, @object
+.size b1, 1
+b1:
+.weak b2
+.type b2, @object
+.size b2, 1
+b2:
+.globl b3
+.type b3, @object
+.size b3, 1
+b3:
+.byte 1
diff --git a/test/ELF/Inputs/relocation-copy-arm.s b/test/ELF/Inputs/relocation-copy-arm.s
new file mode 100644
index 000000000000..ba5ab73043c9
--- /dev/null
+++ b/test/ELF/Inputs/relocation-copy-arm.s
@@ -0,0 +1,22 @@
+.bss
+
+.type x,%object
+.globl x
+.balign 16
+x:
+.long 0
+.size x, 4
+
+.type y,%object
+.globl y
+.balign 16
+y:
+.long 0
+.size y, 4
+
+.type z,%object
+.globl z
+.balign 4
+z:
+.long 0
+.size z, 4
diff --git a/test/ELF/Inputs/resolution-shared.s b/test/ELF/Inputs/resolution-shared.s
new file mode 100644
index 000000000000..2f0ccf81e395
--- /dev/null
+++ b/test/ELF/Inputs/resolution-shared.s
@@ -0,0 +1,2 @@
+ .global foo
+foo:
diff --git a/test/ELF/Inputs/shared.s b/test/ELF/Inputs/shared.s
index 1cfebbfaf373..c3c22fe4b4fb 100644
--- a/test/ELF/Inputs/shared.s
+++ b/test/ELF/Inputs/shared.s
@@ -2,5 +2,9 @@
.type bar, @function
bar:
+.global bar2
+.type bar2, @function
+bar2:
+
.global zed
zed:
diff --git a/test/ELF/Inputs/start-lib-comdat.s b/test/ELF/Inputs/start-lib-comdat.s
new file mode 100644
index 000000000000..dcbaaf443851
--- /dev/null
+++ b/test/ELF/Inputs/start-lib-comdat.s
@@ -0,0 +1,5 @@
+ .global bar
+bar:
+ .section .sec,"aG",@progbits,zed,comdat
+ .global zed
+zed:
diff --git a/test/ELF/Inputs/start-lib1.s b/test/ELF/Inputs/start-lib1.s
new file mode 100644
index 000000000000..d401b20e65dc
--- /dev/null
+++ b/test/ELF/Inputs/start-lib1.s
@@ -0,0 +1,3 @@
+.globl foo
+foo:
+ call bar
diff --git a/test/ELF/Inputs/start-lib2.s b/test/ELF/Inputs/start-lib2.s
new file mode 100644
index 000000000000..f500936565f7
--- /dev/null
+++ b/test/ELF/Inputs/start-lib2.s
@@ -0,0 +1,2 @@
+.globl bar
+bar:
diff --git a/test/ELF/Inputs/symbol-override.s b/test/ELF/Inputs/symbol-override.s
new file mode 100644
index 000000000000..21f3ae244c77
--- /dev/null
+++ b/test/ELF/Inputs/symbol-override.s
@@ -0,0 +1,16 @@
+.text
+.globl foo
+.type foo,@function
+foo:
+nop
+
+.globl bar
+.type bar,@function
+bar:
+nop
+
+.globl do
+.type do,@function
+do:
+callq foo@PLT
+callq bar@PLT
diff --git a/test/ELF/Inputs/tls-got-entry.s b/test/ELF/Inputs/tls-got-entry.s
new file mode 100644
index 000000000000..e1e09a3306a2
--- /dev/null
+++ b/test/ELF/Inputs/tls-got-entry.s
@@ -0,0 +1,13 @@
+.globl __tls_get_addr
+.align 16, 0x90
+.type __tls_get_addr,@function
+__tls_get_addr:
+
+.type tlsshared0,@object
+.section .tbss,"awT",@nobits
+.globl tlsshared0
+.align 4
+tlsshared0:
+ .long 0
+ .size tlsshared0, 4
+
diff --git a/test/ELF/Inputs/tls-in-archive.s b/test/ELF/Inputs/tls-in-archive.s
new file mode 100644
index 000000000000..0474a417659e
--- /dev/null
+++ b/test/ELF/Inputs/tls-in-archive.s
@@ -0,0 +1,3 @@
+ .type foo, @tls_object
+ .globl foo
+foo:
diff --git a/test/ELF/Inputs/trace-ar1.s b/test/ELF/Inputs/trace-ar1.s
new file mode 100644
index 000000000000..0292bae6b4d4
--- /dev/null
+++ b/test/ELF/Inputs/trace-ar1.s
@@ -0,0 +1,2 @@
+.globl _used
+_used:
diff --git a/test/ELF/Inputs/trace-ar2.s b/test/ELF/Inputs/trace-ar2.s
new file mode 100644
index 000000000000..d56f304c82f3
--- /dev/null
+++ b/test/ELF/Inputs/trace-ar2.s
@@ -0,0 +1,2 @@
+.globl _notused
+_notused:
diff --git a/test/ELF/Inputs/trace-symbols-foo-strong.s b/test/ELF/Inputs/trace-symbols-foo-strong.s
new file mode 100644
index 000000000000..874642978c9b
--- /dev/null
+++ b/test/ELF/Inputs/trace-symbols-foo-strong.s
@@ -0,0 +1,14 @@
+.text
+.globl foo
+.type foo, @function
+foo:
+nop
+
+.globl bar
+.type bar, @function
+bar:
+nop
+
+.global func2
+.type func2, @function
+func2:
diff --git a/test/ELF/Inputs/trace-symbols-foo-weak.s b/test/ELF/Inputs/trace-symbols-foo-weak.s
new file mode 100644
index 000000000000..d071ebecc4b5
--- /dev/null
+++ b/test/ELF/Inputs/trace-symbols-foo-weak.s
@@ -0,0 +1,12 @@
+.comm common,4,4
+.text
+.weak foo
+.type foo, @function
+foo:
+callq bar@PLT
+
+.globl func1
+.type func1, @function
+func1:
+call func2@PLT
+
diff --git a/test/ELF/Inputs/undef-with-plt-addr.s b/test/ELF/Inputs/undef-with-plt-addr.s
new file mode 100644
index 000000000000..b12737d9e098
--- /dev/null
+++ b/test/ELF/Inputs/undef-with-plt-addr.s
@@ -0,0 +1,7 @@
+ .globl set_data
+ .type set_data,@function
+set_data:
+
+ .globl foo
+ .type foo,@function
+foo:
diff --git a/test/ELF/Inputs/undef.s b/test/ELF/Inputs/undef.s
new file mode 100644
index 000000000000..01776bf3505e
--- /dev/null
+++ b/test/ELF/Inputs/undef.s
@@ -0,0 +1,3 @@
+ .global zed1
+zed1:
+ .quad zed2
diff --git a/test/ELF/Inputs/unresolved-symbols.s b/test/ELF/Inputs/unresolved-symbols.s
new file mode 100644
index 000000000000..b504708e43da
--- /dev/null
+++ b/test/ELF/Inputs/unresolved-symbols.s
@@ -0,0 +1,3 @@
+.globl _shared
+_shared:
+ callq undef@PLT
diff --git a/test/ELF/Inputs/verdef-defaultver.s b/test/ELF/Inputs/verdef-defaultver.s
new file mode 100644
index 000000000000..2e1d1c36fb92
--- /dev/null
+++ b/test/ELF/Inputs/verdef-defaultver.s
@@ -0,0 +1,22 @@
+b@LIBSAMPLE_1.0 = b_1
+b@@LIBSAMPLE_2.0 = b_2
+
+.globl a
+.type a,@function
+a:
+retq
+
+.globl b_1
+.type b_1,@function
+b_1:
+retq
+
+.globl b_2
+.type b_2,@function
+b_2:
+retq
+
+.globl c
+.type c,@function
+c:
+retq
diff --git a/test/ELF/Inputs/verdef.s b/test/ELF/Inputs/verdef.s
new file mode 100644
index 000000000000..349d5fd0c261
--- /dev/null
+++ b/test/ELF/Inputs/verdef.s
@@ -0,0 +1,6 @@
+.text
+.globl _start
+_start:
+ callq a
+ callq b
+ callq c
diff --git a/test/ELF/Inputs/verneed.so.sh b/test/ELF/Inputs/verneed.so.sh
new file mode 100755
index 000000000000..3423f678e47a
--- /dev/null
+++ b/test/ELF/Inputs/verneed.so.sh
@@ -0,0 +1,58 @@
+#!/bin/sh -eu
+
+# This script was used to produce the verneed{1,2}.so files.
+
+tmp=$(mktemp -d)
+
+echo "v1 {}; v2 {}; v3 {}; { local: *; };" > $tmp/verneed.script
+
+cat > $tmp/verneed1.s <<eof
+.globl f1_v1
+f1_v1:
+ret
+
+.globl f1_v2
+f1_v2:
+ret
+
+.globl f1_v3
+f1_v3:
+ret
+
+.symver f1_v1, f1@v1
+.symver f1_v2, f1@v2
+.symver f1_v3, f1@@v3
+
+.globl f2_v1
+f2_v1:
+ret
+
+.globl f2_v2
+f2_v2:
+ret
+
+.symver f2_v1, f2@v1
+.symver f2_v2, f2@@v2
+
+.globl f3_v1
+f3_v1:
+ret
+
+.symver f3_v1, f3@v1
+eof
+
+as -o $tmp/verneed1.o $tmp/verneed1.s
+ld.gold -shared -o verneed1.so $tmp/verneed1.o --version-script $tmp/verneed.script -soname verneed1.so.0
+
+cat > $tmp/verneed2.s <<eof
+.globl g1_v1
+g1_v1:
+ret
+
+.symver g1_v1, g1@@v1
+eof
+
+as -o $tmp/verneed2.o $tmp/verneed2.s
+ld.gold -shared -o verneed2.so $tmp/verneed2.o --version-script $tmp/verneed.script -soname verneed2.so.0
+
+rm -rf $tmp
diff --git a/test/ELF/Inputs/version-script-err.script b/test/ELF/Inputs/version-script-err.script
new file mode 100644
index 000000000000..37de5980466e
--- /dev/null
+++ b/test/ELF/Inputs/version-script-err.script
@@ -0,0 +1,4 @@
+{
+ global:
+ foo
+};
diff --git a/test/ELF/Inputs/version-use.script b/test/ELF/Inputs/version-use.script
new file mode 100644
index 000000000000..5b2721b05b61
--- /dev/null
+++ b/test/ELF/Inputs/version-use.script
@@ -0,0 +1,6 @@
+ABC {
+global:
+foo;
+local:
+*;
+};
diff --git a/test/ELF/Inputs/visibility.s b/test/ELF/Inputs/visibility.s
index 6ef027d315fa..fe7cd9a49e7e 100644
--- a/test/ELF/Inputs/visibility.s
+++ b/test/ELF/Inputs/visibility.s
@@ -1,3 +1,4 @@
+.data
.quad default
.protected protected
diff --git a/test/ELF/Inputs/warn-common.s b/test/ELF/Inputs/warn-common.s
new file mode 100644
index 000000000000..fc4509ba70c7
--- /dev/null
+++ b/test/ELF/Inputs/warn-common.s
@@ -0,0 +1,2 @@
+.type arr,@object
+.comm arr,8,4
diff --git a/test/ELF/Inputs/warn-common2.s b/test/ELF/Inputs/warn-common2.s
new file mode 100644
index 000000000000..976c5becb09f
--- /dev/null
+++ b/test/ELF/Inputs/warn-common2.s
@@ -0,0 +1,8 @@
+.type arr,@object
+.data
+.globl arr
+.p2align 2
+arr:
+ .long 1
+ .long 0
+ .size arr, 8
diff --git a/test/ELF/Inputs/whole-archive.s b/test/ELF/Inputs/whole-archive.s
index f9d56fc2fa21..816b24e2beca 100644
--- a/test/ELF/Inputs/whole-archive.s
+++ b/test/ELF/Inputs/whole-archive.s
@@ -1,2 +1,2 @@
-.globl _bar;
+.globl _bar
_bar:
diff --git a/test/ELF/Inputs/x86-64-relax-offset.s b/test/ELF/Inputs/x86-64-relax-offset.s
new file mode 100644
index 000000000000..780d1d0e64c1
--- /dev/null
+++ b/test/ELF/Inputs/x86-64-relax-offset.s
@@ -0,0 +1,7 @@
+.global foo
+.hidden foo
+foo:
+ nop
+ nop
+ nop
+ nop
diff --git a/test/ELF/Inputs/x86-64-reloc-error.s b/test/ELF/Inputs/x86-64-reloc-error.s
new file mode 100644
index 000000000000..bce6f8fafaaa
--- /dev/null
+++ b/test/ELF/Inputs/x86-64-reloc-error.s
@@ -0,0 +1,7 @@
+.global big
+.hidden big
+big = 0x1000000000
+
+.global foo
+.hidden foo
+foo = 0
diff --git a/test/ELF/Inputs/x86-64-tls-gd-got.s b/test/ELF/Inputs/x86-64-tls-gd-got.s
new file mode 100644
index 000000000000..67a021a44fce
--- /dev/null
+++ b/test/ELF/Inputs/x86-64-tls-gd-got.s
@@ -0,0 +1,6 @@
+ .globl bar
+ .section .tdata,"awT",@progbits
+ .align 4
+ .type bar, @object
+bar:
+ .long 42
diff --git a/test/ELF/aarch64-abs64-dyn.s b/test/ELF/aarch64-abs64-dyn.s
new file mode 100644
index 000000000000..2220225d5300
--- /dev/null
+++ b/test/ELF/aarch64-abs64-dyn.s
@@ -0,0 +1,27 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
+
+// Creates a R_AARCH64_ABS64 relocation against foo and bar
+ .globl foo
+foo:
+
+ .global bar
+ .hidden bar
+bar:
+
+ .data
+ .xword foo
+ .xword bar
+
+// RUN: ld.lld -shared -o %t.so %t.o
+// RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s
+
+// CHECK: Dynamic Relocations {
+// CHECK-NEXT: {{.*}} R_AARCH64_RELATIVE - [[BAR_ADDR:.*]]
+// CHECK-NEXT: {{.*}} R_AARCH64_ABS64 foo 0x0
+// CHECK-NEXT: }
+
+// CHECK: Symbols [
+// CHECK: Symbol {
+// CHECK: Name: bar
+// CHECK-NEXT: Value: [[BAR_ADDR]]
diff --git a/test/ELF/aarch64-copy.s b/test/ELF/aarch64-copy.s
index 86d972057df0..6e0af27a0c6b 100644
--- a/test/ELF/aarch64-copy.s
+++ b/test/ELF/aarch64-copy.s
@@ -5,7 +5,7 @@
// RUN: ld.lld %t.o %t2.so -o %t3
// RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s
// RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s
-// RUN: llvm-objdump -s -section=.data %t3 | FileCheck -check-prefix=DATA %s
+// RUN: llvm-objdump -s -section=.rodata %t3 | FileCheck -check-prefix=RODATA %s
.text
.globl _start
@@ -13,7 +13,7 @@ _start:
adr x1, x
adrp x2, y
add x2, x2, :lo12:y
-.data
+.rodata
.word z
// CHECK: Name: .bss
@@ -22,7 +22,7 @@ _start:
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x13010
+// CHECK-NEXT: Address: 0x13000
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 24
// CHECK-NEXT: Link:
@@ -32,19 +32,19 @@ _start:
// CHECK: Relocations [
// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x13010
+// CHECK-NEXT: Offset: 0x13000
// CHECK-NEXT: Type: R_AARCH64_COPY
// CHECK-NEXT: Symbol: x
// CHECK-NEXT: Addend: 0x0
// CHECK-NEXT: }
// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x13020
+// CHECK-NEXT: Offset: 0x13010
// CHECK-NEXT: Type: R_AARCH64_COPY
// CHECK-NEXT: Symbol: y
// CHECK-NEXT: Addend: 0x0
// CHECK-NEXT: }
// CHECK-NEXT: Relocation {
-// CHECK-NEXT: Offset: 0x13024
+// CHECK-NEXT: Offset: 0x13014
// CHECK-NEXT: Type: R_AARCH64_COPY
// CHECK-NEXT: Symbol: z
// CHECK-NEXT: Addend: 0x0
@@ -54,21 +54,21 @@ _start:
// CHECK: Symbols [
// CHECK: Name: x
-// CHECK-NEXT: Value: 0x13010
+// CHECK-NEXT: Value: 0x13000
// CHECK-NEXT: Size: 4
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: Object
// CHECK-NEXT: Other:
// CHECK-NEXT: Section: .bss
// CHECK: Name: y
-// CHECK-NEXT: Value: 0x13020
+// CHECK-NEXT: Value: 0x13010
// CHECK-NEXT: Size: 4
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: Object
// CHECK-NEXT: Other:
// CHECK-NEXT: Section: .bss
// CHECK: Name: z
-// CHECK-NEXT: Value: 0x13024
+// CHECK-NEXT: Value: 0x13014
// CHECK-NEXT: Size: 4
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: Object
@@ -78,16 +78,16 @@ _start:
// CODE: Disassembly of section .text:
// CODE-NEXT: _start:
-// S(x) = 0x13010, A = 0, P = 0x11000
-// S + A - P = 0x10B0 = 8208
-// CODE-NEXT: 11000: {{.*}} adr x1, #8208
-// S(y) = 0x13020, A = 0, P = 0x11004
+// S(x) = 0x13000, A = 0, P = 0x11000
+// S + A - P = 0x2000 = 8208
+// CODE-NEXT: 11000: {{.*}} adr x1, #8192
+// S(y) = 0x13010, A = 0, P = 0x11004
// Page(S + A) - Page(P) = 0x13000 - 0x11000 = 0x2000 = 8192
// CODE-NEXT: 11004: {{.*}} adrp x2, #8192
-// S(y) = 0x13020, A = 0
-// (S + A) & 0xFFF = 0x20 = 32
-// CODE-NEXT: 11008: {{.*}} add x2, x2, #32
+// S(y) = 0x13010, A = 0
+// (S + A) & 0xFFF = 0x10 = 16
+// CODE-NEXT: 11008: {{.*}} add x2, x2, #16
-// DATA: Contents of section .data:
-// S(z) = 0x13024
-// DATA-NEXT: 13000 24300100
+// RODATA: Contents of section .rodata:
+// S(z) = 0x13014
+// RODATA-NEXT: 101c8 14300100
diff --git a/test/ELF/aarch64-copy2.s b/test/ELF/aarch64-copy2.s
new file mode 100644
index 000000000000..af99d8ec2aee
--- /dev/null
+++ b/test/ELF/aarch64-copy2.s
@@ -0,0 +1,27 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux
+// RUN: llvm-mc %p/Inputs/aarch64-copy2.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: llvm-readobj -t %t | FileCheck %s
+
+ .global _start
+_start:
+ adrp x8, foo
+ bl bar
+
+// CHECK: Name: bar
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+
+// CHECK: Name: foo
+// CHECK-NEXT: Value: 0x11030
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Function
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
diff --git a/test/ELF/aarch64-fpic-abs16.s b/test/ELF/aarch64-fpic-abs16.s
index 02ac90d3a1f2..e123f57447a5 100644
--- a/test/ELF/aarch64-fpic-abs16.s
+++ b/test/ELF/aarch64-fpic-abs16.s
@@ -1,7 +1,7 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-// CHECK: Relocation R_AARCH64_ABS16 cannot be used when making a shared object; recompile with -fPIC.
+// CHECK: relocation R_AARCH64_ABS16 cannot be used against shared object; recompile with -fPIC.
.data
.hword foo
diff --git a/test/ELF/aarch64-fpic-add_abs_lo12_nc.s b/test/ELF/aarch64-fpic-add_abs_lo12_nc.s
index 9e3216b1e090..7e0b6b833006 100644
--- a/test/ELF/aarch64-fpic-add_abs_lo12_nc.s
+++ b/test/ELF/aarch64-fpic-add_abs_lo12_nc.s
@@ -1,7 +1,7 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-// CHECK: Relocation R_AARCH64_ADD_ABS_LO12_NC cannot be used when making a shared object; recompile with -fPIC.
+// CHECK: can't create dynamic relocation R_AARCH64_ADD_ABS_LO12_NC against readonly segment
add x0, x0, :lo12:dat
.data
diff --git a/test/ELF/aarch64-fpic-adr_prel_lo21.s b/test/ELF/aarch64-fpic-adr_prel_lo21.s
index 2246b64c6a71..501a724616e3 100644
--- a/test/ELF/aarch64-fpic-adr_prel_lo21.s
+++ b/test/ELF/aarch64-fpic-adr_prel_lo21.s
@@ -1,7 +1,7 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-// CHECK: Relocation R_AARCH64_ADR_PREL_LO21 cannot be used when making a shared object; recompile with -fPIC.
+// CHECK: can't create dynamic relocation R_AARCH64_ADR_PREL_LO21 against readonly segment
adr x0, dat
.data
diff --git a/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s b/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s
index af6ebfc3e879..572ecffa6d71 100644
--- a/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s
+++ b/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s
@@ -1,7 +1,7 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-// CHECK: Relocation R_AARCH64_ADR_PREL_PG_HI21 cannot be used when making a shared object; recompile with -fPIC.
+// CHECK: can't create dynamic relocation R_AARCH64_ADR_PREL_PG_HI21 against readonly segment
adrp x0, dat
.data
diff --git a/test/ELF/aarch64-fpic-got.s b/test/ELF/aarch64-fpic-got.s
new file mode 100644
index 000000000000..70b2a7a76f86
--- /dev/null
+++ b/test/ELF/aarch64-fpic-got.s
@@ -0,0 +1,18 @@
+# REQUIRES: aarch64
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %p/Inputs/shared.s -o %t-lib.o
+# RUN: ld.lld -shared %t-lib.o -o %t-lib.so
+# RUN: ld.lld %t-lib.so %t.o -o %t.exe
+# RUN: llvm-readobj -dyn-relocations %t.exe | FileCheck %s
+
+## Checks if got access to dynamic objects is done through a got relative
+## dynamic relocation and not using plt relative (R_AARCH64_JUMP_SLOT).
+# CHECK: Dynamic Relocations {
+# CHECK-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_GLOB_DAT bar 0x0
+# CHECK-NEXT: }
+
+.globl _start
+_start:
+ adrp x0, :got:bar
+ ldr x0, [x0, :got_lo12:bar]
diff --git a/test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s b/test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s
index 2b1e6769e1a0..85772f10fcc7 100644
--- a/test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s
+++ b/test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s
@@ -1,7 +1,7 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-// CHECK: Relocation R_AARCH64_LDST32_ABS_LO12_NC cannot be used when making a shared object; recompile with -fPIC.
+// CHECK: can't create dynamic relocation R_AARCH64_LDST32_ABS_LO12_NC against readonly segment
ldr s4, [x0, :lo12:dat]
.data
diff --git a/test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s b/test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s
index f2553879cf37..d9f7b0c9ad1b 100644
--- a/test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s
+++ b/test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s
@@ -1,7 +1,7 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-// CHECK: Relocation R_AARCH64_LDST64_ABS_LO12_NC cannot be used when making a shared object; recompile with -fPIC.
+// CHECK: can't create dynamic relocation R_AARCH64_LDST64_ABS_LO12_NC against readonly segment
ldr x0, [x0, :lo12:dat]
.data
diff --git a/test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s b/test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s
index f7b465731b46..20e1bba49d1e 100644
--- a/test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s
+++ b/test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s
@@ -1,7 +1,7 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-// CHECK: Relocation R_AARCH64_LDST8_ABS_LO12_NC cannot be used when making a shared object; recompile with -fPIC.
+// CHECK: can't create dynamic relocation R_AARCH64_LDST8_ABS_LO12_NC against readonly segment
ldrsb x0, [x1, :lo12:dat]
.data
diff --git a/test/ELF/aarch64-fpic-prel16.s b/test/ELF/aarch64-fpic-prel16.s
index d80b6e88a67a..52e2402a4831 100644
--- a/test/ELF/aarch64-fpic-prel16.s
+++ b/test/ELF/aarch64-fpic-prel16.s
@@ -1,7 +1,7 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-// CHECK: Relocation R_AARCH64_PREL16 cannot be used when making a shared object; recompile with -fPIC.
+// CHECK: relocation R_AARCH64_PREL16 cannot be used against shared object; recompile with -fPIC.
.data
.hword foo - .
diff --git a/test/ELF/aarch64-fpic-prel32.s b/test/ELF/aarch64-fpic-prel32.s
index af540ce734bb..72ba58f84d56 100644
--- a/test/ELF/aarch64-fpic-prel32.s
+++ b/test/ELF/aarch64-fpic-prel32.s
@@ -1,7 +1,7 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-// CHECK: Relocation R_AARCH64_PREL32 cannot be used when making a shared object; recompile with -fPIC.
+// CHECK: relocation R_AARCH64_PREL32 cannot be used against shared object; recompile with -fPIC.
.data
.word foo - .
diff --git a/test/ELF/aarch64-fpic-prel64.s b/test/ELF/aarch64-fpic-prel64.s
index 2cf4cc916b3e..53a4820962b6 100644
--- a/test/ELF/aarch64-fpic-prel64.s
+++ b/test/ELF/aarch64-fpic-prel64.s
@@ -1,7 +1,7 @@
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-// CHECK: Relocation R_AARCH64_PREL64 cannot be used when making a shared object; recompile with -fPIC.
+// CHECK: relocation R_AARCH64_PREL64 cannot be used against shared object; recompile with -fPIC.
.data
.xword foo - .
diff --git a/test/ELF/aarch64-gnu-ifunc-nosym.s b/test/ELF/aarch64-gnu-ifunc-nosym.s
index d85bf1076601..bb3a0b8b5116 100644
--- a/test/ELF/aarch64-gnu-ifunc-nosym.s
+++ b/test/ELF/aarch64-gnu-ifunc-nosym.s
@@ -6,20 +6,18 @@
// Check that no __rela_iplt_end/__rela_iplt_start
// appear in symtab if there is no references to them.
// CHECK: Symbols [
-// CHECK-NEXT-NOT: __rela_iplt_end
-// CHECK-NEXT-NOT: __rela_iplt_start
+// CHECK-NOT: __rela_iplt_end
+// CHECK-NOT: __rela_iplt_start
// CHECK: ]
.text
.type foo STT_GNU_IFUNC
.globl foo
-.type foo, @function
foo:
ret
.type bar STT_GNU_IFUNC
.globl bar
-.type bar, @function
bar:
ret
diff --git a/test/ELF/aarch64-gnu-ifunc.s b/test/ELF/aarch64-gnu-ifunc.s
index 4cc94200789d..351d0ed0440a 100644
--- a/test/ELF/aarch64-gnu-ifunc.s
+++ b/test/ELF/aarch64-gnu-ifunc.s
@@ -1,7 +1,7 @@
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
// RUN: ld.lld -static %t.o -o %tout
// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
-// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s --check-prefix=CHECK
+// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
// REQUIRES: aarch64
// CHECK: Sections [
@@ -51,8 +51,10 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
-// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .rela.plt
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: __rela_iplt_start
@@ -60,8 +62,10 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
-// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .rela.plt
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: _start
@@ -126,13 +130,11 @@
.text
.type foo STT_GNU_IFUNC
.globl foo
-.type foo, @function
foo:
ret
.type bar STT_GNU_IFUNC
.globl bar
-.type bar, @function
bar:
ret
diff --git a/test/ELF/aarch64-got-relocations.s b/test/ELF/aarch64-got-relocations.s
new file mode 100644
index 000000000000..13ee09a892e9
--- /dev/null
+++ b/test/ELF/aarch64-got-relocations.s
@@ -0,0 +1,21 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-cloudabi %s -o %t.o
+# RUN: ld.lld -pie %t.o -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+
+# If we're addressing a global relatively through the GOT, we still need to
+# emit a relocation for the entry in the GOT itself.
+# CHECK: Relocations [
+# CHECK: Section (4) .rela.dyn {
+# CHECK: 0x{{[0-9A-F]+}} R_AARCH64_RELATIVE - 0x{{[0-9A-F]+}}
+# CHECK: }
+# CHECK: ]
+
+ .globl _start
+ .type _start,@function
+_start:
+ adrp x8, :got:i
+ ldr x8, [x8, :got_lo12:i]
+
+ .type i,@object
+ .comm i,4,4
diff --git a/test/ELF/aarch64-got.s b/test/ELF/aarch64-got.s
new file mode 100644
index 000000000000..f56d8a734784
--- /dev/null
+++ b/test/ELF/aarch64-got.s
@@ -0,0 +1,18 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t.o
+# RUN: ld.lld %t.o -o %t
+# RUN: llvm-readobj -s %t | FileCheck %s
+
+# CHECK-NOT: Name: .got
+
+.globl _start
+_start:
+ adrp x0, :gottprel:foo
+
+ .global foo
+ .section .tdata,"awT",%progbits
+ .align 2
+ .type foo, %object
+ .size foo, 4
+foo:
+ .word 5
diff --git a/test/ELF/aarch64-relative.s b/test/ELF/aarch64-relative.s
new file mode 100644
index 000000000000..b10dd80fae6c
--- /dev/null
+++ b/test/ELF/aarch64-relative.s
@@ -0,0 +1,26 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -r %t.so | FileCheck %s
+
+ adr x8, .Lfoo // R_AARCH64_ADR_PREL_LO21
+ adrp x8, .Lfoo // R_AARCH64_ADR_PREL_PG_HI21
+ strb w9, [x8, :lo12:.Lfoo] // R_AARCH64_LDST8_ABS_LO12_NC
+ ldr h17, [x19, :lo12:.Lfoo] // R_AARCH64_LDST16_ABS_LO12_NC
+ ldr w0, [x8, :lo12:.Lfoo] // R_AARCH64_LDST32_ABS_LO12_NC
+ ldr x0, [x8, :lo12:.Lfoo] // R_AARCH64_LDST64_ABS_LO12_NC
+ ldr q20, [x19, #:lo12:.Lfoo] // R_AARCH64_LDST128_ABS_LO12_NC
+ add x0, x0, :lo12:.Lfoo // R_AARCH64_ADD_ABS_LO12_NC
+ bl .Lfoo // R_AARCH64_CALL26
+ b .Lfoo // R_AARCH64_JUMP26
+ beq .Lfoo // R_AARCH64_CONDBR19
+.Lbranch:
+ tbz x1, 7, .Lbranch // R_AARCH64_TSTBR14
+.data
+.Lfoo:
+
+.rodata
+.long .Lfoo - .
+.xword .Lfoo - . // R_AARCH64_PREL64
+// CHECK: Relocations [
+// CHECK-NEXT: ]
diff --git a/test/ELF/aarch64-relocs.s b/test/ELF/aarch64-relocs.s
index 56b04a679111..90541329587a 100644
--- a/test/ELF/aarch64-relocs.s
+++ b/test/ELF/aarch64-relocs.s
@@ -120,3 +120,33 @@ foo8:
# CHECK: Disassembly of section .R_AARCH64_LDST8_ABS_LO12_NC:
# CHECK-NEXT: ldst8:
# CHECK-NEXT: 11044: ab 21 81 39 ldrsb x11, [x13, #72]
+
+.section .R_AARCH64_LDST128_ABS_LO12_NC,"ax",@progbits
+ldst128:
+ ldr q20, [x19, #:lo12:foo128]
+foo128:
+ .asciz "foo"
+ .size mystr, 3
+
+# S = 0x1104c, A = 0x4
+# R = ((S + A) & 0xFF8) << 6 = 0x00001400
+# 0x00001400 | 0x3dc00274 = 0x3dc01674
+# CHECK: Disassembly of section .R_AARCH64_LDST128_ABS_LO12_NC:
+# CHECK: ldst128:
+# CHECK: 1104c: 74 16 c0 3d ldr q20, [x19, #80]
+#foo128:
+# 11050: 66 6f 6f 00 .word
+
+.section .R_AARCH64_LDST16_ABS_LO12_NC,"ax",@progbits
+ldst16:
+ ldr h17, [x19, :lo12:foo16]
+foo16:
+ .asciz "foo"
+ .size mystr, 3
+
+# S = 0x11054, A = 0x4
+# R = ((S + A) & 0x0FFC) << 9 = 0xb000
+# 0xb000 | 0x7d400271 = 0x7d40b271
+# CHECK: Disassembly of section .R_AARCH64_LDST16_ABS_LO12_NC:
+# CHECK-NEXT: ldst16:
+# CHECK-NEXT: 11054: 71 b2 40 7d ldr h17, [x19, #88]
diff --git a/test/ELF/aarch64-tls-gdie.s b/test/ELF/aarch64-tls-gdie.s
new file mode 100644
index 000000000000..709cc53a8c47
--- /dev/null
+++ b/test/ELF/aarch64-tls-gdie.s
@@ -0,0 +1,34 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux
+// RUN: llvm-mc %p/Inputs/aarch64-tls-gdie.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: llvm-readobj -s %t | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump -d %t | FileCheck %s
+
+ .globl _start
+_start:
+ nop
+ adrp x0, :tlsdesc:a
+ ldr x1, [x0, :tlsdesc_lo12:a]
+ add x0, x0, :tlsdesc_lo12:a
+ .tlsdesccall a
+ blr x1
+
+// SEC: Name: .got
+// SEC-NEXT: Type: SHT_PROGBITS
+// SEC-NEXT: Flags [
+// SEC-NEXT: SHF_ALLOC
+// SEC-NEXT: SHF_WRITE
+// SEC-NEXT: ]
+// SEC-NEXT: Address: 0x120B0
+
+// page(0x120B0) - page(0x11004) = 4096
+// 0x0B0 = 176
+
+// CHECK: _start:
+// CHECK-NEXT: 11000: {{.*}} nop
+// CHECK-NEXT: 11004: {{.*}} adrp x0, #4096
+// CHECK-NEXT: 11008: {{.*}} ldr x0, [x0, #176]
+// CHECK-NEXT: 1100c: {{.*}} nop
+// CHECK-NEXT: 11010: {{.*}} nop
diff --git a/test/ELF/aarch64-tls-gdle.s b/test/ELF/aarch64-tls-gdle.s
new file mode 100644
index 000000000000..dc0c02a31d1c
--- /dev/null
+++ b/test/ELF/aarch64-tls-gdle.s
@@ -0,0 +1,26 @@
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o
+# RUN: ld.lld %tmain.o %ttlsie.o -o %tout
+# RUN: llvm-objdump -d %tout | FileCheck %s
+# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
+# REQUIRES: aarch64
+
+#Local-Dynamic to Initial-Exec relax creates no
+#RELOC: Relocations [
+#RELOC-NEXT: ]
+
+# TCB size = 0x16 and foo is first element from TLS register.
+# CHECK: Disassembly of section .text:
+# CHECK: _start:
+# CHECK: 11000: 00 00 a0 d2 movz x0, #0, lsl #16
+# CHECK: 11004: 00 02 80 f2 movk x0, #16
+# CHECK: 11008: 1f 20 03 d5 nop
+# CHECK: 1100c: 1f 20 03 d5 nop
+
+.globl _start
+_start:
+ adrp x0, :tlsdesc:foo
+ ldr x1, [x0, :tlsdesc_lo12:foo]
+ add x0, x0, :tlsdesc_lo12:foo
+ .tlsdesccall foo
+ blr x1
diff --git a/test/ELF/aarch64-tls-ie.s b/test/ELF/aarch64-tls-ie.s
index 0462addba22d..0cec402b294a 100644
--- a/test/ELF/aarch64-tls-ie.s
+++ b/test/ELF/aarch64-tls-ie.s
@@ -1,3 +1,4 @@
+// REQUIRES: aarch64
# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-tls-ie.s -o %tdso.o
# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o
# RUN: ld.lld -shared %tdso.o -o %tdso.so
@@ -24,8 +25,8 @@
#RELOC-NEXT: }
#RELOC: Relocations [
#RELOC-NEXT: Section ({{.*}}) .rela.dyn {
-#RELOC-NEXT: 0x120B0 R_AARCH64_TLS_TPREL64 foo 0x0
#RELOC-NEXT: 0x120B8 R_AARCH64_TLS_TPREL64 bar 0x0
+#RELOC-NEXT: 0x120B0 R_AARCH64_TLS_TPREL64 foo 0x0
#RELOC-NEXT: }
#RELOC-NEXT:]
diff --git a/test/ELF/aarch64-tls-iele.s b/test/ELF/aarch64-tls-iele.s
new file mode 100644
index 000000000000..91efc092a2cf
--- /dev/null
+++ b/test/ELF/aarch64-tls-iele.s
@@ -0,0 +1,33 @@
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o
+# RUN: ld.lld %tmain.o %ttlsie.o -o %tout
+# RUN: llvm-objdump -d %tout | FileCheck %s
+# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
+# REQUIRES: aarch64
+
+# Initial-Exec to Local-Exec relax creates no dynamic relocations.
+# RELOC: Relocations [
+# RELOC-NEXT: ]
+
+# TCB size = 0x16 and foo is first element from TLS register.
+# CHECK: Disassembly of section .text:
+# CHECK: _start:
+# CHECK-NEXT: 11000: 00 00 a0 d2 movz x0, #0, lsl #16
+# CHECK-NEXT: 11004: 80 02 80 f2 movk x0, #20
+# CHECK-NEXT: 11008: 00 00 a0 d2 movz x0, #0, lsl #16
+# CHECK-NEXT: 1100c: 00 02 80 f2 movk x0, #16
+
+.section .tdata
+.align 2
+.type foo_local, %object
+.size foo_local, 4
+foo_local:
+.word 5
+.text
+
+.globl _start
+_start:
+ adrp x0, :gottprel:foo
+ ldr x0, [x0, :gottprel_lo12:foo]
+ adrp x0, :gottprel:foo_local
+ ldr x0, [x0, :gottprel_lo12:foo_local]
diff --git a/test/ELF/aarch64-tls-le.s b/test/ELF/aarch64-tls-le.s
new file mode 100644
index 000000000000..22bd0ef2dad7
--- /dev/null
+++ b/test/ELF/aarch64-tls-le.s
@@ -0,0 +1,31 @@
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o
+# RUN: ld.lld %tmain.o -o %tout
+# RUN: llvm-objdump -d %tout | FileCheck %s
+# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
+# REQUIRES: aarch64
+
+#Local-Dynamic to Initial-Exec relax creates no
+#RELOC: Relocations [
+#RELOC-NEXT: ]
+
+.globl _start
+_start:
+ mrs x0, TPIDR_EL0
+ add x0, x0, :tprel_hi12:v1
+ add x0, x0, :tprel_lo12_nc:v1
+
+# TCB size = 0x16 and foo is first element from TLS register.
+#CHECK: Disassembly of section .text:
+#CHECK: _start:
+#CHECK: 11000: 40 d0 3b d5 mrs x0, TPIDR_EL0
+#CHECK: 11004: 00 00 00 91 add x0, x0, #0
+#CHECK: 11008: 00 40 00 91 add x0, x0, #16
+
+.type v1,@object
+.section .tbss,"awT",@nobits
+.globl v1
+.p2align 2
+v1:
+.word 0
+.size v1, 4
+
diff --git a/test/ELF/aarch64-tls-pie.s b/test/ELF/aarch64-tls-pie.s
new file mode 100644
index 000000000000..466045d6765d
--- /dev/null
+++ b/test/ELF/aarch64-tls-pie.s
@@ -0,0 +1,28 @@
+# REQUIRES: aarch64
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-cloudabi %s -o %t1.o
+# RUN: ld.lld -pie %t1.o -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+
+# Similar to bug 27174: R_AARCH64_TLSLE_*TPREL* relocations should be
+# eliminated when building a PIE executable, as the static TLS layout is
+# fixed.
+#
+# CHECK: Relocations [
+# CHECK-NEXT: ]
+
+ .globl _start
+_start:
+ # Accessing the variable directly.
+ add x11, x8, :tprel_hi12:i
+ add x11, x11, :tprel_lo12_nc:i
+
+ # Accessing the variable through the GOT.
+ adrp x10, :gottprel:i
+ mrs x8, TPIDR_EL0
+ ldr x10, [x10, :gottprel_lo12:i]
+
+ .section .tbss.i,"awT",@nobits
+ .globl i
+i:
+ .word 0
+ .size i, 4
diff --git a/test/ELF/aarch64-tls-static.s b/test/ELF/aarch64-tls-static.s
new file mode 100644
index 000000000000..c8508ee58b7f
--- /dev/null
+++ b/test/ELF/aarch64-tls-static.s
@@ -0,0 +1,37 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc %s -o %t.o -triple aarch64-pc-linux -filetype=obj
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -s %t.so | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump -d %t.so | FileCheck %s
+
+foo:
+ adrp x0, :tlsdesc:bar
+ ldr x1, [x0, :tlsdesc_lo12:bar]
+ add x0, x0, :tlsdesc_lo12:bar
+ .tlsdesccall bar
+ blr x1
+
+
+ .section .tdata,"awT",@progbits
+bar:
+ .word 42
+
+
+// SEC: Name: .got
+// SEC-NEXT: Type: SHT_PROGBITS
+// SEC-NEXT: Flags [
+// SEC-NEXT: SHF_ALLOC
+// SEC-NEXT: SHF_WRITE
+// SEC-NEXT: ]
+// SEC-NEXT: Address: 0x2098
+// SEC-NEXT: Offset: 0x2098
+// SEC-NEXT: Size: 16
+
+// page(0x2098) - page(0x1000) = 4096
+// 0x98 = 152
+
+// CHECK: foo:
+// CHECK-NEXT: 1000: {{.*}} adrp x0, #4096
+// CHECK-NEXT: 1004: {{.*}} ldr x1, [x0, #152]
+// CHECK-NEXT: 1008: {{.*}} add x0, x0, #152
+// CHECK-NEXT: 100c: {{.*}} blr x1
diff --git a/test/ELF/aarch64-tlsdesc.s b/test/ELF/aarch64-tlsdesc.s
new file mode 100644
index 000000000000..f8c73aff243d
--- /dev/null
+++ b/test/ELF/aarch64-tlsdesc.s
@@ -0,0 +1,24 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t.so
+// RUN: llvm-objdump -d %t.so | FileCheck %s
+// RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=REL %s
+
+ adrp x0, :tlsdesc:a
+ ldr x1, [x0, :tlsdesc_lo12:a]
+ add x0, x0, :tlsdesc_lo12:a
+ .tlsdesccall a
+ blr x1
+
+// CHECK: 1000: {{.*}} adrp x0, #4096
+// CHECK-NEXT: 1004: {{.*}} ldr x1, [x0, #144]
+// CHECK-NEXT: 1008: {{.*}} add x0, x0, #144
+// CHECK-NEXT: 100c: {{.*}} blr x1
+
+// 0x1000 + 4096 + 144 = 0x2090
+
+// REL: Relocations [
+// REL-NEXT: Section (4) .rela.dyn {
+// REL-NEXT: 0x2090 R_AARCH64_TLSDESC a 0x0
+// REL-NEXT: }
+// REL-NEXT: ]
diff --git a/test/ELF/abs-hidden.s b/test/ELF/abs-hidden.s
new file mode 100644
index 000000000000..b93c2c692919
--- /dev/null
+++ b/test/ELF/abs-hidden.s
@@ -0,0 +1,46 @@
+// 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 %p/Inputs/abs-hidden.s -o %t2.o
+// RUN: ld.lld %t.o %t2.o -o %t.so -shared
+// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
+
+ .quad foo
+ .long foo@gotpcrel
+
+// CHECK: Name: .text
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x1000
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 12
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 4
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 42000000 00000000 58100000
+// 0x2060 - (0x1000 + 8) = 1058
+// CHECK-NEXT: )
+
+// CHECK: Name: .got (38)
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x2060
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 8
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 42000000 00000000
+// CHECK-NEXT: )
+
+// CHECK: Relocations [
+// CHECK-NEXT: ]
diff --git a/test/ELF/allow-shlib-undefined.s b/test/ELF/allow-shlib-undefined.s
index 541a7e12007b..2d068b0f60ed 100644
--- a/test/ELF/allow-shlib-undefined.s
+++ b/test/ELF/allow-shlib-undefined.s
@@ -22,4 +22,4 @@
.globl _start
_start:
- call _shared
+ callq _shared@PLT
diff --git a/test/ELF/amdgpu-entry.s b/test/ELF/amdgpu-entry.s
index a17d243214b7..2a47b1778de8 100644
--- a/test/ELF/amdgpu-entry.s
+++ b/test/ELF/amdgpu-entry.s
@@ -1,5 +1,5 @@
# RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o
-# RUN: not lld -e kernel0 -flavor gnu %t.o -o %t
+# RUN: not ld.lld -e kernel0 %t.o -o %t
# REQUIRES: amdgpu
diff --git a/test/ELF/amdgpu-globals.s b/test/ELF/amdgpu-globals.s
index ff0899f60a98..7f46b989b955 100644
--- a/test/ELF/amdgpu-globals.s
+++ b/test/ELF/amdgpu-globals.s
@@ -77,7 +77,7 @@ program_global_readonly:
# CHECK: Symbol {
# CHECK: Name: module_global_agent
-# CHECK: Value: 0x0
+# CHECK: Value:
# CHECK: Size: 4
# CHECK: Binding: Local
# CHECK: Section: .hsadata_global_agent
@@ -85,7 +85,7 @@ program_global_readonly:
# CHECK: Symbol {
# CHECK: Name: module_global_program
-# CHECK: Value: 0x0
+# CHECK: Value:
# CHECK: Size: 4
# CHECK: Binding: Local
# CHECK: Section: .hsadata_global_program
@@ -93,7 +93,7 @@ program_global_readonly:
# CHECK: Symbol {
# CHECK: Name: module_global_readonly
-# CHECK: Value: 0x0
+# CHECK: Value:
# CHECK: Size: 4
# CHECK: Binding: Local
# CHECK: Type: Object
@@ -102,7 +102,7 @@ program_global_readonly:
# CHECK: Symbol {
# CHECK: Name: program_global_agent
-# CHECK: Value: 0x4
+# CHECK: Value:
# CHECK: Size: 4
# CHECK: Binding: Global
# CHECK: Type: Object
@@ -111,7 +111,7 @@ program_global_readonly:
# CHECK: Symbol {
# CHECK: Name: program_global_program
-# CHECK: Value: 0x4
+# CHECK: Value:
# CHECK: Size: 4
# CHECK: Binding: Global
# CHECK: Type: Object
@@ -120,7 +120,7 @@ program_global_readonly:
# CHECK: Symbol {
# CHECK: Name: program_global_readonly
-# CHECK: Value: 0x4
+# CHECK: Value:
# CHECK: Size: 4
# CHECK: Binding: Global
# CHECK: Type: Object
@@ -128,11 +128,11 @@ program_global_readonly:
# CHECK: }
# CHECK: ProgramHeader {
-# CHECK: Type: PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM
-# CHECK: VirtualAddress: [[HSADATA_GLOBAL_PROGRAM_ADDR]]
+# CHECK: Type: PT_LOAD
+# CHECK: VirtualAddress:
# CHECK: }
# CHECK: ProgramHeader {
-# CHECK: Type: PT_AMDGPU_HSA_LOAD_CODE_AGENT
-# CHECK: VirtualAddress: [[HSATEXT_ADDR]]
+# CHECK: Type: PT_LOAD
+# CHECK: VirtualAddress:
# CHECK: }
diff --git a/test/ELF/amdgpu-kernels.s b/test/ELF/amdgpu-kernels.s
index 3f43c71f65d7..62a8cb74a541 100644
--- a/test/ELF/amdgpu-kernels.s
+++ b/test/ELF/amdgpu-kernels.s
@@ -1,5 +1,5 @@
# RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o
-# RUN: lld -flavor gnu %t.o -o %t
+# RUN: ld.lld %t.o -o %t
# RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s
# REQUIRES: amdgpu
@@ -41,7 +41,7 @@ kernel1:
# CHECK: Symbol {
# CHECK: Name: kernel0
-# CHECK: Value: 0x0
+# CHECK: Value:
# CHECK: Size: 4
# CHECK: Binding: Global
# CHECK: Type: AMDGPU_HSA_KERNEL
@@ -50,7 +50,7 @@ kernel1:
# CHECK: Symbol {
# CHECK: Name: kernel1
-# CHECK: Value: 0x100
+# CHECK: Value:
# CHECK: Size: 8
# CHECK: Binding: Global
# CHECK: Type: AMDGPU_HSA_KERNEL
@@ -58,6 +58,6 @@ kernel1:
# CHECK: }
# CHECK: ProgramHeader {
-# CHECK: Type: PT_AMDGPU_HSA_LOAD_CODE_AGENT
-# CHECK: VirtualAddress: [[HSATEXT_ADDR]]
+# CHECK: Type: PT_LOAD
+# CHECK: VirtualAddress:
# CHECK: }
diff --git a/test/ELF/amdgpu-relocs.s b/test/ELF/amdgpu-relocs.s
new file mode 100644
index 000000000000..58c9582a84f1
--- /dev/null
+++ b/test/ELF/amdgpu-relocs.s
@@ -0,0 +1,33 @@
+# RUN: llvm-mc -filetype=obj -triple=amdgcn--amdhsa -mcpu=fiji %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t.so
+# RUN: llvm-readobj -r %t.so | FileCheck %s
+
+# REQUIRES: amdgpu
+
+ .text
+
+kernel0:
+ s_mov_b32 s0, common_var@GOTPCREL+4
+ s_mov_b32 s0, extern_var@GOTPCREL+4
+ s_mov_b32 s0, local_var+4
+ s_mov_b32 s0, global_var@GOTPCREL+4
+ s_mov_b32 s0, weak_var@GOTPCREL+4
+ s_mov_b32 s0, weakref_var@GOTPCREL+4
+ s_endpgm
+
+ .comm common_var,1024,4
+ .globl global_var
+ .local local_var
+ .weak weak_var
+ .weakref weakref_var, weakref_alias_var
+
+# The relocation for local_var should be resolved by the linker.
+# CHECK: Relocations [
+# CHECK: .rela.dyn {
+# CHECK-NEXT: R_AMDGPU_ABS64 common_var 0x0
+# CHECK-NEXT: R_AMDGPU_ABS64 extern_var 0x0
+# CHECK-NEXT: R_AMDGPU_ABS64 global_var 0x0
+# CHECK-NEXT: R_AMDGPU_ABS64 weak_var 0x0
+# CHECK-NEXT: R_AMDGPU_ABS64 weakref_alias_var 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
diff --git a/test/ELF/archive.s b/test/ELF/archive.s
index 41d74451cdd6..59c96a5fba9b 100644
--- a/test/ELF/archive.s
+++ b/test/ELF/archive.s
@@ -6,6 +6,10 @@
# RUN: llvm-ar rcs %tar %t2 %t3 %t4
# RUN: ld.lld %t %tar %t5 -o %tout
# RUN: llvm-nm %tout | FileCheck %s
+# RUN: rm -f %tarthin
+# RUN: llvm-ar --format=gnu rcsT %tarthin %t2 %t3 %t4
+# RUN: ld.lld %t %tarthin %t5 -o %tout
+# RUN: llvm-nm %tout | FileCheck %s
# REQUIRES: x86
# Nothing here. Just needed for the linker to create a undefined _start symbol.
diff --git a/test/ELF/arm-abs32-dyn.s b/test/ELF/arm-abs32-dyn.s
new file mode 100644
index 000000000000..68183fe6f198
--- /dev/null
+++ b/test/ELF/arm-abs32-dyn.s
@@ -0,0 +1,32 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux %s -o %t.o
+
+// Creates a R_ARM_ABS32 relocation against foo and bar, bar has hidden
+// visibility so we expect a R_ARM_RELATIVE
+ .syntax unified
+ .globl foo
+foo:
+ .globl bar
+ .hidden bar
+bar:
+
+ .data
+ .word foo
+ .word bar
+
+// RUN: ld.lld -shared -o %t.so %t.o
+// RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s
+
+// CHECK: Dynamic Relocations {
+// CHECK-NEXT: 0x2004 R_ARM_RELATIVE
+// CHECK-NEXT: 0x2000 R_ARM_ABS32 foo 0x0
+// CHECK-NEXT: }
+
+// CHECK: Symbols [
+// CHECK: Symbol {
+// CHECK: Name: bar
+// CHECK-NEXT: Value: 0x1000
+
+// CHECK: Symbol {
+// CHECK: Name: foo
+// CHECK-NEXT: Value: 0x1000
diff --git a/test/ELF/arm-attributes-remove.s b/test/ELF/arm-attributes-remove.s
new file mode 100644
index 000000000000..010f366cd7fb
--- /dev/null
+++ b/test/ELF/arm-attributes-remove.s
@@ -0,0 +1,45 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: ld.lld %t.o -o %t
+// RUN: llvm-readobj -s %t | FileCheck %s
+// RUN: ld.lld %t.o -shared -o %t2
+// RUN: llvm-readobj -s %t2 | FileCheck %s
+// RUN: ld.lld %t.o -r -o %t3
+// RUN: llvm-readobj -s %t3 | FileCheck %s
+
+// The .ARM.attributes section should be removed from executables and
+// shared objects.
+
+// At present we remove it from the -r object output as well which isn't ideal.
+// Unfortunately combining per-object attributes cannot be safely done by just
+// concatentation of input sections.
+
+// CHECK-NOT: Name: .ARM.attributes
+// REQUIRES: arm
+ .text
+ .syntax unified
+ .eabi_attribute 67, "2.09" @ Tag_conformance
+ .cpu cortex-a8
+ .eabi_attribute 6, 10 @ Tag_CPU_arch
+ .eabi_attribute 7, 65 @ Tag_CPU_arch_profile
+ .eabi_attribute 8, 1 @ Tag_ARM_ISA_use
+ .eabi_attribute 9, 2 @ Tag_THUMB_ISA_use
+ .fpu neon
+ .eabi_attribute 15, 1 @ Tag_ABI_PCS_RW_data
+ .eabi_attribute 16, 1 @ Tag_ABI_PCS_RO_data
+ .eabi_attribute 17, 2 @ Tag_ABI_PCS_GOT_use
+ .eabi_attribute 20, 1 @ Tag_ABI_FP_denormal
+ .eabi_attribute 21, 1 @ Tag_ABI_FP_exceptions
+ .eabi_attribute 23, 3 @ Tag_ABI_FP_number_model
+ .eabi_attribute 34, 1 @ Tag_CPU_unaligned_access
+ .eabi_attribute 24, 1 @ Tag_ABI_align_needed
+ .eabi_attribute 25, 1 @ Tag_ABI_align_preserved
+ .eabi_attribute 38, 1 @ Tag_ABI_FP_16bit_format
+ .eabi_attribute 18, 4 @ Tag_ABI_PCS_wchar_t
+ .eabi_attribute 26, 2 @ Tag_ABI_enum_size
+ .eabi_attribute 14, 0 @ Tag_ABI_PCS_R9_use
+ .eabi_attribute 68, 1 @ Tag_Virtualization_use
+ .globl _start
+ .p2align 2
+ .type _start,%function
+_start:
+ bx lr
diff --git a/test/ELF/arm-blx.s b/test/ELF/arm-blx.s
new file mode 100644
index 000000000000..cccb1324fc8b
--- /dev/null
+++ b/test/ELF/arm-blx.s
@@ -0,0 +1,113 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
+// RUN: echo "SECTIONS { \
+// RUN: .callee1 : { *(.callee_low) } \
+// RUN: .callee2 : { *(.callee_arm_low) } \
+// RUN: .caller : { *(.text) } \
+// RUN: .callee3 : { *(.callee_high) } \
+// RUN: .callee4 : { *(.callee_arm_high) } } " > %t.script
+// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s
+// REQUIRES: arm
+
+// Test BLX instruction is chosen for ARM BL/BLX instruction and Thumb callee
+// Using two callees to ensure at least one has 2-byte alignment.
+ .syntax unified
+ .thumb
+ .section .callee_low, "ax",%progbits
+ .align 2
+ .type callee_low,%function
+callee_low:
+ bx lr
+ .type callee_low2, %function
+callee_low2:
+ bx lr
+
+ .section .callee_arm_low, "ax",%progbits
+ .arm
+ .balign 0x100
+ .type callee_arm_low,%function
+ .align 2
+callee_arm_low:
+ bx lr
+
+.section .text, "ax",%progbits
+ .arm
+ .globl _start
+ .balign 0x10000
+ .type _start,%function
+_start:
+ bl callee_low
+ blx callee_low
+ bl callee_low2
+ blx callee_low2
+ bl callee_high
+ blx callee_high
+ bl callee_high2
+ blx callee_high2
+ bl blx_far
+ blx blx_far2
+// blx to ARM instruction should be written as a BL
+ bl callee_arm_low
+ blx callee_arm_low
+ bl callee_arm_high
+ blx callee_arm_high
+ bx lr
+
+ .section .callee_high, "ax",%progbits
+ .balign 0x100
+ .thumb
+ .type callee_high,%function
+callee_high:
+ bx lr
+ .type callee_high2,%function
+callee_high2:
+ bx lr
+
+ .section .callee_arm_high, "ax",%progbits
+ .arm
+ .balign 0x100
+ .type callee_arm_high,%function
+callee_arm_high:
+ bx lr
+
+// CHECK-THUMB: Disassembly of section .callee1:
+// CHECK-THUMB-NEXT: callee_low:
+// CHECK-THUMB-NEXT: b4: 70 47 bx lr
+// CHECK-THUMB: callee_low2:
+// CHECK-THUMB-NEXT: b6: 70 47 bx lr
+
+// CHECK-ARM: Disassembly of section .callee2:
+// CHECK-ARM-NEXT: callee_arm_low:
+// CHECK-ARM-NEXT: 100: 1e ff 2f e1 bx lr
+
+// CHECK-ARM: Disassembly of section .caller:
+// CHECK-ARM-NEXT: _start:
+// CHECK-ARM-NEXT: 10000: 2b c0 ff fa blx #-65364 <callee_low>
+// CHECK-ARM-NEXT: 10004: 2a c0 ff fa blx #-65368 <callee_low>
+// CHECK-ARM-NEXT: 10008: 29 c0 ff fb blx #-65370 <callee_low2>
+// CHECK-ARM-NEXT: 1000c: 28 c0 ff fb blx #-65374 <callee_low2>
+// CHECK-ARM-NEXT: 10010: 3a 00 00 fa blx #232 <callee_high>
+// CHECK-ARM-NEXT: 10014: 39 00 00 fa blx #228 <callee_high>
+// CHECK-ARM-NEXT: 10018: 38 00 00 fb blx #226 <callee_high2>
+// CHECK-ARM-NEXT: 1001c: 37 00 00 fb blx #222 <callee_high2>
+// 10020 + 1FFFFFC + 8 = 0x2010024 = blx_far
+// CHECK-ARM-NEXT: 10020: ff ff 7f fa blx #33554428
+// 10024 + 1FFFFFC + 8 = 0x2010028 = blx_far2
+// CHECK-ARM-NEXT: 10024: ff ff 7f fa blx #33554428
+// CHECK-ARM-NEXT: 10028: 34 c0 ff eb bl #-65328 <callee_arm_low>
+// CHECK-ARM-NEXT: 1002c: 33 c0 ff eb bl #-65332 <callee_arm_low>
+// CHECK-ARM-NEXT: 10030: 72 00 00 eb bl #456 <callee_arm_high>
+// CHECK-ARM-NEXT: 10034: 71 00 00 eb bl #452 <callee_arm_high>
+// CHECK-ARM-NEXT: 10038: 1e ff 2f e1 bx lr
+
+// CHECK-THUMB: Disassembly of section .callee3:
+// CHECK-THUMB: callee_high:
+// CHECK-THUMB-NEXT: 10100: 70 47 bx lr
+// CHECK-THUMB: callee_high2:
+// CHECK-THUMB-NEXT: 10102: 70 47 bx lr
+
+// CHECK-ARM: Disassembly of section .callee4:
+// CHECK-NEXT-ARM: callee_arm_high:
+// CHECK-NEXT-ARM: 10200: 1e ff 2f e1 bx lr
diff --git a/test/ELF/arm-branch-error.s b/test/ELF/arm-branch-error.s
new file mode 100644
index 000000000000..f1a855d7373f
--- /dev/null
+++ b/test/ELF/arm-branch-error.s
@@ -0,0 +1,19 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
+// RUN: not ld.lld %t %tfar -o %t2 2>&1 | FileCheck %s
+// REQUIRES: arm
+ .syntax unified
+ .section .text, "ax",%progbits
+ .globl _start
+ .balign 0x10000
+ .type _start,%function
+_start:
+ // address of too_far symbols are just out of range of ARM branch with
+ // 26-bit immediate field and an addend of -8
+ bl too_far1
+ b too_far2
+ beq too_far3
+
+// CHECK: R_ARM_CALL out of range
+// CHECK-NEXT: R_ARM_JUMP24 out of range
+// CHECK-NEXT: R_ARM_JUMP24 out of range
diff --git a/test/ELF/arm-branch.s b/test/ELF/arm-branch.s
new file mode 100644
index 000000000000..38266fabf852
--- /dev/null
+++ b/test/ELF/arm-branch.s
@@ -0,0 +1,59 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
+// RUN: echo "SECTIONS { \
+// RUN: .callee1 : { *(.callee_low) } \
+// RUN: .caller : { *(.text) } \
+// RUN: .callee2 : { *(.callee_high) } } " > %t.script
+// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
+// REQUIRES: arm
+ .syntax unified
+ .section .callee_low, "ax",%progbits
+ .align 2
+ .type callee_low,%function
+callee_low:
+ bx lr
+
+ .section .text, "ax",%progbits
+ .globl _start
+ .balign 0x10000
+ .type _start,%function
+_start:
+ bl callee_low
+ b callee_low
+ beq callee_low
+ bl callee_high
+ b callee_high
+ bne callee_high
+ bl far
+ b far
+ bgt far
+ bx lr
+
+ .section .callee_high, "ax",%progbits
+ .align 2
+ .type callee_high,%function
+callee_high:
+ bx lr
+
+// CHECK: Disassembly of section .caller:
+// CHECK-NEXT: _start:
+// S(callee_low) = 0xb4 P = 0x10000 A = -8 = -0xff54 = -65364
+// CHECK-NEXT: 10000: 2b c0 ff eb bl #-65364 <callee_low>
+// S(callee_low) = 0xb4 P = 0x10004 A = -8 = -0xff58 = -65368
+// CHECK-NEXT: 10004: 2a c0 ff ea b #-65368 <callee_low>
+// S(callee_low) = 0xb4 P = 0x10008 A = -8 = -0xff5c -65372
+// CHECK-NEXT: 10008: 29 c0 ff 0a beq #-65372 <callee_low>
+// S(callee_high) = 0x10028 P = 0x1000c A = -8 = 0x14 = 20
+// CHECK-NEXT: 1000c: 05 00 00 eb bl #20 <callee_high>
+// S(callee_high) = 0x10028 P = 0x10010 A = -8 = 0x10 = 16
+// CHECK-NEXT: 10010: 04 00 00 ea b #16 <callee_high>
+// S(callee_high) = 0x10028 P = 0x10014 A = -8 = 0x0c =12
+// CHECK-NEXT: 10014: 03 00 00 1a bne #12 <callee_high>
+// S(far) = 0x201001c P = 0x10018 A = -8 = 0x1fffffc = 33554428
+// CHECK-NEXT: 10018: ff ff 7f eb bl #33554428
+// S(far) = 0x201001c P = 0x1001c A = -8 = 0x1fffff8 = 33554424
+// CHECK-NEXT: 1001c: fe ff 7f ea b #33554424
+// S(far) = 0x201001c P = 0x10020 A = -8 = 0x1fffff4 = 33554420
+// CHECK-NEXT: 10020: fd ff 7f ca bgt #33554420
+// CHECK-NEXT: 10024: 1e ff 2f e1 bx lr
diff --git a/test/ELF/arm-copy.s b/test/ELF/arm-copy.s
new file mode 100644
index 000000000000..e5ce1577babd
--- /dev/null
+++ b/test/ELF/arm-copy.s
@@ -0,0 +1,81 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/relocation-copy-arm.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t.o %t2.so -o %t3
+// RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CODE %s
+// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi -section=.rodata %t3 | FileCheck -check-prefix=RODATA %s
+
+// Copy relocations R_ARM_COPY are required for y and z
+ .syntax unified
+ .text
+ .globl _start
+_start:
+ movw r2,:lower16: y
+ movt r2,:upper16: y
+ ldr r3,[pc,#4]
+ ldr r3,[r3,#0]
+ .rodata
+ .word z
+
+// CHECK: Name: .bss
+// CHECK-NEXT: Type: SHT_NOBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x13000
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment: 16
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section (5) .rel.dyn {
+// CHECK-NEXT: Relocation {
+// CHECK-NEXT: Offset: 0x13000
+// CHECK-NEXT: Type: R_ARM_COPY
+// CHECK-NEXT: Symbol: y
+// CHECK-NEXT: Addend: 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: Relocation {
+// CHECK-NEXT: Offset: 0x13004
+// CHECK-NEXT: Type: R_ARM_COPY
+// CHECK-NEXT: Symbol: z
+// CHECK-NEXT: Addend: 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+
+// CHECK: Symbols [
+// CHECK: Name: y
+// CHECK-NEXT: Value: 0x13000
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Object
+// CHECK-NEXT: Other:
+// CHECK-NEXT: Section: .bss
+// CHECK: Name: z
+// CHECK-NEXT: Value: 0x13004
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Object
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
+
+// CODE: Disassembly of section .text:
+// CODE-NEXT: _start:
+// S(y) = 0x13000, A = 0
+// (S + A) & 0x0000ffff = 0x3000 = #12288
+// CODE-NEXT: 11000: 00 20 03 e3 movw r2, #12288
+// S(y) = 0x13000, A = 0
+// ((S + A) & 0xffff0000) >> 16 = 0x1
+// CODE-NEXT: 11004: 01 20 40 e3 movt r2, #1
+// CODE-NEXT: 11008: 04 30 9f e5 ldr r3, [pc, #4]
+// CODE-NEXT: 1100c: 00 30 93 e5 ldr r3, [r3]
+
+
+// RODATA: Contents of section .rodata:
+// S(z) = 0x13004
+// RODATA-NEXT: 10114 04300100
diff --git a/test/ELF/arm-data-prel.s b/test/ELF/arm-data-prel.s
new file mode 100644
index 000000000000..590d8118ae6e
--- /dev/null
+++ b/test/ELF/arm-data-prel.s
@@ -0,0 +1,63 @@
+// RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj -o %t.o
+// RUN: echo "SECTIONS { \
+// RUN: .text : { *(.text) } \
+// RUN: .ARM.exidx : { *(.ARM.exidx) } \
+// RUN: .ARM.exidx.TEST1 : { *(.ARM.exidx.TEST1) } \
+// RUN: .TEST1 : { *(.TEST1) } } " > %t.script
+// RUN: ld.lld --script %t.script %t.o -o %t
+// RUN: llvm-readobj -s -sd %t | FileCheck --check-prefix=CHECK %s
+// REQUIRES: arm
+
+// The R_ARM_PREL31 relocation is used in by the .ARM.exidx exception tables
+// bit31 of the place denotes whether the field is an inline table entry
+// (bit31=1) or relocation (bit31=0)
+// The linker must preserve the value of bit31
+
+// This test case is adapted from llvm/test/MC/ARM/eh-compact-pr0.s
+// We use a linker script to place the .ARM.exidx sections in between
+// the code sections so that we can test positive and negative offsets
+ .syntax unified
+
+ .section .TEST1, "ax",%progbits
+ .globl _start
+ .align 2
+ .type _start,%function
+_start:
+ .fnstart
+ .save {r11, lr}
+ push {r11, lr}
+ .setfp r11, sp
+ mov r11, sp
+ pop {r11, lr}
+ mov pc, lr
+ .fnend
+
+ .section .text, "ax",%progbits
+// The generated .ARM.exidx section will refer to the personality
+// routine __aeabi_unwind_cpp_pr0. Provide a dummy implementation
+// to stop an undefined symbol error
+ .globl __aeabi_unwind_cpp_pr0
+ .align 2
+ .type __aeabi_unwind_cpp_pr0,%function
+__aeabi_unwind_cpp_pr0:
+ .fnstart
+ bx lr
+ .fnend
+
+// The expected value of the exception table is
+// Word0 0 in bit 31, -4 encoded in 31-bit signed offset
+// Word1 Inline table entry EHT Inline Personality Routine #0
+// CHECK: Name: .ARM.exidx
+// CHECK: SectionData (
+// CHECK: 0000: FCFFFF7F B0B0B080
+// CHECK: )
+
+// The expected value of the exception table is
+// Word0 0 in bit 31, +8 encoded in 31-bit signed offset
+// Word1 Inline table entry EHT Inline Personality Routine #0
+// set vsp = r11
+// pop r11, r14
+// CHECK: Name: .ARM.exidx.TEST1
+// CHECK: SectionData (
+// CHECK: 0000: 08000000 80849B80
+// CHECK: )
diff --git a/test/ELF/arm-data-relocs.s b/test/ELF/arm-data-relocs.s
new file mode 100644
index 000000000000..ed237850c4c1
--- /dev/null
+++ b/test/ELF/arm-data-relocs.s
@@ -0,0 +1,20 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/abs256.s -o %t256.o
+// RUN: ld.lld %t %t256.o -o %t2
+// RUN: llvm-objdump -d %t2 | FileCheck %s
+// REQUIRES: arm
+ .syntax unified
+ .globl _start
+_start:
+ .section .R_ARM_ABS32POS, "ax",%progbits
+ .word foo + 0x24
+
+// S = 0x100, A = 0x24
+// S + A = 0x124
+// CHECK: Disassembly of section .R_ARM_ABS32POS:
+// CHECK: 11000: 24 01 00 00
+ .section .R_ARM_ABS32NEG, "ax",%progbits
+ .word foo - 0x24
+// S = 0x100, A = -0x24
+// CHECK: Disassembly of section .R_ARM_ABS32NEG:
+// CHECK: 11004: dc 00 00 00
diff --git a/test/ELF/arm-fpic-got.s b/test/ELF/arm-fpic-got.s
new file mode 100644
index 000000000000..4b6002d3c077
--- /dev/null
+++ b/test/ELF/arm-fpic-got.s
@@ -0,0 +1,63 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: ld.lld %t.o -o %t
+// RUN: llvm-readobj -s %t | FileCheck %s
+// RUN: llvm-readobj -s -symbols %t | FileCheck -check-prefix=SYMBOLS %s
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t | FileCheck -check-prefix=CODE %s
+
+// Test the R_ARM_GOT_PREL relocation
+ .syntax unified
+ .text
+ .globl _start
+ .align 2
+_start:
+ ldr r0, .LCPI0_0
+.LPC0_0:
+ ldr r0, [pc, r0]
+ ldr r0, [r0]
+ bx lr
+.LCPI0_0:
+.Ltmp0:
+ // Generate R_ARM_GOT_PREL
+ .long val(GOT_PREL)-((.LPC0_0+8)-.Ltmp0)
+
+ .data
+ .type val,%object
+ .globl val
+ .align 2
+val:
+ .long 10
+ .size val, 4
+
+// CHECK: Section {
+// CHECK: Name: .got
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x12000
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment: 4
+// CHECK-NEXT: EntrySize:
+
+// SYMBOLS: Name: val
+// SYMBOLS-NEXT: Value: 0x13000
+// SYMBOLS-NEXT: Size: 4
+// SYMBOLS-NEXT: Binding: Global
+// SYMBOLS-NEXT: Type: Object
+// SYMBOLS-NEXT: Other:
+// SYMBOLS-NEXT: Section: .data
+
+// CODE: Disassembly of section .text:
+// CODE-NEXT: _start:
+// CODE-NEXT: 11000: 08 00 9f e5 ldr r0, [pc, #8]
+// CODE-NEXT: 11004: 00 00 9f e7 ldr r0, [pc, r0]
+// CODE-NEXT: 11008: 00 00 90 e5 ldr r0, [r0]
+// CODE-NEXT: 1100c: 1e ff 2f e1 bx lr
+// CODE: $d.1:
+// 0x11004 + 0x0ff4 + 8 = 0x12000 = .got
+// CODE-NEXT: 11010: f4 0f 00 00
diff --git a/test/ELF/arm-gnu-ifunc-nosym.s b/test/ELF/arm-gnu-ifunc-nosym.s
new file mode 100644
index 000000000000..fa79aef7ced8
--- /dev/null
+++ b/test/ELF/arm-gnu-ifunc-nosym.s
@@ -0,0 +1,27 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: ld.lld -static %t.o -o %tout
+// RUN: llvm-readobj -symbols %tout | FileCheck %s
+// REQUIRES: arm
+
+// Check that no __rel_iplt_end/__rel_iplt_start
+// appear in symtab if there are no references to them.
+// CHECK: Symbols [
+// CHECK-NOT: __rel_iplt_end
+// CHECK-NOT: __rel_iplt_start
+// CHECK: ]
+ .syntax unified
+ .text
+ .type foo STT_GNU_IFUNC
+ .globl foo
+foo:
+ bx lr
+
+ .type bar STT_GNU_IFUNC
+ .globl bar
+bar:
+ bx lr
+
+ .globl _start
+_start:
+ bl foo
+ bl bar
diff --git a/test/ELF/arm-gnu-ifunc.s b/test/ELF/arm-gnu-ifunc.s
new file mode 100644
index 000000000000..c1e8a7183530
--- /dev/null
+++ b/test/ELF/arm-gnu-ifunc.s
@@ -0,0 +1,131 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: ld.lld -static %t.o -o %tout
+// RUN: llvm-objdump -triple armv7a-none-linux-gnueabi -d %tout | FileCheck %s --check-prefix=DISASM
+// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
+// REQUIRES: arm
+ .syntax unified
+ .text
+ .type foo STT_GNU_IFUNC
+ .globl foo
+foo:
+ bx lr
+
+ .type bar STT_GNU_IFUNC
+ .globl bar
+bar:
+ bx lr
+
+ .globl _start
+_start:
+ bl foo
+ bl bar
+ movw r0,:lower16:__rel_iplt_start
+ movt r0,:upper16:__rel_iplt_start
+ movw r0,:lower16:__rel_iplt_end
+ movt r0,:upper16:__rel_iplt_end
+
+// CHECK: Sections [
+// CHECK: Section {
+// CHECK: Index: 1
+// CHECK-NEXT: Name: .rel.plt
+// CHECK-NEXT: Type: SHT_REL
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: [[REL:.*]]
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 16
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment: 4
+// CHECK-NEXT: EntrySize: 8
+// CHECK-NEXT: }
+// CHECK: Relocations [
+// CHECK-NEXT: Section (1) .rel.plt {
+// CHECK-NEXT: 0x1200C R_ARM_IRELATIVE
+// CHECK-NEXT: 0x12010 R_ARM_IRELATIVE
+// CHECK-NEXT: }
+// CHECK-NEXT:]
+// CHECK: Symbols [
+// CHECK: Symbol {
+// CHECK: Name: __rel_iplt_end
+// CHECK-NEXT: Value: 0x100E4
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .rel.plt
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: __rel_iplt_start
+// CHECK-NEXT: Value: 0x100D4
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .rel.plt
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _start (6)
+// CHECK-NEXT: Value: 0x11008
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other:
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: bar
+// CHECK-NEXT: Value: 0x11004
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: GNU_IFunc
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo
+// CHECK-NEXT: Value: 0x11000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: GNU_IFunc
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: foo:
+// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr
+// DISASM: bar:
+// DISASM-NEXT: 11004: 1e ff 2f e1 bx lr
+// DISASM: _start:
+// DISASM-NEXT: 11008: 09 00 00 eb bl #36
+// DISASM-NEXT: 1100c: 0c 00 00 eb bl #48
+// DISASM-NEXT: 11010: d4 00 00 e3 movw r0, #212
+// DISASM-NEXT: 11014: 01 00 40 e3 movt r0, #1
+// r0 = 212 + 1 * 65536 = 100D4 = __rel_iplt_start
+// DISASM-NEXT: 11018: e4 00 00 e3 movw r0, #228
+// DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1
+// r1 = 228 + 1 * 65536 = 100E4 = __rel_iplt_end
+// DISASM-NEXT: Disassembly of section .plt:
+// DISASM-NEXT: .plt:
+// DISASM-NEXT: 11020: 04 e0 2d e5 str lr, [sp, #-4]!
+// DISASM-NEXT: 11024: 04 e0 9f e5 ldr lr, [pc, #4]
+// DISASM-NEXT: 11028: 0e e0 8f e0 add lr, pc, lr
+// DISASM-NEXT: 1102c: 08 f0 be e5 ldr pc, [lr, #8]!
+// 0x0fd0 + 0x11028 + 0x8 = 0x12000
+// DISASM-NEXT: 11030: d0 0f 00 00
+// DISASM-NEXT: 11034: 04 c0 9f e5 ldr r12, [pc, #4]
+// DISASM-NEXT: 11038: 0f c0 8c e0 add r12, r12, pc
+// DISASM-NEXT: 1103c: 00 f0 9c e5 ldr pc, [r12]
+// 0x0fcc + 0x11038 + 0x8 = 0x1200C
+// DISASM-NEXT: 11040: cc 0f 00 00
+// DISASM-NEXT: 11044: 04 c0 9f e5 ldr r12, [pc, #4]
+// DISASM-NEXT: 11048: 0f c0 8c e0 add r12, r12, pc
+// DISASM-NEXT: 1104c: 00 f0 9c e5 ldr pc, [r12]
+// 0x0fc0 + 0x11048 + 0x8 = 0x12010
+// DISASM-NEXT: 11050: c0 0f 00 00
diff --git a/test/ELF/arm-got-relative.s b/test/ELF/arm-got-relative.s
new file mode 100644
index 000000000000..22ccb16a2a58
--- /dev/null
+++ b/test/ELF/arm-got-relative.s
@@ -0,0 +1,53 @@
+// REQUIRES: arm
+// RUN: llvm-mc -position-independent -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: ld.lld %t.o -shared -o %t
+// RUN: llvm-readobj -s -symbols -dyn-relocations %t | FileCheck %s
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t | FileCheck -check-prefix=CODE %s
+ .syntax unified
+ .text
+ .globl _start
+ .align 2
+_start:
+ .type _start, %function
+ ldr r3, .LGOT
+ ldr r2, .LGOT+4
+.LPIC:
+ add r0, pc, r3
+ bx lr
+ .align 2
+.LGOT:
+ // gas implicitly uses (GOT_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC
+ // llvm-mc needs the (GOT_PREL) suffix or it generates R_ARM_REL32
+ .word _GLOBAL_OFFSET_TABLE_(GOT_PREL) - (.LPIC+8)
+ .word function(GOT)
+
+ .globl function
+ .align 2
+function:
+ .type function, %function
+ bx lr
+
+// CHECK: Dynamic Relocations {
+// CHECK-NEXT: 0x204C R_ARM_GLOB_DAT function 0x0
+
+// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (16)
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: Absolute
+
+// CODE: Disassembly of section .text:
+// CODE-NEXT: _start:
+// CODE-NEXT: 1000: 08 30 9f e5 ldr r3, [pc, #8]
+// CODE-NEXT: 1004: 08 20 9f e5 ldr r2, [pc, #8]
+// CODE-NEXT: 1008: 03 00 8f e0 add r0, pc, r3
+// CODE-NEXT: 100c: 1e ff 2f e1 bx lr
+// CODE:$d.1:
+// (_GLOBAL_OFFSET_TABLE_ = 0x2048) - (0x1008 + 8) 0x1038
+// CODE-NEXT: 1010: 38 10 00 00
+// (Got(function) - GotBase = 0x4
+// CODE-NEXT: 1014: 04 00 00 00
diff --git a/test/ELF/arm-gotoff.s b/test/ELF/arm-gotoff.s
new file mode 100644
index 000000000000..5169f84e6a01
--- /dev/null
+++ b/test/ELF/arm-gotoff.s
@@ -0,0 +1,74 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabi %s -o %t.o
+// RUN: ld.lld %t.o -o %t
+// RUN: llvm-readobj -s -r -t %t | FileCheck %s
+// RUN: llvm-objdump -triple=armv7a-linux-gnueabi -d %t | FileCheck --check-prefix=DISASM %s
+// REQUIRES: arm
+
+// Test the R_ARM_GOTOFF32 relocation
+
+// CHECK: Name: .got
+// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x12000
+// CHECK-NEXT: Offset: 0x2000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment:
+
+// CHECK: Name: .bss
+// CHECK-NEXT: Type: SHT_NOBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x12000
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 20
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment: 1
+
+// CHECK-NEXT: EntrySize: 0
+
+// CHECK: Symbol {
+// CHECK: Name: bar
+// CHECK-NEXT: Value: 0x12000
+// CHECK-NEXT: Size: 10
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Object
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: obj
+// CHECK-NEXT: Value: 0x1200A
+// CHECK-NEXT: Size: 10
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Object
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
+
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT :_start:
+// DISASM-NEXT 11000: 1e ff 2f e1 bx lr
+// Offset 0 from .got = bar
+// DISASM 11004: 00 00 00 00
+// Offset 10 from .got = obj
+// DISASM-NEXT 11008: 0a 00 00 00
+// Offset 15 from .got = obj +5
+// DISASM-NEXT 1100c: 0f 00 00 00
+ .syntax unified
+ .globl _start
+_start:
+ bx lr
+ .word bar(GOTOFF)
+ .word obj(GOTOFF)
+ .word obj(GOTOFF)+5
+ .type bar, %object
+ .comm bar, 10
+ .type obj, %object
+ .comm obj, 10
diff --git a/test/ELF/arm-mov-relocs.s b/test/ELF/arm-mov-relocs.s
new file mode 100644
index 000000000000..31ccba4cceaf
--- /dev/null
+++ b/test/ELF/arm-mov-relocs.s
@@ -0,0 +1,94 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-unknown-linux-gnueabi %s -o %t
+// RUN: ld.lld %t -o %t2
+// RUN: llvm-objdump -d %t2 -triple=armv7a-unknown-linux-gnueabi | FileCheck %s
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-unknown-linux-gnueabi %s -o %t3
+// RUN: ld.lld %t3 -o %t4
+// RUN: llvm-objdump -d %t4 -triple=thumbv7a-unknown-linux-gnueabi | FileCheck %s
+// REQUIRES: arm
+
+// Test the R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocations as well as
+// the R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS relocations.
+ .syntax unified
+ .globl _start
+_start:
+ .section .R_ARM_MOVW_ABS_NC, "ax",%progbits
+ movw r0, :lower16:label
+ movw r1, :lower16:label1
+ movw r2, :lower16:label2 + 4
+ movw r3, :lower16:label3
+ movw r4, :lower16:label3 + 4
+// CHECK: Disassembly of section .R_ARM_MOVW_ABS_NC
+// CHECK: movw r0, #0
+// CHECK: movw r1, #4
+// CHECK: movw r2, #12
+// CHECK: movw r3, #65532
+// CHECK: movw r4, #0
+ .section .R_ARM_MOVT_ABS, "ax",%progbits
+ movt r0, :upper16:label
+ movt r1, :upper16:label1
+// FIXME: We shouldn't need to multiply by 65536.
+// arguably llvm-mc incorrectly assembles addends for
+// SHT_REL relocated movt instructions. When there is a relocation
+// the interpretation of the addend for SHT_REL is not shifted
+ movt r2, :upper16:label2 + (4 * 65536)
+ movt r3, :upper16:label3
+// FIXME: We shouldn't need to multiply by 65536 see comment above.
+ movt r4, :upper16:label3 + (4 * 65536)
+// CHECK: Disassembly of section .R_ARM_MOVT_ABS
+// CHECK: movt r0, #2
+// CHECK: movt r1, #2
+// CHECK: movt r2, #2
+// CHECK: movt r3, #2
+// CHECK: movt r4, #3
+
+.section .R_ARM_MOVW_PREL_NC, "ax",%progbits
+ movw r0, :lower16:label - .
+ movw r1, :lower16:label1 - .
+ movw r2, :lower16:label2 + 4 - .
+ movw r3, :lower16:label3 - .
+ movw r4, :lower16:label3 + 0x103c - .
+// 0x20000 - 0x11028 = :lower16:0xefd8 (61400)
+// CHECK: 11028: {{.*}} movw r0, #61400
+// 0x20004 = 0x1102c = :lower16:0xefd8 (61400)
+// CHECK: 1102c: {{.*}} movw r1, #61400
+// 0x20008 - 0x11030 + 4 = :lower16:0xefdc (61404)
+// CHECK: 11030: {{.*}} movw r2, #61404
+// 0x2fffc - 0x11034 = :lower16:0x1efc8 (61384)
+// CHECK: 11034: {{.*}} movw r3, #61384
+// 0x2fffc - 0x11038 +0x103c :lower16:0x20000 (0)
+// CHECK: 11038: {{.*}} movw r4, #0
+
+.section .R_ARM_MOVT_PREL, "ax",%progbits
+ movt r0, :upper16:label - .
+ movt r1, :upper16:label1 - .
+ movt r2, :upper16:label2 + 0x4 - .
+ movt r3, :upper16:label3 - .
+ movt r4, :upper16:label3 + 0x1050 - .
+// 0x20000 - 0x1103c = :upper16:0xefc4 = 0
+// CHECK: 1103c: {{.*}} movt r0, #0
+// 0x20004 - 0x11040 = :upper16:0xefc0 = 0
+// CHECK: 11040: {{.*}} movt r1, #0
+// 0x20008 - 0x11044 + 4 = :upper16:0xefc8 = 0
+// CHECK: 11044: {{.*}} movt r2, #0
+// 0x2fffc - 0x11048 = :upper16:0x1efb4 = 1
+// CHECK: 11048: {{.*}} movt r3, #1
+// 0x2fffc - 0x1104c + 0x1050 = :upper16:0x20000 = 2
+// CHECK: 1104c: {{.*}} movt r4, #2
+ .section .destination, "aw",%progbits
+ .balign 65536
+// 0x20000
+label:
+ .word 0
+// 0x20004
+label1:
+ .word 1
+// 0x20008
+label2:
+ .word 2
+// Test label3 is immediately below 2^16 alignment boundary
+ .space 65536 - 16
+// 0x2fffc
+label3:
+ .word 3
+// label3 + 4 is on a 2^16 alignment boundary
+ .word 4
diff --git a/test/ELF/arm-plt-reloc.s b/test/ELF/arm-plt-reloc.s
new file mode 100644
index 000000000000..0616aa7966a9
--- /dev/null
+++ b/test/ELF/arm-plt-reloc.s
@@ -0,0 +1,90 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2
+// RUN: ld.lld %t1 %t2 -o %t
+// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t | FileCheck %s
+// RUN: ld.lld -shared %t1 %t2 -o %t3
+// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSO %s
+// RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
+// REQUIRES: arm
+//
+// Test PLT entry generation
+ .syntax unified
+ .text
+ .align 2
+ .globl _start
+ .type _start,%function
+_start:
+ b func1
+ bl func2
+ beq func3
+
+// Executable, expect no PLT
+// CHECK: Disassembly of section .text:
+// CHECK-NEXT: func1:
+// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
+// CHECK: func2:
+// CHECK-NEXT: 11004: 1e ff 2f e1 bx lr
+// CHECK: func3:
+// CHECK-NEXT: 11008: 1e ff 2f e1 bx lr
+// CHECK: _start:
+// CHECK-NEXT: 1100c: fb ff ff ea b #-20 <func1>
+// CHECK-NEXT: 11010: fb ff ff eb bl #-20 <func2>
+// CHECK-NEXT: 11014: fb ff ff 0a beq #-20 <func3>
+
+// Expect PLT entries as symbols can be preempted
+// DSO: Disassembly of section .text:
+// DSO-NEXT: func1:
+// DSO-NEXT: 1000: 1e ff 2f e1 bx lr
+// DSO: func2:
+// DSO-NEXT: 1004: 1e ff 2f e1 bx lr
+// DSO: func3:
+// DSO-NEXT: 1008: 1e ff 2f e1 bx lr
+// DSO: _start:
+// S(0x1034) - P(0x100c) + A(-8) = 0x20 = 32
+// DSO-NEXT: 100c: 08 00 00 ea b #32
+// S(0x1044) - P(0x1010) + A(-8) = 0x2c = 44
+// DSO-NEXT: 1010: 0b 00 00 eb bl #44
+// S(0x1054) - P(0x1014) + A(-8) = 0x38 = 56
+// DSO-NEXT: 1014: 0e 00 00 0a beq #56
+// DSO: Disassembly of section .plt:
+// DSO-NEXT:.plt:
+// DSO-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
+// DSO-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4]
+// DSO-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr
+// DSO-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]!
+// 0x1028 + 8 + 1fd0 = 0x3000
+// DSO-NEXT: 1030: d0 1f 00 00
+// DSO-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4]
+// DSO-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc
+// DSO-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12]
+// 0x1038 + 8 + 1fcc = 0x300c
+// DSO-NEXT: 1040: cc 1f 00 00
+// DSO-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4]
+// DSO-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc
+// DSO-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12]
+// 0x1048 + 8 + 1fc0 = 0x3010
+// DSO-NEXT: 1050: c0 1f 00 00
+// DSO-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4]
+// DSO-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc
+// DSO-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12]
+// 0x1058 + 8 + 1fb4 = 0x3014
+// DSO-NEXT: 1060: b4 1f 00 00
+
+// DSOREL: Name: .got.plt
+// DSOREL-NEXT: Type: SHT_PROGBITS
+// DSOREL-NEXT: Flags [
+// DSOREL-NEXT: SHF_ALLOC
+// DSOREL-NEXT: SHF_WRITE
+// DSOREL-NEXT: ]
+// DSOREL-NEXT: Address: 0x3000
+// DSOREL-NEXT: Offset:
+// DSOREL-NEXT: Size: 24
+// DSOREL-NEXT: Link:
+// DSOREL-NEXT: Info:
+// DSOREL-NEXT: AddressAlignment: 4
+// DSOREL-NEXT: EntrySize:
+// DSOREL: Relocations [
+// DSOREL-NEXT: Section (4) .rel.plt {
+// DSOREL-NEXT: 0x300C R_ARM_JUMP_SLOT func1 0x0
+// DSOREL-NEXT: 0x3010 R_ARM_JUMP_SLOT func2 0x0
+// DSOREL-NEXT: 0x3014 R_ARM_JUMP_SLOT func3 0x0
diff --git a/test/ELF/arm-thumb-blx.s b/test/ELF/arm-thumb-blx.s
new file mode 100644
index 000000000000..b581d1dd3acd
--- /dev/null
+++ b/test/ELF/arm-thumb-blx.s
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/arm-thumb-blx-targets.s -o %ttarget
+// RUN: echo "SECTIONS { \
+// RUN: .R_ARM_CALL24_callee1 : { *(.R_ARM_CALL24_callee_low) } \
+// RUN: .R_ARM_CALL24_callee2 : { *(.R_ARM_CALL24_callee_thumb_low) } \
+// RUN: .caller : { *(.text) } \
+// RUN: .R_ARM_CALL24_callee3 : { *(.R_ARM_CALL24_callee_high) } \
+// RUN: .R_ARM_CALL24_callee4 : { *(.R_ARM_CALL24_callee_thumb_high) } } " > %t.script
+// RUN: ld.lld --script %t.script %t %ttarget -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s
+// REQUIRES: arm
+// Test BLX instruction is chosen for Thumb BL/BLX instruction and ARM callee
+// 2 byte nops are used to test the pc-rounding behaviour. As a BLX from a
+// 2 byte aligned destination is defined as Align(PC,4) + immediate:00
+// FIXME: llvm-mc has problems assembling BLX unless the destination is
+// external. The targets of the BL and BLX instructions are in arm-thumb-blx-target.s
+ .syntax unified
+ .section .text, "ax",%progbits
+ .thumb
+ .globl _start
+ .balign 0x10000
+ .type _start,%function
+_start:
+ blx callee_low
+ nop
+ bl callee_low
+ nop
+ blx callee_high
+ nop
+ bl callee_high
+ nop
+ blx blx_far
+ nop
+ bl blx_far
+ nop
+// Expect BLX to thumb target to be written out as a BL
+ blx callee_thumb_low
+ nop
+ blx callee_thumb_high
+ bx lr
+
+// CHECK-ARM: Disassembly of section .R_ARM_CALL24_callee1:
+// CHECK-NEXT-ARM: callee_low:
+// CHECK-NEXT-ARM: b4: 1e ff 2f e1 bx lr
+
+// CHECK-THUMB: Disassembly of section .R_ARM_CALL24_callee2:
+// CHECK-NEXT-THUMB: callee_thumb_low:
+// CHECK-NEXT-THUMB: 100: 70 47 bx lr
+
+// CHECK-THUMB: Disassembly of section .caller:
+// CHECK-THUMB: _start:
+// Align(0x10000,4) - 0xff50 (65360) + 4 = 0xb4 = callee_low
+// CHECK-NEXT-THUMB: 10000: f0 f7 58 e8 blx #-65360
+// CHECK-NEXT-THUMB: 10004: 00 bf nop
+// Align(0x10006,4) - 0xff54 (65364) + 4 = 0xb4 = callee_low
+// CHECK-NEXT-THUMB: 10006: f0 f7 56 e8 blx #-65364
+// CHECK-NEXT-THUMB: 1000a: 00 bf nop
+// Align(0x1000c,4) + 0xf0 (240) + 4 = 0x10100 = callee_high
+// CHECK-NEXT-THUMB: 1000c: 00 f0 78 e8 blx #240
+// CHECK-NEXT-THUMB: 10010: 00 bf nop
+// Align(0x10012,4) + 0xec (236) + 4 = 0x10100 = callee_high
+// CHECK-NEXT-THUMB: 10012: 00 f0 76 e8 blx #236
+// CHECK-NEXT-THUMB: 10016: 00 bf nop
+// Align(0x10018,4) + 0xfffffc (16777212) = 0x1010018 = blx_far
+// CHECK-NEXT-THUMB: 10018: ff f3 fe c7 blx #16777212
+// CHECK-NEXT-THUMB: 1001c: 00 bf nop
+// Align(0x1001e,4) + 0xfffff8 (16777208) = 0x1010018 = blx_far
+// CHECK-NEXT-THUMB: 1001e: ff f3 fc c7 blx #16777208
+// CHECK-NEXT-THUMB: 10022: 00 bf nop
+// 10024 - 0xff28 (65320) + 4 = 0x100 = callee_thumb_low
+// CHECK-NEXT-THUMB: 10024: f0 f7 6c f8 bl #-65320
+// CHECK-NEXT-THUMB: 10028: 00 bf nop
+// 1002a + 0x1d2 (466) + 4 = 0x10200 = callee_thumb_high
+// CHECK-NEXT-THUMB: 1002a: 00 f0 e9 f8 bl #466
+// CHECK-NEXT-THUMB: 1002e: 70 47 bx lr
+
+
+// CHECK-ARM: Disassembly of section .R_ARM_CALL24_callee3:
+// CHECK-NEXT-ARM: callee_high:
+// CHECK-NEXT-ARM: 10100: 1e ff 2f e1 bx lr
+
+// CHECK: Disassembly of section .R_ARM_CALL24_callee4:
+// CHECK-NEXT-THUMB:callee_thumb_high:
+// CHECK-NEXT-THUMB: 10200: 70 47 bx lr
diff --git a/test/ELF/arm-thumb-branch-error.s b/test/ELF/arm-thumb-branch-error.s
new file mode 100644
index 000000000000..de6c1bc16c96
--- /dev/null
+++ b/test/ELF/arm-thumb-branch-error.s
@@ -0,0 +1,19 @@
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
+// RUN: not ld.lld %t %tfar -o %t2 2>&1 | FileCheck %s
+// REQUIRES: arm
+ .syntax unified
+ .section .text, "ax",%progbits
+ .globl _start
+ .balign 0x10000
+ .type _start,%function
+_start:
+ // address of too_far symbols are just out of range of ARM branch with
+ // 26-bit immediate field and an addend of -8
+ bl too_far1
+ b too_far2
+ beq.w too_far3
+
+// CHECK: R_ARM_THM_CALL out of range
+// CHECK-NEXT: R_ARM_THM_JUMP24 out of range
+// CHECK-NEXT: R_ARM_THM_JUMP19 out of range
diff --git a/test/ELF/arm-thumb-branch.s b/test/ELF/arm-thumb-branch.s
new file mode 100644
index 000000000000..94be9ecb6e53
--- /dev/null
+++ b/test/ELF/arm-thumb-branch.s
@@ -0,0 +1,59 @@
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
+// RUN: echo "SECTIONS { \
+// RUN: .callee1 : { *(.callee_low) } \
+// RUN: .caller : { *(.text) } \
+// RUN: .callee2 : { *(.callee_high) } } " > %t.script
+// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s
+// REQUIRES: arm
+
+ .syntax unified
+ .thumb
+ .section .callee_low, "ax",%progbits
+ .align 2
+ .type callee_low,%function
+callee_low:
+ bx lr
+
+ .section .text, "ax",%progbits
+ .globl _start
+ .balign 0x10000
+ .type _start,%function
+_start:
+ bl callee_low
+ b callee_low
+ beq callee_low
+ bl callee_high
+ b callee_high
+ bne callee_high
+ bl far_uncond
+ b far_uncond
+ bgt far_cond
+ bx lr
+
+ .section .callee_high, "ax",%progbits
+ .align 2
+ .type callee_high,%function
+callee_high:
+ bx lr
+
+// CHECK: Disassembly of section .callee1:
+// CHECK-NEXT: callee_low:
+// CHECK-NEXT: b4: 70 47 bx lr
+// CHECK-NEXT: Disassembly of section .caller:
+// CHECK-NEXT: _start:
+// CHECK-NEXT: 10000: f0 f7 58 f8 bl #-65360
+// CHECK-NEXT: 10004: f0 f7 56 b8 b.w #-65364
+// CHECK-NEXT: 10008: 30 f4 54 a8 beq.w #-65368
+// CHECK-NEXT: 1000c: 00 f0 0c f8 bl #24
+// CHECK-NEXT: 10010: 00 f0 0a b8 b.w #20
+// CHECK-NEXT: 10014: 40 f0 08 80 bne.w #16
+// CHECK-NEXT: 10018: ff f3 ff d7 bl #16777214
+// CHECK-NEXT: 1001c: ff f3 fd 97 b.w #16777210
+// CHECK-NEXT: 10020: 3f f3 ff af bgt.w #1048574
+// CHECK-NEXT: 10024: 70 47 bx lr
+// CHECK-NEXT: 10026: 00 00 movs r0, r0
+// CHECK-NEXT: Disassembly of section .callee2:
+// CHECK-NEXT: callee_high:
+// CHECK-NEXT: 10028: 70 47 bx lr
diff --git a/test/ELF/arm-thumb-interwork-thunk.s b/test/ELF/arm-thumb-interwork-thunk.s
new file mode 100644
index 000000000000..6173df3c066b
--- /dev/null
+++ b/test/ELF/arm-thumb-interwork-thunk.s
@@ -0,0 +1,375 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN: .R_ARM_JUMP24_callee_1 : { *(.R_ARM_JUMP24_callee_low) } \
+// RUN: .R_ARM_THM_JUMP_callee_1 : { *(.R_ARM_THM_JUMP_callee_low)} \
+// RUN: .text : { *(.text) } \
+// RUN: .arm_caller : { *(.arm_caller) } \
+// RUN: .thumb_caller : { *(.thumb_caller) } \
+// RUN: .R_ARM_JUMP24_callee_2 : { *(.R_ARM_JUMP24_callee_high) } \
+// RUN: .R_ARM_THM_JUMP_callee_2 : { *(.R_ARM_THM_JUMP_callee_high) } } " > %t.script
+// RUN: ld.lld --script %t.script %t -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-ABS-THUMB %s
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-ABS-ARM %s
+// RUN: ld.lld --script %t.script %t -pie -o %t3 2>&1
+// RUN: ld.lld --script %t.script %t --shared -o %t4 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-PI-THUMB %s
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-PI-ARM %s
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-PI-PLT-THUMB %s
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-PI-PLT-ARM %s
+// RUN: llvm-readobj -s -r %t4 | FileCheck -check-prefix=CHECK-DSO-REL %s
+// REQUIRES: arm
+
+// Test ARM Thumb Interworking
+// The file is linked and checked 3 times to check the following contexts
+// - Absolute executables, absolute Thunks are used.
+// - Position independent executables, position independent Thunks are used.
+// - Shared object, position independent Thunks to PLT entries are used.
+
+ .syntax unified
+
+// Target Sections for thunks at a lower address than the callers.
+.section .R_ARM_JUMP24_callee_low, "ax", %progbits
+ .thumb
+ .balign 0x1000
+ .globl thumb_callee1
+ .type thumb_callee1, %function
+thumb_callee1:
+ bx lr
+
+// CHECK-THUMB: Disassembly of section .R_ARM_JUMP24_callee_1:
+// CHECK-THUMB: thumb_callee1:
+// CHECK-THUMB: 1000: 70 47 bx
+ .section .R_ARM_THM_JUMP_callee_low, "ax", %progbits
+ .arm
+ .balign 0x100
+ .globl arm_callee1
+ .type arm_callee1, %function
+arm_callee1:
+ bx lr
+// Disassembly of section .R_ARM_THM_JUMP_callee_1:
+// CHECK-ARM: arm_callee1:
+// CHECK-ARM-NEXT: 1100: 1e ff 2f e1 bx lr
+
+ // Calling sections
+ // At present ARM and Thumb interworking thunks are always added to the calling
+ // section.
+ .section .arm_caller, "ax", %progbits
+ .arm
+ .balign 0x100
+ .globl arm_caller
+ .type arm_caller, %function
+arm_caller:
+ // If target supports BLX and target is in range we don't need an
+ // interworking thunk for a BL or BLX instruction.
+ bl thumb_callee1
+ blx thumb_callee1
+ // A B instruction can't be transformed into a BLX and needs an interworking
+ // thunk
+ b thumb_callee1
+ // As long as the thunk is in range it can be reused
+ b thumb_callee1
+ // There can be more than one thunk associated with a section
+ b thumb_callee2
+ b thumb_callee3
+ // In range ARM targets do not require interworking thunks
+ b arm_callee1
+ beq arm_callee2
+ bne arm_callee3
+ bx lr
+// CHECK-ABS-ARM: Disassembly of section .arm_caller:
+// CHECK-ABS-ARM-NEXT: arm_caller:
+// CHECK-ABS-ARM-NEXT: 1300: 3e ff ff fa blx #-776 <thumb_callee1>
+// CHECK-ABS-ARM-NEXT: 1304: 3d ff ff fa blx #-780 <thumb_callee1>
+// CHECK-ABS-ARM-NEXT: 1308: 06 00 00 ea b #24 <arm_caller+0x28>
+// CHECK-ABS-ARM-NEXT: 130c: 05 00 00 ea b #20 <arm_caller+0x28>
+// CHECK-ABS-ARM-NEXT: 1310: 07 00 00 ea b #28 <arm_caller+0x34>
+// CHECK-ABS-ARM-NEXT: 1314: 09 00 00 ea b #36 <arm_caller+0x40>
+// CHECK-ABS-ARM-NEXT: 1318: 78 ff ff ea b #-544 <arm_callee1>
+// CHECK-ABS-ARM-NEXT: 131c: b7 00 00 0a beq #732 <arm_callee2>
+// CHECK-ABS-ARM-NEXT: 1320: b7 00 00 1a bne #732 <arm_callee3>
+// CHECK-ABS-ARM-NEXT: 1324: 1e ff 2f e1 bx lr
+// 0x1001 = thumb_callee1
+// CHECK-ABS-ARM-NEXT: 1328: 01 c0 01 e3 movw r12, #4097
+// CHECK-ABS-ARM-NEXT: 132c: 00 c0 40 e3 movt r12, #0
+// CHECK-ABS-ARM-NEXT: 1330: 1c ff 2f e1 bx r12
+// 0x1501 = thumb_callee2
+// CHECK-ABS-ARM-NEXT: 1334: 01 c5 01 e3 movw r12, #5377
+// CHECK-ABS-ARM-NEXT: 1338: 00 c0 40 e3 movt r12, #0
+// CHECK-ABS-ARM-NEXT: 133c: 1c ff 2f e1 bx r12
+// 0x1503 = thumb_callee3
+// CHECK-ABS-ARM-NEXT: 1340: 03 c5 01 e3 movw r12, #5379
+// CHECK-ABS-ARM-NEXT: 1344: 00 c0 40 e3 movt r12, #0
+// CHECK-ABS-ARM-NEXT: 1348: 1c ff 2f e1 bx r12
+
+// CHECK-PI-ARM: Disassembly of section .arm_caller:
+// CHECK-PI-ARM-NEXT: arm_caller:
+// CHECK-PI-ARM-NEXT: 1300: 3e ff ff fa blx #-776 <thumb_callee1>
+// CHECK-PI-ARM-NEXT: 1304: 3d ff ff fa blx #-780 <thumb_callee1>
+// 0x1308 + 8 + 0x18 = 0x1328
+// CHECK-PI-ARM-NEXT: 1308: 06 00 00 ea b #24 <arm_caller+0x28>
+// 0x130c + 8 + 0x14 = 0x1328
+// CHECK-PI-ARM-NEXT: 130c: 05 00 00 ea b #20 <arm_caller+0x28>
+// 0x1310 + 8 + 0x20 = 0x1338
+// CHECK-PI-ARM-NEXT: 1310: 08 00 00 ea b #32 <arm_caller+0x38>
+// 0x1314 + 8 + 0x2c = 0x1348
+// CHECK-PI-ARM-NEXT: 1314: 0b 00 00 ea b #44 <arm_caller+0x48>
+// CHECK-PI-ARM-NEXT: 1318: 78 ff ff ea b #-544 <arm_callee1>
+// CHECK-PI-ARM-NEXT: 131c: b7 00 00 0a beq #732 <arm_callee2>
+// CHECK-PI-ARM-NEXT: 1320: b7 00 00 1a bne #732 <arm_callee3>
+// CHECK-PI-ARM-NEXT: 1324: 1e ff 2f e1 bx lr
+// 0x1330 + 8 - 0x337 = 0x1001 = thumb_callee1
+// CHECK-PI-ARM-NEXT: 1328: c9 cc 0f e3 movw r12, #64713
+// CHECK-PI-ARM-NEXT: 132c: ff cf 4f e3 movt r12, #65535
+// CHECK-PI-ARM-NEXT: 1330: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-NEXT: 1334: 1c ff 2f e1 bx r12
+// 0x1340 + 8 + 0x1b9 = 0x1501
+// CHECK-PI-ARM-NEXT: 1338: b9 c1 00 e3 movw r12, #441
+// CHECK-PI-ARM-NEXT: 133c: 00 c0 40 e3 movt r12, #0
+// CHECK-PI-ARM-NEXT: 1340: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-NEXT: 1344: 1c ff 2f e1 bx r12
+// 1350 + 8 + 0x1ab = 0x1503
+// CHECK-PI-ARM-NEXT: 1348: ab c1 00 e3 movw r12, #427
+// CHECK-PI-ARM-NEXT: 134c: 00 c0 40 e3 movt r12, #0
+// CHECK-PI-ARM-NEXT: 1350: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-NEXT: 1354: 1c ff 2f e1 bx r12
+
+// All PLT entries are ARM, no need for interworking thunks
+// CHECK-PI-ARM-PLT: Disassembly of section .arm_caller:
+// CHECK-PI-ARM-PLT-NEXT: arm_caller:
+// 0x17e4 PLT(thumb_callee1)
+// CHECK-PI-ARM-PLT-NEXT: 1300: 37 01 00 eb bl #1244
+// 0x17e4 PLT(thumb_callee1)
+// CHECK-PI-ARM-PLT-NEXT: 1304: 36 01 00 eb bl #1240
+// 0x17e4 PLT(thumb_callee1)
+// CHECK-PI-ARM-PLT-NEXT: 1308: 35 01 00 ea b #1236
+// 0x17e4 PLT(thumb_callee1)
+// CHECK-PI-ARM-PLT-NEXT: 130c: 34 01 00 ea b #1232
+// 0x17f4 PLT(thumb_callee2)
+// CHECK-PI-ARM-PLT-NEXT: 1310: 37 01 00 ea b #1244
+// 0x1804 PLT(thumb_callee3)
+// CHECK-PI-ARM-PLT-NEXT: 1314: 3a 01 00 ea b #1256
+// 0x1814 PLT(arm_callee1)
+// CHECK-PI-ARM-PLT-NEXT: 1318: 3d 01 00 ea b #1268
+// 0x1824 PLT(arm_callee2)
+// CHECK-PI-ARM-PLT-NEXT: 131c: 40 01 00 0a beq #1280
+// 0x1834 PLT(arm_callee3)
+// CHECK-PI-ARM-PLT-NEXT: 1320: 43 01 00 1a bne #1292
+// CHECK-PI-ARM-PLT-NEXT: 1324: 1e ff 2f e1 bx lr
+
+ .section .thumb_caller, "ax", %progbits
+ .balign 0x100
+ .thumb
+ .globl thumb_caller
+ .type thumb_caller, %function
+thumb_caller:
+ // If target supports BLX and target is in range we don't need an
+ // interworking thunk for a BL or BLX instruction.
+ bl arm_callee1
+ blx arm_callee1
+ // A B instruction can't be transformed into a BLX and needs an interworking
+ // thunk
+ b.w arm_callee1
+ // As long as the thunk is in range it can be reused
+ b.w arm_callee2
+ // There can be more than one thunk associated with a section
+ b.w arm_callee3
+ // Conditional branches also require interworking thunks, they can use the
+ // same interworking thunks.
+ beq.w arm_callee1
+ beq.w arm_callee2
+ bne.w arm_callee3
+// CHECK-ABS-THUMB: Disassembly of section .thumb_caller:
+// CHECK-ABS-THUMB-NEXT: thumb_caller:
+// 0x1400 + 4 - 0x304 = 0x1100 = arm_callee1
+// CHECK-ABS-THUMB-NEXT: 1400: ff f7 7e ee blx #-772
+// 0x1404 + 4 - 0x308 = 0x1100 = arm_callee1
+// CHECK-ABS-THUMB-NEXT: 1404: ff f7 7c ee blx #-776
+// 0x1408 + 4 + 0x14 = 0x520
+// CHECK-ABS-THUMB-NEXT: 1408: 00 f0 0a b8 b.w #20
+// 0x140c + 4 + 0x1a = 0x52a
+// CHECK-ABS-THUMB-NEXT: 140c: 00 f0 0d b8 b.w #26
+// 0x1410 + 4 + 0x20 = 0x534
+// CHECK-ABS-THUMB-NEXT: 1410: 00 f0 10 b8 b.w #32
+// 0x1414 + 4 + 8 = 0x520
+// CHECK-ABS-THUMB-NEXT: 1414: 00 f0 04 80 beq.w #8
+// 0x1418 + 4 + 0xe = 0x52a
+// CHECK-ABS-THUMB-NEXT: 1418: 00 f0 07 80 beq.w #14
+// 0x141c + 4 + 0x14 = 0x534
+// CHECK-ABS-THUMB-NEXT: 141c: 40 f0 0a 80 bne.w #20
+// 0x1100 = arm_callee1
+// CHECK-ABS-THUMB-NEXT: 1420: 41 f2 00 1c movw r12, #4352
+// CHECK-ABS-THUMB-NEXT: 1424: c0 f2 00 0c movt r12, #0
+// CHECK-ABS-THUMB-NEXT: 1428: 60 47 bx r12
+// 0x1600 = arm_callee2
+// CHECK-ABS-THUMB-NEXT: 142a: 41 f2 00 6c movw r12, #5632
+// CHECK-ABS-THUMB-NEXT: 142e: c0 f2 00 0c movt r12, #0
+// CHECK-ABS-THUMB-NEXT: 1432: 60 47 bx r12
+// 0x1604 = arm_callee3
+// CHECK-ABS-THUMB-NEXT: 1434: 41 f2 04 6c movw r12, #5636
+// CHECK-ABS-THUMB-NEXT: 1438: c0 f2 00 0c movt r12, #0
+// CHECK-ABS-THUMB-NEXT: 143c: 60 47 bx r12
+
+// CHECK-PI-THUMB: Disassembly of section .thumb_caller:
+// CHECK-PI-THUMB-NEXT: thumb_caller:
+// CHECK-PI-THUMB-NEXT: 1400: ff f7 7e ee blx #-772
+// CHECK-PI-THUMB-NEXT: 1404: ff f7 7c ee blx #-776
+// CHECK-PI-THUMB-NEXT: 1408: 00 f0 0a b8 b.w #20
+// CHECK-PI-THUMB-NEXT: 140c: 00 f0 0e b8 b.w #28
+// CHECK-PI-THUMB-NEXT: 1410: 00 f0 12 b8 b.w #36
+// CHECK-PI-THUMB-NEXT: 1414: 00 f0 04 80 beq.w #8
+// CHECK-PI-THUMB-NEXT: 1418: 00 f0 08 80 beq.w #16
+// CHECK-PI-THUMB-NEXT: 141c: 40 f0 0c 80 bne.w #24
+// 0x1428 + 4 - 0x32c = 0x1100 = arm_callee1
+// CHECK-PI-THUMB-NEXT: 1420: 4f f6 d4 4c movw r12, #64724
+// CHECK-PI-THUMB-NEXT: 1424: cf f6 ff 7c movt r12, #65535
+// CHECK-PI-THUMB-NEXT: 1428: fc 44 add r12, pc
+// CHECK-PI-THUMB-NEXT: 142a: 60 47 bx r12
+// 0x1434 + 4 + 0x1c8 = 0x1600 = arm_callee2
+// CHECK-PI-THUMB-NEXT: 142c: 40 f2 c8 1c movw r12, #456
+// CHECK-PI-THUMB-NEXT: 1430: c0 f2 00 0c movt r12, #0
+// CHECK-PI-THUMB-NEXT: 1434: fc 44 add r12, pc
+// CHECK-PI-THUMB-NEXT: 1436: 60 47 bx r12
+// 0x1440 + 4 + 0x1c0 = 0x1604 = arm_callee3
+// CHECK-PI-THUMB-NEXT: 1438: 40 f2 c0 1c movw r12, #448
+// CHECK-PI-THUMB-NEXT: 143c: c0 f2 00 0c movt r12, #0
+// CHECK-PI-THUMB-NEXT: 1440: fc 44 add r12, pc
+// CHECK-PI-THUMB-NEXT: 1442: 60 47 bx r12
+
+// CHECK-PI-THUMB-PLT: Disassembly of section .arm_caller:
+// CHECK-PI-THUMB-PLT-NEXT: thumb_caller:
+// 0x1400 + 4 + 0x410 = 0x1814 = PLT(arm_callee1)
+// CHECK-PI-THUMB-PLT-NEXT: 1400: 00 f0 08 ea blx #1040
+// 0x1404 + 4 + 0x40c = 0x1814 = PLT(arm_callee1)
+// CHECK-PI-THUMB-PLT-NEXT: 1404: 00 f0 06 ea blx #1036
+// 0x1408 + 4 + 0x14 = 0x1420 = IWV(PLT(arm_callee1)
+// CHECK-PI-THUMB-PLT-NEXT: 1408: 00 f0 0a b8 b.w #20
+// 0x140c + 4 + 0x1c = 0x142c = IWV(PLT(arm_callee2)
+// CHECK-PI-THUMB-PLT-NEXT: 140c: 00 f0 0e b8 b.w #28
+// 0x1410 + 4 + 0x24 = 0x1438 = IWV(PLT(arm_callee3)
+// CHECK-PI-THUMB-PLT-NEXT: 1410: 00 f0 12 b8 b.w #36
+// 0x1414 + 4 + 8 = 0x1420 = IWV(PLT(arm_callee1)
+// CHECK-PI-THUMB-PLT-NEXT: 1414: 00 f0 04 80 beq.w #8
+// 0x1418 + 4 + 0x10 = 0x142c = IWV(PLT(arm_callee2)
+// CHECK-PI-THUMB-PLT-NEXT: 1418: 00 f0 08 80 beq.w #16
+// 0x141c + 4 + 0x18 = 0x1438 = IWV(PLT(arm_callee3)
+// CHECK-PI-THUMB-PLT-NEXT: 141c: 40 f0 0c 80 bne.w #24
+// 0x1428 + 4 + 0x3e8 = 0x1814 = PLT(arm_callee1)
+// CHECK-PI-THUMB-PLT-NEXT: 1420: 40 f2 e8 3c movw r12, #1000
+// CHECK-PI-THUMB-PLT-NEXT: 1424: c0 f2 00 0c movt r12, #0
+// CHECK-PI-THUMB-PLT-NEXT: 1428: fc 44 add r12, pc
+// CHECK-PI-THUMB-PLT-NEXT: 142a: 60 47 bx r12
+// 0x1434 + 4 + 0x3ec = 0x1824 = PLT(arm_callee2)
+// CHECK-PI-THUMB-PLT-NEXT: 142c: 40 f2 ec 3c movw r12, #1004
+// CHECK-PI-THUMB-PLT-NEXT: 1430: c0 f2 00 0c movt r12, #0
+// CHECK-PI-THUMB-PLT-NEXT: 1434: fc 44 add r12, pc
+// CHECK-PI-THUMB-PLT-NEXT: 1436: 60 47 bx r12
+// 0x1440 + 4 + 0x3f0 = 0x1834 = PLT(arm_callee3)
+// CHECK-PI-THUMB-PLT-NEXT: 1438: 40 f2 f0 3c movw r12, #1008
+// CHECK-PI-THUMB-PLT-NEXT: 143c: c0 f2 00 0c movt r12, #0
+// CHECK-PI-THUMB-PLT-NEXT: 1440: fc 44 add r12, pc
+// CHECK-PI-THUMB-PLT-NEXT: 1442: 60 47 bx r12
+
+// Target Sections for thunks at a higher address than the callers.
+.section .R_ARM_JUMP24_callee_high, "ax", %progbits
+ .thumb
+ .balign 0x100
+ .globl thumb_callee2
+ .type thumb_callee2, %function
+thumb_callee2:
+ bx lr
+
+ .globl thumb_callee3
+ .type thumb_callee3, %function
+thumb_callee3:
+ bx lr
+// CHECK-THUMB: Disassembly of section .R_ARM_JUMP24_callee_2:
+// CHECK-THUMB-NEXT: thumb_callee2:
+// CHECK-THUMB-NEXT: 1500: 70 47 bx lr
+// CHECK-THUMB: thumb_callee3:
+// CHECK-THUMB-NEXT: 1502: 70 47 bx lr
+
+ .section .R_ARM_THM_JUMP_callee_high, "ax", %progbits
+ .arm
+ .balign 0x100
+ .globl arm_callee2
+ .type arm_callee2, %function
+arm_callee2:
+ bx lr
+ .globl arm_callee3
+ .type arm_callee3, %function
+arm_callee3:
+ bx lr
+// CHECK-ARM: Disassembly of section .R_ARM_THM_JUMP_callee_2:
+// CHECK-ARM-NEXT: arm_callee2:
+// CHECK-ARM-NEXT: 1600: 1e ff 2f e1 bx lr
+// CHECK-ARM: arm_callee3:
+// CHECK-ARM-NEXT: 1604: 1e ff 2f e1 bx lr
+
+// _start section just calls the arm and thumb calling sections
+ .text
+ .arm
+ .globl _start
+ .balign 0x100
+ .type _start, %function
+_start:
+ bl arm_caller
+ bl thumb_caller
+ bx lr
+
+
+// CHECK-PI-ARM-PLT: Disassembly of section .plt:
+// CHECK-PI-ARM-PLT-NEXT: .plt:
+// CHECK-PI-ARM-PLT-NEXT: 17b0: 04 e0 2d e5 str lr, [sp, #-4]!
+// CHECK-PI-ARM-PLT-NEXT: 17b4: 04 e0 9f e5 ldr lr, [pc, #4]
+// CHECK-PI-ARM-PLT-NEXT: 17b8: 0e e0 8f e0 add lr, pc, lr
+// CHECK-PI-ARM-PLT-NEXT: 17bc: 08 f0 be e5 ldr pc, [lr, #8]!
+// CHECK-PI-ARM-PLT-NEXT: 17c0: d4 00 00 00
+// 0x17c8 + 8 + 0xd0 = 0x18a0 arm_caller
+// CHECK-PI-ARM-PLT-NEXT: 17c4: 04 c0 9f e5 ldr r12, [pc, #4]
+// CHECK-PI-ARM-PLT-NEXT: 17c8: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-PLT-NEXT: 17cc: 00 f0 9c e5 ldr pc, [r12]
+// CHECK-PI-ARM-PLT-NEXT: 17d0: d0 00 00 00
+// 0x17d8 + 8 + 0xc4 = 0x18a4 thumb_caller
+// CHECK-PI-ARM-PLT-NEXT: 17d4: 04 c0 9f e5 ldr r12, [pc, #4]
+// CHECK-PI-ARM-PLT-NEXT: 17d8: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-PLT-NEXT: 17dc: 00 f0 9c e5 ldr pc, [r12]
+// CHECK-PI-ARM-PLT-NEXT: 17e0: c4 00 00 00
+// 0x17e8 + 8 + 0xb8 = 0x18a8 thumb_callee1
+// CHECK-PI-ARM-PLT-NEXT: 17e4: 04 c0 9f e5 ldr r12, [pc, #4]
+// CHECK-PI-ARM-PLT-NEXT: 17e8: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-PLT-NEXT: 17ec: 00 f0 9c e5 ldr pc, [r12]
+// CHECK-PI-ARM-PLT-NEXT: 17f0: b8 00 00 00
+// 0x17f8 + 8 + 0xac = 0x18ac thumb_callee2
+// CHECK-PI-ARM-PLT-NEXT: 17f4: 04 c0 9f e5 ldr r12, [pc, #4]
+// CHECK-PI-ARM-PLT-NEXT: 17f8: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-PLT-NEXT: 17fc: 00 f0 9c e5 ldr pc, [r12]
+// CHECK-PI-ARM-PLT-NEXT: 1800: ac 00 00 00
+// 0x1808 + 8 + 0xa0 = 0x18b0 thumb_callee3
+// CHECK-PI-ARM-PLT-NEXT: 1804: 04 c0 9f e5 ldr r12, [pc, #4]
+// CHECK-PI-ARM-PLT-NEXT: 1808: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-PLT-NEXT: 180c: 00 f0 9c e5 ldr pc, [r12]
+// CHECK-PI-ARM-PLT-NEXT: 1810: a0 00 00 00
+// 0x1818 + 8 + 0x94 = 0x18b4 arm_callee1
+// CHECK-PI-ARM-PLT-NEXT: 1814: 04 c0 9f e5 ldr r12, [pc, #4]
+// CHECK-PI-ARM-PLT-NEXT: 1818: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-PLT-NEXT: 181c: 00 f0 9c e5 ldr pc, [r12]
+// CHECK-PI-ARM-PLT-NEXT: 1820: 94 00 00 00
+// 0x1828 + 8 + 0x88 = 0x18b8 arm_callee2
+// CHECK-PI-ARM-PLT-NEXT: 1824: 04 c0 9f e5 ldr r12, [pc, #4]
+// CHECK-PI-ARM-PLT-NEXT: 1828: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-PLT-NEXT: 182c: 00 f0 9c e5 ldr pc, [r12]
+// CHECK-PI-ARM-PLT-NEXT: 1830: 88 00 00 00
+// 0x1838 + 8 + 0x7c = 0x18bc arm_callee3
+// CHECK-PI-ARM-PLT-NEXT: 1834: 04 c0 9f e5 ldr r12, [pc, #4]
+// CHECK-PI-ARM-PLT-NEXT: 1838: 0f c0 8c e0 add r12, r12, pc
+// CHECK-PI-ARM-PLT-NEXT: 183c: 00 f0 9c e5 ldr pc, [r12]
+// CHECK-PI-ARM-PLT-NEXT: 1840: 7c 00 00 00
+
+// CHECK-DSO-REL: 0x18A0 R_ARM_JUMP_SLOT arm_caller
+// CHECK-DSO-REL-NEXT: 0x18A4 R_ARM_JUMP_SLOT thumb_caller
+// CHECK-DSO-REL-NEXT: 0x18A8 R_ARM_JUMP_SLOT thumb_callee1
+// CHECK-DSO-REL-NEXT: 0x18AC R_ARM_JUMP_SLOT thumb_callee2
+// CHECK-DSO-REL-NEXT: 0x18B0 R_ARM_JUMP_SLOT thumb_callee3
+// CHECK-DSO-REL-NEXT: 0x18B4 R_ARM_JUMP_SLOT arm_callee1
+// CHECK-DSO-REL-NEXT: 0x18B8 R_ARM_JUMP_SLOT arm_callee2
+// CHECK-DSO-REL-NEXT: 0x18BC R_ARM_JUMP_SLOT arm_callee3
diff --git a/test/ELF/arm-thumb-narrow-branch-check.s b/test/ELF/arm-thumb-narrow-branch-check.s
new file mode 100644
index 000000000000..b601b6d5dc26
--- /dev/null
+++ b/test/ELF/arm-thumb-narrow-branch-check.s
@@ -0,0 +1,72 @@
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN: .R_ARM_PC11_1 : { *(.R_ARM_PC11_1) } \
+// RUN: .caller : { *(.caller) } \
+// RUN: .R_ARM_PC11_2 : { *(.R_ARM_PC11_2) } \
+// RUN: .text : { *(.text) } } " > %t.script
+// RUN: ld.lld --script %t.script %t %S/Inputs/arm-thumb-narrow-branch.o -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s
+// REQUIRES: arm
+
+// Test the R_ARM_PC11 relocation which is used with the narrow encoding of B.N
+// the source of these relocations is a binary file arm-thumb-narrow-branch.o
+// which has been assembled with the GNU assembler as llvm-mc doesn't emit it
+// as the range of +-2048 bytes is too small to be practically useful for out
+// of section branches.
+ .syntax unified
+
+.global callee_low_far
+.type callee_low_far,%function
+callee_low_far = 0x809
+
+ .section .R_ARM_PC11_1,"ax",%progbits
+ .thumb
+ .balign 0x1000
+ .type callee_low,%function
+ .globl callee_low
+callee_low:
+ bx lr
+
+ .text
+ .align 2
+ .thumb
+ .globl _start
+ .type _start, %function
+_start:
+ bl callers
+ bx lr
+
+ .section .R_ARM_PC11_2,"ax",%progbits
+ .thumb
+ .align 2
+ .type callee_high,%function
+ .globl callee_high
+callee_high:
+ bx lr
+
+.global callee_high_far
+.type callee_high_far,%function
+callee_high_far = 0x180d
+
+// CHECK: Disassembly of section .R_ARM_PC11_1:
+// CHECK-NEXT: callee_low:
+// CHECK-NEXT: 1000: 70 47 bx lr
+// CHECK-NEXT: Disassembly of section .caller:
+// CHECK-NEXT: callers:
+// 1004 - 0x800 (2048) + 4 = 0x808 = callee_low_far
+// CHECK-NEXT: 1004: 00 e4 b #-2048
+// 1006 - 0xa (10) + 4 = 0x1000 = callee_low
+// CHECK-NEXT: 1006: fb e7 b #-10
+// 1008 + 4 + 4 = 0x1010 = callee_high
+// CHECK-NEXT: 1008: 02 e0 b #4
+// 100a + 0x7fe (2046) + 4 = 0x180c = callee_high_far
+// CHECK-NEXT: 100a: ff e3 b #2046
+// CHECK-NEXT: 100c: 70 47 bx lr
+// CHECK-NEXT: 100e: 00 bf nop
+// CHECK-NEXT: Disassembly of section .R_ARM_PC11_2:
+// CHECK-NEXT: callee_high:
+// CHECK-NEXT: 1010: 70 47 bx lr
+// CHECK-NEXT: Disassembly of section .text:
+// CHECK-NEXT: _start:
+// CHECK-NEXT: 1014: ff f7 f6 ff bl #-20
+// CHECK-NEXT: 1018: 70 47 bx lr
diff --git a/test/ELF/arm-thumb-plt-reloc.s b/test/ELF/arm-thumb-plt-reloc.s
new file mode 100644
index 000000000000..6294e909f078
--- /dev/null
+++ b/test/ELF/arm-thumb-plt-reloc.s
@@ -0,0 +1,101 @@
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1
+// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2
+// RUN: ld.lld %t1 %t2 -o %t
+// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t | FileCheck %s
+// RUN: ld.lld -shared %t1 %t2 -o %t3
+// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOTHUMB %s
+// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOARM %s
+// RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
+// REQUIRES: arm
+//
+// Test PLT entry generation
+ .syntax unified
+ .text
+ .align 2
+ .globl _start
+ .type _start,%function
+_start:
+// FIXME, interworking is only supported for BL via BLX at the moment, when
+// interworking thunks are available for b.w and b<cond>.w this can be altered
+// to test the different forms of interworking.
+ bl func1
+ bl func2
+ bl func3
+
+// Executable, expect no PLT
+// CHECK: Disassembly of section .text:
+// CHECK-NEXT: func1:
+// CHECK-NEXT: 11000: 70 47 bx lr
+// CHECK: func2:
+// CHECK-NEXT: 11002: 70 47 bx lr
+// CHECK: func3:
+// CHECK-NEXT: 11004: 70 47 bx lr
+// CHECK-NEXT: 11006: 00 00 movs r0, r0
+// CHECK: _start:
+// 11008 + 4 -12 = 0x11000 = func1
+// CHECK-NEXT: 11008: ff f7 fa ff bl #-12
+// 1100c + 4 -14 = 0x11002 = func2
+// CHECK-NEXT: 1100c: ff f7 f9 ff bl #-14
+// 11010 + 4 -16 = 0x11004 = func3
+// CHECK-NEXT: 11010: ff f7 f8 ff bl #-16
+
+// Expect PLT entries as symbols can be preempted
+// .text is Thumb and .plt is ARM, llvm-objdump can currently only disassemble
+// as ARM or Thumb. Work around by disassembling twice.
+// DSOTHUMB: Disassembly of section .text:
+// DSOTHUMB: func1:
+// DSOTHUMB-NEXT: 1000: 70 47 bx lr
+// DSOTHUMB: func2:
+// DSOTHUMB-NEXT: 1002: 70 47 bx lr
+// DSOTHUMB: func3:
+// DSOTHUMB-NEXT: 1004: 70 47 bx lr
+// DSOTHUMB-NEXT: 1006: 00 00 movs r0, r0
+// DSOTHUMB: _start:
+// 0x1008 + 0x28 + 4 = 0x1034 = PLT func1
+// DSOTHUMB-NEXT: 1008: 00 f0 14 e8 blx #40
+// 0x100c + 0x34 + 4 = 0x1044 = PLT func2
+// DSOTHUMB-NEXT: 100c: 00 f0 1a e8 blx #52
+// 0x1010 + 0x40 + 4 = 0x1054 = PLT func3
+// DSOTHUMB-NEXT: 1010: 00 f0 20 e8 blx #64
+// DSOARM: Disassembly of section .plt:
+// DSOARM: .plt:
+// DSOARM-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
+// DSOARM-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4]
+// DSOARM-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr
+// DSOARM-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]!
+// DSOARM-NEXT: 1030: d0 1f 00 00
+// 0x1028 + 8 + 1fd0 = 0x3000
+// DSOARM-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4]
+// DSOARM-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc
+// DSOARM-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12]
+// DSOARM-NEXT: 1040: cc 1f 00 00
+// 0x1038 + 8 + 1fcc = 0x300c
+// DSOARM-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4]
+// DSOARM-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc
+// DSOARM-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12]
+// DSOARM-NEXT: 1050: c0 1f 00 00
+// 0x1048 + 8 + 1fc0 = 0x3010
+// DSOARM-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4]
+// DSOARM-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc
+// DSOARM-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12]
+// DSOARM-NEXT: 1060: b4 1f 00 00
+// 0x1058 + 8 + 1fb4 = 0x3014
+
+// DSOREL: Name: .got.plt
+// DSOREL-NEXT: Type: SHT_PROGBITS
+// DSOREL-NEXT: Flags [
+// DSOREL-NEXT: SHF_ALLOC
+// DSOREL-NEXT: SHF_WRITE
+// DSOREL-NEXT: ]
+// DSOREL-NEXT: Address: 0x3000
+// DSOREL-NEXT: Offset:
+// DSOREL-NEXT: Size: 24
+// DSOREL-NEXT: Link:
+// DSOREL-NEXT: Info:
+// DSOREL-NEXT: AddressAlignment: 4
+// DSOREL-NEXT: EntrySize:
+// DSOREL: Relocations [
+// DSOREL-NEXT: Section (4) .rel.plt {
+// DSOREL-NEXT: 0x300C R_ARM_JUMP_SLOT func1 0x0
+// DSOREL-NEXT: 0x3010 R_ARM_JUMP_SLOT func2 0x0
+// DSOREL-NEXT: 0x3014 R_ARM_JUMP_SLOT func3 0x0
diff --git a/test/ELF/as-needed-no-reloc.s b/test/ELF/as-needed-no-reloc.s
new file mode 100644
index 000000000000..0706ca0a932d
--- /dev/null
+++ b/test/ELF/as-needed-no-reloc.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -o %t2.so
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld -o %t %t.o --as-needed %t2.so
+# RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck %s
+
+
+# There must be a NEEDED entry for each undefined
+
+# CHECK: Name: bar
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined
+
+# CHECK: NEEDED SharedLibrary ({{.*}}2.so)
+
+ .globl _start
+_start:
+ .global bar
diff --git a/test/ELF/as-needed.s b/test/ELF/as-needed.s
index 2c5174d54077..4f1a48abac36 100644
--- a/test/ELF/as-needed.s
+++ b/test/ELF/as-needed.s
@@ -20,11 +20,11 @@
/// GROUP directive is the same as --as-needed.
-// RUN: echo "GROUP(" %t2.so %t3.so %t4.so ")" > %t.script
+// RUN: echo "GROUP(\"%t2.so\" \"%t3.so\" \"%t4.so\")" > %t.script
// RUN: ld.lld %t.o %t.script -o %t2
// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
-// RUN: echo "GROUP(AS_NEEDED(" %t2.so %t3.so %t4.so "))" > %t.script
+// RUN: echo "GROUP(AS_NEEDED(\"%t2.so\" \"%t3.so\" \"%t4.so\"))" > %t.script
// RUN: ld.lld %t.o %t.script -o %t2
// RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
@@ -38,6 +38,7 @@
.global _start
_start:
+.data
.long bar
.long zed
.weak baz
diff --git a/test/ELF/avoid-empty-program-headers.s b/test/ELF/avoid-empty-program-headers.s
new file mode 100644
index 000000000000..f7315677e1a3
--- /dev/null
+++ b/test/ELF/avoid-empty-program-headers.s
@@ -0,0 +1,78 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+// RUN: ld.lld %t -o %tout
+// RUN: llvm-readobj -program-headers %tout | FileCheck %s
+
+.global _start
+_start:
+ retq
+
+.section .tbss,"awT",@nobits
+ .zero 4
+// FIXME: Test that we don't create unecessary empty PT_LOAD and PT_GNU_RELRO
+// for the .tbss section.
+
+// CHECK: ProgramHeaders [
+// CHECK-NEXT: ProgramHeader {
+// CHECK-NEXT: Type: PT_PHDR (0x6)
+// CHECK-NEXT: Offset: 0x40
+// CHECK-NEXT: VirtualAddress: 0x10040
+// CHECK-NEXT: PhysicalAddress: 0x10040
+// CHECK-NEXT: FileSize: 280
+// CHECK-NEXT: MemSize: 280
+// CHECK-NEXT: Flags [ (0x4)
+// CHECK-NEXT: PF_R (0x4)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Alignment: 8
+// CHECK-NEXT: }
+// CHECK-NEXT: ProgramHeader {
+// CHECK-NEXT: Type: PT_LOAD (0x1)
+// CHECK-NEXT: Offset: 0x0
+// CHECK-NEXT: VirtualAddress: 0x10000
+// CHECK-NEXT: PhysicalAddress: 0x10000
+// CHECK-NEXT: FileSize: 344
+// CHECK-NEXT: MemSize: 344
+// CHECK-NEXT: Flags [ (0x4)
+// CHECK-NEXT: PF_R (0x4)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Alignment: 4096
+// CHECK-NEXT: }
+// CHECK-NEXT: ProgramHeader {
+// CHECK-NEXT: Type: PT_LOAD (0x1)
+// CHECK-NEXT: Offset: 0x1000
+// CHECK-NEXT: VirtualAddress: 0x11000
+// CHECK-NEXT: PhysicalAddress: 0x11000
+// CHECK-NEXT: FileSize: 1
+// CHECK-NEXT: MemSize: 1
+// CHECK-NEXT: Flags [ (0x5)
+// CHECK-NEXT: PF_R (0x4)
+// CHECK-NEXT: PF_X (0x1)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Alignment: 4096
+// CHECK-NEXT: }
+// CHECK-NEXT: ProgramHeader {
+// CHECK-NEXT: Type: PT_TLS (0x7)
+// CHECK-NEXT: Offset: 0x1001
+// CHECK-NEXT: VirtualAddress: 0x11001
+// CHECK-NEXT: PhysicalAddress: 0x11001
+// CHECK-NEXT: FileSize: 0
+// CHECK-NEXT: MemSize: 4
+// CHECK-NEXT: Flags [ (0x4)
+// CHECK-NEXT: PF_R (0x4)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Alignment: 1
+// CHECK-NEXT: }
+// CHECK-NEXT: ProgramHeader {
+// CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
+// CHECK-NEXT: Offset: 0x0
+// CHECK-NEXT: VirtualAddress: 0x0
+// CHECK-NEXT: PhysicalAddress: 0x0
+// CHECK-NEXT: FileSize: 0
+// CHECK-NEXT: MemSize: 0
+// CHECK-NEXT: Flags [ (0x6)
+// CHECK-NEXT: PF_R (0x4)
+// CHECK-NEXT: PF_W (0x2)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Alignment: 0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/basic-aarch64.s b/test/ELF/basic-aarch64.s
index 61b6707e49a4..84105f0acdb7 100644
--- a/test/ELF/basic-aarch64.s
+++ b/test/ELF/basic-aarch64.s
@@ -5,7 +5,7 @@
# REQUIRES: aarch64
# exits with return code 42 on FreeBSD/AArch64
-.globl _start;
+.globl _start
_start:
mov x0, 42
mov x8, 1
diff --git a/test/ELF/basic-mips.s b/test/ELF/basic-mips.s
index 7b2ef564f1ce..c598c7b5f2f7 100644
--- a/test/ELF/basic-mips.s
+++ b/test/ELF/basic-mips.s
@@ -27,7 +27,7 @@ __start:
# CHECK-NEXT: Version: 1
# CHECK-NEXT: Entry: 0x20000
# CHECK-NEXT: ProgramHeaderOffset: 0x34
-# CHECK-NEXT: SectionHeaderOffset: 0x20084
+# CHECK-NEXT: SectionHeaderOffset: 0x30088
# CHECK-NEXT: Flags [
# CHECK-NEXT: EF_MIPS_ABI_O32
# CHECK-NEXT: EF_MIPS_ARCH_32R2
@@ -35,10 +35,10 @@ __start:
# CHECK-NEXT: ]
# CHECK-NEXT: HeaderSize: 52
# CHECK-NEXT: ProgramHeaderEntrySize: 32
-# CHECK-NEXT: ProgramHeaderCount: 5
+# CHECK-NEXT: ProgramHeaderCount: 6
# CHECK-NEXT: SectionHeaderEntrySize: 40
-# CHECK-NEXT: SectionHeaderCount: 9
-# CHECK-NEXT: StringTableSectionIndex: 7
+# CHECK-NEXT: SectionHeaderCount: 10
+# CHECK-NEXT: StringTableSectionIndex: 8
# CHECK-NEXT: }
# CHECK-NEXT: Sections [
# CHECK-NEXT: Section {
@@ -62,8 +62,8 @@ __start:
# CHECK-NEXT: Flags [ (0x2)
# CHECK-NEXT: SHF_ALLOC (0x2)
# CHECK-NEXT: ]
-# CHECK-NEXT: Address: 0x100D4
-# CHECK-NEXT: Offset: 0xD4
+# CHECK-NEXT: Address: 0x100F4
+# CHECK-NEXT: Offset: 0xF4
# CHECK-NEXT: Size: 24
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
@@ -77,8 +77,8 @@ __start:
# CHECK-NEXT: Flags [ (0x2)
# CHECK-NEXT: SHF_ALLOC (0x2)
# CHECK-NEXT: ]
-# CHECK-NEXT: Address: 0x100F0
-# CHECK-NEXT: Offset: 0xF0
+# CHECK-NEXT: Address: 0x10110
+# CHECK-NEXT: Offset: 0x110
# CHECK-NEXT: Size: 24
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
@@ -103,14 +103,31 @@ __start:
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 4
-# CHECK-NEXT: Name: .data
+# CHECK-NEXT: Name: .got (31)
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
-# CHECK-NEXT: Flags [ (0x3)
+# CHECK-NEXT: Flags [ (0x10000003)
# CHECK-NEXT: SHF_ALLOC (0x2)
+# CHECK-NEXT: SHF_MIPS_GPREL (0x10000000)
# CHECK-NEXT: SHF_WRITE (0x1)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x30000
# CHECK-NEXT: Offset: 0x20000
+# CHECK-NEXT: Size: 8
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 4
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 5
+# CHECK-NEXT: Name: .data
+# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
+# CHECK-NEXT: Flags [ (0x3)
+# CHECK-NEXT: SHF_ALLOC (0x2)
+# CHECK-NEXT: SHF_WRITE (0x1)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x40000
+# CHECK-NEXT: Offset: 0x30000
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
@@ -118,15 +135,15 @@ __start:
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 5
-# CHECK-NEXT: Name: .bss (37)
+# CHECK-NEXT: Index: 6
+# CHECK-NEXT: Name: .bss
# CHECK-NEXT: Type: SHT_NOBITS (0x8)
# CHECK-NEXT: Flags [ (0x3)
# CHECK-NEXT: SHF_ALLOC (0x2)
# CHECK-NEXT: SHF_WRITE (0x1)
# CHECK-NEXT: ]
-# CHECK-NEXT: Address: 0x30000
-# CHECK-NEXT: Offset: 0x20000
+# CHECK-NEXT: Address: 0x40000
+# CHECK-NEXT: Offset: 0x30000
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
@@ -134,41 +151,41 @@ __start:
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 6
+# CHECK-NEXT: Index: 7
# CHECK-NEXT: Name: .symtab
# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
-# CHECK-NEXT: Offset: 0x20000
+# CHECK-NEXT: Offset: 0x30000
# CHECK-NEXT: Size: 48
-# CHECK-NEXT: Link: 8
+# CHECK-NEXT: Link: 9
# CHECK-NEXT: Info: 1
# CHECK-NEXT: AddressAlignment: 4
# CHECK-NEXT: EntrySize: 16
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 7
+# CHECK-NEXT: Index: 8
# CHECK-NEXT: Name: .shstrtab
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
-# CHECK-NEXT: Offset: 0x20030
-# CHECK-NEXT: Size: 68
+# CHECK-NEXT: Offset: 0x30030
+# CHECK-NEXT: Size: 73
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 8
-# CHECK-NEXT: Name: .strtab (60)
+# CHECK-NEXT: Index: 9
+# CHECK-NEXT: Name: .strtab
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
-# CHECK-NEXT: Offset: 0x20074
+# CHECK-NEXT: Offset: 0x30079
# CHECK-NEXT: Size: 13
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
@@ -188,12 +205,14 @@ __start:
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: _gp
-# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Value: 0x37FF0
# CHECK-NEXT: Size: 0
-# CHECK-NEXT: Binding: Local (0x0)
+# CHECK-NEXT: Binding: Local
# CHECK-NEXT: Type: None (0x0)
-# CHECK-NEXT: Other: 0
-# CHECK-NEXT: Section: Absolute (0xFFF1)
+# CHECK-NEXT: Other [ (0x2)
+# CHECK-NEXT: STV_HIDDEN (0x2)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Section: .got
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: __start
@@ -211,20 +230,20 @@ __start:
# CHECK-NEXT: Offset: 0x34
# CHECK-NEXT: VirtualAddress: 0x10034
# CHECK-NEXT: PhysicalAddress: 0x10034
-# CHECK-NEXT: FileSize: 160
-# CHECK-NEXT: MemSize: 160
+# CHECK-NEXT: FileSize: 192
+# CHECK-NEXT: MemSize: 192
# CHECK-NEXT: Flags [ (0x4)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: ]
-# CHECK-NEXT: Alignment: 8
+# CHECK-NEXT: Alignment: 4
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x0
# CHECK-NEXT: VirtualAddress: 0x10000
# CHECK-NEXT: PhysicalAddress: 0x10000
-# CHECK-NEXT: FileSize: 264
-# CHECK-NEXT: MemSize: 264
+# CHECK-NEXT: FileSize: 296
+# CHECK-NEXT: MemSize: 296
# CHECK-NEXT: Flags [ (0x4)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: ]
@@ -248,8 +267,8 @@ __start:
# CHECK-NEXT: Offset: 0x20000
# CHECK-NEXT: VirtualAddress: 0x30000
# CHECK-NEXT: PhysicalAddress: 0x30000
-# CHECK-NEXT: FileSize: 0
-# CHECK-NEXT: MemSize: 0
+# CHECK-NEXT: FileSize: 65536
+# CHECK-NEXT: MemSize: 65536
# CHECK-NEXT: Flags [
# CHECK-NEXT: PF_R
# CHECK-NEXT: PF_W
@@ -257,6 +276,18 @@ __start:
# CHECK-NEXT: Alignment: 65536
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_GNU_RELRO (0x6474E552)
+# CHECK-NEXT: Offset: 0x20000
+# CHECK-NEXT: VirtualAddress: 0x30000
+# CHECK-NEXT: PhysicalAddress: 0x30000
+# CHECK-NEXT: FileSize: 8
+# CHECK-NEXT: MemSize: 8
+# CHECK-NEXT: Flags [ (0x4)
+# CHECK-NEXT: PF_R (0x4)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 1
+# CHECK-NEXT: }
+# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_GNU_STACK
# CHECK-NEXT: Offset: 0x0
# CHECK-NEXT: VirtualAddress: 0x0
diff --git a/test/ELF/basic-ppc.s b/test/ELF/basic-ppc.s
index 90acd8d8ddac..83ace9a4983d 100644
--- a/test/ELF/basic-ppc.s
+++ b/test/ELF/basic-ppc.s
@@ -28,7 +28,7 @@
// CHECK-NEXT: Version: 1
// CHECK-NEXT: Entry: 0x0
// CHECK-NEXT: ProgramHeaderOffset: 0x34
-// CHECK-NEXT: SectionHeaderOffset: 0x2084
+// CHECK-NEXT: SectionHeaderOffset: 0x209C
// CHECK-NEXT: Flags [ (0x0)
// CHECK-NEXT: ]
// CHECK-NEXT: HeaderSize: 52
@@ -157,13 +157,14 @@
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x2030
-// CHECK-NEXT: Size: 16
+// CHECK-NEXT: Size: 32
// CHECK-NEXT: Link: 8
// CHECK-NEXT: Info: 1
// CHECK-NEXT: AddressAlignment: 4
// CHECK-NEXT: EntrySize: 16
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
+// CHECK-NEXT: 0010: 00000001 00002000 00000000 00020005 |...... .........|
// CHECK-NEXT: )
// CHECK-NEXT: }
// CHECK-NEXT: Section {
@@ -173,7 +174,7 @@
// CHECK-NEXT: Flags [ (0x0)
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x0
-// CHECK-NEXT: Offset: 0x2040
+// CHECK-NEXT: Offset: 0x2050
// CHECK-NEXT: Size: 64
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
@@ -193,14 +194,14 @@
// CHECK-NEXT: Flags [ (0x0)
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x0
-// CHECK-NEXT: Offset: 0x2080
+// CHECK-NEXT: Offset: 0x2090
// CHECK-NEXT: Size: 1
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 1
// CHECK-NEXT: EntrySize: 0
// CHECK-NEXT: SectionData (
-// CHECK-NEXT: 0000: 00 |.|
+// CHECK-NEXT: 0000: 005F4459 4E414D49 4300 |._DYNAMIC.|
// CHECK-NEXT: )
// CHECK-NEXT: }
// CHECK-NEXT: ]
@@ -215,7 +216,7 @@
// CHECK-NEXT: Flags [ (0x4)
// CHECK-NEXT: PF_R (0x4)
// CHECK-NEXT: ]
-// CHECK-NEXT: Alignment: 8
+// CHECK-NEXT: Alignment: 4
// CHECK-NEXT: }
// CHECK-NEXT: ProgramHeader {
// CHECK-NEXT: Type: PT_LOAD (0x1)
diff --git a/test/ELF/basic.s b/test/ELF/basic.s
index bbc674ced2ed..28449331d3fa 100644
--- a/test/ELF/basic.s
+++ b/test/ELF/basic.s
@@ -6,7 +6,7 @@
# RUN: | FileCheck %s
# exits with return code 42 on linux
-.globl _start;
+.globl _start
_start:
mov $60, %rax
mov $42, %rdi
@@ -184,12 +184,23 @@ _start:
# CHECK-NEXT: }
# CHECK-NEXT: ]
-# Test for the response file
+# Test for the response file (POSIX quoting style)
# RUN: echo " -o %t2" > %t.responsefile
-# RUN: ld.lld %t @%t.responsefile
+# RUN: ld.lld %t --rsp-quoting=posix @%t.responsefile
# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \
# RUN: | FileCheck %s
+# Test for the response file (Windows quoting style)
+# RUN: echo " c:\blah\foo" > %t.responsefile
+# RUN: not ld.lld --rsp-quoting=windows %t @%t.responsefile 2>&1 | FileCheck \
+# RUN: %s --check-prefix=WINRSP
+# WINRSP: cannot open c:\blah\foo
+
+# Test for the response file (invalid quoting style)
+# RUN: not ld.lld --rsp-quoting=patatino %t 2>&1 | FileCheck %s \
+# RUN: --check-prefix=INVRSP
+# INVRSP: invalid response file quoting: patatino
+
# RUN: not ld.lld %t.foo -o %t2 2>&1 | \
# RUN: FileCheck --check-prefix=MISSING %s
# MISSING: cannot open {{.*}}.foo: {{[Nn]}}o such file or directory
@@ -213,4 +224,7 @@ _start:
# DUP: duplicate symbol: _start in {{.*}} and {{.*}}
# RUN: not ld.lld %t -o %t -m wrong_emul 2>&1 | FileCheck --check-prefix=UNKNOWN_EMUL %s
-# UNKNOWN_EMUL: Unknown emulation: wrong_emul
+# UNKNOWN_EMUL: unknown emulation: wrong_emul
+
+# RUN: not ld.lld %t --lto-jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADS %s
+# NOTHREADS: number of threads must be > 0
diff --git a/test/ELF/basic32.s b/test/ELF/basic32.s
index f4f9c410a048..44ebe7a46225 100644
--- a/test/ELF/basic32.s
+++ b/test/ELF/basic32.s
@@ -4,7 +4,7 @@
# REQUIRES: x86
# exits with return code 42 on linux
-.globl _start;
+.globl _start
_start:
mov $1, %eax
mov $42, %ebx
@@ -120,7 +120,7 @@ _start:
# CHECK-NEXT: Flags [ (0x4)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: ]
-# CHECK-NEXT: Alignment: 8
+# CHECK-NEXT: Alignment: 4
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
diff --git a/test/ELF/basic64be.s b/test/ELF/basic64be.s
index 32d8974dae01..fb0bf7bfdb80 100644
--- a/test/ELF/basic64be.s
+++ b/test/ELF/basic64be.s
@@ -43,10 +43,10 @@ _start:
# CHECK-NEXT: ]
# CHECK-NEXT: HeaderSize: 64
# CHECK-NEXT: ProgramHeaderEntrySize: 56
-# CHECK-NEXT: ProgramHeaderCount: 5
+# CHECK-NEXT: ProgramHeaderCount: 6
# CHECK-NEXT: SectionHeaderEntrySize: 64
-# CHECK-NEXT: SectionHeaderCount: 8
-# CHECK-NEXT: StringTableSectionIndex: 6
+# CHECK-NEXT: SectionHeaderCount: 9
+# CHECK-NEXT: StringTableSectionIndex: 7
# CHECK-NEXT: }
# CHECK-NEXT: Sections [
# CHECK-NEXT: Section {
@@ -85,6 +85,24 @@ _start:
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 2
+# CHECK-NEXT: Name: .got
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_WRITE
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x10020000
+# CHECK-NEXT: Offset: 0x20000
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 8
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: SectionData (
+# CHECK-NEXT: )
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 3
# CHECK-NEXT: Name: .toc
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x3)
@@ -104,7 +122,7 @@ _start:
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 3
+# CHECK-NEXT: Index: 4
# CHECK-NEXT: Name: .toc1
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x3)
@@ -124,7 +142,7 @@ _start:
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 4
+# CHECK-NEXT: Index: 5
# CHECK-NEXT: Name: .opd
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x3)
@@ -139,12 +157,12 @@ _start:
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
-# CHECK-NEXT: 0000: 00000000 10010000 00000000 00008000 |................|
-# CHECK-NEXT: 0010: 00000000 00000000 |........|
+# CHECK-NEXT: 0000: 00000000 10010000 00000000 10028000 |................|
+# CHECK-NEXT: 0010: 00000000 00000000 |........|
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 5
+# CHECK-NEXT: Index: 6
# CHECK-NEXT: Name: .symtab
# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
# CHECK-NEXT: Flags [ (0x0)
@@ -152,7 +170,7 @@ _start:
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x20058
# CHECK-NEXT: Size: 48
-# CHECK-NEXT: Link: 7
+# CHECK-NEXT: Link: 8
# CHECK-NEXT: Info: 1
# CHECK-NEXT: AddressAlignment: 8
# CHECK-NEXT: EntrySize: 24
@@ -160,14 +178,14 @@ _start:
# CHECK: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 6
+# CHECK-NEXT: Index: 7
# CHECK-NEXT: Name: .shstrtab
-# CHECK-NEXT: Type: SHT_STRTAB (0x3)
-# CHECK-NEXT: Flags [ (0x0)
+# CHECK-NEXT: Type: SHT_STRTAB
+# CHECK-NEXT: Flags [
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x20088
-# CHECK-NEXT: Size: 49
+# CHECK-NEXT: Size: 54
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
@@ -176,13 +194,13 @@ _start:
# CHECK: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 7
-# CHECK-NEXT: Name: .strtab (41)
-# CHECK-NEXT: Type: SHT_STRTAB (0x3)
+# CHECK-NEXT: Index: 8
+# CHECK-NEXT: Name: .strtab
+# CHECK-NEXT: Type: SHT_STRTAB
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
-# CHECK-NEXT: Offset: 0x200B9
+# CHECK-NEXT: Offset: 0x200BE
# CHECK-NEXT: Size: 8
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
@@ -199,10 +217,10 @@ _start:
# CHECK-NEXT: Offset: 0x40
# CHECK-NEXT: VirtualAddress: 0x10000040
# CHECK-NEXT: PhysicalAddress: 0x10000040
-# CHECK-NEXT: FileSize: 280
-# CHECK-NEXT: MemSize: 280
-# CHECK-NEXT: Flags [ (0x4)
-# CHECK-NEXT: PF_R (0x4)
+# CHECK-NEXT: FileSize: 336
+# CHECK-NEXT: MemSize: 336
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: PF_R
# CHECK-NEXT: ]
# CHECK-NEXT: Alignment: 8
# CHECK-NEXT: }
@@ -211,8 +229,8 @@ _start:
# CHECK-NEXT: Offset: 0x0
# CHECK-NEXT: VirtualAddress: 0x10000000
# CHECK-NEXT: PhysicalAddress: 0x10000000
-# CHECK-NEXT: FileSize: 344
-# CHECK-NEXT: MemSize: 344
+# CHECK-NEXT: FileSize: 400
+# CHECK-NEXT: MemSize: 400
# CHECK-NEXT: Flags [
# CHECK-NEXT: PF_R
# CHECK-NEXT: ]
@@ -245,6 +263,18 @@ _start:
# CHECK-NEXT: Alignment: 65536
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_GNU_RELRO
+# CHECK-NEXT: Offset: 0x20000
+# CHECK-NEXT: VirtualAddress: 0x10020000
+# CHECK-NEXT: PhysicalAddress: 0x10020000
+# CHECK-NEXT: FileSize: 0
+# CHECK-NEXT: MemSize: 0
+# CHECK-NEXT: Flags [ (0x4)
+# CHECK-NEXT: PF_R (0x4)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 1
+# CHECK-NEXT: }
+# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
# CHECK-NEXT: Offset: 0x0
# CHECK-NEXT: VirtualAddress: 0x0
diff --git a/test/ELF/bsymbolic-undef.s b/test/ELF/bsymbolic-undef.s
new file mode 100644
index 000000000000..6590bbcb50b7
--- /dev/null
+++ b/test/ELF/bsymbolic-undef.s
@@ -0,0 +1,26 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared -Bsymbolic %t.o -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
+
+# CHECK: DynamicSymbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: @ (0)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local (0x0)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined (0x0)
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: undef@ (1)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global (0x1)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined (0x0)
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+call undef@PLT
diff --git a/test/ELF/bsymbolic.s b/test/ELF/bsymbolic.s
new file mode 100644
index 000000000000..d713588d5952
--- /dev/null
+++ b/test/ELF/bsymbolic.s
@@ -0,0 +1,34 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t0.so
+// RUN: ld.lld -shared -Bsymbolic %t.o -o %t1.so
+// RUN: ld.lld -shared -Bsymbolic-functions %t.o -o %t2.so
+// RUN: llvm-readobj -s %t0.so | FileCheck -check-prefix=NOOPTION %s
+// RUN: llvm-readobj -s %t1.so | FileCheck -check-prefix=SYMBOLIC %s
+// RUN: llvm-readobj -s %t2.so | FileCheck -check-prefix=SYMBOLIC %s
+
+// NOOPTION: Section {
+// NOOPTION: Name: .plt
+
+// SYMBOLIC: Section {
+// SYMBOLIC-NOT: Name: .plt
+
+.text
+.globl foo
+.type foo,@function
+foo:
+nop
+
+.globl bar
+.type bar,@function
+bar:
+nop
+
+.globl do
+.type do,@function
+do:
+callq foo@PLT
+callq bar@PLT
+
+.weak zed
+.protected zed
+.quad zed
diff --git a/test/ELF/build-id.s b/test/ELF/build-id.s
new file mode 100644
index 000000000000..f1eac42812b4
--- /dev/null
+++ b/test/ELF/build-id.s
@@ -0,0 +1,38 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld --build-id %t -o %t2
+# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s
+# RUN: ld.lld --build-id=md5 %t -o %t2
+# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=MD5 %s
+# RUN: ld.lld --build-id=sha1 %t -o %t2
+# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SHA1 %s
+# RUN: ld.lld --build-id=0x12345678 %t -o %t2
+# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=HEX %s
+# RUN: ld.lld %t -o %t2
+# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=NONE %s
+# RUN: ld.lld --build-id=md5 --build-id=none %t -o %t2
+# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=NONE %s
+
+.globl _start
+_start:
+ nop
+
+.section .note.test, "a", @note
+ .quad 42
+
+# DEFAULT: Contents of section .note.gnu.build-id:
+# DEFAULT-NEXT: 04000000 08000000 03000000 474e5500 ............GNU.
+# DEFAULT: Contents of section .note.test:
+
+# MD5: Contents of section .note.gnu.build-id:
+# MD5-NEXT: 04000000 10000000 03000000 474e5500 ............GNU.
+
+# SHA1: Contents of section .note.gnu.build-id:
+# SHA1-NEXT: 04000000 14000000 03000000 474e5500 ............GNU.
+
+# HEX: Contents of section .note.gnu.build-id:
+# HEX-NEXT: 04000000 04000000 03000000 474e5500 ............GNU.
+# HEX-NEXT: 12345678
+
+# NONE-NOT: Contents of section .note.gnu.build-id:
diff --git a/test/ELF/combrelocs.s b/test/ELF/combrelocs.s
new file mode 100644
index 000000000000..5b876ee221a4
--- /dev/null
+++ b/test/ELF/combrelocs.s
@@ -0,0 +1,92 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t.out
+# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
+# CHECK-NEXT: Relocation {
+# CHECK-NEXT: Offset: 0x2000
+# CHECK-NEXT: Type: R_X86_64_64
+# CHECK-NEXT: Symbol: aaa (1)
+# CHECK-NEXT: Addend: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: Relocation {
+# CHECK-NEXT: Offset: 0x2018
+# CHECK-NEXT: Type: R_X86_64_64
+# CHECK-NEXT: Symbol: aaa (1)
+# CHECK-NEXT: Addend: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: Relocation {
+# CHECK-NEXT: Offset: 0x2010
+# CHECK-NEXT: Type: R_X86_64_64
+# CHECK-NEXT: Symbol: bbb (2)
+# CHECK-NEXT: Addend: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: Relocation {
+# CHECK-NEXT: Offset: 0x2008
+# CHECK-NEXT: Type: R_X86_64_64
+# CHECK-NEXT: Symbol: ccc (3)
+# CHECK-NEXT: Addend: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: Relocation {
+# CHECK-NEXT: Offset: 0x2020
+# CHECK-NEXT: Type: R_X86_64_64
+# CHECK-NEXT: Symbol: ddd (4)
+# CHECK-NEXT: Addend: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK: DynamicSection [
+# CHECK-NEXT: Tag
+# CHECK-NOT: RELACOUNT
+
+# RUN: ld.lld -z nocombreloc -shared %t.o -o %t.out
+# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | \
+# RUN: FileCheck --check-prefix=NOCOMB %s
+
+# NOCOMB: Relocations [
+# NOCOMB-NEXT: Section ({{.*}}) .rela.dyn {
+# NOCOMB-NEXT: Relocation {
+# NOCOMB-NEXT: Offset: 0x2000
+# NOCOMB-NEXT: Type: R_X86_64_64
+# NOCOMB-NEXT: Symbol: aaa (1)
+# NOCOMB-NEXT: Addend: 0x0
+# NOCOMB-NEXT: }
+# NOCOMB-NEXT: Relocation {
+# NOCOMB-NEXT: Offset: 0x2008
+# NOCOMB-NEXT: Type: R_X86_64_64
+# NOCOMB-NEXT: Symbol: ccc (3)
+# NOCOMB-NEXT: Addend: 0x0
+# NOCOMB-NEXT: }
+# NOCOMB-NEXT: Relocation {
+# NOCOMB-NEXT: Offset: 0x2010
+# NOCOMB-NEXT: Type: R_X86_64_64
+# NOCOMB-NEXT: Symbol: bbb (2)
+# NOCOMB-NEXT: Addend: 0x0
+# NOCOMB-NEXT: }
+# NOCOMB-NEXT: Relocation {
+# NOCOMB-NEXT: Offset: 0x2018
+# NOCOMB-NEXT: Type: R_X86_64_64
+# NOCOMB-NEXT: Symbol: aaa (1)
+# NOCOMB-NEXT: Addend: 0x0
+# NOCOMB-NEXT: }
+# NOCOMB-NEXT: Relocation {
+# NOCOMB-NEXT: Offset: 0x2020
+# NOCOMB-NEXT: Type: R_X86_64_64
+# NOCOMB-NEXT: Symbol: ddd (4)
+# NOCOMB-NEXT: Addend: 0x0
+# NOCOMB-NEXT: }
+# NOCOMB-NEXT: }
+# NOCOMB-NEXT: ]
+# NOCOMB: DynamicSection [
+# NOCOMB-NEXT: Tag
+# NOCOMB-NOT: RELACOUNT
+
+.data
+ .quad aaa
+ .quad ccc
+ .quad bbb
+ .quad aaa
+ .quad ddd
diff --git a/test/ELF/comdat.s b/test/ELF/comdat.s
index 4f8955e289d5..d422ee8fba33 100644
--- a/test/ELF/comdat.s
+++ b/test/ELF/comdat.s
@@ -61,6 +61,17 @@ foo:
// READ-NEXT: Section: .text
// READ-NEXT: }
// READ-NEXT: Symbol {
+// READ-NEXT: Name: _DYNAMIC
+// READ-NEXT: Value: 0x2000
+// READ-NEXT: Size: 0
+// READ-NEXT: Binding: Local
+// READ-NEXT: Type: None
+// READ-NEXT: Other [ (0x2)
+// READ-NEXT: STV_HIDDEN
+// READ-NEXT: ]
+// READ-NEXT: Section: .dynamic
+// READ-NEXT: }
+// READ-NEXT: Symbol {
// READ-NEXT: Name: abc
// READ-NEXT: Value: 0x0
// READ-NEXT: Size: 0
diff --git a/test/ELF/common.s b/test/ELF/common.s
index 67cedbccb866..f16f948fe64e 100644
--- a/test/ELF/common.s
+++ b/test/ELF/common.s
@@ -13,6 +13,9 @@
// CHECK-NEXT: Address: 0x11000
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 22
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 16
// CHECK: Name: sym1
// CHECK-NEXT: Value: 0x11004
diff --git a/test/ELF/compressed-debug-input.s b/test/ELF/compressed-debug-input.s
new file mode 100644
index 000000000000..7339833dbb7f
--- /dev/null
+++ b/test/ELF/compressed-debug-input.s
@@ -0,0 +1,61 @@
+# REQUIRES: zlib
+
+# RUN: llvm-mc -compress-debug-sections=zlib -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: llvm-readobj -sections %t | FileCheck -check-prefix=COMPRESSED %s
+
+# COMPRESSED: Section {
+# COMPRESSED: Index: 2
+# COMPRESSED: Name: .debug_str
+# COMPRESSED-NEXT: Type: SHT_PROGBITS
+# COMPRESSED-NEXT: Flags [
+# COMPRESSED-NEXT: SHF_COMPRESSED (0x800)
+# COMPRESSED-NEXT: SHF_MERGE (0x10)
+# COMPRESSED-NEXT: SHF_STRINGS (0x20)
+# COMPRESSED-NEXT: ]
+# COMPRESSED-NEXT: Address:
+# COMPRESSED-NEXT: Offset:
+# COMPRESSED-NEXT: Size: 66
+# COMPRESSED-NEXT: Link:
+# COMPRESSED-NEXT: Info:
+# COMPRESSED-NEXT: AddressAlignment: 1
+# COMPRESSED-NEXT: EntrySize: 1
+# COMPRESSED-NEXT: }
+
+# RUN: ld.lld %t -o %t.so -shared
+# RUN: llvm-readobj -sections -section-data %t.so | FileCheck -check-prefix=UNCOMPRESSED %s
+
+# UNCOMPRESSED: Section {
+# UNCOMPRESSED: Index: 6
+# UNCOMPRESSED: Name: .debug_str
+# UNCOMPRESSED-NEXT: Type: SHT_PROGBITS
+# UNCOMPRESSED-NEXT: Flags [
+# UNCOMPRESSED-NEXT: SHF_MERGE (0x10)
+# UNCOMPRESSED-NEXT: SHF_STRINGS (0x20)
+# UNCOMPRESSED-NEXT: ]
+# UNCOMPRESSED-NEXT: Address: 0x0
+# UNCOMPRESSED-NEXT: Offset: 0x1060
+# UNCOMPRESSED-NEXT: Size: 69
+# UNCOMPRESSED-NEXT: Link: 0
+# UNCOMPRESSED-NEXT: Info: 0
+# UNCOMPRESSED-NEXT: AddressAlignment: 1
+# UNCOMPRESSED-NEXT: EntrySize: 1
+# UNCOMPRESSED-NEXT: SectionData (
+# UNCOMPRESSED-NEXT: 0000: 73686F72 7420756E 7369676E 65642069 |short unsigned i|
+# UNCOMPRESSED-NEXT: 0010: 6E740075 6E736967 6E656420 696E7400 |nt.unsigned int.|
+# UNCOMPRESSED-NEXT: 0020: 6C6F6E67 20756E73 69676E65 6420696E |long unsigned in|
+# UNCOMPRESSED-NEXT: 0030: 74006368 61720075 6E736967 6E656420 |t.char.unsigned |
+# UNCOMPRESSED-NEXT: 0040: 63686172 00 |char.|
+# UNCOMPRESSED-NEXT: )
+# UNCOMPRESSED-NEXT: }
+
+.section .debug_str,"MS",@progbits,1
+.LASF2:
+ .string "short unsigned int"
+.LASF3:
+ .string "unsigned int"
+.LASF0:
+ .string "long unsigned int"
+.LASF8:
+ .string "char"
+.LASF1:
+ .string "unsigned char"
diff --git a/test/ELF/conflict.s b/test/ELF/conflict.s
new file mode 100644
index 000000000000..7598eea3711c
--- /dev/null
+++ b/test/ELF/conflict.s
@@ -0,0 +1,26 @@
+# REQUIRES: x86, shell
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: not ld.lld %t1.o %t1.o -o %t2 2>&1 | FileCheck -check-prefix=DEMANGLE %s
+
+# DEMANGLE: duplicate symbol: mul(double, double) in
+# DEMANGLE: duplicate symbol: foo in
+
+# RUN: not ld.lld %t1.o %t1.o -o %t2 --no-demangle 2>&1 | \
+# RUN: FileCheck -check-prefix=NO_DEMANGLE %s
+
+# NO_DEMANGLE: duplicate symbol: _Z3muldd in
+# NO_DEMANGLE: duplicate symbol: foo in
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/conflict.s -o %t2.o
+# RUN: llvm-ar rcs %t3.a %t2.o
+# RUN: not ld.lld %t1.o %t3.a -u baz -o %t2 2>&1 | FileCheck -check-prefix=ARCHIVE %s
+
+# ARCHIVE: duplicate symbol: foo in {{.*}}1.o and {{.*}}3.a({{.*}}2.o)
+
+.globl _Z3muldd, foo
+_Z3muldd:
+foo:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
diff --git a/test/ELF/copy-errors.s b/test/ELF/copy-errors.s
new file mode 100644
index 000000000000..9d8b72ddb43b
--- /dev/null
+++ b/test/ELF/copy-errors.s
@@ -0,0 +1,15 @@
+// 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 %p/Inputs/protected-shared.s -o %t2.o
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
+
+.global _start
+_start:
+
+
+call bar
+// CHECK: cannot preempt symbol
+
+call zed
+// CHECK: symbol is missing type
diff --git a/test/ELF/copy-in-shared.s b/test/ELF/copy-in-shared.s
new file mode 100644
index 000000000000..4114d95fb101
--- /dev/null
+++ b/test/ELF/copy-in-shared.s
@@ -0,0 +1,10 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-in-shared.s -o %t1.o
+// RUN: ld.lld -shared %t1.o -o %t1.so
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
+// RUN: not ld.lld %t2.o %t1.so -o %t2.so -shared 2>&1 | FileCheck %s
+
+
+.quad foo
+
+// CHECK: can't create dynamic relocation R_X86_64_64 against readonly segment
diff --git a/test/ELF/copy-rel-corrupted.s b/test/ELF/copy-rel-corrupted.s
new file mode 100644
index 000000000000..a3f72f71c1da
--- /dev/null
+++ b/test/ELF/copy-rel-corrupted.s
@@ -0,0 +1,10 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: llvm-mc %p/Inputs/copy-rel-corrupted.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: not ld.lld %t.o %t2.so -o %t.exe 2>&1 | FileCheck %s
+
+// CHECK: cannot create a copy relocation for x
+
+.global _start
+_start:
+ call x
diff --git a/test/ELF/copy-rel-pie-error.s b/test/ELF/copy-rel-pie-error.s
new file mode 100644
index 000000000000..1f427023baa5
--- /dev/null
+++ b/test/ELF/copy-rel-pie-error.s
@@ -0,0 +1,12 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: not ld.lld %t.o %t2.so -o %t.exe -pie 2>&1 | FileCheck %s
+
+// CHECK: can't create dynamic relocation R_X86_64_64 against readonly segment
+// CHECK: can't create dynamic relocation R_X86_64_64 against readonly segment
+
+.global _start
+_start:
+ .quad bar
+ .quad foo
diff --git a/test/ELF/copy-rel-pie.s b/test/ELF/copy-rel-pie.s
new file mode 100644
index 000000000000..be7d5acaeba9
--- /dev/null
+++ b/test/ELF/copy-rel-pie.s
@@ -0,0 +1,44 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t.exe -pie
+// RUN: llvm-readobj -s -r %t.exe | FileCheck %s
+// RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASM %s
+
+.global _start
+_start:
+ call bar
+ call foo
+
+// CHECK: Name: .plt
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x1010
+
+// CHECK: Name: .bss
+// CHECK-NEXT: Type: SHT_NOBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x3020
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section (4) .rela.dyn {
+// CHECK-NEXT: 0x3020 R_X86_64_COPY foo 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: Section (5) .rela.plt {
+// CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT bar 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+// (0x1010 + 0x10) - 0x1005 = 27
+// 0x3020 - 0x100a = 8214
+
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: _start:
+// DISASM-NEXT: 1000: e8 1b 00 00 00 callq 27
+// DISASM-NEXT: 1005: e8 16 20 00 00 callq 8214 <foo>
diff --git a/test/ELF/ctors_dtors_priority.s b/test/ELF/ctors_dtors_priority.s
new file mode 100644
index 000000000000..10d6471f953a
--- /dev/null
+++ b/test/ELF/ctors_dtors_priority.s
@@ -0,0 +1,41 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+// RUN: %p/Inputs/ctors_dtors_priority1.s -o %t-crtbegin.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+// RUN: %p/Inputs/ctors_dtors_priority2.s -o %t2
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+// RUN: %p/Inputs/ctors_dtors_priority3.s -o %t-crtend.o
+// RUN: ld.lld %t1 %t2 %t-crtend.o %t-crtbegin.o -o %t.exe
+// RUN: llvm-objdump -s %t.exe | FileCheck %s
+// REQUIRES: x86
+
+.globl _start
+_start:
+ nop
+
+.section .ctors, "aw", @progbits
+ .byte 1
+.section .ctors.100, "aw", @progbits
+ .byte 2
+.section .ctors.005, "aw", @progbits
+ .byte 3
+.section .ctors, "aw", @progbits
+ .byte 4
+.section .ctors, "aw", @progbits
+ .byte 5
+
+.section .dtors, "aw", @progbits
+ .byte 0x11
+.section .dtors.100, "aw", @progbits
+ .byte 0x12
+.section .dtors.005, "aw", @progbits
+ .byte 0x13
+.section .dtors, "aw", @progbits
+ .byte 0x14
+.section .dtors, "aw", @progbits
+ .byte 0x15
+
+// CHECK: Contents of section .ctors:
+// CHECK-NEXT: a1010405 b10302c1
+// CHECK: Contents of section .dtors:
+// CHECK-NEXT: a2111415 b21312c2
diff --git a/test/ELF/default-output.s b/test/ELF/default-output.s
index 8da3bb40eac0..c0766acf6e55 100644
--- a/test/ELF/default-output.s
+++ b/test/ELF/default-output.s
@@ -9,7 +9,7 @@
# RUN: ld.lld %t
# RUN: llvm-readobj a.out > /dev/null 2>&1
-.globl _start;
+.globl _start
_start:
mov $60, %rax
mov $42, %rdi
diff --git a/test/ELF/discard-merge-locals.s b/test/ELF/discard-merge-locals.s
index 51676da192ca..01b4d337cb2d 100644
--- a/test/ELF/discard-merge-locals.s
+++ b/test/ELF/discard-merge-locals.s
@@ -21,4 +21,15 @@
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: Undefined
// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _DYNAMIC
+// CHECK-NEXT: Value: 0x2000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .dynamic
+// CHECK-NEXT: }
// CHECK-NEXT: ]
diff --git a/test/ELF/discard-merge-unnamed.s b/test/ELF/discard-merge-unnamed.s
index bd0058cbd7db..be174f27b50b 100644
--- a/test/ELF/discard-merge-unnamed.s
+++ b/test/ELF/discard-merge-unnamed.s
@@ -13,4 +13,15 @@
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: Undefined
// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _DYNAMIC
+// CHECK-NEXT: Value: 0x2000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .dynamic
+// CHECK-NEXT: }
// CHECK-NEXT: ]
diff --git a/test/ELF/discard-none.s b/test/ELF/discard-none.s
index c13b544f514d..e3a7a2032082 100644
--- a/test/ELF/discard-none.s
+++ b/test/ELF/discard-none.s
@@ -21,7 +21,7 @@
// CHECK-NEXT: EntrySize:
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 002E4C6D 796F7468 65727661 72002E4C |..Lmyothervar..L|
-// CHECK-NEXT: 0010: 6D797661 7200 |myvar.|
+// CHECK-NEXT: 0010: 6D797661 72005F44 594E414D 494300 |myvar._DYNAMIC.|
// CHECK-NEXT: )
// CHECK-NEXT: }
diff --git a/test/ELF/dont-export-hidden.s b/test/ELF/dont-export-hidden.s
new file mode 100644
index 000000000000..8819a6e99fdb
--- /dev/null
+++ b/test/ELF/dont-export-hidden.s
@@ -0,0 +1,39 @@
+// RUN: llvm-mc %p/Inputs/shared.s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: ld.lld %t2.o %t.so -o %t.exe
+// RUN: llvm-readobj --dyn-symbols %t.exe | FileCheck %s
+
+ .global _start
+_start:
+ .global bar
+ .hidden bar
+bar:
+
+ .global bar2
+bar2:
+
+ .global foo
+foo:
+
+// CHECK: DynamicSymbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: @ (0)
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: bar2
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
diff --git a/test/ELF/driver.test b/test/ELF/driver.test
new file mode 100644
index 000000000000..95e2100b4abf
--- /dev/null
+++ b/test/ELF/driver.test
@@ -0,0 +1,49 @@
+# REQUIRES: x86
+
+# RUN: not ld.lld --unknown1 --unknown2 -m foo /no/such/file -lnosuchlib \
+# RUN: 2>&1 | FileCheck -check-prefix=UNKNOWN %s
+
+# UNKNOWN: unknown argument: --unknown1
+# UNKNOWN: unknown argument: --unknown2
+# UNKNOWN: unknown emulation: foo
+# UNKNOWN: cannot open /no/such/file
+# UNKNOWN: unable to find library -lnosuchlib
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: not ld.lld %t -o /no/such/file 2>&1 | FileCheck -check-prefix=MISSING %s
+# MISSING: failed to open /no/such/file
+
+# RUN: ld.lld --help 2>&1 | FileCheck -check-prefix=HELP %s
+# HELP: USAGE:
+
+# RUN: ld.lld --version 2>&1 | FileCheck -check-prefix=VERSION %s
+# VERSION: LLD
+
+## Attempt to link DSO with -r
+# RUN: ld.lld -shared %t -o %t.so
+# RUN: not ld.lld -r %t.so %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR %s
+# ERR: attempted static link of dynamic object
+
+## Attempt to use -r and -shared together
+# RUN: not ld.lld -r -shared %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR2 %s
+# ERR2: -r and -shared may not be used together
+
+## Attempt to use -r and --gc-sections together
+# RUN: not ld.lld -r --gc-sections %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR3 %s
+# ERR3: -r and --gc-sections may not be used together
+
+## Attempt to use -r and --icf together
+# RUN: not ld.lld -r --icf=all %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR4 %s
+# ERR4: -r and --icf may not be used together
+
+## Attempt to use -r and -pie together
+# RUN: not ld.lld -r -pie %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR5 %s
+# ERR5: -r and -pie may not be used together
+
+## Attempt to use -shared and -pie together
+# RUN: not ld.lld -shared -pie %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR6 %s
+# ERR6: -shared and -pie may not be used together
+
+.globl _start
+_start:
+ nop
diff --git a/test/ELF/duplicate-internal.s b/test/ELF/duplicate-internal.s
index 2395a6cae0db..d1ccf5322127 100644
--- a/test/ELF/duplicate-internal.s
+++ b/test/ELF/duplicate-internal.s
@@ -3,7 +3,7 @@
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
-# CHECK: duplicate symbol: _gp in (internal) and {{.*}}
+# CHECK: duplicate symbol: _gp in {{.*}} and (internal)
# REQUIRES: mips
diff --git a/test/ELF/duplicated-plt-entry.s b/test/ELF/duplicated-plt-entry.s
new file mode 100644
index 000000000000..4644bed0ca8b
--- /dev/null
+++ b/test/ELF/duplicated-plt-entry.s
@@ -0,0 +1,17 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/duplicated-plt-entry.s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t.so
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
+// RUN: ld.lld %t2.o %t.so -o %t2.so -shared
+
+// RUN: llvm-readobj -r %t2.so | FileCheck %s
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rela.plt {
+// CHECK-NEXT: R_X86_64_JUMP_SLOT bar 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+callq bar@PLT
+callq bar@PLT
diff --git a/test/ELF/dynamic-list.s b/test/ELF/dynamic-list.s
new file mode 100644
index 000000000000..5e257b31d1f3
--- /dev/null
+++ b/test/ELF/dynamic-list.s
@@ -0,0 +1,110 @@
+## There is some bad quoting interaction between lit's internal shell, which is
+## implemented in Python, and the Cygwin implementations of the Unix utilities.
+## Avoid running these tests on Windows for now by requiring a real shell.
+
+# REQUIRES: shell
+
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -soname shared -o %t2.so
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+## Check exporting only one symbol.
+# RUN: echo "{ foo1; };" > %t.list
+# RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe
+# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
+
+## And now using quoted strings (the output is the same since it does
+## use any wildcard character).
+# RUN: echo "{ \"foo1\"; };" > %t.list
+# RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe
+# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
+
+## And now using --export-dynamic-symbol.
+# RUN: ld.lld --export-dynamic-symbol foo1 %t %t2.so -o %t.exe
+# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
+# RUN: ld.lld --export-dynamic-symbol=foo1 %t %t2.so -o %t.exe
+# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
+
+# CHECK: DynamicSymbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: @ (0)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: foo1@ (1)
+# CHECK-NEXT: Value: 0x11000
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global (0x1)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: .text (0x4)
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+
+## Now export all the foo1, foo2, and foo31 symbols
+# RUN: echo "{ foo1; foo2; foo31; };" > %t.list
+# RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe
+# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK2 %s
+
+# CHECK2: DynamicSymbols [
+# CHECK2-NEXT: Symbol {
+# CHECK2-NEXT: Name: @ (0)
+# CHECK2-NEXT: Value: 0x0
+# CHECK2-NEXT: Size: 0
+# CHECK2-NEXT: Binding: Local
+# CHECK2-NEXT: Type: None
+# CHECK2-NEXT: Other: 0
+# CHECK2-NEXT: Section: Undefined
+# CHECK2-NEXT: }
+# CHECK2-NEXT: Symbol {
+# CHECK2-NEXT: Name: foo1@ (1)
+# CHECK2-NEXT: Value: 0x11000
+# CHECK2-NEXT: Size: 0
+# CHECK2-NEXT: Binding: Global (0x1)
+# CHECK2-NEXT: Type: None (0x0)
+# CHECK2-NEXT: Other: 0
+# CHECK2-NEXT: Section: .text (0x4)
+# CHECK2-NEXT: }
+# CHECK2-NEXT: Symbol {
+# CHECK2-NEXT: Name: foo2@ (6)
+# CHECK2-NEXT: Value: 0x11001
+# CHECK2-NEXT: Size: 0
+# CHECK2-NEXT: Binding: Global (0x1)
+# CHECK2-NEXT: Type: None (0x0)
+# CHECK2-NEXT: Other: 0
+# CHECK2-NEXT: Section: .text (0x4)
+# CHECK2-NEXT: }
+# CHECK2-NEXT: Symbol {
+# CHECK2-NEXT: Name: foo31@ (11)
+# CHECK2-NEXT: Value: 0x11002
+# CHECK2-NEXT: Size: 0
+# CHECK2-NEXT: Binding: Global (0x1)
+# CHECK2-NEXT: Type: None (0x0)
+# CHECK2-NEXT: Other: 0
+# CHECK2-NEXT: Section: .text (0x4)
+# CHECK2-NEXT: }
+# CHECK2-NEXT: ]
+
+.globl foo1
+foo1:
+ ret
+
+.globl foo2
+foo2:
+ ret
+
+.globl foo31
+foo31:
+ ret
+
+.globl _start
+_start:
+ retq
diff --git a/test/ELF/dynamic-reloc-in-ro.s b/test/ELF/dynamic-reloc-in-ro.s
new file mode 100644
index 000000000000..2ef36f695fb6
--- /dev/null
+++ b/test/ELF/dynamic-reloc-in-ro.s
@@ -0,0 +1,8 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
+
+foo:
+.quad foo
+
+// CHECK: can't create dynamic relocation R_X86_64_64 against readonly segment
diff --git a/test/ELF/dynamic-reloc-weak.s b/test/ELF/dynamic-reloc-weak.s
index fe1b7eedb6d7..b4da2e552e11 100644
--- a/test/ELF/dynamic-reloc-weak.s
+++ b/test/ELF/dynamic-reloc-weak.s
@@ -1,5 +1,5 @@
// 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/shared.s -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc-weak.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld %t.o %t2.so -o %t
// RUN: llvm-readobj -r %t | FileCheck %s
@@ -19,9 +19,12 @@ _start:
.weak sym3
.quad sym3
-// Both gold and bfd ld will produce a relocation for sym1 and sym2 only. That
-// That seems odd. If the dynamic linker must get a chance to resolve sym1
-// and sym2, that should also be the case for sym3.
+ .type sym4,@function
+ .weak sym4
+ .quad sym4
+
+// Test that we produce dynamic relocation for every weak undefined symbol
+// we found.
// CHECK: Relocations [
// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
@@ -29,5 +32,6 @@ _start:
// CHECK-NEXT: }
// CHECK-NEXT: Section ({{.*}}) .rela.plt {
// CHECK-NEXT: 0x{{.*}} R_X86_64_JUMP_SLOT sym2 0x0
+// CHECK-NEXT: 0x{{.*}} R_X86_64_JUMP_SLOT sym3 0x0
// CHECK-NEXT: }
-// CHECK-NEXT: ] \ No newline at end of file
+// CHECK-NEXT: ]
diff --git a/test/ELF/dynamic-reloc.s b/test/ELF/dynamic-reloc.s
index 295396006543..5e23ba93d5a9 100644
--- a/test/ELF/dynamic-reloc.s
+++ b/test/ELF/dynamic-reloc.s
@@ -43,6 +43,7 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
+// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x0000000000000017 JMPREL
// CHECK-NEXT: 0x0000000000000002 PLTRELSZ 24 (bytes)
// CHECK-NEXT: 0x0000000000000003 PLTGOT
@@ -52,7 +53,6 @@
// CHECK-NEXT: 0x0000000000000005 STRTAB
// CHECK-NEXT: 0x000000000000000A STRSZ
// CHECK-NEXT: 0x0000000000000004 HASH
-// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000000 NULL 0x0
// CHECK-NEXT: ]
diff --git a/test/ELF/dynamic.s b/test/ELF/dynamic.s
new file mode 100644
index 000000000000..2efd2990c52c
--- /dev/null
+++ b/test/ELF/dynamic.s
@@ -0,0 +1,44 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t.o
+
+## Check that _DYNAMIC symbol is created when creating dynamic output,
+## and has hidden visibility and address equal to .dynamic section.
+# RUN: ld.lld -shared %t.o -o %t.so
+# RUN: llvm-readobj -sections -symbols %t.so | FileCheck %s
+# CHECK: Section {
+# CHECK: Index: 5
+# CHECK: Name: .dynamic
+# CHECK-NEXT: Type: SHT_DYNAMIC
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_WRITE
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x[[ADDR:.*]]
+# CHECK-NEXT: Offset: 0x1000
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK: Symbols [
+# CHECK: Symbol {
+# CHECK: Name: _DYNAMIC
+# CHECK-NEXT: Value: 0x[[ADDR]]
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other [ (0x2)
+# CHECK-NEXT: STV_HIDDEN
+# CHECK-NEXT: ]
+# CHECK-NEXT: Section: .dynamic
+# CHECK-NEXT: }
+
+# RUN: ld.lld %t.o -o %t.o
+# RUN: llvm-readobj -sections -symbols %t.o | FileCheck -check-prefix=NODYN %s
+# NODYN: Symbols [
+# NODYN-NOT: Name: _DYNAMIC
+# NODYN: ]
+
+.globl _start
+_start:
diff --git a/test/ELF/dynsym-pie.s b/test/ELF/dynsym-pie.s
new file mode 100644
index 000000000000..9d3a9ffe304f
--- /dev/null
+++ b/test/ELF/dynsym-pie.s
@@ -0,0 +1,36 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+# RUN: ld.lld -pie %t -o %t.out
+# RUN: llvm-readobj -t -dyn-symbols %t.out | FileCheck %s
+
+# CHECK: DynamicSymbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: @
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+.text
+.globl _start
+_start:
+
+.global default
+default:
+
+.global protected
+protected:
+
+.global hidden
+hidden:
+
+.global internal
+internal:
+
+.global protected_with_hidden
+.protected
+protected_with_hidden:
diff --git a/test/ELF/edata-etext.s b/test/ELF/edata-etext.s
new file mode 100644
index 000000000000..e0538d690d7c
--- /dev/null
+++ b/test/ELF/edata-etext.s
@@ -0,0 +1,117 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t
+# RUN: llvm-readobj -sections -symbols %t | FileCheck %s
+
+## This checks that:
+## 1) Address of _etext is the first location after the last read-only loadable segment.
+## 2) Address of _edata points to the end of the last non SHT_NOBITS section.
+## That is how gold/bfd do. At the same time specs says: "If the address of _edata is
+## greater than the address of _etext, the address of _end is same as the address
+## of _edata." (https://docs.oracle.com/cd/E53394_01/html/E54766/u-etext-3c.html).
+## 3) Address of _end is different from _edata because of 2.
+# CHECK: Section {
+# CHECK: Index: 1
+# CHECK: Name: .text
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_EXECINSTR
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x11000
+# CHECK-NEXT: Offset: 0x1000
+# CHECK-NEXT: Size: 1
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 2
+# CHECK-NEXT: Name: .data
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_WRITE
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x12000
+# CHECK-NEXT: Offset: 0x2000
+# CHECK-NEXT: Size: 2
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 3
+# CHECK-NEXT: Name: .bss
+# CHECK-NEXT: Type: SHT_NOBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_WRITE
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x12004
+# CHECK-NEXT: Offset: 0x2002
+# CHECK-NEXT: Size: 6
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK: Symbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name:
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _start
+# CHECK-NEXT: Value: 0x11000
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _edata
+# CHECK-NEXT: Value: 0x12002
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Absolute
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _end
+# CHECK-NEXT: Value: 0x1200A
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Absolute
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _etext
+# CHECK-NEXT: Value: 0x11001
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Absolute
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+.global _start,_end,_etext,_edata
+.text
+_start:
+ nop
+.data
+ .word 1
+.bss
+ .align 4
+ .space 6
diff --git a/test/ELF/eh-frame-dyn-rel.s b/test/ELF/eh-frame-dyn-rel.s
new file mode 100644
index 000000000000..62d56951b2cf
--- /dev/null
+++ b/test/ELF/eh-frame-dyn-rel.s
@@ -0,0 +1,10 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: not ld.lld %t.o %t.o -o %t -shared 2>&1 | FileCheck %s
+
+ .section bar,"axG",@progbits,foo,comdat
+ .cfi_startproc
+ .cfi_personality 0x8c, foo
+ .cfi_endproc
+
+// CHECK: can't create dynamic relocation R_X86_64_64 against readonly segment
diff --git a/test/ELF/eh-frame-gc.s b/test/ELF/eh-frame-gc.s
new file mode 100644
index 000000000000..b2e21f497f41
--- /dev/null
+++ b/test/ELF/eh-frame-gc.s
@@ -0,0 +1,20 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
+# RUN: ld.lld -shared --gc-sections %t.o -o %t
+# RUN: llvm-readobj -s %t | FileCheck %s
+
+## Check that section containing personality is
+## not garbage collected.
+# CHECK: Sections [
+# CHECK: Name: .test_personality_section
+
+.text
+.globl foo
+.type foo,@function
+foo:
+ .cfi_startproc
+ .cfi_personality 155, DW.ref.__gxx_personality_v0
+ .cfi_endproc
+
+.section .test_personality_section
+DW.ref.__gxx_personality_v0:
diff --git a/test/ELF/eh-frame-hdr-abs-fde.s b/test/ELF/eh-frame-hdr-abs-fde.s
new file mode 100644
index 000000000000..37705d6ad818
--- /dev/null
+++ b/test/ELF/eh-frame-hdr-abs-fde.s
@@ -0,0 +1,33 @@
+# Check reading PC values of FDEs and writing lookup table in the .eh_frame_hdr
+# if CIE augmentation string has 'L' token and PC values are encoded using
+# absolute (not relative) format.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld --eh-frame-hdr %t.o -o %t
+# RUN: llvm-objdump -s -dwarf=frames %t | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Contents of section .eh_frame_hdr:
+# CHECK-NEXT: 10178 011b033b ffffffcc 00000001 0000fe88
+# ^-- 0x20000 - 0x10178
+# .text - .eh_frame_hdr
+# CHECK-NEXT: 10188 ffffffe8
+# CHECK-NEXT: Contents of section .text:
+# CHECK-NEXT: 20000 00000000
+
+# CHECK: Augmentation: "zLR"
+# CHECK: Augmentation data: 00 0B
+# ^-- DW_EH_PE_udata4 | DW_EH_PE_signed
+
+ .text
+ .globl __start
+__start:
+ .cfi_startproc
+ .cfi_lsda 0, _ex
+ nop
+ .cfi_endproc
+
+ .data
+_ex:
+ .word 0
diff --git a/test/ELF/eh-frame-hdr-augmentation.s b/test/ELF/eh-frame-hdr-augmentation.s
new file mode 100644
index 000000000000..91e6a9cc1ccb
--- /dev/null
+++ b/test/ELF/eh-frame-hdr-augmentation.s
@@ -0,0 +1,38 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld --eh-frame-hdr %t.o -o %t -shared
+// RUN: llvm-objdump --dwarf=frames %t | FileCheck %s
+
+// CHECK: .eh_frame contents:
+
+// CHECK: 00000000 0000001c ffffffff CIE
+// CHECK-NEXT: Version: 1
+// CHECK-NEXT: Augmentation: "zPLR"
+// CHECK-NEXT: Code alignment factor: 1
+// CHECK-NEXT: Data alignment factor: -8
+// CHECK-NEXT: Return address column: 16
+// CHECK-NEXT: Augmentation data:
+
+// CHECK: DW_CFA_def_cfa: reg7 +8
+// CHECK-NEXT: DW_CFA_offset: reg16 -8
+// CHECK-NEXT: DW_CFA_nop:
+// CHECK-NEXT: DW_CFA_nop:
+
+// CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000dd8...00000dd8
+// CHECK-NEXT: DW_CFA_nop:
+// CHECK-NEXT: DW_CFA_nop:
+// CHECK-NEXT: DW_CFA_nop:
+
+ .cfi_startproc
+ .cfi_personality 0x9b, g
+ .cfi_lsda 0x1b, h
+ .cfi_endproc
+
+ .global g
+ .hidden g
+g:
+
+ .global h
+ .hidden h
+h:
+
diff --git a/test/ELF/eh-frame-hdr-icf.s b/test/ELF/eh-frame-hdr-icf.s
new file mode 100644
index 000000000000..2e7b335fb46d
--- /dev/null
+++ b/test/ELF/eh-frame-hdr-icf.s
@@ -0,0 +1,27 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 --icf=all --eh-frame-hdr
+# RUN: llvm-objdump -s %t2 | FileCheck %s
+
+# CHECK: Contents of section .eh_frame_hdr:
+# CHECK-NEXT: 101a0 011b033b b4ffffff 01000000 600e0000
+# ^ FDE count
+# CHECK-NEXT: 101b0 d0ffffff 00000000 00000000
+# ^ FDE for f2
+
+.globl _start, f1, f2
+_start:
+ ret
+
+.section .text.f1, "ax"
+f1:
+ .cfi_startproc
+ ret
+ .cfi_endproc
+
+.section .text.f2, "ax"
+f2:
+ .cfi_startproc
+ ret
+ .cfi_endproc
diff --git a/test/ELF/eh-frame-hdr-no-out.s b/test/ELF/eh-frame-hdr-no-out.s
new file mode 100644
index 000000000000..edbafad07247
--- /dev/null
+++ b/test/ELF/eh-frame-hdr-no-out.s
@@ -0,0 +1,6 @@
+// REQUIRES: x86
+// RUN: not ld.lld --eh-frame-hdr %p/Inputs/invalid-cie-version2.elf -o %t >& %t.log
+// RUN: FileCheck %s < %t.log
+
+// invalid-cie-version2.elf contains unsupported version of CIE = 2.
+// CHECK: FDE version 1 or 3 expected, but got 2
diff --git a/test/ELF/eh-frame-hdr-no-out2.s b/test/ELF/eh-frame-hdr-no-out2.s
new file mode 100644
index 000000000000..0eeb0ea5548d
--- /dev/null
+++ b/test/ELF/eh-frame-hdr-no-out2.s
@@ -0,0 +1,19 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld --eh-frame-hdr %t.o -o %t
+// RUN: llvm-readobj -s -program-headers %t | FileCheck %s --check-prefix=NOHDR
+
+.section foo,"ax",@progbits
+ nop
+
+.text
+.globl _start
+_start:
+
+// There is no .eh_frame section,
+// therefore .eh_frame_hdr also not created.
+// NOHDR: Sections [
+// NOHDR-NOT: Name: .eh_frame
+// NOHDR-NOT: Name: .eh_frame_hdr
+// NOHDR: ProgramHeaders [
+// NOHDR-NOT: PT_GNU_EH_FRAME
diff --git a/test/ELF/eh-frame-hdr.s b/test/ELF/eh-frame-hdr.s
new file mode 100644
index 000000000000..16fb49ac8e9f
--- /dev/null
+++ b/test/ELF/eh-frame-hdr.s
@@ -0,0 +1,127 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t
+// RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t | FileCheck %s --check-prefix=NOHDR
+// RUN: ld.lld --eh-frame-hdr %t.o -o %t
+// RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t | FileCheck %s --check-prefix=HDR
+// RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=HDRDISASM
+
+.section foo,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section bar,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section dah,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.text
+.globl _start
+_start:
+
+// NOHDR: Sections [
+// NOHDR-NOT: Name: .eh_frame_hdr
+// NOHDR: ProgramHeaders [
+// NOHDR-NOT: PT_GNU_EH_FRAME
+
+//HDRDISASM: Disassembly of section foo:
+//HDRDISASM-NEXT: foo:
+//HDRDISASM-NEXT: 11000: 90 nop
+//HDRDISASM-NEXT: Disassembly of section bar:
+//HDRDISASM-NEXT: bar:
+//HDRDISASM-NEXT: 11001: 90 nop
+//HDRDISASM-NEXT: Disassembly of section dah:
+//HDRDISASM-NEXT: dah:
+//HDRDISASM-NEXT: 11002: 90 nop
+
+// HDR: Sections [
+// HDR: Section {
+// HDR: Index: 1
+// HDR-NEXT: Name: .eh_frame
+// HDR-NEXT: Type: SHT_PROGBITS
+// HDR-NEXT: Flags [
+// HDR-NEXT: SHF_ALLOC
+// HDR-NEXT: ]
+// HDR-NEXT: Address: 0x10158
+// HDR-NEXT: Offset: 0x158
+// HDR-NEXT: Size: 96
+// HDR-NEXT: Link: 0
+// HDR-NEXT: Info: 0
+// HDR-NEXT: AddressAlignment: 8
+// HDR-NEXT: EntrySize: 0
+// HDR-NEXT: SectionData (
+// HDR-NEXT: 0000: 14000000 00000000 017A5200 01781001 |
+// HDR-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000 |
+// HDR-NEXT: 0020: 880E0000 01000000 00000000 00000000 |
+// HDR-NEXT: 0030: 14000000 34000000 710E0000 01000000 |
+// HDR-NEXT: 0040: 00000000 00000000 14000000 4C000000 |
+// HDR-NEXT: 0050: 5A0E0000 01000000 00000000 00000000 |
+// CIE: 14000000 00000000 017A5200 01781001 1B0C0708 90010000
+// FDE(1): 14000000 1C000000 880E0000 01000000 00000000 00000000
+// address of data (starts with 0x880E0000) = 0x10158 + 0x0020 = 0x10178
+// The starting address to which this FDE applies = 0xE88 + 0x10178 = 0x11000
+// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1
+// FDE(2): 14000000 34000000 710E0000 01000000 00000000 00000000
+// address of data (starts with 0x710E0000) = 0x10158 + 0x0038 = 0x10190
+// The starting address to which this FDE applies = 0xE71 + 0x10190 = 0x11001
+// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1
+// FDE(3): 14000000 4C000000 5A0E0000 01000000 00000000 00000000
+// address of data (starts with 0x5A0E0000) = 0x10158 + 0x0050 = 0x101A8
+// The starting address to which this FDE applies = 0xE5A + 0x101A8 = 0x11002
+// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1
+// HDR-NEXT: )
+// HDR-NEXT: }
+// HDR-NEXT: Section {
+// HDR-NEXT: Index: 2
+// HDR-NEXT: Name: .eh_frame_hdr
+// HDR-NEXT: Type: SHT_PROGBITS
+// HDR-NEXT: Flags [
+// HDR-NEXT: SHF_ALLOC
+// HDR-NEXT: ]
+// HDR-NEXT: Address: 0x101B8
+// HDR-NEXT: Offset: 0x1B8
+// HDR-NEXT: Size: 36
+// HDR-NEXT: Link: 0
+// HDR-NEXT: Info: 0
+// HDR-NEXT: AddressAlignment: 1
+// HDR-NEXT: EntrySize: 0
+// HDR-NEXT: SectionData (
+// HDR-NEXT: 0000: 011B033B 9CFFFFFF 03000000 480E0000 |
+// HDR-NEXT: 0010: B8FFFFFF 490E0000 D0FFFFFF 4A0E0000 |
+// HDR-NEXT: 0020: E8FFFFFF |
+// Header (always 4 bytes): 0x011B033B
+// 9CFFFFFF = .eh_frame(0x10158) - .eh_frame_hdr(0x101B8) - 4
+// 03000000 = 3 = the number of FDE pointers in the table.
+// Entry(1): 480E0000 B8FFFFFF
+// 480E0000 = 0x11000 - .eh_frame_hdr(0x101B8) = 0xE48
+// B8FFFFFF = address of FDE(1) - .eh_frame_hdr(0x101B8) =
+// = .eh_frame(0x10158) + 24 - 0x101B8 = 0xFFFFFFB8
+// Entry(2): 490E0000 D0FFFFFF
+// 490E0000 = 0x11001 - .eh_frame_hdr(0x101B8) = 0xE49
+// D0FFFFFF = address of FDE(2) - .eh_frame_hdr(0x101B8) =
+// = .eh_frame(0x10158) + 24 + 24 - 0x101B8 = 0xFFFFFFD0
+// Entry(3): 4A0E0000 E8FFFFFF
+// 4A0E0000 = 0x11002 - .eh_frame_hdr(0x101B8) = 0xE4A
+// E8FFFFFF = address of FDE(2) - .eh_frame_hdr(0x101B8) =
+// = .eh_frame(0x10158) + 24 + 24 - 0x101B8 = 0xFFFFFFE8
+// HDR-NEXT: )
+// HDR-NEXT: }
+// HDR: ProgramHeaders [
+// HDR: ProgramHeader {
+// HDR: Type: PT_GNU_EH_FRAME
+// HDR-NEXT: Offset: 0x1B8
+// HDR-NEXT: VirtualAddress: 0x101B8
+// HDR-NEXT: PhysicalAddress: 0x101B8
+// HDR-NEXT: FileSize: 36
+// HDR-NEXT: MemSize: 36
+// HDR-NEXT: Flags [
+// HDR-NEXT: PF_R
+// HDR-NEXT: ]
+// HDR-NEXT: Alignment: 1
+// HDR-NEXT: }
diff --git a/test/ELF/eh-frame-marker.s b/test/ELF/eh-frame-marker.s
new file mode 100644
index 000000000000..a5de2a7c3d40
--- /dev/null
+++ b/test/ELF/eh-frame-marker.s
@@ -0,0 +1,6 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld --eh-frame-hdr %t.o -o %t.so -shared
+// We used to crash on this.
+ .section .eh_frame
+foo:
+ .long 0
diff --git a/test/ELF/eh-frame-merge.s b/test/ELF/eh-frame-merge.s
index 2b0e4a52822d..2610d4d4d2de 100644
--- a/test/ELF/eh-frame-merge.s
+++ b/test/ELF/eh-frame-merge.s
@@ -21,7 +21,7 @@
// * There is only one copy of the second FDE
// CHECK: Name: .eh_frame
-// CHECK-NEXT: Type: SHT_X86_64_UNWIND
+// CHECK-NEXT: Type: SHT_PROGBITS
// CHECK-NEXT: Flags [
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: ]
diff --git a/test/ELF/eh-frame-multilpe-cie.s b/test/ELF/eh-frame-multilpe-cie.s
new file mode 100644
index 000000000000..12781ff5b6e9
--- /dev/null
+++ b/test/ELF/eh-frame-multilpe-cie.s
@@ -0,0 +1,12 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld --eh-frame-hdr %t.o -o %t.so -shared
+// We would fail to parse multiple cies in the same file.
+
+ .cfi_startproc
+ .cfi_personality 0x9b, foo
+ .cfi_endproc
+
+ .cfi_startproc
+ .cfi_endproc
+
+foo:
diff --git a/test/ELF/eh-frame-type.test b/test/ELF/eh-frame-type.test
index f59ab116d7dd..756299739e16 100644
--- a/test/ELF/eh-frame-type.test
+++ b/test/ELF/eh-frame-type.test
@@ -1,10 +1,11 @@
-# RUN: yaml2obj -format elf %s -o %t.o
+# RUN: yaml2obj %s -o %t.o
# RUN: ld.lld %t.o -o %t -shared
# RUN: llvm-readobj -s %t | FileCheck %s
# CHECK: Name: .eh_frame
-# CHECK-NEXT: Type: SHT_X86_64_UNWIND
+# CHECK-NEXT: Type: SHT_PROGBITS
+!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
diff --git a/test/ELF/ehframe-relocation.s b/test/ELF/ehframe-relocation.s
index f952ebc60865..8d5e14919e92 100644
--- a/test/ELF/ehframe-relocation.s
+++ b/test/ELF/ehframe-relocation.s
@@ -1,17 +1,19 @@
// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
-// RUN: ld.lld %t.o -o %t
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/ehframe-relocation.s -o %t2.o
+// RUN: ld.lld %t.o %t2.o -o %t
// RUN: llvm-readobj -s %t | FileCheck %s
// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
// CHECK: Name: .eh_frame
-// CHECK-NEXT: Type: SHT_X86_64_UNWIND
+// CHECK-NEXT: Type: SHT_PROGBITS
// CHECK-NEXT: Flags [
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x10120
// CHECK-NEXT: Offset:
-// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Size: 48
+// CHECK-NOT: .eh_frame
// 0x10120 = 65824
// 0x10120 + 5 = 65829
diff --git a/test/ELF/empty-ver.s b/test/ELF/empty-ver.s
new file mode 100644
index 000000000000..f200d2876e09
--- /dev/null
+++ b/test/ELF/empty-ver.s
@@ -0,0 +1,25 @@
+// REQUIRES: x86
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared -version-script %p/Inputs/empty-ver.ver
+// RUN: llvm-readobj -version-info %t.so | FileCheck %s
+
+// CHECK: Version symbols {
+// CHECK-NEXT: Section Name:
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Symbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Version: 0
+// CHECK-NEXT: Name: @
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Version: 2
+// CHECK-NEXT: Name: foo@ver
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// CHECK-NEXT: }
+
+
+.global foo@ver
+foo@ver:
diff --git a/test/ELF/emulation.s b/test/ELF/emulation.s
index a8a8f398c42c..7cc764fc6c18 100644
--- a/test/ELF/emulation.s
+++ b/test/ELF/emulation.s
@@ -29,6 +29,37 @@
# X86-64-NEXT: StringTableSectionIndex:
# X86-64-NEXT: }
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnux32 %s -o %tx32
+# RUN: ld.lld -m elf32_x86_64 %tx32 -o %t2x32
+# RUN: llvm-readobj -file-headers %t2x32 | FileCheck --check-prefix=X32 %s
+# RUN: ld.lld %tx32 -o %t3x32
+# RUN: llvm-readobj -file-headers %t3x32 | FileCheck --check-prefix=X32 %s
+# X32: ElfHeader {
+# X32-NEXT: Ident {
+# X32-NEXT: Magic: (7F 45 4C 46)
+# X32-NEXT: Class: 32-bit (0x1)
+# X32-NEXT: DataEncoding: LittleEndian (0x1)
+# X32-NEXT: FileVersion: 1
+# X32-NEXT: OS/ABI: SystemV (0x0)
+# X32-NEXT: ABIVersion: 0
+# X32-NEXT: Unused: (00 00 00 00 00 00 00)
+# X32-NEXT: }
+# X32-NEXT: Type: Executable (0x2)
+# X32-NEXT: Machine: EM_X86_64 (0x3E)
+# X32-NEXT: Version: 1
+# X32-NEXT: Entry:
+# X32-NEXT: ProgramHeaderOffset: 0x34
+# X32-NEXT: SectionHeaderOffset:
+# X32-NEXT: Flags [ (0x0)
+# X32-NEXT: ]
+# X32-NEXT: HeaderSize: 52
+# X32-NEXT: ProgramHeaderEntrySize: 32
+# X32-NEXT: ProgramHeaderCount:
+# X32-NEXT: SectionHeaderEntrySize: 40
+# X32-NEXT: SectionHeaderCount:
+# X32-NEXT: StringTableSectionIndex:
+# X32-NEXT: }
+
# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %tx86
# RUN: ld.lld -m elf_i386 %tx86 -o %t2x86
# RUN: llvm-readobj -file-headers %t2x86 | FileCheck --check-prefix=X86 %s
@@ -60,6 +91,37 @@
# X86-NEXT: StringTableSectionIndex:
# 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 %tx86fbsd -o %t3x86fbsd
+# RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s
+# X86FBSD: ElfHeader {
+# X86FBSD-NEXT: Ident {
+# X86FBSD-NEXT: Magic: (7F 45 4C 46)
+# X86FBSD-NEXT: Class: 32-bit (0x1)
+# X86FBSD-NEXT: DataEncoding: LittleEndian (0x1)
+# X86FBSD-NEXT: FileVersion: 1
+# X86FBSD-NEXT: OS/ABI: FreeBSD (0x9)
+# X86FBSD-NEXT: ABIVersion: 0
+# X86FBSD-NEXT: Unused: (00 00 00 00 00 00 00)
+# X86FBSD-NEXT: }
+# X86FBSD-NEXT: Type: Executable (0x2)
+# X86FBSD-NEXT: Machine: EM_386 (0x3)
+# X86FBSD-NEXT: Version: 1
+# X86FBSD-NEXT: Entry:
+# X86FBSD-NEXT: ProgramHeaderOffset: 0x34
+# X86FBSD-NEXT: SectionHeaderOffset:
+# X86FBSD-NEXT: Flags [ (0x0)
+# X86FBSD-NEXT: ]
+# X86FBSD-NEXT: HeaderSize: 52
+# X86FBSD-NEXT: ProgramHeaderEntrySize: 32
+# X86FBSD-NEXT: ProgramHeaderCount:
+# X86FBSD-NEXT: SectionHeaderEntrySize: 40
+# X86FBSD-NEXT: SectionHeaderCount:
+# X86FBSD-NEXT: StringTableSectionIndex:
+# X86FBSD-NEXT: }
+
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %tppc64
# RUN: ld.lld -m elf64ppc %tppc64 -o %t2ppc64
# RUN: llvm-readobj -file-headers %t2ppc64 | FileCheck --check-prefix=PPC64 %s
@@ -147,6 +209,60 @@
# MIPSEL-NEXT: EF_MIPS_CPIC
# MIPSEL-NEXT: ]
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %tmips64
+# RUN: ld.lld -m elf64btsmip -e _start %tmips64 -o %t2mips64
+# RUN: llvm-readobj -file-headers %t2mips64 | FileCheck --check-prefix=MIPS64 %s
+# RUN: ld.lld %tmips64 -e _start -o %t3mips64
+# RUN: llvm-readobj -file-headers %t3mips64 | FileCheck --check-prefix=MIPS64 %s
+# MIPS64: ElfHeader {
+# MIPS64-NEXT: Ident {
+# MIPS64-NEXT: Magic: (7F 45 4C 46)
+# MIPS64-NEXT: Class: 64-bit (0x2)
+# MIPS64-NEXT: DataEncoding: BigEndian (0x2)
+# MIPS64-NEXT: FileVersion: 1
+# MIPS64-NEXT: OS/ABI: SystemV (0x0)
+# MIPS64-NEXT: ABIVersion: 0
+# MIPS64-NEXT: Unused: (00 00 00 00 00 00 00)
+# MIPS64-NEXT: }
+# MIPS64-NEXT: Type: Executable (0x2)
+# MIPS64-NEXT: Machine: EM_MIPS (0x8)
+# MIPS64-NEXT: Version: 1
+# MIPS64-NEXT: Entry:
+# MIPS64-NEXT: ProgramHeaderOffset: 0x40
+# MIPS64-NEXT: SectionHeaderOffset:
+# MIPS64-NEXT: Flags [
+# MIPS64-NEXT: EF_MIPS_ARCH_64R2
+# MIPS64-NEXT: EF_MIPS_CPIC
+# MIPS64-NEXT: EF_MIPS_PIC
+# MIPS64-NEXT: ]
+
+# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux %s -o %tmips64el
+# RUN: ld.lld -m elf64ltsmip -e _start %tmips64el -o %t2mips64el
+# RUN: llvm-readobj -file-headers %t2mips64el | FileCheck --check-prefix=MIPS64EL %s
+# RUN: ld.lld %tmips64el -e _start -o %t3mips64el
+# RUN: llvm-readobj -file-headers %t3mips64el | FileCheck --check-prefix=MIPS64EL %s
+# MIPS64EL: ElfHeader {
+# MIPS64EL-NEXT: Ident {
+# MIPS64EL-NEXT: Magic: (7F 45 4C 46)
+# MIPS64EL-NEXT: Class: 64-bit (0x2)
+# MIPS64EL-NEXT: DataEncoding: LittleEndian (0x1)
+# MIPS64EL-NEXT: FileVersion: 1
+# MIPS64EL-NEXT: OS/ABI: SystemV (0x0)
+# MIPS64EL-NEXT: ABIVersion: 0
+# MIPS64EL-NEXT: Unused: (00 00 00 00 00 00 00)
+# MIPS64EL-NEXT: }
+# MIPS64EL-NEXT: Type: Executable (0x2)
+# MIPS64EL-NEXT: Machine: EM_MIPS (0x8)
+# MIPS64EL-NEXT: Version: 1
+# MIPS64EL-NEXT: Entry:
+# MIPS64EL-NEXT: ProgramHeaderOffset: 0x40
+# MIPS64EL-NEXT: SectionHeaderOffset:
+# MIPS64EL-NEXT: Flags [
+# MIPS64EL-NEXT: EF_MIPS_ARCH_64R2
+# MIPS64EL-NEXT: EF_MIPS_CPIC
+# MIPS64EL-NEXT: EF_MIPS_PIC
+# MIPS64EL-NEXT: ]
+
# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %taarch64
# RUN: ld.lld -m aarch64linux %taarch64 -o %t2aarch64
# RUN: llvm-readobj -file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s
@@ -173,5 +289,5 @@
# REQUIRES: x86,ppc,mips,aarch64
-.globl _start;
+.globl _start
_start:
diff --git a/test/ELF/end.s b/test/ELF/end.s
index 390e4445e2d8..689157f82070 100644
--- a/test/ELF/end.s
+++ b/test/ELF/end.s
@@ -36,13 +36,13 @@
// NOBSS-NEXT: SHF_ALLOC
// NOBSS-NEXT: SHF_WRITE
// NOBSS-NEXT: ]
-// NOBSS-NEXT: Address: 0x12000
+// NOBSS-NEXT: Address: 0x159
// NOBSS-NEXT: Offset:
// NOBSS-NEXT: Size: 2
// NOBSS: ]
// NOBSS: Symbols [
// NOBSS: Name: _end
-// NOBSS-NEXT: Value: 0x12002
+// NOBSS-NEXT: Value: 0x15B
// NOBSS: ]
// If the layout of the sections is changed, "_end" should point to the end of allocated address space.
@@ -60,13 +60,13 @@
// TEXTATEND-NEXT: SHF_ALLOC
// TEXTATEND-NEXT: SHF_EXECINSTR
// TEXTATEND-NEXT: ]
-// TEXTATEND-NEXT: Address: 0x12000
+// TEXTATEND-NEXT: Address: 0x160
// TEXTATEND-NEXT: Offset:
// TEXTATEND-NEXT: Size: 1
// TEXTATEND: ]
// TEXTATEND: Symbols [
// TEXTATEND: Name: _end
-// TEXTATEND-NEXT: Value: 0x12001
+// TEXTATEND-NEXT: Value: 0x161
// TEXTATEND: ]
.global _start,_end
diff --git a/test/ELF/entry.s b/test/ELF/entry.s
index c8758ece69eb..6175c7623a34 100644
--- a/test/ELF/entry.s
+++ b/test/ELF/entry.s
@@ -4,9 +4,9 @@
# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=SYM %s
# RUN: ld.lld %t1 -shared -o %t2 -e entry
# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=DSO %s
-# RUN: ld.lld %t1 -o %t2 -e 4096
+# RUN: ld.lld %t1 -o %t2 --entry=4096
# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=DEC %s
-# RUN: ld.lld %t1 -o %t2 -e 0xcafe
+# RUN: ld.lld %t1 -o %t2 --entry 0xcafe
# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=HEX %s
# RUN: ld.lld %t1 -o %t2 -e 0777
# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=OCT %s
diff --git a/test/ELF/fatal-warnings.s b/test/ELF/fatal-warnings.s
new file mode 100644
index 000000000000..0bc2a2b44476
--- /dev/null
+++ b/test/ELF/fatal-warnings.s
@@ -0,0 +1,16 @@
+# REQUIRES: x86
+# 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/warn-common.s -o %t2.o
+
+# RUN: ld.lld --warn-common %t1.o %t2.o -o %t1.out 2>&1 | \
+# RUN: FileCheck -check-prefix=ERR %s
+# ERR: multiple common of
+
+# RUN: not ld.lld --warn-common --fatal-warnings %t1.o %t2.o -o %t2.out 2>&1 | \
+# RUN: FileCheck -check-prefix=ERR %s
+
+.globl _start
+_start:
+
+.type arr,@object
+.comm arr,4,4
diff --git a/test/ELF/file-sym.s b/test/ELF/file-sym.s
new file mode 100644
index 000000000000..eddb461490c6
--- /dev/null
+++ b/test/ELF/file-sym.s
@@ -0,0 +1,12 @@
+# Check that we do not keep STT_FILE symbols in the symbol table
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -shared -o %t.so
+# RUN: llvm-readobj -symbols %t.so | FileCheck %s
+
+# REQUIRES: x86
+
+# CHECK-NOT: xxx
+
+.file "xxx"
+.file ""
diff --git a/test/ELF/gc-merge-local-sym.s b/test/ELF/gc-merge-local-sym.s
new file mode 100644
index 000000000000..b02a3a4e4762
--- /dev/null
+++ b/test/ELF/gc-merge-local-sym.s
@@ -0,0 +1,34 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared -O3 --gc-sections
+// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s
+
+// CHECK: Name: .rodata
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_MERGE
+// CHECK-NEXT: SHF_STRINGS
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x1C8
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 1
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 61626300 |abc.|
+// CHECK-NEXT: )
+
+// CHECK: Symbols [
+// CHECK: Symbol {
+// CHECK-NOT: Name: bar
+
+ .global foo
+foo:
+ leaq .L.str(%rip), %rsi
+ .section .rodata.str1.1,"aMS",@progbits,1
+.L.str:
+ .asciz "abc"
+bar:
+ .asciz "def"
diff --git a/test/ELF/gc-sections-eh.s b/test/ELF/gc-sections-eh.s
index 042b68ebdfe2..88c3dd0d9ca4 100644
--- a/test/ELF/gc-sections-eh.s
+++ b/test/ELF/gc-sections-eh.s
@@ -1,10 +1,23 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
# RUN: ld.lld %t -o %t2 --gc-sections
# RUN: llvm-readobj -t %t2 | FileCheck %s
+# RUN: llvm-objdump --dwarf=frames %t2 | FileCheck --check-prefix=EH %s
+
+# RUN: ld.lld %t -o %t3
+# RUN: llvm-readobj -t %t3 | FileCheck --check-prefix=NOGC %s
+# RUN: llvm-objdump --dwarf=frames %t3 | FileCheck --check-prefix=EHNOGC %s
# CHECK-NOT: foo
+# NOGC: foo
+
+# EH: FDE cie={{.*}} pc=
+# EH-NOT: FDE
+
+# EHNOGC: FDE cie={{.*}} pc=
+# EHNOGC: FDE cie={{.*}} pc=
.section .text,"ax",@progbits,unique,0
.globl foo
diff --git a/test/ELF/gc-sections-local-sym.s b/test/ELF/gc-sections-local-sym.s
new file mode 100644
index 000000000000..89121e289cc2
--- /dev/null
+++ b/test/ELF/gc-sections-local-sym.s
@@ -0,0 +1,57 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+// RUN: ld.lld %t -o %t2 -shared --gc-sections
+// RUN: llvm-readobj -t -s -section-data %t2 | FileCheck %s
+// REQUIRES: x86
+
+.global foo
+foo:
+
+.section .bar,"a"
+zed:
+
+// CHECK: Name: .strtab
+// CHECK-NEXT: Type: SHT_STRTAB
+// 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: 00666F6F 005F4459 4E414D49 4300 |.foo._DYNAMIC.|
+// CHECK-NEXT: )
+
+// CHECK: Symbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: (0)
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _DYNAMIC
+// CHECK-NEXT: Value: 0x1000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .dynamic
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other:
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/gc-sections-lsda.s b/test/ELF/gc-sections-lsda.s
new file mode 100644
index 000000000000..b5bed8f0c816
--- /dev/null
+++ b/test/ELF/gc-sections-lsda.s
@@ -0,0 +1,21 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld -shared --gc-sections %t.o -o %t
+
+// Test that we handle .eh_frame keeping sections alive. We could be more
+// precise and gc the entire contents of this file, but test that at least
+// we are consistent: if we keep .abc, we have to keep .foo
+
+// RUN: llvm-readobj -s %t | FileCheck %s
+// CHECK: Name: .abc
+// CHECK: Name: .foo (38)
+
+ .cfi_startproc
+ .cfi_lsda 0x1b,zed
+ .cfi_endproc
+ .section .abc,"a"
+zed:
+ .long bar-.
+ .section .foo,"ax"
+bar:
diff --git a/test/ELF/gc-sections-merge-addend.s b/test/ELF/gc-sections-merge-addend.s
new file mode 100644
index 000000000000..8595f5802be5
--- /dev/null
+++ b/test/ELF/gc-sections-merge-addend.s
@@ -0,0 +1,39 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared --gc-sections
+// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
+
+
+// CHECK: Name: .rodata
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_MERGE
+// CHECK-NEXT: SHF_STRINGS
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 1
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 62617200 |bar.|
+// CHECK-NEXT: )
+
+ .section .data.f,"aw",@progbits
+ .globl f
+f:
+ .quad .rodata.str1.1 + 4
+
+ .section .data.g,"aw",@progbits
+ .hidden g
+ .globl g
+g:
+ .quad .rodata.str1.1
+
+ .section .rodata.str1.1,"aMS",@progbits,1
+.L.str:
+ .asciz "foo"
+.L.str.1:
+ .asciz "bar"
diff --git a/test/ELF/gc-sections-merge-implicit-addend.s b/test/ELF/gc-sections-merge-implicit-addend.s
new file mode 100644
index 000000000000..8a7c804a830a
--- /dev/null
+++ b/test/ELF/gc-sections-merge-implicit-addend.s
@@ -0,0 +1,39 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=i386-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared --gc-sections
+// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
+
+
+// CHECK: Name: .rodata
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_MERGE
+// CHECK-NEXT: SHF_STRINGS
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 1
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 62617200 |bar.|
+// CHECK-NEXT: )
+
+ .section .data.f,"aw",@progbits
+ .globl f
+f:
+ .long .rodata.str1.1 + 4
+
+ .section .data.g,"aw",@progbits
+ .hidden g
+ .globl g
+g:
+ .long .rodata.str1.1
+
+ .section .rodata.str1.1,"aMS",@progbits,1
+.L.str:
+ .asciz "foo"
+.L.str.1:
+ .asciz "bar"
diff --git a/test/ELF/gc-sections-merge.s b/test/ELF/gc-sections-merge.s
new file mode 100644
index 000000000000..ef2688659871
--- /dev/null
+++ b/test/ELF/gc-sections-merge.s
@@ -0,0 +1,61 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: ld.lld %t.o -o %t.gc.so -shared --gc-sections
+// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
+// RUN: llvm-readobj -s -section-data %t.gc.so | FileCheck --check-prefix=GC %s
+
+
+// CHECK: Name: .rodata
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_MERGE
+// CHECK-NEXT: SHF_STRINGS
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 1
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 666F6F00 62617200 |foo.bar.|
+// CHECK-NEXT: )
+
+// GC: Name: .rodata
+// GC-NEXT: Type: SHT_PROGBITS
+// GC-NEXT: Flags [
+// GC-NEXT: SHF_ALLOC
+// GC-NEXT: SHF_MERGE
+// GC-NEXT: SHF_STRINGS
+// GC-NEXT: ]
+// GC-NEXT: Address:
+// GC-NEXT: Offset:
+// GC-NEXT: Size: 4
+// GC-NEXT: Link: 0
+// GC-NEXT: Info: 0
+// GC-NEXT: AddressAlignment: 1
+// GC-NEXT: EntrySize: 1
+// GC-NEXT: SectionData (
+// GC-NEXT: 0000: 666F6F00 |foo.|
+// GC-NEXT: )
+
+ .section .text.f,"ax",@progbits
+ .globl f
+f:
+ leaq .L.str(%rip), %rax
+ retq
+
+ .section .text.g,"ax",@progbits
+ .hidden g
+ .globl g
+g:
+ leaq .L.str.1(%rip), %rax
+ retq
+
+ .section .rodata.str1.1,"aMS",@progbits,1
+.L.str:
+ .asciz "foo"
+.L.str.1:
+ .asciz "bar"
diff --git a/test/ELF/gc-sections-protected.s b/test/ELF/gc-sections-protected.s
new file mode 100644
index 000000000000..9f1efed5938a
--- /dev/null
+++ b/test/ELF/gc-sections-protected.s
@@ -0,0 +1,18 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared --gc-sections
+// RUN: llvm-readobj -s %t.so | FileCheck %s
+
+// CHECK: Name: .text
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 1
+
+.protected g
+.globl g
+g:
+retq
diff --git a/test/ELF/gc-sections-shared.s b/test/ELF/gc-sections-shared.s
new file mode 100644
index 000000000000..d52eae2177b2
--- /dev/null
+++ b/test/ELF/gc-sections-shared.s
@@ -0,0 +1,34 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -o %t2.so
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld --gc-sections --export-dynamic-symbol foo -o %t %t.o --as-needed %t2.so
+# RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck %s
+
+# This test the property that we have a needed line for every undefined.
+# It would also be OK to drop bar2 and the need for the .so
+
+
+# CHECK: Name: bar
+# CHECK: Name: bar2
+# CHECK: Name: foo
+# CHECK: NEEDED SharedLibrary ({{.*}}.so)
+
+
+.section .text.foo, "ax"
+.globl foo
+foo:
+call bar
+
+.section .text.bar, "ax"
+.globl bar
+bar:
+ret
+
+.section .text._start, "ax"
+.globl _start
+_start:
+ret
+
+.section .text.unused, "ax"
+call bar2
diff --git a/test/ELF/gc-sections-weak.s b/test/ELF/gc-sections-weak.s
new file mode 100644
index 000000000000..625b613843ba
--- /dev/null
+++ b/test/ELF/gc-sections-weak.s
@@ -0,0 +1,24 @@
+// 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 %p/Inputs/gc-sections-weak.s -o %t2.o
+// RUN: ld.lld %t.o %t2.o -o %t.so -shared --gc-sections
+// RUN: llvm-readobj -s %t.so | FileCheck %s
+
+.global foo
+foo:
+nop
+
+.data
+.global bar1
+bar1:
+.quad foo
+
+// CHECK: Name: .text
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 1
diff --git a/test/ELF/global_offset_table_shared.s b/test/ELF/global_offset_table_shared.s
new file mode 100644
index 000000000000..7935925ae2b3
--- /dev/null
+++ b/test/ELF/global_offset_table_shared.s
@@ -0,0 +1,9 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+// RUN: ld.lld -shared %t -o %t2
+// RUN: llvm-readobj -t %t2 | FileCheck %s
+.long _GLOBAL_OFFSET_TABLE_
+
+// CHECK: Name: _GLOBAL_OFFSET_TABLE_
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
diff --git a/test/ELF/gnu-ifunc-gotpcrel.s b/test/ELF/gnu-ifunc-gotpcrel.s
new file mode 100644
index 000000000000..08aa0af37a1b
--- /dev/null
+++ b/test/ELF/gnu-ifunc-gotpcrel.s
@@ -0,0 +1,14 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-gotpcrel.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -o %t2.so
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o %t2.so -o %t
+# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
+
+# CHECK: Dynamic Relocations {
+# CHECK-NEXT: 0x120B0 R_X86_64_GLOB_DAT foo 0x0
+# CHECK-NEXT: }
+
+.globl _start
+_start:
+mov foo@gotpcrel(%rip), %rax
diff --git a/test/ELF/gnu-ifunc-i386.s b/test/ELF/gnu-ifunc-i386.s
index 6dcdf256d70c..bc2d0f9610b3 100644
--- a/test/ELF/gnu-ifunc-i386.s
+++ b/test/ELF/gnu-ifunc-i386.s
@@ -1,7 +1,7 @@
// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
// RUN: ld.lld -static %t.o -o %tout
// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
-// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s --check-prefix=CHECK
+// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
// REQUIRES: x86
// CHECK: Sections [
@@ -43,8 +43,10 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
-// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .rel.plt
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: __rel_iplt_start
@@ -52,8 +54,10 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
-// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .rel.plt
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: _start
@@ -112,13 +116,11 @@
.text
.type foo STT_GNU_IFUNC
.globl foo
-.type foo, @function
foo:
ret
.type bar STT_GNU_IFUNC
.globl bar
-.type bar, @function
bar:
ret
diff --git a/test/ELF/gnu-ifunc-nosym-i386.s b/test/ELF/gnu-ifunc-nosym-i386.s
index 1101b6d763d5..d22cedbfe6de 100644
--- a/test/ELF/gnu-ifunc-nosym-i386.s
+++ b/test/ELF/gnu-ifunc-nosym-i386.s
@@ -6,20 +6,18 @@
// Check that no __rel_iplt_end/__rel_iplt_start
// appear in symtab if there is no references to them.
// CHECK: Symbols [
-// CHECK-NEXT-NOT: __rel_iplt_end
-// CHECK-NEXT-NOT: __rel_iplt_start
+// CHECK-NOT: __rel_iplt_end
+// CHECK-NOT: __rel_iplt_start
// CHECK: ]
.text
.type foo STT_GNU_IFUNC
.globl foo
-.type foo, @function
foo:
ret
.type bar STT_GNU_IFUNC
.globl bar
-.type bar, @function
bar:
ret
diff --git a/test/ELF/gnu-ifunc-nosym.s b/test/ELF/gnu-ifunc-nosym.s
index c97fd749c02b..08e498e97c19 100644
--- a/test/ELF/gnu-ifunc-nosym.s
+++ b/test/ELF/gnu-ifunc-nosym.s
@@ -6,20 +6,18 @@
// Check that no __rela_iplt_end/__rela_iplt_start
// appear in symtab if there is no references to them.
// CHECK: Symbols [
-// CHECK-NEXT-NOT: __rela_iplt_end
-// CHECK-NEXT-NOT: __rela_iplt_start
+// CHECK-NOT: __rela_iplt_end
+// CHECK-NOT: __rela_iplt_start
// CHECK: ]
.text
.type foo STT_GNU_IFUNC
.globl foo
-.type foo, @function
foo:
ret
.type bar STT_GNU_IFUNC
.globl bar
-.type bar, @function
bar:
ret
diff --git a/test/ELF/gnu-ifunc-relative.s b/test/ELF/gnu-ifunc-relative.s
new file mode 100644
index 000000000000..dc35102c5787
--- /dev/null
+++ b/test/ELF/gnu-ifunc-relative.s
@@ -0,0 +1,23 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld -static %t.o -o %tout
+// RUN: llvm-readobj -r -t %tout | FileCheck %s
+// REQUIRES: x86
+
+.type foo STT_GNU_IFUNC
+.globl foo
+foo:
+ ret
+
+.globl _start
+_start:
+ call foo
+
+// CHECK: Section ({{.*}}) .rela.plt {
+// CHECK-NEXT: R_X86_64_IRELATIVE - 0x[[ADDR:.*]]
+// CHECK-NEXT: }
+
+// CHECK: Name: foo
+// CHECK-NEXT: Value: 0x[[ADDR]]
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: GNU_IFunc
diff --git a/test/ELF/gnu-ifunc.s b/test/ELF/gnu-ifunc.s
index b04f2758e22c..5336c89a563b 100644
--- a/test/ELF/gnu-ifunc.s
+++ b/test/ELF/gnu-ifunc.s
@@ -1,7 +1,7 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: ld.lld -static %t.o -o %tout
// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
-// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s --check-prefix=CHECK
+// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
// REQUIRES: x86
// CHECK: Sections [
@@ -42,8 +42,10 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
-// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .rela.plt
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: __rela_iplt_start
@@ -51,8 +53,10 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
-// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .rela.plt
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: _start
@@ -93,6 +97,7 @@
// DISASM-NEXT: 11007: e8 34 00 00 00 callq 52
// DISASM-NEXT: 1100c: ba 58 01 01 00 movl $65880, %edx
// DISASM-NEXT: 11011: ba 88 01 01 00 movl $65928, %edx
+// DISASM-NEXT: 11016: ba 89 01 01 00 movl $65929, %edx
// DISASM-NEXT: Disassembly of section .plt:
// DISASM-NEXT: .plt:
// DISASM-NEXT: 11020: ff 35 e2 0f 00 00 pushq 4066(%rip)
@@ -108,13 +113,11 @@
.text
.type foo STT_GNU_IFUNC
.globl foo
-.type foo, @function
foo:
ret
.type bar STT_GNU_IFUNC
.globl bar
-.type bar, @function
bar:
ret
@@ -124,3 +127,4 @@ _start:
call bar
movl $__rela_iplt_start,%edx
movl $__rela_iplt_end,%edx
+ movl $__rela_iplt_end + 1,%edx
diff --git a/test/ELF/gnu-unique.s b/test/ELF/gnu-unique.s
index f7206cf8c97f..afc0da27063d 100644
--- a/test/ELF/gnu-unique.s
+++ b/test/ELF/gnu-unique.s
@@ -1,7 +1,11 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+//
// RUN: ld.lld %t -shared -o %tout.so
-// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck %s
-// REQUIRES: x86
+// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=GNU %s
+//
+// RUN: ld.lld %t -shared -o %tout.so --no-gnu-unique
+// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=NO %s
// Check that STB_GNU_UNIQUE is treated as a global and ends up in the dynamic
// symbol table as STB_GNU_UNIQUE.
@@ -14,11 +18,20 @@ _start:
.type symb, @gnu_unique_object
symb:
-# CHECK: Name: symb@
-# CHECK-NEXT: Value:
-# CHECK-NEXT: Size: 0
-# CHECK-NEXT: Binding: Unique
-# CHECK-NEXT: Type: Object
-# CHECK-NEXT: Other: 0
-# CHECK-NEXT: Section: .data
-# CHECK-NEXT: }
+# GNU: Name: symb@
+# GNU-NEXT: Value:
+# GNU-NEXT: Size: 0
+# GNU-NEXT: Binding: Unique
+# GNU-NEXT: Type: Object
+# GNU-NEXT: Other: 0
+# GNU-NEXT: Section: .data
+# GNU-NEXT: }
+
+# NO: Name: symb@
+# NO-NEXT: Value:
+# NO-NEXT: Size: 0
+# NO-NEXT: Binding: Global
+# NO-NEXT: Type: Object
+# NO-NEXT: Other: 0
+# NO-NEXT: Section: .data
+# NO-NEXT: }
diff --git a/test/ELF/got-plt-header.s b/test/ELF/got-plt-header.s
new file mode 100644
index 000000000000..691516d1a348
--- /dev/null
+++ b/test/ELF/got-plt-header.s
@@ -0,0 +1,30 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
+
+ call foo@plt
+
+// Check that the first .got.plt entry has the address of the dynamic table.
+
+// CHECK: Type: SHT_DYNAMIC
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x2000
+
+// CHECK: Name: .got.plt
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x3000
+// CHECK-NEXT: Offset: 0x3000
+// CHECK-NEXT: Size: 32
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 8
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 00200000 00000000 00000000 00000000
diff --git a/test/ELF/gotpc-relax-nopic.s b/test/ELF/gotpc-relax-nopic.s
new file mode 100644
index 000000000000..278173557837
--- /dev/null
+++ b/test/ELF/gotpc-relax-nopic.s
@@ -0,0 +1,81 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t1
+# RUN: llvm-readobj -symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s
+# RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
+
+## There is no relocations.
+# SYMRELOC: Relocations [
+# SYMRELOC-NEXT: ]
+# SYMRELOC: Symbols [
+# SYMRELOC: Symbol {
+# SYMRELOC: Name: bar
+# SYMRELOC-NEXT: Value: 0x12000
+
+## 73728 = 0x12000 (bar)
+# DISASM: Disassembly of section .text:
+# DISASM-NEXT: _start:
+# DISASM-NEXT: 11000: 48 81 d0 00 20 01 00 adcq $73728, %rax
+# DISASM-NEXT: 11007: 48 81 c3 00 20 01 00 addq $73728, %rbx
+# DISASM-NEXT: 1100e: 48 81 e1 00 20 01 00 andq $73728, %rcx
+# DISASM-NEXT: 11015: 48 81 fa 00 20 01 00 cmpq $73728, %rdx
+# DISASM-NEXT: 1101c: 48 81 cf 00 20 01 00 orq $73728, %rdi
+# DISASM-NEXT: 11023: 48 81 de 00 20 01 00 sbbq $73728, %rsi
+# DISASM-NEXT: 1102a: 48 81 ed 00 20 01 00 subq $73728, %rbp
+# DISASM-NEXT: 11031: 49 81 f0 00 20 01 00 xorq $73728, %r8
+# DISASM-NEXT: 11038: 49 f7 c7 00 20 01 00 testq $73728, %r15
+
+# RUN: ld.lld -shared %t.o -o %t2
+# RUN: llvm-readobj -s %t2 | FileCheck --check-prefix=SEC-PIC %s
+# RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM-PIC %s
+# SEC-PIC: Section {
+# SEC-PIC: Index:
+# SEC-PIC: Name: .got
+# SEC-PIC-NEXT: Type: SHT_PROGBITS
+# SEC-PIC-NEXT: Flags [
+# SEC-PIC-NEXT: SHF_ALLOC
+# SEC-PIC-NEXT: SHF_WRITE
+# SEC-PIC-NEXT: ]
+# SEC-PIC-NEXT: Address: 0x2090
+# SEC-PIC-NEXT: Offset: 0x2090
+# SEC-PIC-NEXT: Size: 8
+# SEC-PIC-NEXT: Link:
+# SEC-PIC-NEXT: Info:
+# SEC-PIC-NEXT: AddressAlignment:
+# SEC-PIC-NEXT: EntrySize:
+# SEC-PIC-NEXT: }
+
+## Check that there was no relaxation performed. All values refer to got entry.
+## Ex: 0x1000 + 4233 + 7 = 0x2090
+## 0x102a + 4191 + 7 = 0x2090
+# DISASM-PIC: Disassembly of section .text:
+# DISASM-PIC-NEXT: _start:
+# DISASM-PIC-NEXT: 1000: 48 13 05 89 10 00 00 adcq 4233(%rip), %rax
+# DISASM-PIC-NEXT: 1007: 48 03 1d 82 10 00 00 addq 4226(%rip), %rbx
+# DISASM-PIC-NEXT: 100e: 48 23 0d 7b 10 00 00 andq 4219(%rip), %rcx
+# DISASM-PIC-NEXT: 1015: 48 3b 15 74 10 00 00 cmpq 4212(%rip), %rdx
+# DISASM-PIC-NEXT: 101c: 48 0b 3d 6d 10 00 00 orq 4205(%rip), %rdi
+# DISASM-PIC-NEXT: 1023: 48 1b 35 66 10 00 00 sbbq 4198(%rip), %rsi
+# DISASM-PIC-NEXT: 102a: 48 2b 2d 5f 10 00 00 subq 4191(%rip), %rbp
+# DISASM-PIC-NEXT: 1031: 4c 33 05 58 10 00 00 xorq 4184(%rip), %r8
+# DISASM-PIC-NEXT: 1038: 4c 85 3d 51 10 00 00 testq 4177(%rip), %r15
+
+.data
+.type bar, @object
+bar:
+ .byte 1
+ .size bar, .-bar
+
+.text
+.globl _start
+.type _start, @function
+_start:
+ adcq bar@GOTPCREL(%rip), %rax
+ addq bar@GOTPCREL(%rip), %rbx
+ andq bar@GOTPCREL(%rip), %rcx
+ cmpq bar@GOTPCREL(%rip), %rdx
+ orq bar@GOTPCREL(%rip), %rdi
+ sbbq bar@GOTPCREL(%rip), %rsi
+ subq bar@GOTPCREL(%rip), %rbp
+ xorq bar@GOTPCREL(%rip), %r8
+ testq %r15, bar@GOTPCREL(%rip)
diff --git a/test/ELF/gotpc-relax-und-dso.s b/test/ELF/gotpc-relax-und-dso.s
new file mode 100644
index 000000000000..ed6c4bc9bb15
--- /dev/null
+++ b/test/ELF/gotpc-relax-und-dso.s
@@ -0,0 +1,72 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %S/Inputs/gotpc-relax-und-dso.s -o %tdso.o
+# RUN: ld.lld -shared %tdso.o -o %t.so
+# RUN: ld.lld -shared %t.o %t.so -o %tout
+# RUN: llvm-readobj -r -s %tout | FileCheck --check-prefix=RELOC %s
+# RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s
+
+# RELOC: Relocations [
+# RELOC-NEXT: Section ({{.*}}) .rela.dyn {
+# RELOC-NEXT: R_X86_64_GLOB_DAT dsofoo 0x0
+# RELOC-NEXT: R_X86_64_GLOB_DAT foo 0x0
+# RELOC-NEXT: R_X86_64_GLOB_DAT und 0x0
+# RELOC-NEXT: }
+# RELOC-NEXT: ]
+
+# 0x101e + 7 - 36 = 0x1001
+# 0x1025 + 7 - 43 = 0x1001
+# DISASM: Disassembly of section .text:
+# DISASM-NEXT: foo:
+# DISASM-NEXT: nop
+# DISASM: hid:
+# DISASM-NEXT: nop
+# DISASM: _start:
+# DISASM-NEXT: movq 4247(%rip), %rax
+# DISASM-NEXT: movq 4240(%rip), %rax
+# DISASM-NEXT: movq 4241(%rip), %rax
+# DISASM-NEXT: movq 4234(%rip), %rax
+# DISASM-NEXT: leaq -36(%rip), %rax
+# DISASM-NEXT: leaq -43(%rip), %rax
+# DISASM-NEXT: movq 4221(%rip), %rax
+# DISASM-NEXT: movq 4214(%rip), %rax
+# DISASM-NEXT: movq 4191(%rip), %rax
+# DISASM-NEXT: movq 4184(%rip), %rax
+# DISASM-NEXT: movq 4185(%rip), %rax
+# DISASM-NEXT: movq 4178(%rip), %rax
+# DISASM-NEXT: leaq -92(%rip), %rax
+# DISASM-NEXT: leaq -99(%rip), %rax
+# DISASM-NEXT: movq 4165(%rip), %rax
+# DISASM-NEXT: movq 4158(%rip), %rax
+
+.text
+.globl foo
+.type foo, @function
+foo:
+ nop
+
+.globl hid
+.hidden hid
+.type hid, @function
+hid:
+ nop
+
+.globl _start
+.type _start, @function
+_start:
+ movq und@GOTPCREL(%rip), %rax
+ movq und@GOTPCREL(%rip), %rax
+ movq dsofoo@GOTPCREL(%rip), %rax
+ movq dsofoo@GOTPCREL(%rip), %rax
+ movq hid@GOTPCREL(%rip), %rax
+ movq hid@GOTPCREL(%rip), %rax
+ movq foo@GOTPCREL(%rip), %rax
+ movq foo@GOTPCREL(%rip), %rax
+ movq und@GOTPCREL(%rip), %rax
+ movq und@GOTPCREL(%rip), %rax
+ movq dsofoo@GOTPCREL(%rip), %rax
+ movq dsofoo@GOTPCREL(%rip), %rax
+ movq hid@GOTPCREL(%rip), %rax
+ movq hid@GOTPCREL(%rip), %rax
+ movq foo@GOTPCREL(%rip), %rax
+ movq foo@GOTPCREL(%rip), %rax
diff --git a/test/ELF/gotpc-relax.s b/test/ELF/gotpc-relax.s
new file mode 100644
index 000000000000..422e10439d00
--- /dev/null
+++ b/test/ELF/gotpc-relax.s
@@ -0,0 +1,98 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t1
+# RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOC %s
+# RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
+
+## There is no relocations.
+# RELOC: Relocations [
+# RELOC: ]
+
+# 0x11003 + 7 - 10 = 0x11000
+# 0x1100a + 7 - 17 = 0x11000
+# 0x11011 + 7 - 23 = 0x11001
+# 0x11018 + 7 - 30 = 0x11001
+# DISASM: Disassembly of section .text:
+# DISASM-NEXT: foo:
+# DISASM-NEXT: 11000: 90 nop
+# DISASM: hid:
+# DISASM-NEXT: 11001: 90 nop
+# DISASM: ifunc:
+# DISASM-NEXT: 11002: c3 retq
+# DISASM: _start:
+# DISASM-NEXT: leaq -10(%rip), %rax
+# DISASM-NEXT: leaq -17(%rip), %rax
+# DISASM-NEXT: leaq -23(%rip), %rax
+# DISASM-NEXT: leaq -30(%rip), %rax
+# DISASM-NEXT: movq 4058(%rip), %rax
+# DISASM-NEXT: movq 4051(%rip), %rax
+# DISASM-NEXT: leaq -52(%rip), %rax
+# DISASM-NEXT: leaq -59(%rip), %rax
+# DISASM-NEXT: leaq -65(%rip), %rax
+# DISASM-NEXT: leaq -72(%rip), %rax
+# DISASM-NEXT: movq 4016(%rip), %rax
+# DISASM-NEXT: movq 4009(%rip), %rax
+# DISASM-NEXT: callq -93 <foo>
+# DISASM-NEXT: callq -99 <foo>
+# DISASM-NEXT: callq -104 <hid>
+# DISASM-NEXT: callq -110 <hid>
+# DISASM-NEXT: callq *3979(%rip)
+# DISASM-NEXT: callq *3973(%rip)
+# DISASM-NEXT: jmp -128 <foo>
+# DISASM-NEXT: nop
+# DISASM-NEXT: jmp -134 <foo>
+# DISASM-NEXT: nop
+# DISASM-NEXT: jmp -139 <hid>
+# DISASM-NEXT: nop
+# DISASM-NEXT: jmp -145 <hid>
+# DISASM-NEXT: nop
+# DISASM-NEXT: jmpq *3943(%rip)
+# DISASM-NEXT: jmpq *3937(%rip)
+
+.text
+.globl foo
+.type foo, @function
+foo:
+ nop
+
+.globl hid
+.hidden hid
+.type hid, @function
+hid:
+ nop
+
+.text
+.type ifunc STT_GNU_IFUNC
+.globl ifunc
+.type ifunc, @function
+ifunc:
+ ret
+
+.globl _start
+.type _start, @function
+_start:
+ movq foo@GOTPCREL(%rip), %rax
+ movq foo@GOTPCREL(%rip), %rax
+ movq hid@GOTPCREL(%rip), %rax
+ movq hid@GOTPCREL(%rip), %rax
+ movq ifunc@GOTPCREL(%rip), %rax
+ movq ifunc@GOTPCREL(%rip), %rax
+ movq foo@GOTPCREL(%rip), %rax
+ movq foo@GOTPCREL(%rip), %rax
+ movq hid@GOTPCREL(%rip), %rax
+ movq hid@GOTPCREL(%rip), %rax
+ movq ifunc@GOTPCREL(%rip), %rax
+ movq ifunc@GOTPCREL(%rip), %rax
+
+ call *foo@GOTPCREL(%rip)
+ call *foo@GOTPCREL(%rip)
+ call *hid@GOTPCREL(%rip)
+ call *hid@GOTPCREL(%rip)
+ call *ifunc@GOTPCREL(%rip)
+ call *ifunc@GOTPCREL(%rip)
+ jmp *foo@GOTPCREL(%rip)
+ jmp *foo@GOTPCREL(%rip)
+ jmp *hid@GOTPCREL(%rip)
+ jmp *hid@GOTPCREL(%rip)
+ jmp *ifunc@GOTPCREL(%rip)
+ jmp *ifunc@GOTPCREL(%rip)
diff --git a/test/ELF/gotpcrelx.s b/test/ELF/gotpcrelx.s
new file mode 100644
index 000000000000..95dbf663ffe8
--- /dev/null
+++ b/test/ELF/gotpcrelx.s
@@ -0,0 +1,30 @@
+// RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux-gnu \
+// RUN: %s -o %t.o
+// RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELS %s
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -s -r %t.so | FileCheck %s
+
+movq foo@GOTPCREL(%rip), %rax
+movq bar@GOTPCREL(%rip), %rax
+
+// RELS: Relocations [
+// RELS-NEXT: Section ({{.*}}) .rela.text {
+// RELS-NEXT: R_X86_64_REX_GOTPCRELX foo 0xFFFFFFFFFFFFFFFC
+// RELS-NEXT: R_X86_64_REX_GOTPCRELX bar 0xFFFFFFFFFFFFFFFC
+// RELS-NEXT: }
+// RELS-NEXT: ]
+
+// CHECK: Name: .got
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x2090
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT: 0x2098 R_X86_64_GLOB_DAT bar 0x0
+// CHECK-NEXT: 0x2090 R_X86_64_GLOB_DAT foo 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/i386-got-and-copy.s b/test/ELF/i386-got-and-copy.s
new file mode 100644
index 000000000000..f5b0b8ec5bb8
--- /dev/null
+++ b/test/ELF/i386-got-and-copy.s
@@ -0,0 +1,25 @@
+# REQUIRES: x86
+
+# If there are two relocations such that the first one requires
+# dynamic COPY relocation, the second one requires GOT entry
+# creation, linker should create both - dynamic relocation
+# and GOT entry.
+
+# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux \
+# RUN: %S/Inputs/copy-in-shared.s -o %t.so.o
+# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
+# RUN: ld.lld %t.so.o -shared -o %t.so
+# RUN: ld.lld %t.o %t.so -o %t.exe
+# RUN: llvm-readobj -r %t.exe | FileCheck %s
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section (4) .rel.dyn {
+# CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_COPY foo
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+ .text
+ .global _start
+_start:
+ movl $foo, (%esp) # R_386_32 - requires R_386_COPY relocation
+ movl foo@GOT, %eax # R_386_GOT32 - requires GOT entry
diff --git a/test/ELF/i386-gotpc.s b/test/ELF/i386-gotpc.s
new file mode 100644
index 000000000000..14c2fcbec064
--- /dev/null
+++ b/test/ELF/i386-gotpc.s
@@ -0,0 +1,20 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -s %t.so | FileCheck %s
+// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s
+
+movl $_GLOBAL_OFFSET_TABLE_, %eax
+
+// CHECK: Name: .got (38)
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x2030
+
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: .text:
+// DISASM-NEXT: 1000: {{.*}} movl $4144, %eax
+// 0x2030 - 0x1000 = 4144
diff --git a/test/ELF/i386-merge.s b/test/ELF/i386-merge.s
new file mode 100644
index 000000000000..5d48d4d07f08
--- /dev/null
+++ b/test/ELF/i386-merge.s
@@ -0,0 +1,50 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t -shared
+// RUN: llvm-readobj -s -section-data %t | FileCheck %s
+
+// CHECK: Name: .mysec
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_MERGE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x114
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment:
+// CHECK-NEXT: EntrySize:
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 42000000 |
+// CHECK-NEXT: )
+
+
+// CHECK: Name: .data
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x2000
+// CHECK-NEXT: Offset: 0x2000
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 14010000 |
+// CHECK-NEXT: )
+
+// The content of .data should be the address of .mysec. 14010000 is 0x114 in
+// little endian.
+
+ .data
+ .long .mysec+4
+
+ .section .mysec,"aM",@progbits,4
+ .align 4
+ .long 0x42
+ .long 0x42
diff --git a/test/ELF/i386-relative.s b/test/ELF/i386-relative.s
new file mode 100644
index 000000000000..d814b5b6786a
--- /dev/null
+++ b/test/ELF/i386-relative.s
@@ -0,0 +1,14 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t.so
+// RUN: llvm-readobj -r %t.so | FileCheck %s
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rel.dyn {
+// CHECK-NEXT: R_386_RELATIVE - 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+ .data
+foo:
+ .long foo
diff --git a/test/ELF/i386-relax-reloc.s b/test/ELF/i386-relax-reloc.s
new file mode 100644
index 000000000000..a7fdc404ceca
--- /dev/null
+++ b/test/ELF/i386-relax-reloc.s
@@ -0,0 +1,12 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o -relax-relocations
+// RUN: ld.lld -shared %t.o -o %t.so
+// RUN: llvm-objdump -d %t.so | FileCheck %s
+
+foo:
+ movl bar@GOT(%ebx), %eax
+ movl bar+8@GOT(%ebx), %eax
+
+// CHECK: foo:
+// CHECK-NEXT: movl -4(%ebx), %eax
+// CHECK-NEXT: movl 4(%ebx), %eax
diff --git a/test/ELF/i386-tls-ie-shared.s b/test/ELF/i386-tls-ie-shared.s
new file mode 100644
index 000000000000..a2c25e2d2f81
--- /dev/null
+++ b/test/ELF/i386-tls-ie-shared.s
@@ -0,0 +1,110 @@
+// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o
+// RUN: ld.lld -shared %tso.o -o %tso
+// RUN: ld.lld -shared %t.o %tso -o %t1
+// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTRELSHARED %s
+// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s
+
+// GOTRELSHARED: Section {
+// GOTRELSHARED: Index: 8
+// GOTRELSHARED: Name: .got
+// GOTRELSHARED-NEXT: Type: SHT_PROGBITS
+// GOTRELSHARED-NEXT: Flags [
+// GOTRELSHARED-NEXT: SHF_ALLOC
+// GOTRELSHARED-NEXT: SHF_WRITE
+// GOTRELSHARED-NEXT: ]
+// GOTRELSHARED-NEXT: Address: 0x1050
+// GOTRELSHARED-NEXT: Offset: 0x1050
+// GOTRELSHARED-NEXT: Size: 16
+// GOTRELSHARED-NEXT: Link: 0
+// GOTRELSHARED-NEXT: Info: 0
+// GOTRELSHARED-NEXT: AddressAlignment: 4
+// GOTRELSHARED-NEXT: EntrySize: 0
+// GOTRELSHARED-NEXT: }
+// GOTRELSHARED: Relocations [
+// GOTRELSHARED-NEXT: Section ({{.*}}) .rel.dyn {
+// GOTRELSHARED-NEXT: 0x2002 R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x200A R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x2013 R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x201C R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x2024 R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x202D R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x2036 R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x203F R_386_RELATIVE - 0x0
+// GOTRELSHARED-NEXT: 0x1050 R_386_TLS_TPOFF tlslocal0 0x0
+// GOTRELSHARED-NEXT: 0x1054 R_386_TLS_TPOFF tlslocal1 0x0
+// GOTRELSHARED-NEXT: 0x1058 R_386_TLS_TPOFF tlsshared0 0x0
+// GOTRELSHARED-NEXT: 0x105C R_386_TLS_TPOFF tlsshared1 0x0
+// GOTRELSHARED-NEXT: }
+// GOTRELSHARED-NEXT: ]
+
+// DISASMSHARED: Disassembly of section test:
+// DISASMSHARED-NEXT: _start:
+// (.got)[0] = 0x2050 = 8272
+// (.got)[1] = 0x2054 = 8276
+// (.got)[2] = 0x2058 = 8280
+// (.got)[3] = 0x205C = 8284
+// DISASMSHARED-NEXT: 2000: 8b 0d 50 10 00 00 movl 4176, %ecx
+// DISASMSHARED-NEXT: 2006: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 2009: a1 50 10 00 00 movl 4176, %eax
+// DISASMSHARED-NEXT: 200e: 65 8b 00 movl %gs:(%eax), %eax
+// DISASMSHARED-NEXT: 2011: 03 0d 50 10 00 00 addl 4176, %ecx
+// DISASMSHARED-NEXT: 2017: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 201a: 8b 0d 54 10 00 00 movl 4180, %ecx
+// DISASMSHARED-NEXT: 2020: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 2023: a1 54 10 00 00 movl 4180, %eax
+// DISASMSHARED-NEXT: 2028: 65 8b 00 movl %gs:(%eax), %eax
+// DISASMSHARED-NEXT: 202b: 03 0d 54 10 00 00 addl 4180, %ecx
+// DISASMSHARED-NEXT: 2031: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 2034: 8b 0d 58 10 00 00 movl 4184, %ecx
+// DISASMSHARED-NEXT: 203a: 65 8b 01 movl %gs:(%ecx), %eax
+// DISASMSHARED-NEXT: 203d: 03 0d 5c 10 00 00 addl 4188, %ecx
+// DISASMSHARED-NEXT: 2043: 65 8b 01 movl %gs:(%ecx), %eax
+
+.type tlslocal0,@object
+.section .tbss,"awT",@nobits
+.globl tlslocal0
+.align 4
+tlslocal0:
+ .long 0
+ .size tlslocal0, 4
+
+.type tlslocal1,@object
+.section .tbss,"awT",@nobits
+.globl tlslocal1
+.align 4
+tlslocal1:
+ .long 0
+ .size tlslocal1, 4
+
+.section .text
+.globl ___tls_get_addr
+.type ___tls_get_addr,@function
+___tls_get_addr:
+
+.section test, "axw"
+.globl _start
+_start:
+movl tlslocal0@indntpoff,%ecx
+movl %gs:(%ecx),%eax
+
+movl tlslocal0@indntpoff,%eax
+movl %gs:(%eax),%eax
+
+addl tlslocal0@indntpoff,%ecx
+movl %gs:(%ecx),%eax
+
+movl tlslocal1@indntpoff,%ecx
+movl %gs:(%ecx),%eax
+
+movl tlslocal1@indntpoff,%eax
+movl %gs:(%eax),%eax
+
+addl tlslocal1@indntpoff,%ecx
+movl %gs:(%ecx),%eax
+
+movl tlsshared0@indntpoff,%ecx
+movl %gs:(%ecx),%eax
+
+addl tlsshared1@indntpoff,%ecx
+movl %gs:(%ecx),%eax
diff --git a/test/ELF/icf1.s b/test/ELF/icf1.s
new file mode 100644
index 000000000000..bb060078476e
--- /dev/null
+++ b/test/ELF/icf1.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
+
+# CHECK: selected .text.f1
+# CHECK: removed .text.f2
+
+.globl _start, f1, f2
+_start:
+ ret
+
+.section .text.f1, "ax"
+f1:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
+
+.section .text.f2, "ax"
+f2:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
diff --git a/test/ELF/icf2.s b/test/ELF/icf2.s
new file mode 100644
index 000000000000..be595112b7e7
--- /dev/null
+++ b/test/ELF/icf2.s
@@ -0,0 +1,17 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2
+# RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose | FileCheck %s
+
+# CHECK: selected .text.f1
+# CHECK: removed .text.f2
+
+.globl _start, f1, f2
+_start:
+ ret
+
+.section .text.f1, "ax"
+f1:
+ mov $60, %rdi
+ call f2
diff --git a/test/ELF/icf3.s b/test/ELF/icf3.s
new file mode 100644
index 000000000000..9f39ff6c7477
--- /dev/null
+++ b/test/ELF/icf3.s
@@ -0,0 +1,19 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2
+# RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose | FileCheck %s
+
+# CHECK-NOT: Selected .text.f1
+# CHECK-NOT: Selected .text.f2
+
+.globl _start, f1, f2
+_start:
+ ret
+
+# This section is not mergeable because the content is different from f2.
+.section .text.f1, "ax"
+f1:
+ mov $60, %rdi
+ call f2
+ mov $0, %rax
diff --git a/test/ELF/icf4.s b/test/ELF/icf4.s
new file mode 100644
index 000000000000..ad16d48775d6
--- /dev/null
+++ b/test/ELF/icf4.s
@@ -0,0 +1,19 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t --icf=all --verbose | FileCheck %s
+
+# CHECK-NOT: Selected .text.f1
+# CHECK-NOT: Selected .text.f2
+
+.globl _start, f1, f2
+_start:
+ ret
+
+.section .text.f1, "ax"
+f1:
+ mov $1, %rax
+
+.section .text.f2, "ax"
+f2:
+ mov $0, %rax
diff --git a/test/ELF/icf5.s b/test/ELF/icf5.s
new file mode 100644
index 000000000000..cf466585c581
--- /dev/null
+++ b/test/ELF/icf5.s
@@ -0,0 +1,19 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t --icf=all --verbose | FileCheck %s
+
+# CHECK-NOT: Selected .text.f1
+# CHECK-NOT: Selected .text.f2
+
+.globl _start, f1, f2
+_start:
+ ret
+
+.section .text.f1, "ax"
+f1:
+ mov $0, %rax
+
+.section .text.f2, "awx"
+f2:
+ mov $0, %rax
diff --git a/test/ELF/icf6.s b/test/ELF/icf6.s
new file mode 100644
index 000000000000..ecb62fee2a0c
--- /dev/null
+++ b/test/ELF/icf6.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
+
+# CHECK-NOT: Selected .text.f1
+# CHECK-NOT: Selected .text.f2
+
+.globl _start, f1, f2
+_start:
+ ret
+
+.section .init, "ax"
+f1:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
+
+.section .fini, "ax"
+f2:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
diff --git a/test/ELF/icf7.s b/test/ELF/icf7.s
new file mode 100644
index 000000000000..f1fca5b2f2d5
--- /dev/null
+++ b/test/ELF/icf7.s
@@ -0,0 +1,29 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
+# RUN: llvm-objdump -t %t2 | FileCheck -check-prefix=ALIGN %s
+
+# CHECK: selected .text.f1
+# CHECK: removed .text.f2
+
+# ALIGN: 0000000000011000 .text 00000000 _start
+# ALIGN: 0000000000011100 .text 00000000 f1
+
+.globl _start, f1, f2
+_start:
+ ret
+
+.section .text.f1, "ax"
+ .align 1
+f1:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
+
+.section .text.f2, "ax"
+ .align 256
+f2:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
diff --git a/test/ELF/image-base.s b/test/ELF/image-base.s
new file mode 100644
index 000000000000..0be5059dcad8
--- /dev/null
+++ b/test/ELF/image-base.s
@@ -0,0 +1,60 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld -image-base=0x1000000 %t -o %t1
+# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
+
+.global _start
+_start:
+ nop
+
+# CHECK: ProgramHeaders [
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_PHDR (0x6)
+# CHECK-NEXT: Offset: 0x40
+# CHECK-NEXT: VirtualAddress: 0x1000040
+# CHECK-NEXT: PhysicalAddress: 0x1000040
+# CHECK-NEXT: FileSize: 224
+# CHECK-NEXT: MemSize: 224
+# CHECK-NEXT: Flags [ (0x4)
+# CHECK-NEXT: PF_R (0x4)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 8
+# CHECK-NEXT: }
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_LOAD (0x1)
+# CHECK-NEXT: Offset: 0x0
+# CHECK-NEXT: VirtualAddress: 0x1000000
+# CHECK-NEXT: PhysicalAddress: 0x1000000
+# CHECK-NEXT: FileSize: 288
+# CHECK-NEXT: MemSize: 288
+# CHECK-NEXT: Flags [ (0x4)
+# CHECK-NEXT: PF_R (0x4)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 4096
+# CHECK-NEXT: }
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_LOAD (0x1)
+# CHECK-NEXT: Offset: 0x1000
+# CHECK-NEXT: VirtualAddress: 0x1001000
+# CHECK-NEXT: PhysicalAddress: 0x1001000
+# CHECK-NEXT: FileSize: 1
+# CHECK-NEXT: MemSize: 1
+# CHECK-NEXT: Flags [ (0x5)
+# CHECK-NEXT: PF_R (0x4)
+# CHECK-NEXT: PF_X (0x1)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 4096
+# CHECK-NEXT: }
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
+# CHECK-NEXT: Offset: 0x0
+# CHECK-NEXT: VirtualAddress: 0x0
+# CHECK-NEXT: PhysicalAddress: 0x0
+# CHECK-NEXT: FileSize: 0
+# CHECK-NEXT: MemSize: 0
+# CHECK-NEXT: Flags [ (0x6)
+# CHECK-NEXT: PF_R (0x4)
+# CHECK-NEXT: PF_W (0x2)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 0
+# CHECK-NEXT: }
diff --git a/test/ELF/incompatible.s b/test/ELF/incompatible.s
index 1696d83de7ac..82055b7a104a 100644
--- a/test/ELF/incompatible.s
+++ b/test/ELF/incompatible.s
@@ -53,6 +53,7 @@
// ARCHIVE: a.o is incompatible with {{.*}}b.o
.global _start
_start:
+.data
.long foo
// REQUIRES: x86,aarch64
diff --git a/test/ELF/init-fini.s b/test/ELF/init-fini.s
index d2b24088d1e1..400679066636 100644
--- a/test/ELF/init-fini.s
+++ b/test/ELF/init-fini.s
@@ -35,7 +35,7 @@
// NOENTRY-NOT: FINI
// NOENTRY: ]
-.global _start,_init,_fini,_foo,_bar,_undef;
+.global _start,_init,_fini,_foo,_bar,_undef
_start:
_init = 0x11010
_fini = 0x11020
diff --git a/test/ELF/init_fini_priority.s b/test/ELF/init_fini_priority.s
new file mode 100644
index 000000000000..84e5dc35e9d2
--- /dev/null
+++ b/test/ELF/init_fini_priority.s
@@ -0,0 +1,37 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+// RUN: ld.lld %t -o %t.exe
+// RUN: llvm-objdump -s %t.exe | FileCheck %s
+// REQUIRES: x86
+
+.globl _start
+_start:
+ nop
+
+.section .init_array, "aw", @init_array
+ .align 8
+ .byte 1
+.section .init_array.100, "aw", @init_array
+ .long 2
+.section .init_array.5, "aw", @init_array
+ .byte 3
+.section .init_array, "aw", @init_array
+ .byte 4
+.section .init_array, "aw", @init_array
+ .byte 5
+
+.section .fini_array, "aw", @fini_array
+ .align 8
+ .byte 0x11
+.section .fini_array.100, "aw", @fini_array
+ .long 0x12
+.section .fini_array.5, "aw", @fini_array
+ .byte 0x13
+.section .fini_array, "aw", @fini_array
+ .byte 0x14
+.section .fini_array, "aw", @fini_array
+ .byte 0x15
+
+// CHECK: Contents of section .init_array:
+// CHECK-NEXT: 03020000 00000000 010405
+// CHECK: Contents of section .fini_array:
+// CHECK-NEXT: 13120000 00000000 111415
diff --git a/test/ELF/invalid-cie-length.s b/test/ELF/invalid-cie-length.s
index 36d1e03fb567..e9ad3ca8ba82 100644
--- a/test/ELF/invalid-cie-length.s
+++ b/test/ELF/invalid-cie-length.s
@@ -6,4 +6,4 @@
.section .eh_frame
.byte 0
-// CHECK: Truncated CIE/FDE length
+// CHECK: CIE/FDE too small
diff --git a/test/ELF/invalid-cie-length3.s b/test/ELF/invalid-cie-length3.s
index 8f3ab1cf29d0..665fc80a24b4 100644
--- a/test/ELF/invalid-cie-length3.s
+++ b/test/ELF/invalid-cie-length3.s
@@ -6,4 +6,4 @@
.section .eh_frame
.long 0xFFFFFFFC
-// CHECK: CIE/FIE size is too large
+// CHECK: CIE/FIE ends past the end of the section
diff --git a/test/ELF/invalid-cie-length4.s b/test/ELF/invalid-cie-length4.s
index 4a51ca1f812d..daa20d196811 100644
--- a/test/ELF/invalid-cie-length4.s
+++ b/test/ELF/invalid-cie-length4.s
@@ -7,4 +7,4 @@
.long 0xFFFFFFFF
.byte 0
-// CHECK: Truncated CIE/FDE length
+// CHECK: CIE/FDE too large
diff --git a/test/ELF/invalid-cie-length5.s b/test/ELF/invalid-cie-length5.s
index 14054a2dee84..bfa35edf7db5 100644
--- a/test/ELF/invalid-cie-length5.s
+++ b/test/ELF/invalid-cie-length5.s
@@ -7,4 +7,4 @@
.long 0xFFFFFFFF
.quad 0xFFFFFFFFFFFFFFF4
-// CHECK: CIE/FIE size is too large
+// CHECK: CIE/FDE too large
diff --git a/test/ELF/invalid-cie-reference.s b/test/ELF/invalid-cie-reference.s
index 1b099d19b7e1..fba2467e216a 100644
--- a/test/ELF/invalid-cie-reference.s
+++ b/test/ELF/invalid-cie-reference.s
@@ -29,4 +29,4 @@
.long 0x0
.long 0x0
-// CHECK: Invalid CIE reference
+// CHECK: invalid CIE reference
diff --git a/test/ELF/invalid-dynamic-list.test b/test/ELF/invalid-dynamic-list.test
new file mode 100644
index 000000000000..0e7c820f563e
--- /dev/null
+++ b/test/ELF/invalid-dynamic-list.test
@@ -0,0 +1,37 @@
+## Different "echo" commands on Windows interpret quoted strings and
+## wildcards in similar but different way (On Windows, ARGV tokenization
+## and wildcard expansion are not done by the shell but by each command.)
+## Because of that reason, this test fails on some Windows environment.
+## We can't write quoted strings that are interpreted the same way
+## by all echo commands. So, we don't want to run this on Windows.
+
+# REQUIRES: shell
+
+# RUN: mkdir -p %t.dir
+
+# RUN: echo foobar > %t1
+# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR1 %s
+# ERR1: line 1: { expected, but got foobar
+
+# RUN: echo "{ foobar;" > %t1
+# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR2 %s
+# ERR2: line 1: unexpected EOF
+
+## Missing ';' before '}'
+# RUN: echo "{ foobar }" > %t1
+# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR3 %s
+# ERR3: line 1: ; expected, but got }
+
+## Missing final ';'
+# RUN: echo "{ foobar; }" > %t1
+# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR4 %s
+# ERR4: line 1: unexpected EOF
+
+## Missing \" in foobar definition
+# RUN echo "{ \"foobar; };" > %t1
+# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR5 %s
+# ERR5: line 1: unexpected EOF
+
+# RUN: echo "{ extern \"BOGUS\" { test }; };" > %t1
+# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR6 %s
+# ERR6: line 1: ; expected, but got BOGUS
diff --git a/test/ELF/invalid-elf.test b/test/ELF/invalid-elf.test
index 05e95cab0d27..c3a97d37ffa9 100644
--- a/test/ELF/invalid-elf.test
+++ b/test/ELF/invalid-elf.test
@@ -2,26 +2,27 @@
# RUN: not ld.lld %t %p/Inputs/invalid-data-encoding.a -o %t2 2>&1 | \
# RUN: FileCheck --check-prefix=INVALID-DATA-ENC %s
-# INVALID-DATA-ENC: Invalid data encoding: test.o
+# INVALID-DATA-ENC: invalid data encoding: test.o
# RUN: not ld.lld %t %p/Inputs/invalid-file-class.a -o %t2 2>&1 | \
# RUN: FileCheck --check-prefix=INVALID-FILE-CLASS %s
-# INVALID-FILE-CLASS: Invalid file class: test.o
+# INVALID-FILE-CLASS: invalid file class: test.o
# RUN: not ld.lld %p/Inputs/invalid-symtab-sh_info.elf -o %t2 2>&1 | \
# RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s
-# INVALID-SYMTAB-SHINFO: Invalid sh_info in symbol table
+# INVALID-SYMTAB-SHINFO: invalid sh_info in symbol table
# RUN: not ld.lld %p/Inputs/invalid-binding.elf -o %t2 2>&1 | \
# RUN: FileCheck --check-prefix=INVALID-BINDING %s
# INVALID-BINDING: unexpected binding
# RUN: not ld.lld %p/Inputs/invalid-section-index.elf -o %t2 2>&1 | \
-# RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX %s
-# INVALID-SECTION-INDEX: Invalid section index
+# RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX-LLD %s
+# INVALID-SECTION-INDEX-LLD: invalid section index
# RUN: not ld.lld %p/Inputs/invalid-shstrndx.so -o %t2 2>&1 | \
# RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX %s
+# INVALID-SECTION-INDEX: Invalid section index
# RUN: not ld.lld %p/Inputs/invalid-shentsize-zero.elf -o %t2 2>&1 | \
# RUN: FileCheck --check-prefix=INVALID-SHENTSIZE-ZERO %s
@@ -29,6 +30,6 @@
# RUN: not ld.lld %p/Inputs/invalid-multiple-eh-relocs.elf -o %t2 2>&1 | \
# RUN: FileCheck --check-prefix=INVALID-EH-RELOCS %s
-# INVALID-EH-RELOCS: Multiple relocation sections to .eh_frame are not supported
+# INVALID-EH-RELOCS: multiple relocation sections to .eh_frame are not supported
.long foo
diff --git a/test/ELF/invalid-linkerscript.test b/test/ELF/invalid-linkerscript.test
new file mode 100644
index 000000000000..e0881662b962
--- /dev/null
+++ b/test/ELF/invalid-linkerscript.test
@@ -0,0 +1,54 @@
+## Different "echo" commands on Windows interpret quoted strings and
+## wildcards in similar but different way (On Windows, ARGV tokenization
+## and wildcard expansion are not done by the shell but by each command.)
+## Because of that reason, this test fails on some Windows environment.
+## We can't write quoted strings that are interpreted the same way
+## by all echo commands. So, we don't want to run this on Windows.
+
+# REQUIRES: shell
+
+# RUN: mkdir -p %t.dir
+
+## Note that we are using "cannot open no-such-file: " as a marker that the
+## linker keep going when it found an error. That specific error message is not
+## related to the linker script tests.
+
+# RUN: echo foobar > %t1
+# RUN: not ld.lld %t1 no-such-file 2>&1 | FileCheck -check-prefix=ERR1 %s
+# ERR1: unknown directive: foobar
+# ERR1: cannot open no-such-file:
+
+# RUN: echo "foo \"bar" > %t2
+# RUN: not ld.lld %t2 no-such-file 2>&1 | FileCheck -check-prefix=ERR2 %s
+# ERR2: unclosed quote
+# ERR2: cannot open no-such-file:
+
+# RUN: echo "/*" > %t3
+# RUN: not ld.lld %t3 no-such-file 2>&1 | FileCheck -check-prefix=ERR3 %s
+# ERR3: unclosed comment
+# ERR3: cannot open no-such-file:
+
+# RUN: echo "EXTERN (" > %t4
+# RUN: not ld.lld %t4 no-such-file 2>&1 | FileCheck -check-prefix=ERR4 %s
+# ERR4: unexpected EOF
+# ERR4: cannot open no-such-file:
+
+# RUN: echo "EXTERN (" > %t5
+# RUN: not ld.lld %t5 no-such-file 2>&1 | FileCheck -check-prefix=ERR5 %s
+# ERR5: unexpected EOF
+# ERR5: cannot open no-such-file:
+
+# RUN: echo "EXTERN xyz" > %t6
+# RUN: not ld.lld %t6 no-such-file 2>&1 | FileCheck -check-prefix=ERR6 %s
+# ERR6: ( expected, but got xyz
+# ERR6: cannot open no-such-file:
+
+# RUN: echo "INCLUDE /no/such/file" > %t7
+# RUN: not ld.lld %t7 no-such-file 2>&1 | FileCheck -check-prefix=ERR7 %s
+# ERR7: cannot open /no/such/file
+# ERR7: cannot open no-such-file:
+
+# RUN: echo "OUTPUT_FORMAT(x y z)" > %t8
+# RUN: not ld.lld %t8 no-such-file 2>&1 | FileCheck -check-prefix=ERR8 %s
+# ERR8: unexpected token: y
+# ERR8: cannot open no-such-file:
diff --git a/test/ELF/invalid-relocations.test b/test/ELF/invalid-relocations.test
index 2b4a6c4a4210..cfeb44b03c67 100644
--- a/test/ELF/invalid-relocations.test
+++ b/test/ELF/invalid-relocations.test
@@ -1,6 +1,7 @@
-# RUN: yaml2obj -format elf %s -o %t
+# RUN: yaml2obj %s -o %t
# RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s
+!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
@@ -19,4 +20,4 @@ Symbols:
Global:
- Name: lulz
-# CHECK: Invalid relocated section index
+# CHECK: invalid relocated section index
diff --git a/test/ELF/libsearch.s b/test/ELF/libsearch.s
index c965b9ba91fc..782d755f7341 100644
--- a/test/ELF/libsearch.s
+++ b/test/ELF/libsearch.s
@@ -23,7 +23,7 @@
// Should fail if cannot find specified library (without -L switch)
// RUN: not ld.lld -o %t3 %t.o -lls 2>&1 \
// RUN: | FileCheck --check-prefix=NOLIB %s
-// NOLIB: Unable to find library -lls
+// NOLIB: unable to find library -lls
// Should use explicitly specified static library
// Also ensure that we accept -L <arg>
@@ -44,6 +44,12 @@
// RUN: ld.lld -o %t3 %t.o -L%t.dir -lls
// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
+// Check for library search order
+// RUN: mkdir -p %t.dir2
+// RUN: cp %t.dir/libls.a %t.dir2
+// RUN: ld.lld -o %t3 %t.o -L%t.dir2 -L%t.dir -lls
+// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s
+
// -L can be placed after -l
// RUN: ld.lld -o %t3 %t.o -lls -L%t.dir
@@ -55,7 +61,7 @@
// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s
// RUN: not ld.lld -o %t3 %t.o -L%t.dir -Bstatic -lls2 2>&1 \
// RUN: | FileCheck --check-prefix=NOLIB2 %s
-// NOLIB2: Unable to find library -lls2
+// NOLIB2: unable to find library -lls2
// -Bdynamic should restore default behaviour
// RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -Bdynamic -lls
@@ -79,5 +85,5 @@
// RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -call_shared -lls
// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
-.globl _start,_bar;
+.globl _start,_bar
_start:
diff --git a/test/ELF/linkerscript-align.s b/test/ELF/linkerscript-align.s
new file mode 100644
index 000000000000..5f6e6f770766
--- /dev/null
+++ b/test/ELF/linkerscript-align.s
@@ -0,0 +1,41 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "SECTIONS { \
+# RUN: . = 0x10000; \
+# RUN: .aaa : \
+# RUN: { \
+# RUN: *(.aaa) \
+# RUN: } \
+# RUN: . = ALIGN(4096); \
+# RUN: .bbb : \
+# RUN: { \
+# RUN: *(.bbb) \
+# RUN: } \
+# RUN: . = ALIGN(4096 * 4); \
+# RUN: .ccc : \
+# RUN: { \
+# RUN: *(.ccc) \
+# RUN: } \
+# RUN: }" > %t.script
+# 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: 0 00000000 0000000000000000
+# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA
+# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA
+# CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA
+
+.global _start
+_start:
+ nop
+
+.section .aaa, "a"
+.quad 0
+
+.section .bbb, "a"
+.quad 0
+
+.section .ccc, "a"
+.quad 0
diff --git a/test/ELF/linkerscript-diagnostic.s b/test/ELF/linkerscript-diagnostic.s
new file mode 100644
index 000000000000..f42cbe82cf38
--- /dev/null
+++ b/test/ELF/linkerscript-diagnostic.s
@@ -0,0 +1,66 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+## Take some valid script with multiline comments
+## and check it actually works:
+# RUN: echo "SECTIONS {" > %t.script
+# RUN: echo ".text : { *(.text) }" >> %t.script
+# RUN: echo ".keep : { *(.keep) } /*" >> %t.script
+# RUN: echo "comment line 1" >> %t.script
+# RUN: echo "comment line 2 */" >> %t.script
+# RUN: echo ".temp : { *(.temp) } }" >> %t.script
+# RUN: ld.lld -shared %t -o %t1 --script %t.script
+
+## Change ":" to "+" at line 2, check that error
+## message starts from correct line number:
+# RUN: echo "SECTIONS {" > %t.script
+# RUN: echo ".text + { *(.text) }" >> %t.script
+# RUN: echo ".keep : { *(.keep) } /*" >> %t.script
+# RUN: echo "comment line 1" >> %t.script
+# RUN: echo "comment line 2 */" >> %t.script
+# RUN: echo ".temp : { *(.temp) } }" >> %t.script
+# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR1 %s
+# ERR1: line 2:
+
+## Change ":" to "+" at line 3 now, check correct error line number:
+# RUN: echo "SECTIONS {" > %t.script
+# RUN: echo ".text : { *(.text) }" >> %t.script
+# RUN: echo ".keep + { *(.keep) } /*" >> %t.script
+# RUN: echo "comment line 1" >> %t.script
+# RUN: echo "comment line 2 */" >> %t.script
+# RUN: echo ".temp : { *(.temp) } }" >> %t.script
+# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR2 %s
+# ERR2: line 3:
+
+## Change ":" to "+" at line 6, after multiline comment,
+## check correct error line number:
+# RUN: echo "SECTIONS {" > %t.script
+# RUN: echo ".text : { *(.text) }" >> %t.script
+# RUN: echo ".keep : { *(.keep) } /*" >> %t.script
+# RUN: echo "comment line 1" >> %t.script
+# RUN: echo "comment line 2 */" >> %t.script
+# RUN: echo ".temp + { *(.temp) } }" >> %t.script
+# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR5 %s
+# ERR5: line 6:
+
+## Check that text of lines and pointer to 'bad' token are working ok.
+# RUN: echo "UNKNOWN_TAG {" > %t.script
+# RUN: echo ".text : { *(.text) }" >> %t.script
+# RUN: echo ".keep : { *(.keep) }" >> %t.script
+# RUN: echo ".temp : { *(.temp) } }" >> %t.script
+# RUN: not ld.lld -shared %t -o %t1 --script %t.script > %t.log 2>&1
+# RUN: FileCheck -check-prefix=ERR6 %s < %t.log
+# ERR6: line 1:
+# ERR6-NEXT: UNKNOWN_TAG {
+# RUN: grep '^^' %t.log
+
+## One more check that text of lines and pointer to 'bad' token are working ok.
+# RUN: echo "SECTIONS {" > %t.script
+# RUN: echo ".text : { *(.text) }" >> %t.script
+# RUN: echo ".keep : { *(.keep) }" >> %t.script
+# RUN: echo "boom .temp : { *(.temp) } }" >> %t.script
+# RUN: not ld.lld -shared %t -o %t1 --script %t.script > %t.log 2>&1
+# RUN: FileCheck -check-prefix=ERR7 %s < %t.log
+# ERR7: line 4: : expected, but got .temp
+# ERR7-NEXT: boom .temp : { *(.temp) } }
+# RUN: grep '^ ^' %t.log
diff --git a/test/ELF/linkerscript-locationcounter.s b/test/ELF/linkerscript-locationcounter.s
new file mode 100644
index 000000000000..c6e8e7ef8ea8
--- /dev/null
+++ b/test/ELF/linkerscript-locationcounter.s
@@ -0,0 +1,340 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "SECTIONS { \
+# RUN: . = 0xFFF0; \
+# RUN: . = . + 0x10; \
+# RUN: .plus : { *(.plus) } \
+# RUN: . = 0x11010 - 0x10; \
+# RUN: .minus : { *(.minus) } \
+# RUN: . = 0x24000 / 0x2; \
+# RUN: .div : { *(.div) } \
+# RUN: . = 0x11000 + 0x1000 * 0x2; \
+# RUN: .mul : { *(.mul) } \
+# RUN: . = 0x10000 + (0x1000 + 0x1000) * 0x2; \
+# RUN: .bracket : { *(.bracket) } \
+# RUN: . = 0x17000 & 0x15000; \
+# RUN: .and : { *(.and) } \
+# RUN: . = 0x1 ? 0x16000 : 0x999999; \
+# RUN: .ternary1 : { *(.ternary1) } \
+# RUN: . = 0x0 ? 0x999999 : 0x17000; \
+# RUN: .ternary2 : { *(.ternary2) } \
+# RUN: . = 0x0 < 0x1 ? 0x18000 : 0x999999; \
+# RUN: .less : { *(.less) } \
+# RUN: . = 0x1 <= 0x1 ? 0x19000 : 0x999999; \
+# RUN: .lesseq : { *(.lesseq) } \
+# RUN: . = 0x1 > 0x0 ? 0x20000 : 0x999999; \
+# RUN: .great : { *(.great) } \
+# RUN: . = 0x1 >= 0x1 ? 0x21000 : 0x999999; \
+# RUN: .greateq : { *(.greateq) } \
+# RUN: . = 0x1 == 0x1 ? 0x22000 : 0x999999; \
+# RUN: .eq : { *(.eq) } \
+# RUN: . = 0x2 != 0x1 ? 0x23000 : 0x999999; \
+# RUN: .neq : { *(.neq) } \
+# RUN: }" > %t.script
+# RUN: ld.lld %t --script %t.script -o %t2
+# RUN: llvm-readobj -s %t2 | FileCheck %s
+
+# CHECK: Section {
+# CHECK: Index: 1
+# CHECK: Name: .plus
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x10000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 2
+# CHECK-NEXT: Name: .minus
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x11000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 3
+# CHECK-NEXT: Name: .div
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x12000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 4
+# CHECK-NEXT: Name: .mul
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x13000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 5
+# CHECK-NEXT: Name: .bracket
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x14000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index:
+# CHECK-NEXT: Name: .and
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x15000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index:
+# CHECK-NEXT: Name: .ternary1
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x16000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index:
+# CHECK-NEXT: Name: .ternary2
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x17000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index:
+# CHECK-NEXT: Name: .less
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x18000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index:
+# CHECK-NEXT: Name: .lesseq
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x19000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index:
+# CHECK-NEXT: Name: .great
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x20000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index:
+# CHECK-NEXT: Name: .greateq
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x21000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index:
+# CHECK-NEXT: Name: .eq
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x22000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index:
+# CHECK-NEXT: Name: .neq
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x23000
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: }
+
+## Mailformed number error.
+# RUN: echo "SECTIONS { \
+# RUN: . = 0x12Q41; \
+# RUN: }" > %t.script
+# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
+# RUN: FileCheck --check-prefix=NUMERR %s
+# NUMERR: malformed number: 0x12Q41
+
+## Missing closing bracket.
+# RUN: echo "SECTIONS { \
+# RUN: . = 0x10000 + (0x1000 + 0x1000 * 0x2; \
+# RUN: }" > %t.script
+# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
+# RUN: FileCheck --check-prefix=BRACKETERR %s
+# BRACKETERR: unexpected EOF
+
+## Missing opening bracket.
+# RUN: echo "SECTIONS { \
+# RUN: . = 0x10000 + 0x1000 + 0x1000) * 0x2; \
+# RUN: }" > %t.script
+# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
+# RUN: FileCheck --check-prefix=BRACKETERR2 %s
+# BRACKETERR2: stray token: )
+
+## Empty expression.
+# RUN: echo "SECTIONS { \
+# RUN: . = ; \
+# RUN: }" > %t.script
+# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
+# RUN: FileCheck --check-prefix=ERREXPR %s
+# ERREXPR: error in location counter expression
+
+## Div by zero error.
+# RUN: echo "SECTIONS { \
+# RUN: . = 0x10000 / 0x0; \
+# RUN: }" > %t.script
+# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
+# RUN: FileCheck --check-prefix=DIVZERO %s
+# DIVZERO: division by zero
+
+## Broken ternary operator expression.
+# RUN: echo "SECTIONS { \
+# RUN: . = 0x1 ? 0x2; \
+# RUN: }" > %t.script
+# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
+# RUN: FileCheck --check-prefix=TERNERR %s
+# TERNERR: unexpected EOF
+
+.globl _start
+_start:
+nop
+
+.section .plus, "a"
+.quad 0
+
+.section .minus, "a"
+.quad 0
+
+.section .div, "a"
+.quad 0
+
+.section .mul, "a"
+.quad 0
+
+.section .bracket, "a"
+.quad 0
+
+.section .and, "a"
+.quad 0
+
+.section .ternary1, "a"
+.quad 0
+
+.section .ternary2, "a"
+.quad 0
+
+.section .less, "a"
+.quad 0
+
+.section .lesseq, "a"
+.quad 0
+
+.section .great, "a"
+.quad 0
+
+.section .greateq, "a"
+.quad 0
+
+.section .eq, "a"
+.quad 0
+
+.section .neq, "a"
+.quad 0
diff --git a/test/ELF/linkerscript-orphans.s b/test/ELF/linkerscript-orphans.s
new file mode 100644
index 000000000000..fa7d30bf7f7c
--- /dev/null
+++ b/test/ELF/linkerscript-orphans.s
@@ -0,0 +1,31 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "SECTIONS { .writable : { *(.writable) } }" > %t.script
+# RUN: ld.lld -o %t.out --script %t.script %t
+# RUN: llvm-objdump -section-headers %t.out | \
+# RUN: FileCheck -check-prefix=TEXTORPHAN %s
+
+# RUN: echo "SECTIONS { .text : { *(.text) } }" > %t.script
+# RUN: ld.lld -o %t.out --script %t.script %t
+# RUN: llvm-objdump -section-headers %t.out | \
+# RUN: FileCheck -check-prefix=WRITABLEORPHAN %s
+
+# TEXTORPHAN: Sections:
+# TEXTORPHAN-NEXT: Idx Name
+# TEXTORPHAN-NEXT: 0
+# TEXTORPHAN-NEXT: 1 .writable
+# TEXTORPHAN-NEXT: 2 .text
+
+# WRITABLEORPHAN: Sections:
+# WRITABLEORPHAN-NEXT: Idx Name
+# WRITABLEORPHAN-NEXT: 0
+# WRITABLEORPHAN-NEXT: 1 .text
+# WRITABLEORPHAN-NEXT: 2 .writable
+
+.global _start
+_start:
+ nop
+
+.section .writable,"aw"
+ .zero 4
diff --git a/test/ELF/linkerscript-phdr-check.s b/test/ELF/linkerscript-phdr-check.s
new file mode 100644
index 000000000000..c7229ed3312c
--- /dev/null
+++ b/test/ELF/linkerscript-phdr-check.s
@@ -0,0 +1,15 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "SECTIONS { . = 0x10000000; .text : {*(.text.*)} }" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
+# CHECK: ProgramHeaders [
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_PHDR (0x6)
+# CHECK-NEXT: Offset: 0x40
+# CHECK-NEXT: VirtualAddress: 0xFFFF040
+
+.global _start
+_start:
+ nop
diff --git a/test/ELF/linkerscript-repsection-va.s b/test/ELF/linkerscript-repsection-va.s
new file mode 100644
index 000000000000..4feeaa0e1c38
--- /dev/null
+++ b/test/ELF/linkerscript-repsection-va.s
@@ -0,0 +1,24 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "SECTIONS {.foo : {*(.foo.*)} }" > %t.script
+# 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: 0 00000000 0000000000000000
+# CHECK-NEXT: 1 .foo 00000004 0000000000000158 DATA
+# CHECK-NEXT: 2 .foo 00000004 000000000000015c DATA
+# CHECK-NEXT: 3 .text 00000001 0000000000000160 TEXT DATA
+
+.global _start
+_start:
+ nop
+
+.section .foo.1,"a"
+foo1:
+ .long 0
+
+.section .foo.2,"aw"
+foo2:
+ .long 0
diff --git a/test/ELF/linkerscript-sections-keep.s b/test/ELF/linkerscript-sections-keep.s
new file mode 100644
index 000000000000..fae6383ca499
--- /dev/null
+++ b/test/ELF/linkerscript-sections-keep.s
@@ -0,0 +1,80 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+## First check that section "keep" is garbage collected without using KEEP
+# RUN: echo "SECTIONS { \
+# RUN: .text : { *(.text) } \
+# RUN: .keep : { *(.keep) } \
+# RUN: .temp : { *(.temp) }}" > %t.script
+# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t
+# RUN: llvm-objdump -section-headers %t1 | \
+# RUN: FileCheck -check-prefix=SECGC %s
+# SECGC: Sections:
+# SECGC-NEXT: Idx Name Size Address Type
+# SECGC-NEXT: 0 00000000 0000000000000000
+# SECGC-NEXT: 1 .text 00000007 0000000000000158 TEXT DATA
+# SECGC-NEXT: 2 .temp 00000004 000000000000015f DATA
+
+## Now apply KEEP command to preserve the section.
+# RUN: echo "SECTIONS { \
+# RUN: .text : { *(.text) } \
+# RUN: .keep : { KEEP(*(.keep)) } \
+# RUN: .temp : { *(.temp) }}" > %t.script
+# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t
+# RUN: llvm-objdump -section-headers %t1 | \
+# RUN: FileCheck -check-prefix=SECNOGC %s
+# SECNOGC: Sections:
+# SECNOGC-NEXT: Idx Name Size Address Type
+# SECNOGC-NEXT: 0 00000000 0000000000000000
+# SECNOGC-NEXT: 1 .text 00000007 0000000000000158 TEXT DATA
+# SECNOGC-NEXT: 2 .keep 00000004 000000000000015f DATA
+# SECNOGC-NEXT: 3 .temp 00000004 0000000000000163 DATA
+
+## A section name matches two entries in the SECTIONS directive. The
+## first one doesn't have KEEP, the second one does. If section that have
+## KEEP is the first in order then section is NOT collected.
+# RUN: echo "SECTIONS { \
+# RUN: .keep : { KEEP(*(.keep)) } \
+# RUN: .nokeep : { *(.keep) }}" > %t.script
+# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t
+# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=MIXED1 %s
+# MIXED1: Sections:
+# MIXED1-NEXT: Idx Name Size Address Type
+# MIXED1-NEXT: 0 00000000 0000000000000000
+# MIXED1-NEXT: 1 .keep 00000004 0000000000000120 DATA
+# MIXED1-NEXT: 2 .temp 00000004 0000000000000124 DATA
+# MIXED1-NEXT: 3 .text 00000007 0000000000000128 TEXT DATA
+# MIXED1-NEXT: 4 .symtab 00000060 0000000000000000
+# MIXED1-NEXT: 5 .shstrtab 0000002d 0000000000000000
+# MIXED1-NEXT: 6 .strtab 00000012 0000000000000000
+
+## The same, but now section without KEEP is at first place.
+## gold and bfd linkers disagree here. gold collects .keep while
+## bfd keeps it. Our current behavior is compatible with bfd although
+## we can choose either way.
+# RUN: echo "SECTIONS { \
+# RUN: .nokeep : { *(.keep) } \
+# RUN: .keep : { KEEP(*(.keep)) }}" > %t.script
+# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t
+# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=MIXED2 %s
+# MIXED2: Sections:
+# MIXED2-NEXT: Idx Name Size Address Type
+# MIXED2-NEXT: 0 00000000 0000000000000000
+# MIXED2-NEXT: 1 .nokeep 00000004 0000000000000120 DATA
+# MIXED2-NEXT: 2 .temp 00000004 0000000000000124 DATA
+# MIXED2-NEXT: 3 .text 00000007 0000000000000128 TEXT DATA
+# MIXED2-NEXT: 4 .symtab 00000060 0000000000000000
+# MIXED2-NEXT: 5 .shstrtab 0000002f 0000000000000000
+# MIXED2-NEXT: 6 .strtab 00000012 0000000000000000
+
+.global _start
+_start:
+ mov temp, %eax
+
+.section .keep, "a"
+keep:
+ .long 1
+
+.section .temp, "a"
+temp:
+ .long 2
diff --git a/test/ELF/linkerscript-sections-padding.s b/test/ELF/linkerscript-sections-padding.s
new file mode 100644
index 000000000000..545739efe5a8
--- /dev/null
+++ b/test/ELF/linkerscript-sections-padding.s
@@ -0,0 +1,44 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+## Check that padding value works:
+# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x112233445566778899 }" > %t.script
+# RUN: ld.lld -o %t.out --script %t.script %t
+# RUN: hexdump -C %t.out | FileCheck -check-prefix=YES %s
+# YES: 00000120 66 22 33 44 55 66 77 88 99 11 22 33 44 55 66 77
+
+## Confirming that address was correct:
+# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x998877665544332211 }" > %t.script
+# RUN: ld.lld -o %t.out --script %t.script %t
+# RUN: hexdump -C %t.out | FileCheck -check-prefix=YES2 %s
+# YES2: 00000120 66 88 77 66 55 44 33 22 11 99 88 77 66 55 44
+
+## Default padding value is 0x00:
+# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } }" > %t.script
+# RUN: ld.lld -o %t.out --script %t.script %t
+# RUN: hexdump -C %t.out | FileCheck -check-prefix=NO %s
+# NO: 00000120 66 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+## Filler should be a hex value (1):
+# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =99 }" > %t.script
+# RUN: not ld.lld -o %t.out --script %t.script %t 2>&1 \
+# RUN: | FileCheck --check-prefix=ERR %s
+# ERR: filler should be a hexadecimal value
+
+## Filler should be a hex value (2):
+# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99XX }" > %t.script
+# RUN: not ld.lld -o %t.out --script %t.script %t 2>&1 \
+# RUN: | FileCheck --check-prefix=ERR2 %s
+# ERR2: not a hexadecimal value: XX
+
+.section .mysec.1,"a"
+.align 16
+.byte 0x66
+
+.section .mysec.2,"a"
+.align 16
+.byte 0x66
+
+.globl _start
+_start:
+ nop
diff --git a/test/ELF/linkerscript-sections.s b/test/ELF/linkerscript-sections.s
index 165ec335ec13..b68dac765a77 100644
--- a/test/ELF/linkerscript-sections.s
+++ b/test/ELF/linkerscript-sections.s
@@ -22,7 +22,7 @@
# SEC-DEFAULT: 4 .bss 00000002 {{[0-9a-f]*}} BSS
# SEC-DEFAULT: 5 .shstrtab 00000002 {{[0-9a-f]*}}
# SEC-DEFAULT: 6 .symtab 00000030 {{[0-9a-f]*}}
-# SEC-DEFAULT: 7 .shstrtab 0000003c {{[0-9a-f]*}}
+# SEC-DEFAULT: 7 .shstrtab 00000032 {{[0-9a-f]*}}
# SEC-DEFAULT: 8 .strtab 00000008 {{[0-9a-f]*}}
# Sections are put in order specified in linker script.
@@ -42,7 +42,7 @@
# SEC-ORDER: 1 .bss 00000002 {{[0-9a-f]*}} BSS
# SEC-ORDER: 2 other 00000003 {{[0-9a-f]*}} DATA
# SEC-ORDER: 3 .shstrtab 00000002 {{[0-9a-f]*}}
-# SEC-ORDER: 4 .shstrtab 0000003c {{[0-9a-f]*}}
+# SEC-ORDER: 4 .shstrtab 00000032 {{[0-9a-f]*}}
# SEC-ORDER: 5 .symtab 00000030 {{[0-9a-f]*}}
# SEC-ORDER: 6 .strtab 00000008 {{[0-9a-f]*}}
# SEC-ORDER: 7 .data 00000020 {{[0-9a-f]*}} DATA
@@ -63,7 +63,7 @@
# SEC-SWAP-NAMES: 4 .bss 00000002 {{[0-9a-f]*}} BSS
# SEC-SWAP-NAMES: 5 .shstrtab 00000002 {{[0-9a-f]*}}
# SEC-SWAP-NAMES: 6 .symtab 00000030 {{[0-9a-f]*}}
-# SEC-SWAP-NAMES: 7 .shstrtab 0000003c {{[0-9a-f]*}}
+# SEC-SWAP-NAMES: 7 .shstrtab 00000032 {{[0-9a-f]*}}
# SEC-SWAP-NAMES: 8 .strtab 00000008 {{[0-9a-f]*}}
# .shstrtab from the input object file is discarded.
@@ -100,10 +100,10 @@
# SEC-MULTI: 3 .bss 00000002 {{[0-9a-f]*}} BSS
# SEC-MULTI: 4 .shstrtab 00000002 {{[0-9a-f]*}}
# SEC-MULTI: 5 .symtab 00000030 {{[0-9a-f]*}}
-# SEC-MULTI: 6 .shstrtab 00000036 {{[0-9a-f]*}}
+# SEC-MULTI: 6 .shstrtab 0000002c {{[0-9a-f]*}}
# SEC-MULTI: 7 .strtab 00000008 {{[0-9a-f]*}}
-.globl _start;
+.globl _start
_start:
mov $60, %rax
mov $42, %rdi
diff --git a/test/ELF/linkerscript-symbol-conflict.s b/test/ELF/linkerscript-symbol-conflict.s
new file mode 100644
index 000000000000..30186ed5cb87
--- /dev/null
+++ b/test/ELF/linkerscript-symbol-conflict.s
@@ -0,0 +1,11 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "SECTIONS {.text : {*(.text.*)} end = .;}" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-objdump -t %t1 | FileCheck %s
+# CHECK: 0000000000000121 *ABS* 00000000 end
+
+.global _start
+_start:
+ nop
diff --git a/test/ELF/linkerscript-symbols.s b/test/ELF/linkerscript-symbols.s
new file mode 100644
index 000000000000..1fcd4e8a8481
--- /dev/null
+++ b/test/ELF/linkerscript-symbols.s
@@ -0,0 +1,11 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "SECTIONS {.text : {*(.text.*)} text_end = .;}" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-objdump -t %t1 | FileCheck %s
+# CHECK: 0000000000000121 *ABS* 00000000 text_end
+
+.global _start
+_start:
+ nop
diff --git a/test/ELF/linkerscript-va.s b/test/ELF/linkerscript-va.s
new file mode 100644
index 000000000000..25d0bd2268c0
--- /dev/null
+++ b/test/ELF/linkerscript-va.s
@@ -0,0 +1,24 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "SECTIONS {}" > %t.script
+# 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: 0 00000000 0000000000000000
+# CHECK-NEXT: 1 .foo 00000004 0000000000000120 DATA
+# CHECK-NEXT: 2 .boo 00000004 0000000000000124 DATA
+# CHECK-NEXT: 3 .text 00000001 0000000000000128 TEXT DATA
+
+.global _start
+_start:
+ nop
+
+.section .foo, "a"
+foo:
+ .long 0
+
+.section .boo, "a"
+boo:
+ .long 0
diff --git a/test/ELF/linkerscript.s b/test/ELF/linkerscript.s
index bff285b97612..4ee7416a4b84 100644
--- a/test/ELF/linkerscript.s
+++ b/test/ELF/linkerscript.s
@@ -1,3 +1,9 @@
+# There is some bad quoting interaction between lit's internal shell, which is
+# implemented in Python, and the Cygwin implementations of the Unix utilities.
+# Avoid running these tests on Windows for now by requiring a real shell.
+
+# REQUIRES: shell
+
# REQUIRES: x86
# RUN: mkdir -p %t.dir
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
@@ -10,43 +16,43 @@
# RUN: ld.lld %t -o %t2 %t.script
# RUN: llvm-readobj %t2 > /dev/null
-# RUN: echo "GROUP(" %t ")" > %t.script
+# RUN: echo "GROUP(\"%t\")" > %t.script
# RUN: ld.lld -o %t2 %t.script
# RUN: llvm-readobj %t2 > /dev/null
-# RUN: echo "INPUT(" %t ")" > %t.script
+# RUN: echo "INPUT(\"%t\")" > %t.script
# RUN: ld.lld -o %t2 %t.script
# RUN: llvm-readobj %t2 > /dev/null
-# RUN: echo "GROUP(" %t libxyz.a ")" > %t.script
+# RUN: echo "GROUP(\"%t\" libxyz.a )" > %t.script
# RUN: not ld.lld -o %t2 %t.script
# RUN: ld.lld -o %t2 %t.script -L%t.dir
# RUN: llvm-readobj %t2 > /dev/null
-# RUN: echo "GROUP(" %t =libxyz.a ")" > %t.script
+# RUN: echo "GROUP(\"%t\" =libxyz.a )" > %t.script
# RUN: not ld.lld -o %t2 %t.script
# RUN: ld.lld -o %t2 %t.script --sysroot=%t.dir
# RUN: llvm-readobj %t2 > /dev/null
-# RUN: echo "GROUP(" %t -lxyz ")" > %t.script
+# RUN: echo "GROUP(\"%t\" -lxyz )" > %t.script
# RUN: not ld.lld -o %t2 %t.script
# RUN: ld.lld -o %t2 %t.script -L%t.dir
# RUN: llvm-readobj %t2 > /dev/null
-# RUN: echo "GROUP(" %t libxyz.a ")" > %t.script
+# RUN: echo "GROUP(\"%t\" libxyz.a )" > %t.script
# RUN: not ld.lld -o %t2 %t.script
# RUN: ld.lld -o %t2 %t.script -L%t.dir
# RUN: llvm-readobj %t2 > /dev/null
-# RUN: echo "GROUP(" %t /libxyz.a ")" > %t.script
-# RUN: echo "GROUP(" %t /libxyz.a ")" > %t.dir/xyz.script
+# RUN: echo "GROUP(\"%t\" /libxyz.a )" > %t.script
+# RUN: echo "GROUP(\"%t\" /libxyz.a )" > %t.dir/xyz.script
# RUN: not ld.lld -o %t2 %t.script
# RUN: not ld.lld -o %t2 %t.script --sysroot=%t.dir
# RUN: ld.lld -o %t2 %t.dir/xyz.script --sysroot=%t.dir
# RUN: llvm-readobj %t2 > /dev/null
-# RUN: echo "GROUP(" %t.script2 ")" > %t.script1
-# RUN: echo "GROUP(" %t ")" > %t.script2
+# RUN: echo "GROUP(\"%t.script2\")" > %t.script1
+# RUN: echo "GROUP(\"%t\")" > %t.script2
# RUN: ld.lld -o %t2 %t.script1
# RUN: llvm-readobj %t2 > /dev/null
@@ -70,16 +76,16 @@
# ENTRY-OVERLOAD: Name: _start
# ENTRY-OVERLOAD-NEXT: Value: [[ENTRY]]
-# RUN: echo "OUTPUT_FORMAT(\"elf64-x86-64\") /*/*/ GROUP(" %t ")" > %t.script
+# RUN: echo "OUTPUT_FORMAT(elf64-x86-64) /*/*/ GROUP(\"%t\" )" > %t.script
# RUN: ld.lld -o %t2 %t.script
# RUN: llvm-readobj %t2 > /dev/null
-# RUN: echo "GROUP(AS_NEEDED(" %t "))" > %t.script
+# RUN: echo "GROUP(AS_NEEDED(\"%t\"))" > %t.script
# RUN: ld.lld -o %t2 %t.script
# RUN: llvm-readobj %t2 > /dev/null
# RUN: rm -f %t.out
-# RUN: echo "OUTPUT(" %t.out ")" > %t.script
+# RUN: echo "OUTPUT(\"%t.out\")" > %t.script
# RUN: ld.lld %t.script %t
# RUN: llvm-readobj %t.out > /dev/null
@@ -95,8 +101,8 @@
# RUN: ld.lld %t.script %t
# RUN: llvm-readobj %t.out > /dev/null
-# RUN: echo "INCLUDE " %t.script2 "OUTPUT(" %t.out ")" > %t.script1
-# RUN: echo "GROUP(" %t ")" > %t.script2
+# RUN: echo "INCLUDE \"%t.script2\" OUTPUT(\"%t.out\")" > %t.script1
+# RUN: echo "GROUP(\"%t\")" > %t.script2
# RUN: ld.lld %t.script1
# RUN: llvm-readobj %t2 > /dev/null
@@ -106,7 +112,7 @@
# ERR1: unknown directive: FOO
-.globl _start, _label;
+.globl _start, _label
_start:
mov $60, %rax
mov $42, %rdi
diff --git a/test/ELF/linkerscript2.s b/test/ELF/linkerscript2.s
index f83198f759fd..6ecd9e7ea975 100644
--- a/test/ELF/linkerscript2.s
+++ b/test/ELF/linkerscript2.s
@@ -1,10 +1,16 @@
+# There is some bad quoting interaction between lit's internal shell, which is
+# implemented in Python, and the Cygwin implementations of the Unix utilities.
+# Avoid running these tests on Windows for now by requiring a real shell.
+
+# REQUIRES: shell
+
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd \
# RUN: %p/Inputs/libsearch-dyn.s -o %tdyn.o
# RUN: mkdir -p %t.dir
# RUN: ld.lld -shared %tdyn.o -o %t.dir/libls.so
-# RUN: echo "SEARCH_DIR(" %t.dir ")" > %t.script
+# RUN: echo "SEARCH_DIR(\"%t.dir\")" > %t.script
# RUN: ld.lld -o %t2 --script %t.script -lls %t
.globl _start,_bar
diff --git a/test/ELF/lit.local.cfg b/test/ELF/lit.local.cfg
index 0011e796e5f4..b93a36d2b50b 100644
--- a/test/ELF/lit.local.cfg
+++ b/test/ELF/lit.local.cfg
@@ -1,2 +1,2 @@
-config.suffixes = ['.test', '.s']
+config.suffixes = ['.test', '.s', '.ll']
diff --git a/test/ELF/llvm33-rela-outside-group.s b/test/ELF/llvm33-rela-outside-group.s
new file mode 100644
index 000000000000..8e7e7c4e6a4d
--- /dev/null
+++ b/test/ELF/llvm33-rela-outside-group.s
@@ -0,0 +1,11 @@
+// Input file generated with:
+// llvm33/llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %S/Inputs/llvm33-rela-outside-group.o
+//
+// RUN: ld.lld -shared %S/Inputs/llvm33-rela-outside-group.o %S/Inputs/llvm33-rela-outside-group.o
+
+ .global bar
+ .weak _Z3fooIiEvv
+
+ .section .text._Z3fooIiEvv,"axG",@progbits,_Z3fooIiEvv,comdat
+_Z3fooIiEvv:
+ callq bar@PLT
diff --git a/test/ELF/local-dynamic.s b/test/ELF/local-dynamic.s
index 162c58cb57ed..436516a91190 100644
--- a/test/ELF/local-dynamic.s
+++ b/test/ELF/local-dynamic.s
@@ -42,6 +42,17 @@
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _DYNAMIC
+// CHECK-NEXT: Value: 0x1000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .dynamic
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: _start
// CHECK-NEXT: Value: 0x1000
// CHECK-NEXT: Size: 0
diff --git a/test/ELF/local-got-pie.s b/test/ELF/local-got-pie.s
new file mode 100644
index 000000000000..e846bd454445
--- /dev/null
+++ b/test/ELF/local-got-pie.s
@@ -0,0 +1,36 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t -pie
+// RUN: llvm-readobj -s -r %t | FileCheck %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
+
+.globl _start
+_start:
+ call foo@gotpcrel
+
+ .hidden foo
+ .global foo
+foo:
+ nop
+
+// 0x20A0 - 1001 - 5 = 4250
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: _start:
+// DISASM-NEXT: 1000: {{.*}} callq 4251
+// DISASM: foo:
+// DISASM-NEXT: 1005: {{.*}} nop
+
+// CHECK: Name: .got
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x20A0
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 8
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT: 0x20A0 R_X86_64_RELATIVE - 0x1005
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/local-undefined-symbol.s b/test/ELF/local-undefined-symbol.s
new file mode 100644
index 000000000000..34ef847180ae
--- /dev/null
+++ b/test/ELF/local-undefined-symbol.s
@@ -0,0 +1,13 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t1
+# RUN: llvm-readobj -t %t1 | FileCheck %s
+
+# CHECK: Symbols [
+# CHECK-NOT: Name: foo
+
+.global _start
+_start:
+ jmp foo
+
+.local foo
diff --git a/test/ELF/lto/Inputs/archive-2.ll b/test/ELF/lto/Inputs/archive-2.ll
new file mode 100644
index 000000000000..8236cfe5cd84
--- /dev/null
+++ b/test/ELF/lto/Inputs/archive-2.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @_start() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/archive-3.ll b/test/ELF/lto/Inputs/archive-3.ll
new file mode 100644
index 000000000000..ad8fb1e33ef2
--- /dev/null
+++ b/test/ELF/lto/Inputs/archive-3.ll
@@ -0,0 +1,5 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/archive.ll b/test/ELF/lto/Inputs/archive.ll
new file mode 100644
index 000000000000..71c1e4f35600
--- /dev/null
+++ b/test/ELF/lto/Inputs/archive.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/available-externally.ll b/test/ELF/lto/Inputs/available-externally.ll
new file mode 100644
index 000000000000..b8583eab829d
--- /dev/null
+++ b/test/ELF/lto/Inputs/available-externally.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @zed() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/comdat.s b/test/ELF/lto/Inputs/comdat.s
new file mode 100644
index 000000000000..6f6e5ae1d9df
--- /dev/null
+++ b/test/ELF/lto/Inputs/comdat.s
@@ -0,0 +1,5 @@
+ .section .text.f,"axG",@progbits,c,comdat
+ .globl foo
+
+foo:
+ retq
diff --git a/test/ELF/lto/Inputs/common.s b/test/ELF/lto/Inputs/common.s
new file mode 100644
index 000000000000..e2cd9e6d50c3
--- /dev/null
+++ b/test/ELF/lto/Inputs/common.s
@@ -0,0 +1 @@
+ .comm a,8,4
diff --git a/test/ELF/lto/Inputs/drop-debug-info.bc b/test/ELF/lto/Inputs/drop-debug-info.bc
new file mode 100644
index 000000000000..f9c471f8e0d1
--- /dev/null
+++ b/test/ELF/lto/Inputs/drop-debug-info.bc
Binary files differ
diff --git a/test/ELF/lto/Inputs/drop-linkage.ll b/test/ELF/lto/Inputs/drop-linkage.ll
new file mode 100644
index 000000000000..0e3dc7a41421
--- /dev/null
+++ b/test/ELF/lto/Inputs/drop-linkage.ll
@@ -0,0 +1,12 @@
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+$foo = comdat any
+define linkonce void @foo() comdat {
+ ret void
+}
+
+define void @bar() {
+ call void @foo()
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/dynsym.s b/test/ELF/lto/Inputs/dynsym.s
new file mode 100644
index 000000000000..a69f870a1b60
--- /dev/null
+++ b/test/ELF/lto/Inputs/dynsym.s
@@ -0,0 +1,3 @@
+.globl foo
+foo:
+ret
diff --git a/test/ELF/lto/Inputs/internalize-exportdyn.ll b/test/ELF/lto/Inputs/internalize-exportdyn.ll
new file mode 100644
index 000000000000..21ac3580762c
--- /dev/null
+++ b/test/ELF/lto/Inputs/internalize-exportdyn.ll
@@ -0,0 +1,6 @@
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define weak_odr void @bah() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/internalize-undef.ll b/test/ELF/lto/Inputs/internalize-undef.ll
new file mode 100644
index 000000000000..71c1e4f35600
--- /dev/null
+++ b/test/ELF/lto/Inputs/internalize-undef.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/irmover-error.ll b/test/ELF/lto/Inputs/irmover-error.ll
new file mode 100644
index 000000000000..86ed259b2a00
--- /dev/null
+++ b/test/ELF/lto/Inputs/irmover-error.ll
@@ -0,0 +1,6 @@
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+!0 = !{ i32 1, !"foo", i32 2 }
+
+!llvm.module.flags = !{ !0 }
diff --git a/test/ELF/lto/Inputs/linkonce-odr.ll b/test/ELF/lto/Inputs/linkonce-odr.ll
new file mode 100644
index 000000000000..0b3828846eb5
--- /dev/null
+++ b/test/ELF/lto/Inputs/linkonce-odr.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define linkonce_odr void @f() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/linkonce.ll b/test/ELF/lto/Inputs/linkonce.ll
new file mode 100644
index 000000000000..a6738b3ad71e
--- /dev/null
+++ b/test/ELF/lto/Inputs/linkonce.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define linkonce void @f() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/resolution.s b/test/ELF/lto/Inputs/resolution.s
new file mode 100644
index 000000000000..60b7870efbf4
--- /dev/null
+++ b/test/ELF/lto/Inputs/resolution.s
@@ -0,0 +1,4 @@
+ .data
+ .global a
+a:
+ .long 9
diff --git a/test/ELF/lto/Inputs/save-temps.ll b/test/ELF/lto/Inputs/save-temps.ll
new file mode 100644
index 000000000000..d6e6eb661f33
--- /dev/null
+++ b/test/ELF/lto/Inputs/save-temps.ll
@@ -0,0 +1,6 @@
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @bar() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/shared.s b/test/ELF/lto/Inputs/shared.s
new file mode 100644
index 000000000000..ab79ed131c3f
--- /dev/null
+++ b/test/ELF/lto/Inputs/shared.s
@@ -0,0 +1,7 @@
+.globl printf
+.type printf, @function
+printf:
+
+.globl puts
+.type puts, @function
+puts:
diff --git a/test/ELF/lto/Inputs/start-lib1.ll b/test/ELF/lto/Inputs/start-lib1.ll
new file mode 100644
index 000000000000..9f42e6afff0f
--- /dev/null
+++ b/test/ELF/lto/Inputs/start-lib1.ll
@@ -0,0 +1,8 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @bar()
+
+define void @foo() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/start-lib2.ll b/test/ELF/lto/Inputs/start-lib2.ll
new file mode 100644
index 000000000000..68b3c8362808
--- /dev/null
+++ b/test/ELF/lto/Inputs/start-lib2.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @bar() {
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/tls-mixed.s b/test/ELF/lto/Inputs/tls-mixed.s
new file mode 100644
index 000000000000..b31ae3dd54d1
--- /dev/null
+++ b/test/ELF/lto/Inputs/tls-mixed.s
@@ -0,0 +1,4 @@
+.globl foo
+.section .tbss,"awT",@nobits
+foo:
+.long 0
diff --git a/test/ELF/lto/Inputs/type-merge.ll b/test/ELF/lto/Inputs/type-merge.ll
new file mode 100644
index 000000000000..c31642105f3a
--- /dev/null
+++ b/test/ELF/lto/Inputs/type-merge.ll
@@ -0,0 +1,8 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @zed() {
+ call void @bar()
+ ret void
+}
+declare void @bar()
diff --git a/test/ELF/lto/Inputs/type-merge2.ll b/test/ELF/lto/Inputs/type-merge2.ll
new file mode 100644
index 000000000000..79fd1f886306
--- /dev/null
+++ b/test/ELF/lto/Inputs/type-merge2.ll
@@ -0,0 +1,8 @@
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+%zed = type { i16 }
+define void @bar(%zed* %this) {
+ store %zed* %this, %zed** null
+ ret void
+}
diff --git a/test/ELF/lto/Inputs/undef-mixed.s b/test/ELF/lto/Inputs/undef-mixed.s
new file mode 100644
index 000000000000..2e4b7e114bb5
--- /dev/null
+++ b/test/ELF/lto/Inputs/undef-mixed.s
@@ -0,0 +1,3 @@
+ .globl bar
+bar:
+ retq
diff --git a/test/ELF/lto/Inputs/unnamed-addr-lib.s b/test/ELF/lto/Inputs/unnamed-addr-lib.s
new file mode 100644
index 000000000000..e6ebce024f05
--- /dev/null
+++ b/test/ELF/lto/Inputs/unnamed-addr-lib.s
@@ -0,0 +1,6 @@
+ .protected foo
+ .global foo
+foo:
+
+ .global bar
+bar:
diff --git a/test/ELF/lto/Inputs/visibility.s b/test/ELF/lto/Inputs/visibility.s
new file mode 100644
index 000000000000..db1379cc441f
--- /dev/null
+++ b/test/ELF/lto/Inputs/visibility.s
@@ -0,0 +1,8 @@
+ .global g
+g:
+ ret
+
+ .data
+ .global a
+a:
+ .long 41
diff --git a/test/ELF/lto/archive-2.ll b/test/ELF/lto/archive-2.ll
new file mode 100644
index 000000000000..6712d60c11e3
--- /dev/null
+++ b/test/ELF/lto/archive-2.ll
@@ -0,0 +1,28 @@
+; REQUIRES: x86
+; RUN: llvm-as %S/Inputs/archive-2.ll -o %t1.o
+; RUN: rm -f %t.a
+; RUN: llvm-ar rcs %t.a %t1.o
+; RUN: llvm-as %s -o %t2.o
+; RUN: ld.lld -m elf_x86_64 %t2.o %t.a -o %t3
+; RUN: llvm-readobj -t %t3 | FileCheck %s
+; RUN: ld.lld -m elf_x86_64 %t2.o --whole-archive %t.a -o %t3 -shared
+; RUN: llvm-readobj -t %t3 | FileCheck %s
+
+; CHECK: Name: _start (
+; CHECK-NEXT: Value:
+; CHECK-NEXT: Size:
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: Function
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .text
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @g() {
+ call void @_start()
+ ret void
+}
+
+declare void @_start()
+
diff --git a/test/ELF/lto/archive-3.ll b/test/ELF/lto/archive-3.ll
new file mode 100644
index 000000000000..350c8929c9df
--- /dev/null
+++ b/test/ELF/lto/archive-3.ll
@@ -0,0 +1,19 @@
+; REQUIRES: x86
+; RUN: llvm-as %S/Inputs/archive-3.ll -o %t1.o
+; RUN: llvm-as %s -o %t2.o
+
+; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t3 -save-temps
+; RUN: llvm-dis %t3.lto.bc -o - | FileCheck %s
+
+; RUN: rm -f %t.a
+; RUN: llvm-ar rcs %t.a %t1.o
+; RUN: ld.lld -m elf_x86_64 %t.a %t1.o %t2.o -o %t3 -save-temps
+; RUN: llvm-dis %t3.lto.bc -o - | FileCheck %s
+
+; CHECK: define internal void @foo() {
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+define void @_start() {
+ ret void
+}
diff --git a/test/ELF/lto/archive.ll b/test/ELF/lto/archive.ll
new file mode 100644
index 000000000000..b3f69fb9920f
--- /dev/null
+++ b/test/ELF/lto/archive.ll
@@ -0,0 +1,37 @@
+; REQUIRES: x86
+; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o
+; RUN: rm -f %t.a
+; RUN: llvm-ar rcs %t.a %t1.o
+; RUN: llvm-as %s -o %t2.o
+; RUN: ld.lld -m elf_x86_64 %t2.o %t.a -o %t3 -shared
+; RUN: llvm-readobj -t %t3 | FileCheck %s
+; RUN: ld.lld -m elf_x86_64 %t2.o --whole-archive %t.a -o %t3 -shared
+; RUN: llvm-readobj -t %t3 | FileCheck %s
+
+
+; CHECK: Name: g (
+; CHECK-NEXT: Value:
+; CHECK-NEXT: Size:
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: Function
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .text
+
+; CHECK: Name: f (
+; CHECK-NEXT: Value:
+; CHECK-NEXT: Size:
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: Function
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .text
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @g() {
+ call void @f()
+ ret void
+}
+
+declare void @f()
+
diff --git a/test/ELF/lto/asmundef.ll b/test/ELF/lto/asmundef.ll
new file mode 100644
index 000000000000..d76e418fce81
--- /dev/null
+++ b/test/ELF/lto/asmundef.ll
@@ -0,0 +1,25 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t -save-temps
+; RUN: llvm-dis %t.lto.bc -o - | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+module asm ".weak patatino"
+module asm ".equ patatino, foo"
+
+declare void @patatino()
+
+define void @foo() {
+ ret void
+}
+
+define void @_start() {
+ call void @patatino()
+ ret void
+}
+
+; CHECK: @llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (void ()* @foo to i8*)], section "llvm.metadata"
+; CHECK: define internal void @foo
+
diff --git a/test/ELF/lto/available-externally.ll b/test/ELF/lto/available-externally.ll
new file mode 100644
index 000000000000..74aa86002c9e
--- /dev/null
+++ b/test/ELF/lto/available-externally.ll
@@ -0,0 +1,22 @@
+; RUN: llvm-as %s -o %t1.o
+; RUN: llvm-as %p/Inputs/available-externally.ll -o %t2.o
+; RUN: ld.lld %t1.o %t2.o -m elf_x86_64 -o %t.so -shared -save-temps
+; RUN: llvm-dis < %t.so.lto.bc | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @foo() {
+ call void @bar()
+ call void @zed()
+ ret void
+}
+define available_externally void @bar() {
+ ret void
+}
+define available_externally void @zed() {
+ ret void
+}
+
+; CHECK: define available_externally void @bar() {
+; CHECK: define void @zed() {
diff --git a/test/ELF/lto/combined-lto-object-name.ll b/test/ELF/lto/combined-lto-object-name.ll
new file mode 100644
index 000000000000..f5b7e3ae40e6
--- /dev/null
+++ b/test/ELF/lto/combined-lto-object-name.ll
@@ -0,0 +1,14 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2 2>&1 | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+declare void @foo()
+define void @_start() {
+ call void @foo()
+ ret void
+}
+
+; CHECK: undefined symbol: foo in {{.*}}combined-lto-object-name.ll.tmp.o
diff --git a/test/ELF/lto/comdat.ll b/test/ELF/lto/comdat.ll
new file mode 100644
index 000000000000..e1384d0abd23
--- /dev/null
+++ b/test/ELF/lto/comdat.ll
@@ -0,0 +1,21 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared
+; RUN: llvm-readobj -t %t.so | FileCheck %s
+
+; CHECK: Name: foo
+; CHECK-NEXT: Value:
+; CHECK-NEXT: Size: 1
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: Function
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .text
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+$foo = comdat any
+define void @foo() comdat {
+ ret void
+}
+
diff --git a/test/ELF/lto/comdat2.ll b/test/ELF/lto/comdat2.ll
new file mode 100644
index 000000000000..1509585f1553
--- /dev/null
+++ b/test/ELF/lto/comdat2.ll
@@ -0,0 +1,40 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj
+; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared
+; RUN: llvm-readobj -t %t.so | FileCheck %s
+; RUN: ld.lld -m elf_x86_64 %t2.o %t.o -o %t2.so -shared
+; RUN: llvm-readobj -t %t2.so | FileCheck %s --check-prefix=OTHER
+
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+$c = comdat any
+
+define protected void @foo() comdat($c) {
+ ret void
+}
+
+; CHECK: Symbol {
+; CHECK: Name: foo
+; CHECK-NEXT: Value: 0x1000
+; CHECK-NEXT: Size: 1
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: Function
+; CHECK-NEXT: Other [
+; CHECK-NEXT: STV_PROTECTED
+; CHECK-NEXT: ]
+; CHECK-NEXT: Section: .text
+; CHECK-NEXT: }
+
+; OTHER: Symbol {
+; OTHER: Name: foo
+; OTHER-NEXT: Value: 0x1000
+; OTHER-NEXT: Size: 0
+; OTHER-NEXT: Binding: Global
+; OTHER-NEXT: Type: None
+; OTHER-NEXT: Other [
+; OTHER-NEXT: STV_PROTECTED
+; OTHER-NEXT: ]
+; OTHER-NEXT: Section: .text
+; OTHER-NEXT: }
diff --git a/test/ELF/lto/common.ll b/test/ELF/lto/common.ll
new file mode 100644
index 000000000000..b02002431320
--- /dev/null
+++ b/test/ELF/lto/common.ll
@@ -0,0 +1,31 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t1.o
+; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/common.s -o %t2.o -filetype=obj
+; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
+; RUN: llvm-readobj -s -t %t.so | FileCheck %s
+
+; CHECK: Name: .bss
+; CHECK-NEXT: Type: SHT_NOBITS
+; CHECK-NEXT: Flags [
+; CHECK-NEXT: SHF_ALLOC
+; CHECK-NEXT: SHF_WRITE
+; CHECK-NEXT: ]
+; CHECK-NEXT: Address:
+; CHECK-NEXT: Offset:
+; CHECK-NEXT: Size: 8
+; CHECK-NEXT: Link: 0
+; CHECK-NEXT: Info: 0
+; CHECK-NEXT: AddressAlignment: 8
+
+; CHECK: Name: a
+; CHECK-NEXT: Value:
+; CHECK-NEXT: Size: 8
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: Object
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .bss
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@a = common global i32 0, align 8
diff --git a/test/ELF/lto/common2.ll b/test/ELF/lto/common2.ll
new file mode 100644
index 000000000000..59a2676e4fc9
--- /dev/null
+++ b/test/ELF/lto/common2.ll
@@ -0,0 +1,24 @@
+; RUN: llvm-as %s -o %t1.o
+; RUN: ld.lld -m elf_x86_64 %t1.o -o %t -shared -save-temps
+; RUN: llvm-dis < %t.lto.bc | FileCheck %s
+; RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SHARED
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@a = common global i8 0, align 8
+
+; Shared library case, we ensure that the bitcode generated file
+; has not the a symbol but is appears in the final shared library
+; produced.
+; CHECK-NOT: @a = common global i8 0, align 8
+
+; SHARED: Symbol {
+; SHARED: Name: a
+; SHARED-NEXT: Value: 0x2000
+; SHARED-NEXT: Size: 1
+; SHARED-NEXT: Binding: Global
+; SHARED-NEXT: Type: Object
+; SHARED-NEXT: Other: 0
+; SHARED-NEXT: Section: .bss
+; SHARED-NEXT: }
diff --git a/test/ELF/lto/ctors.ll b/test/ELF/lto/ctors.ll
new file mode 100644
index 000000000000..7fce645f28f6
--- /dev/null
+++ b/test/ELF/lto/ctors.ll
@@ -0,0 +1,18 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
+; RUN: llvm-readobj -sections %t.so | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }]
+define void @ctor() {
+ call void asm "nop", ""()
+ ret void
+}
+
+; The llvm.global_ctors should end up producing constructors.
+; On x86-64 (linux) we should always emit .init_array and never .ctors.
+; CHECK: Name: .init_array
+; CHECK-NOT: Name: .ctors
diff --git a/test/ELF/lto/discard-value-names.ll b/test/ELF/lto/discard-value-names.ll
new file mode 100644
index 000000000000..c6cd94fd2e18
--- /dev/null
+++ b/test/ELF/lto/discard-value-names.ll
@@ -0,0 +1,23 @@
+; RUN: llvm-as %s -o %t.o
+
+; RUN: ld.lld -m elf_x86_64 -shared -save-temps %t.o -o %t2.o
+; RUN: llvm-dis < %t2.o.lto.bc | FileCheck %s
+
+; CHECK: @GlobalValueName
+; CHECK: @foo(i32 %in)
+; CHECK: somelabel:
+; CHECK: %GV = load i32, i32* @GlobalValueName
+; CHECK: %add = add i32 %in, %GV
+; CHECK: ret i32 %add
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@GlobalValueName = global i32 0
+
+define i32 @foo(i32 %in) {
+somelabel:
+ %GV = load i32, i32* @GlobalValueName
+ %add = add i32 %in, %GV
+ ret i32 %add
+}
diff --git a/test/ELF/lto/drop-debug-info.ll b/test/ELF/lto/drop-debug-info.ll
new file mode 100644
index 000000000000..7a7ed5ea41d1
--- /dev/null
+++ b/test/ELF/lto/drop-debug-info.ll
@@ -0,0 +1,9 @@
+; REQUIRES: x86
+;
+; drop-debug-info.bc was created from "void f(void) {}" with clang 3.5 and
+; -gline-tables-only, so it contains old debug info.
+;
+; RUN: ld.lld -m elf_x86_64 -shared %p/Inputs/drop-debug-info.bc \
+; RUN: -disable-verify 2>&1 | FileCheck %s
+; CHECK: warning: ignoring debug info with an invalid version (1) in {{.*}}drop-debug-info.bc
+
diff --git a/test/ELF/lto/drop-linkage.ll b/test/ELF/lto/drop-linkage.ll
new file mode 100644
index 000000000000..fd111c18bd13
--- /dev/null
+++ b/test/ELF/lto/drop-linkage.ll
@@ -0,0 +1,14 @@
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+; REQUIRES: x86
+; RUN: llc %s -o %t.o -filetype=obj
+; RUN: llvm-as %p/Inputs/drop-linkage.ll -o %t2.o
+; RUN: ld.lld %t.o %t2.o -o %t.so -save-temps -shared
+; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s
+
+define void @foo() {
+ ret void
+}
+
+; CHECK: declare void @foo()
diff --git a/test/ELF/lto/duplicated.ll b/test/ELF/lto/duplicated.ll
new file mode 100644
index 000000000000..6ef6772c5f20
--- /dev/null
+++ b/test/ELF/lto/duplicated.ll
@@ -0,0 +1,10 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: not ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared 2>&1 | FileCheck %s
+; CHECK: duplicate symbol: f in {{.*}}.o and {{.*}}.o
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @f() {
+ ret void
+}
diff --git a/test/ELF/lto/dynamic-list.ll b/test/ELF/lto/dynamic-list.ll
new file mode 100644
index 000000000000..0e950b3c83fd
--- /dev/null
+++ b/test/ELF/lto/dynamic-list.ll
@@ -0,0 +1,25 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: echo "{ foo; };" > %t.list
+; RUN: ld.lld -m elf_x86_64 -o %t --dynamic-list %t.list -pie %t.o
+; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
+
+; CHECK: Name: foo@
+; CHECK-NEXT: Value: 0x1010
+; CHECK-NEXT: Size: 1
+; CHECK-NEXT: Binding: Global (0x1)
+; CHECK-NEXT: Type: Function
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .text
+; CHECK-NEXT: }
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @_start() {
+ ret void
+}
+
+define void @foo() {
+ ret void
+}
diff --git a/test/ELF/lto/dynsym.ll b/test/ELF/lto/dynsym.ll
new file mode 100644
index 000000000000..5885960c7bc3
--- /dev/null
+++ b/test/ELF/lto/dynsym.ll
@@ -0,0 +1,25 @@
+; REQUIRES: x86
+; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t.o %p/Inputs/dynsym.s
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
+; RUN: llvm-as %s -o %t2.o
+; RUN: ld.lld -m elf_x86_64 %t2.o %t.so -o %t
+; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @_start() {
+ call void @foo()
+ ret void
+}
+
+; CHECK: Name: foo
+; CHECK-NEXT: Value:
+; CHECK-NEXT: Size:
+; CHECK-NEXT: Binding:
+; CHECK-NEXT: Type:
+; CHECK-NEXT: Other:
+; CHECK-NEXT: Section: .text
+define void @foo() {
+ ret void
+}
diff --git a/test/ELF/lto/inline-asm.ll b/test/ELF/lto/inline-asm.ll
new file mode 100644
index 000000000000..b6af6a5a5cbb
--- /dev/null
+++ b/test/ELF/lto/inline-asm.ll
@@ -0,0 +1,11 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @foo() {
+ call void asm "nop", ""()
+ ret void
+}
diff --git a/test/ELF/lto/internalize-basic.ll b/test/ELF/lto/internalize-basic.ll
new file mode 100644
index 000000000000..396b9cb60f17
--- /dev/null
+++ b/test/ELF/lto/internalize-basic.ll
@@ -0,0 +1,21 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps
+; RUN: llvm-dis < %t2.lto.bc | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @_start() {
+ ret void
+}
+
+define hidden void @foo() {
+ ret void
+}
+
+; Check that _start is not internalized.
+; CHECK: define void @_start()
+
+; Check that foo function is correctly internalized.
+; CHECK: define internal void @foo()
diff --git a/test/ELF/lto/internalize-exportdyn.ll b/test/ELF/lto/internalize-exportdyn.ll
new file mode 100644
index 000000000000..bee9a1e6a1ee
--- /dev/null
+++ b/test/ELF/lto/internalize-exportdyn.ll
@@ -0,0 +1,47 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-as %p/Inputs/internalize-exportdyn.ll -o %t2.o
+; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t2 --export-dynamic -save-temps
+; RUN: llvm-dis < %t2.lto.bc | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @_start() {
+ ret void
+}
+
+define void @foo() {
+ ret void
+}
+
+define hidden void @bar() {
+ ret void
+}
+
+define linkonce_odr void @zed() local_unnamed_addr {
+ ret void
+}
+
+define linkonce_odr void @zed2() unnamed_addr {
+ ret void
+}
+
+define linkonce_odr void @bah() {
+ ret void
+}
+
+define linkonce_odr void @baz() {
+ ret void
+}
+
+@use_baz = global void ()* @baz
+
+; Check what gets internalized.
+; CHECK: define void @_start()
+; CHECK: define void @foo()
+; CHECK: define internal void @bar()
+; CHECK: define internal void @zed()
+; CHECK: define internal void @zed2()
+; CHECK: define weak_odr void @bah()
+; CHECK: define weak_odr void @baz()
diff --git a/test/ELF/lto/internalize-llvmused.ll b/test/ELF/lto/internalize-llvmused.ll
new file mode 100644
index 000000000000..46c90a65ff72
--- /dev/null
+++ b/test/ELF/lto/internalize-llvmused.ll
@@ -0,0 +1,20 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps
+; RUN: llvm-dis < %t2.lto.bc | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @_start() {
+ ret void
+}
+
+define hidden void @f() {
+ ret void
+}
+
+@llvm.used = appending global [1 x i8*] [ i8* bitcast (void ()* @f to i8*)]
+
+; Check that f is not internalized.
+; CHECK: define hidden void @f()
diff --git a/test/ELF/lto/internalize-undef.ll b/test/ELF/lto/internalize-undef.ll
new file mode 100644
index 000000000000..5d74c31eee8b
--- /dev/null
+++ b/test/ELF/lto/internalize-undef.ll
@@ -0,0 +1,16 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-as %p/Inputs/internalize-undef.ll -o %t2.o
+; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -save-temps
+; RUN: llvm-dis < %t.lto.bc | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @f()
+define void @_start() {
+ call void @f()
+ ret void
+}
+
+; CHECK: define internal void @f()
diff --git a/test/ELF/lto/internalize-version-script.ll b/test/ELF/lto/internalize-version-script.ll
new file mode 100644
index 000000000000..c25328fb56e2
--- /dev/null
+++ b/test/ELF/lto/internalize-version-script.ll
@@ -0,0 +1,22 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: echo "{ global: foo; local: *; };" > %t.script
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps
+; RUN: llvm-dis < %t2.lto.bc | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @foo() {
+ ret void
+}
+
+define void @bar() {
+ ret void
+}
+
+; Check that foo is not internalized.
+; CHECK: define void @foo()
+
+; Check that bar is correctly internalized.
+; CHECK: define internal void @bar()
diff --git a/test/ELF/lto/invalid-bitcode.ll b/test/ELF/lto/invalid-bitcode.ll
new file mode 100644
index 000000000000..eceffb10d8ad
--- /dev/null
+++ b/test/ELF/lto/invalid-bitcode.ll
@@ -0,0 +1,12 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: not ld.lld -m elf_x86_64 %t.o 2>&1 | FileCheck %s
+
+; CHECK: invalid bitcode file:
+
+; This bitcode file has no datalayout.
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @_start() {
+ ret void
+}
diff --git a/test/ELF/lto/irmover-error.ll b/test/ELF/lto/irmover-error.ll
new file mode 100644
index 000000000000..aee411441c47
--- /dev/null
+++ b/test/ELF/lto/irmover-error.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-as -o %t1.bc %s
+; RUN: llvm-as -o %t2.bc %S/Inputs/irmover-error.ll
+; RUN: not ld.lld -m elf_x86_64 %t1.bc %t2.bc -o %t 2>&1 | FileCheck %s
+
+; CHECK: failed to link module {{.*}}2.bc: linking module flags 'foo': IDs have conflicting values
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+!0 = !{ i32 1, !"foo", i32 1 }
+
+!llvm.module.flags = !{ !0 }
diff --git a/test/ELF/lto/linkage.ll b/test/ELF/lto/linkage.ll
new file mode 100644
index 000000000000..5af9b321eeec
--- /dev/null
+++ b/test/ELF/lto/linkage.ll
@@ -0,0 +1,20 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t1.o
+; RUN: ld.lld -m elf_x86_64 %t1.o %t1.o -o %t.so -shared
+; RUN: llvm-nm %t.so | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Should not encounter a duplicate symbol error for @.str
+@.str = private unnamed_addr constant [4 x i8] c"Hey\00", align 1
+
+; Should not encounter a duplicate symbol error for @llvm.global_ctors
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }]
+define internal void @ctor() {
+ ret void
+}
+
+; Should not try to merge a declaration into the combined module.
+declare i32 @llvm.ctpop.i32(i32)
+; CHECK-NOT: llvm.ctpop.i32
diff --git a/test/ELF/lto/linkonce-odr.ll b/test/ELF/lto/linkonce-odr.ll
new file mode 100644
index 000000000000..569e27154545
--- /dev/null
+++ b/test/ELF/lto/linkonce-odr.ll
@@ -0,0 +1,17 @@
+; REQUIRES: x86
+; RUN: llvm-as %p/Inputs/linkonce-odr.ll -o %t1.o
+; RUN: llc -relocation-model=pic %s -o %t2.o -filetype=obj
+; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps
+; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+declare void @f()
+
+define void @g() {
+ call void @f()
+ ret void
+}
+
+; Be sure that 'f' is kept and has weak_odr linkage.
+; CHECK: define weak_odr void @f()
diff --git a/test/ELF/lto/linkonce.ll b/test/ELF/lto/linkonce.ll
new file mode 100644
index 000000000000..f980eff887b1
--- /dev/null
+++ b/test/ELF/lto/linkonce.ll
@@ -0,0 +1,17 @@
+; REQUIRES: x86
+; RUN: llvm-as %p/Inputs/linkonce.ll -o %t1.o
+; RUN: llc -relocation-model=pic %s -o %t2.o -filetype=obj
+; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps
+; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+declare void @f()
+
+define void @g() {
+ call void @f()
+ ret void
+}
+
+; Be sure that 'f' is kept and has weak linkage.
+; CHECK: define weak void @f()
diff --git a/test/ELF/lto/lto-start.ll b/test/ELF/lto/lto-start.ll
new file mode 100644
index 000000000000..e93eecfbf033
--- /dev/null
+++ b/test/ELF/lto/lto-start.ll
@@ -0,0 +1,23 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t2
+; RUN: llvm-readobj -t %t2 | FileCheck %s
+
+; CHECK: Format: ELF64-x86-64
+; CHECK-NEXT: Arch: x86_64
+; CHECK-NEXT: AddressSize: 64bit
+
+; CHECK: Name: _start
+; CHECK-NEXT: Value:
+; CHECK-NEXT: Size: 1
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: Function
+; CHECK-NEXT: Other:
+; CHECK-NEXT: Section: .text
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @_start() {
+ ret void
+}
diff --git a/test/ELF/lto/ltopasses-basic.ll b/test/ELF/lto/ltopasses-basic.ll
new file mode 100644
index 000000000000..5bd5f4122fd0
--- /dev/null
+++ b/test/ELF/lto/ltopasses-basic.ll
@@ -0,0 +1,18 @@
+; REQUIRES: x86
+; RUN: rm -f %t.so.lto.bc %t.so.lto.opt.bc %t.so.lto.o
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -mllvm -debug-pass=Arguments -shared 2>&1 | FileCheck %s --check-prefix=MLLVM
+; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }]
+define void @ctor() {
+ ret void
+}
+
+; `@ctor` doesn't do anything and so the optimizer should kill it, leaving no ctors
+; CHECK: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer
+
+; MLLVM: Pass Arguments:
diff --git a/test/ELF/lto/ltopasses-custom.ll b/test/ELF/lto/ltopasses-custom.ll
new file mode 100644
index 000000000000..3e982e079fb1
--- /dev/null
+++ b/test/ELF/lto/ltopasses-custom.ll
@@ -0,0 +1,30 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps --lto-aa-pipeline=basic-aa \
+; RUN: --lto-newpm-passes=ipsccp -shared
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t2.so -save-temps --lto-newpm-passes=loweratomic -shared
+; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s
+; RUN: llvm-dis %t2.so.lto.opt.bc -o - | FileCheck %s --check-prefix=ATOMIC
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @barrier() {
+ fence seq_cst
+ ret void
+}
+
+; IPSCCP won't remove the fence.
+; CHECK: define void @barrier() {
+; CHECK-NEXT: fence seq_cst
+; CHECK-NEXT: ret void
+
+; LowerAtomic will remove the fence.
+; ATOMIC: define void @barrier() {
+; ATOMIC-NEXT: ret void
+
+; Check that invalid passes are rejected gracefully.
+; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2.so \
+; RUN: --lto-newpm-passes=iamnotapass -shared 2>&1 | \
+; RUN: FileCheck %s --check-prefix=INVALID
+; INVALID: unable to parse pass pipeline description: iamnotapass
diff --git a/test/ELF/lto/metadata.ll b/test/ELF/lto/metadata.ll
new file mode 100644
index 000000000000..3e73de5aab47
--- /dev/null
+++ b/test/ELF/lto/metadata.ll
@@ -0,0 +1,13 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t1.o
+; RUN: ld.lld -m elf_x86_64 %t1.o %t1.o -o %t.so -shared
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define weak void @foo(i32* %p) {
+ store i32 5, i32* %p, align 4, !tbaa !0
+ ret void
+}
+
+!0 = !{!"Simple C/C++ TBAA"}
diff --git a/test/ELF/lto/mix-platforms.ll b/test/ELF/lto/mix-platforms.ll
new file mode 100644
index 000000000000..3478caa5cff6
--- /dev/null
+++ b/test/ELF/lto/mix-platforms.ll
@@ -0,0 +1,10 @@
+; REQUIRES: x86
+; RUN: llvm-mc %p/Inputs/shared.s -o %t386.o -filetype=obj -triple=i386-pc-linux
+; RUN: ld.lld %t386.o -o %ti386.so -shared
+; RUN: llvm-as %s -o %tx64.o
+; RUN: not ld.lld %ti386.so %tx64.o -o %t 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK: {{.*}}x64.o is incompatible with {{.*}}i386.so
diff --git a/test/ELF/lto/module-asm.ll b/test/ELF/lto/module-asm.ll
new file mode 100644
index 000000000000..1389b9f5472e
--- /dev/null
+++ b/test/ELF/lto/module-asm.ll
@@ -0,0 +1,19 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t
+; RUN: llvm-nm %t | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+module asm ".text"
+module asm ".globl foo"
+; CHECK: T foo
+module asm "foo: ret"
+
+declare void @foo()
+
+define void @_start() {
+ call void @foo()
+ ret void
+}
diff --git a/test/ELF/lto/opt-level.ll b/test/ELF/lto/opt-level.ll
new file mode 100644
index 000000000000..934bf01b6c32
--- /dev/null
+++ b/test/ELF/lto/opt-level.ll
@@ -0,0 +1,29 @@
+; RUN: llvm-as -o %t.o %s
+; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --lto-O0 %t.o
+; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s
+; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --lto-O2 %t.o
+; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s
+; RUN: ld.lld -o %t2a -m elf_x86_64 -e main %t.o
+; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s
+
+; Reject invalid optimization levels.
+; RUN: not ld.lld -o %t3 -m elf_x86_64 -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: FileCheck --check-prefix=INVALIDNEGATIVE %s
+; INVALIDNEGATIVE: invalid optimization level for LTO: -1
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK-O0: foo
+; CHECK-O2-NOT: foo
+define internal void @foo() {
+ ret void
+}
+
+define void @main() {
+ call void @foo()
+ ret void
+}
diff --git a/test/ELF/lto/parallel-internalize.ll b/test/ELF/lto/parallel-internalize.ll
new file mode 100644
index 000000000000..58ed50eab894
--- /dev/null
+++ b/test/ELF/lto/parallel-internalize.ll
@@ -0,0 +1,57 @@
+; REQUIRES: x86
+; RUN: llvm-as -o %t.bc %s
+; RUN: ld.lld -m elf_x86_64 --lto-jobs=2 -save-temps -o %t %t.bc -e foo --lto-O0
+; RUN: llvm-readobj -t -dyn-symbols %t | FileCheck %s
+; RUN: llvm-nm %t0.lto.o | FileCheck --check-prefix=CHECK0 %s
+; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s
+
+; CHECK: Symbols [
+; CHECK-NEXT: Symbol {
+; CHECK-NEXT: Name: (0)
+; CHECK-NEXT: Value: 0x0
+; CHECK-NEXT: Size: 0
+; CHECK-NEXT: Binding: Local (0x0)
+; CHECK-NEXT: Type: None (0x0)
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: Undefined (0x0)
+; CHECK-NEXT: }
+; CHECK-NEXT: Symbol {
+; CHECK-NEXT: Name: bar (5)
+; CHECK-NEXT: Value: 0x11010
+; CHECK-NEXT: Size: 8
+; CHECK-NEXT: Binding: Local (0x0)
+; CHECK-NEXT: Type: Function (0x2)
+; CHECK-NEXT: Other [ (0x2)
+; CHECK-NEXT: STV_HIDDEN (0x2)
+; CHECK-NEXT: ]
+; CHECK-NEXT: Section: .text (0x2)
+; CHECK-NEXT: }
+; CHECK-NEXT: Symbol {
+; CHECK-NEXT: Name: foo (1)
+; CHECK-NEXT: Value: 0x11000
+; CHECK-NEXT: Size: 8
+; CHECK-NEXT: Binding: Global (0x1)
+; CHECK-NEXT: Type: Function (0x2)
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .text (0x2)
+; CHECK-NEXT: }
+; CHECK-NEXT: ]
+; CHECK-NEXT: DynamicSymbols [
+; CHECK-NEXT: ]
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK0: U bar
+; CHECK0: T foo
+define void @foo() {
+ call void @bar()
+ ret void
+}
+
+; CHECK1: T bar
+; CHECK1: U foo
+define void @bar() {
+ call void @foo()
+ ret void
+}
diff --git a/test/ELF/lto/parallel.ll b/test/ELF/lto/parallel.ll
new file mode 100644
index 000000000000..8ea62ef3ae08
--- /dev/null
+++ b/test/ELF/lto/parallel.ll
@@ -0,0 +1,24 @@
+; REQUIRES: x86
+; RUN: llvm-as -o %t.bc %s
+; RUN: ld.lld -m elf_x86_64 --lto-jobs=2 -save-temps -o %t %t.bc -shared
+; RUN: llvm-nm %t0.lto.o | FileCheck --check-prefix=CHECK0 %s
+; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK0-NOT: bar
+; CHECK0: T foo
+; CHECK0-NOT: bar
+define void @foo() {
+ call void @bar()
+ ret void
+}
+
+; CHECK1-NOT: foo
+; CHECK1: T bar
+; CHECK1-NOT: foo
+define void @bar() {
+ call void @foo()
+ ret void
+}
diff --git a/test/ELF/lto/pic.ll b/test/ELF/lto/pic.ll
new file mode 100644
index 000000000000..abc514d7ca3d
--- /dev/null
+++ b/test/ELF/lto/pic.ll
@@ -0,0 +1,20 @@
+; REQUIRES: x86
+
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld %t.o -o %t.so -shared
+; RUN: llvm-readobj -r %t.so | FileCheck %s
+
+; CHECK: Relocations [
+; CHECK-NEXT: Section ({{.*}}) .rela.plt {
+; CHECK-NEXT: R_X86_64_JUMP_SLOT bar 0x0
+; CHECK-NEXT: }
+; CHECK-NEXT: ]
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @bar()
+define void @foo() {
+ call void @bar()
+ ret void
+}
diff --git a/test/ELF/lto/relax-relocs.ll b/test/ELF/lto/relax-relocs.ll
new file mode 100644
index 000000000000..929e124b2d8e
--- /dev/null
+++ b/test/ELF/lto/relax-relocs.ll
@@ -0,0 +1,15 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 -save-temps -shared %t.o -o %t.so
+; RUN: llvm-readobj -r %t.so.lto.o | FileCheck %s
+
+; Test that we produce R_X86_64_REX_GOTPCRELX instead of R_X86_64_GOTPCREL
+; CHECK: R_X86_64_REX_GOTPCRELX foo
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@foo = external global i32
+define i32 @bar() {
+ %t = load i32, i32* @foo
+ ret i32 %t
+}
diff --git a/test/ELF/lto/resolution.ll b/test/ELF/lto/resolution.ll
new file mode 100644
index 000000000000..b3fcf1db3a1b
--- /dev/null
+++ b/test/ELF/lto/resolution.ll
@@ -0,0 +1,27 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t1.o
+; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/resolution.s -o %t2.o -filetype=obj
+; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
+; RUN: llvm-readobj -s --section-data %t.so | FileCheck %s
+
+; CHECK: Name: .data
+; CHECK-NEXT: Type: SHT_PROGBITS
+; CHECK-NEXT: Flags [
+; CHECK-NEXT: SHF_ALLOC
+; CHECK-NEXT: SHF_WRITE
+; CHECK-NEXT: ]
+; CHECK-NEXT: Address:
+; CHECK-NEXT: Offset:
+; CHECK-NEXT: Size: 4
+; CHECK-NEXT: Link: 0
+; CHECK-NEXT: Info: 0
+; CHECK-NEXT: AddressAlignment: 1
+; CHECK-NEXT: EntrySize: 0
+; CHECK-NEXT: SectionData (
+; CHECK-NEXT: 0000: 09000000 |{{.*}}|
+; CHECK-NEXT: )
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@a = weak global i32 8
diff --git a/test/ELF/lto/save-temps.ll b/test/ELF/lto/save-temps.ll
new file mode 100644
index 000000000000..0b0f939c53f1
--- /dev/null
+++ b/test/ELF/lto/save-temps.ll
@@ -0,0 +1,20 @@
+; REQUIRES: x86
+; RUN: cd %T
+; RUN: rm -f a.out a.out.lto.bc a.out.lto.o
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o
+; RUN: ld.lld -shared -m elf_x86_64 %t.o %t2.o -save-temps
+; RUN: llvm-nm a.out | FileCheck %s
+; RUN: llvm-nm a.out.lto.bc | FileCheck %s
+; RUN: llvm-nm a.out.lto.o | FileCheck %s
+; RUN: llvm-dis a.out.lto.bc
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @foo() {
+ ret void
+}
+
+; CHECK: T bar
+; CHECK: T foo
diff --git a/test/ELF/lto/shlib-undefined.ll b/test/ELF/lto/shlib-undefined.ll
new file mode 100644
index 000000000000..db60de8e21b2
--- /dev/null
+++ b/test/ELF/lto/shlib-undefined.ll
@@ -0,0 +1,27 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: echo .global __progname > %t2.s
+; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o
+; RUN: ld.lld -shared %t2.o -o %t2.so
+; RUN: ld.lld -o %t %t.o %t2.so
+; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
+
+; CHECK: Name: __progname@
+; CHECK-NEXT: Value: 0x11010
+; CHECK-NEXT: Size: 1
+; CHECK-NEXT: Binding: Global (0x1)
+; CHECK-NEXT: Type: Function
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .text
+; CHECK-NEXT: }
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @_start() {
+ ret void
+}
+
+define void @__progname() {
+ ret void
+}
diff --git a/test/ELF/lto/start-lib.ll b/test/ELF/lto/start-lib.ll
new file mode 100644
index 000000000000..ec73954a80ca
--- /dev/null
+++ b/test/ELF/lto/start-lib.ll
@@ -0,0 +1,27 @@
+; REQUIRES: x86
+;
+; RUN: llvm-as %s -o %t1.o
+; RUN: llvm-as %p/Inputs/start-lib1.ll -o %t2.o
+; RUN: llvm-as %p/Inputs/start-lib2.ll -o %t3.o
+;
+; RUN: ld.lld -m elf_x86_64 -shared -o %t3 %t1.o %t2.o %t3.o
+; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST1 %s
+; TEST1: Name: bar
+; TEST1: Name: foo
+;
+; RUN: ld.lld -m elf_x86_64 -shared -o %t3 -u bar %t1.o --start-lib %t2.o %t3.o
+; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST2 %s
+; TEST2: Name: bar
+; TEST2-NOT: Name: foo
+;
+; RUN: ld.lld -m elf_x86_64 -shared -o %t3 %t1.o --start-lib %t2.o %t3.o
+; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST3 %s
+; TEST3-NOT: Name: bar
+; TEST3-NOT: Name: foo
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @_start() {
+ ret void
+}
diff --git a/test/ELF/lto/tls-mixed.ll b/test/ELF/lto/tls-mixed.ll
new file mode 100644
index 000000000000..524bb4fb44a3
--- /dev/null
+++ b/test/ELF/lto/tls-mixed.ll
@@ -0,0 +1,10 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t1.o
+; RUN: llvm-mc %p/Inputs/tls-mixed.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -shared
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Should not encounter TLS-ness mismatch for @foo
+@foo = external thread_local global i32, align 4
diff --git a/test/ELF/lto/tls-preserve.ll b/test/ELF/lto/tls-preserve.ll
new file mode 100644
index 000000000000..8aebcb783f48
--- /dev/null
+++ b/test/ELF/lto/tls-preserve.ll
@@ -0,0 +1,25 @@
+; TLS attribute needs to be preserved.
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t1.o
+; RUN: ld.lld -shared %t1.o -m elf_x86_64 -o %t1
+; RUN: llvm-readobj -t %t1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@tsp_int = thread_local global i32 1
+
+define void @_start() {
+ %val = load i32, i32* @tsp_int
+ ret void
+}
+
+; CHECK: Symbol {
+; CHECK: Name: tsp_int
+; CHECK-NEXT: Value: 0x0
+; CHECK-NEXT: Size: 4
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: TLS
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .tdata
+; CHECK-NEXT: }
diff --git a/test/ELF/lto/type-merge.ll b/test/ELF/lto/type-merge.ll
new file mode 100644
index 000000000000..98db53970b0c
--- /dev/null
+++ b/test/ELF/lto/type-merge.ll
@@ -0,0 +1,26 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-as %p/Inputs/type-merge.ll -o %t2.o
+; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -shared -save-temps
+; RUN: llvm-dis < %t.lto.bc | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @foo() {
+ call void @bar(i8* null)
+ ret void
+}
+declare void @bar(i8*)
+
+; CHECK: define void @foo() {
+; CHECK-NEXT: call void @bar(i8* null)
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+
+; CHECK: declare void @bar(i8*)
+
+; CHECK: define void @zed() {
+; CHECK-NEXT: call void bitcast (void (i8*)* @bar to void ()*)()
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
diff --git a/test/ELF/lto/type-merge2.ll b/test/ELF/lto/type-merge2.ll
new file mode 100644
index 000000000000..f0931ddc9d5e
--- /dev/null
+++ b/test/ELF/lto/type-merge2.ll
@@ -0,0 +1,27 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-as %p/Inputs/type-merge2.ll -o %t2.o
+; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared -save-temps
+; RUN: llvm-dis %t.so.lto.bc -o - | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+%zed = type { i8 }
+define void @foo() {
+ call void @bar(%zed* null)
+ ret void
+}
+declare void @bar(%zed*)
+
+; CHECK: %zed = type { i8 }
+; CHECK-NEXT: %zed.0 = type { i16 }
+
+; CHECK: define void @foo() {
+; CHECK-NEXT: call void bitcast (void (%zed.0*)* @bar to void (%zed*)*)(%zed* null)
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+
+; CHECK: define void @bar(%zed.0* %this) {
+; CHECK-NEXT: store %zed.0* %this, %zed.0** null
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
diff --git a/test/ELF/lto/undef-mixed.ll b/test/ELF/lto/undef-mixed.ll
new file mode 100644
index 000000000000..0fff5781020c
--- /dev/null
+++ b/test/ELF/lto/undef-mixed.ll
@@ -0,0 +1,22 @@
+; REQUIRES: x86
+; RUN: llvm-mc %p/Inputs/undef-mixed.s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+; RUN: llvm-as %s -o %t2.o
+; RUN: ld.lld %t2.o %t.o -o %t.so -shared
+; RUN: llvm-readobj -t %t.so | FileCheck %s
+
+; CHECK: Name: bar
+; CHECK-NEXT: Value:
+; CHECK-NEXT: Size: 0
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: None
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .text
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @bar()
+define void @foo() {
+ call void @bar()
+ ret void
+}
diff --git a/test/ELF/lto/undef-weak.ll b/test/ELF/lto/undef-weak.ll
new file mode 100644
index 000000000000..215978a73df0
--- /dev/null
+++ b/test/ELF/lto/undef-weak.ll
@@ -0,0 +1,29 @@
+; REQUIRES: x86
+
+; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o
+; RUN: rm -f %t.a
+; RUN: llvm-ar rcs %t.a %t1.o
+
+
+; RUN: llvm-as %s -o %t2.o
+; RUN: ld.lld -m elf_x86_64 %t2.o -o %t2.so %t.a -shared
+; RUN: llvm-readobj -t %t2.so | FileCheck %s
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+declare extern_weak void @f()
+define void @foo() {
+ call void @f()
+ ret void
+}
+
+; We should not fetch the archive member.
+
+; CHECK: Name: f ({{.*}})
+; CHECK-NEXT: Value: 0x0
+; CHECK-NEXT: Size: 0
+; CHECK-NEXT: Binding: Weak
+; CHECK-NEXT: Type: None
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: Undefined
+
diff --git a/test/ELF/lto/undef.ll b/test/ELF/lto/undef.ll
new file mode 100644
index 000000000000..41da61052290
--- /dev/null
+++ b/test/ELF/lto/undef.ll
@@ -0,0 +1,20 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
+; RUN: llvm-readobj -t %t.so | FileCheck %s
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+declare void @bar()
+define void @foo() {
+ call void @bar()
+ ret void
+}
+
+; CHECK: Name: bar
+; CHECK-NEXT: Value: 0x0
+; CHECK-NEXT: Size: 0
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: None
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: Undefined
diff --git a/test/ELF/lto/undefined-puts.ll b/test/ELF/lto/undefined-puts.ll
new file mode 100644
index 000000000000..54fb32cef4a2
--- /dev/null
+++ b/test/ELF/lto/undefined-puts.ll
@@ -0,0 +1,28 @@
+; REQUIRES: x86
+; RUN: llvm-mc %p/Inputs/shared.s -o %t1.o -filetype=obj -triple=x86_64-unknown-linux
+; RUN: ld.lld %t1.o -o %t1.so -shared
+; RUN: llvm-as %s -o %t2.o
+; RUN: ld.lld %t1.so %t2.o -m elf_x86_64 -o %t
+; RUN: llvm-readobj -dyn-symbols -dyn-relocations %t | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@.str = private unnamed_addr constant [6 x i8] c"blah\0A\00", align 1
+
+define i32 @_start() {
+ %str = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0))
+ ret i32 0
+}
+
+declare i32 @printf(i8*, ...)
+
+; Check that puts symbol is present in the dynamic symbol table and
+; there's a relocation for it.
+; CHECK: Dynamic Relocations {
+; CHECK-NEXT: 0x13018 R_X86_64_JUMP_SLOT puts 0x0
+; CHECK-NEXT: }
+
+; CHECK: DynamicSymbols [
+; CHECK: Symbol {
+; CHECK: Name: puts@
diff --git a/test/ELF/lto/unnamed-addr-comdat.ll b/test/ELF/lto/unnamed-addr-comdat.ll
new file mode 100644
index 000000000000..c8c36de88d4c
--- /dev/null
+++ b/test/ELF/lto/unnamed-addr-comdat.ll
@@ -0,0 +1,11 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -save-temps -shared
+; RUN: llvm-dis %t.so.lto.bc -o - | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+$foo = comdat any
+@foo = linkonce_odr unnamed_addr constant i32 42, comdat
+
+; CHECK: @foo = internal unnamed_addr constant i32 42, comdat
diff --git a/test/ELF/lto/unnamed-addr-lib.ll b/test/ELF/lto/unnamed-addr-lib.ll
new file mode 100644
index 000000000000..c1c31f84bc8e
--- /dev/null
+++ b/test/ELF/lto/unnamed-addr-lib.ll
@@ -0,0 +1,21 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-mc %p/Inputs/unnamed-addr-lib.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+; RUN: ld.lld %t2.o -shared -o %t2.so
+; RUN: ld.lld -m elf_x86_64 %t.o %t2.so -o %t.so -save-temps -shared
+; RUN: llvm-dis %t.so.lto.bc -o - | FileCheck %s
+
+; This documents a small limitation of lld's internalization logic. We decide
+; that bar should be in the symbol table because if it is it will preempt the
+; one in the shared library.
+; We could add one extra bit for ODR so that we know that preemption is not
+; necessary, but that is probably not worth it.
+
+; CHECK: @foo = internal unnamed_addr constant i8 42
+; CHECK: @bar = weak_odr unnamed_addr constant i8 42
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@foo = linkonce_odr unnamed_addr constant i8 42
+@bar = linkonce_odr unnamed_addr constant i8 42
diff --git a/test/ELF/lto/unnamed-addr.ll b/test/ELF/lto/unnamed-addr.ll
new file mode 100644
index 000000000000..a2c0105fd85f
--- /dev/null
+++ b/test/ELF/lto/unnamed-addr.ll
@@ -0,0 +1,14 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -shared
+; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+@a = internal unnamed_addr constant i8 42
+
+define i8* @f() {
+ ret i8* @a
+}
+
+; CHECK: @a = internal unnamed_addr constant i8 42
diff --git a/test/ELF/lto/verify-invalid.ll b/test/ELF/lto/verify-invalid.ll
new file mode 100644
index 000000000000..16d6a3e54f12
--- /dev/null
+++ b/test/ELF/lto/verify-invalid.ll
@@ -0,0 +1,17 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \
+; RUN: 2>&1 | FileCheck -check-prefix=DEFAULT %s
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \
+; RUN: -disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @_start() {
+ ret void
+}
+
+; -disable-verify should disable the verification of bitcode.
+; DEFAULT: Pass Arguments: {{.*}} -verify {{.*}} -verify
+; DISABLE-NOT: Pass Arguments: {{.*}} -verify {{.*}} -verify
diff --git a/test/ELF/lto/version-script.ll b/test/ELF/lto/version-script.ll
new file mode 100644
index 000000000000..11a7f073ab51
--- /dev/null
+++ b/test/ELF/lto/version-script.ll
@@ -0,0 +1,50 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: echo "VERSION_1.0{ global: foo; local: *; }; VERSION_2.0{ global: bar; local: *; };" > %t.script
+; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps
+; RUN: llvm-dis < %t2.lto.bc | FileCheck %s
+; RUN: llvm-readobj -V -dyn-symbols %t2 | FileCheck --check-prefix=DSO %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @foo() {
+ ret void
+}
+
+define void @bar() {
+ ret void
+}
+
+; CHECK: define void @foo()
+; CHECK: define void @bar()
+
+; DSO: DynamicSymbols [
+; DSO: Symbol {
+; DSO: Name: @ (0)
+; DSO: Value: 0x0
+; DSO: Size: 0
+; DSO: Binding: Local
+; DSO: Type: None
+; DSO: Other: 0
+; DSO: Section: Undefined
+; DSO: }
+; DSO: Symbol {
+; DSO: Name: foo@@VERSION_1.0
+; DSO: Value: 0x1000
+; DSO: Size: 1
+; DSO: Binding: Global
+; DSO: Type: Function
+; DSO: Other: 0
+; DSO: Section: .text
+; DSO: }
+; DSO: Symbol {
+; DSO: Name: bar@@VERSION_2.0
+; DSO: Value: 0x1010
+; DSO: Size: 1
+; DSO: Binding: Global
+; DSO: Type: Function
+; DSO: Other: 0
+; DSO: Section: .text
+; DSO: }
+; DSO: ]
diff --git a/test/ELF/lto/visibility.ll b/test/ELF/lto/visibility.ll
new file mode 100644
index 000000000000..718cc5b06986
--- /dev/null
+++ b/test/ELF/lto/visibility.ll
@@ -0,0 +1,35 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t1.o
+; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2.o -filetype=obj
+; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
+; RUN: llvm-readobj -t %t.so | FileCheck %s
+
+; CHECK: Name: g
+; CHECK-NEXT: Value: 0x1000
+; CHECK-NEXT: Size: 0
+; CHECK-NEXT: Binding: Local
+; CHECK-NEXT: Type: None
+; CHECK-NEXT: Other [ (0x2)
+; CHECK-NEXT: STV_HIDDEN
+; CHECK-NEXT: ]
+; CHECK-NEXT: Section: .text
+
+; CHECK: Name: a
+; CHECK-NEXT: Value: 0x3000
+; CHECK-NEXT: Size: 0
+; CHECK-NEXT: Binding: Local
+; CHECK-NEXT: Type: None
+; CHECK-NEXT: Other [ (0x2)
+; CHECK-NEXT: STV_HIDDEN
+; CHECK-NEXT: ]
+; CHECK-NEXT: Section: .data
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare hidden void @g()
+define void @f() {
+ call void @g()
+ ret void
+}
+@a = weak hidden global i32 42
diff --git a/test/ELF/lto/weak.ll b/test/ELF/lto/weak.ll
new file mode 100644
index 000000000000..381ef7a1a347
--- /dev/null
+++ b/test/ELF/lto/weak.ll
@@ -0,0 +1,16 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared
+; RUN: llvm-readobj -t %t.so | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define weak void @f() {
+ ret void
+}
+
+; CHECK: Name: f
+; CHECK-NEXT: Value: 0x1000
+; CHECK-NEXT: Size: 1
+; CHECK-NEXT: Binding: Weak
diff --git a/test/ELF/merge-shared-str.s b/test/ELF/merge-shared-str.s
new file mode 100644
index 000000000000..2ab03a4d66ab
--- /dev/null
+++ b/test/ELF/merge-shared-str.s
@@ -0,0 +1,28 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared -O3
+// RUN: llvm-readobj -r -s %t.so | FileCheck %s
+
+
+ .section foo,"aMS",@progbits,1
+ .asciz "bar"
+ .asciz "ar"
+
+ .data
+ .quad foo + 4
+
+
+// CHECK: Name: foo
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_MERGE
+// CHECK-NEXT: SHF_STRINGS
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x1C8
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x1C9
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/merge-shared.s b/test/ELF/merge-shared.s
index 702a4e195f32..4c1d7c06a0ba 100644
--- a/test/ELF/merge-shared.s
+++ b/test/ELF/merge-shared.s
@@ -7,7 +7,7 @@
.long 42
.long 42
- .text
+ .data
.quad foo + 6
diff --git a/test/ELF/merge-string-align.s b/test/ELF/merge-string-align.s
index b06920ac0af8..0cb1afc8ba7d 100644
--- a/test/ELF/merge-string-align.s
+++ b/test/ELF/merge-string-align.s
@@ -1,15 +1,20 @@
// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: ld.lld %t.o -o %t.so -shared
-// RUN: llvm-readobj -s %t.so | FileCheck %s
+// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
- .section .rodata.str1.16,"aMS",@progbits,1
+ .section .rodata.foo,"aMS",@progbits,1
.align 16
.asciz "foo"
- .section .rodata.str1.1,"aMS",@progbits,1
+ .section .rodata.foo2,"aMS",@progbits,1
+ .align 16
.asciz "foo"
+ .section .rodata.bar,"aMS",@progbits,1
+ .align 16
+ .asciz "bar"
+
// CHECK: Name: .rodata
// CHECK-NEXT: Type: SHT_PROGBITS
// CHECK-NEXT: Flags [
@@ -19,10 +24,18 @@
// CHECK-NEXT: ]
// CHECK-NEXT: Address:
// CHECK-NEXT: Offset:
-// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Size: 20
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 16
+// CHECK-NEXT: EntrySize:
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 666F6F00 00000000 00000000 00000000 |foo.............|
+// CHECK-NEXT: 0010: 62617200 |bar.|
+// CHECK-NEXT: )
+
+ .section .rodata.str1.1,"aMS",@progbits,1
+ .asciz "foo"
// CHECK: Name: .rodata
// CHECK-NEXT: Type: SHT_PROGBITS
@@ -37,3 +50,7 @@
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize:
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 666F6F00 |foo.|
+// CHECK-NEXT: )
diff --git a/test/ELF/merge-string-error.s b/test/ELF/merge-string-error.s
index 58a624329ed9..c5088acf63b6 100644
--- a/test/ELF/merge-string-error.s
+++ b/test/ELF/merge-string-error.s
@@ -5,7 +5,7 @@
.section .rodata.str1.1,"aMS",@progbits,1
.asciz "abc"
- .text
+ .data
.long .rodata.str1.1 + 4
-// CHECK: Entry is past the end of the section
+// CHECK: entry is past the end of the section
diff --git a/test/ELF/merge-string-no-null.s b/test/ELF/merge-string-no-null.s
index 70d6bbbc32e8..fd3f5073810a 100644
--- a/test/ELF/merge-string-no-null.s
+++ b/test/ELF/merge-string-no-null.s
@@ -5,4 +5,4 @@
.section .rodata.str1.1,"aMS",@progbits,1
.ascii "abc"
-// CHECK: String is not null terminated
+// CHECK: string is not null terminated
diff --git a/test/ELF/merge-string.s b/test/ELF/merge-string.s
index 40cc4415f956..2ad8afa53d6e 100644
--- a/test/ELF/merge-string.s
+++ b/test/ELF/merge-string.s
@@ -4,6 +4,8 @@
// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s
// RUN: ld.lld -O1 %t.o -o %t.so -shared
// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOTAIL %s
+// RUN: ld.lld -O0 %t.o -o %t.so -shared
+// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOMERGE %s
.section .rodata.str1.1,"aMS",@progbits,1
.asciz "abc"
@@ -32,7 +34,7 @@ zed:
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 1
-// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: EntrySize: 1
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 61626300 |abc.|
// CHECK-NEXT: )
@@ -50,11 +52,29 @@ zed:
// NOTAIL-NEXT: Link: 0
// NOTAIL-NEXT: Info: 0
// NOTAIL-NEXT: AddressAlignment: 1
-// NOTAIL-NEXT: EntrySize: 0
+// NOTAIL-NEXT: EntrySize: 1
// NOTAIL-NEXT: SectionData (
// NOTAIL-NEXT: 0000: 61626300 626300 |abc.bc.|
// NOTAIL-NEXT: )
+// NOMERGE: Name: .rodata
+// NOMERGE-NEXT: Type: SHT_PROGBITS
+// NOMERGE-NEXT: Flags [
+// NOMERGE-NEXT: SHF_ALLOC
+// NOMERGE-NEXT: SHF_MERGE
+// NOMERGE-NEXT: SHF_STRINGS
+// NOMERGE-NEXT: ]
+// NOMERGE-NEXT: Address: 0x1C8
+// NOMERGE-NEXT: Offset: 0x1C8
+// NOMERGE-NEXT: Size: 16
+// NOMERGE-NEXT: Link: 0
+// NOMERGE-NEXT: Info: 0
+// NOMERGE-NEXT: AddressAlignment: 2
+// NOMERGE-NEXT: EntrySize: 0
+// NOMERGE-NEXT: SectionData (
+// NOMERGE-NEXT: 0000: 61626300 61626300 62630000 14000000 |abc.abc.bc......|
+// NOMERGE-NEXT: )
+
// CHECK: Name: .rodata
// CHECK-NEXT: Type: SHT_PROGBITS
// CHECK-NEXT: Flags [
@@ -68,7 +88,7 @@ zed:
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 2
-// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: EntrySize: 2
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 14000000 |....|
// CHECK-NEXT: )
diff --git a/test/ELF/merge.s b/test/ELF/merge.s
index 9cead642fa8c..5039ec2251c0 100644
--- a/test/ELF/merge.s
+++ b/test/ELF/merge.s
@@ -29,7 +29,7 @@ zed:
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 4
-// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: EntrySize: 4
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 10000000 42000000
// CHECK-NEXT: )
@@ -61,7 +61,9 @@ zed:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 2
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .mysec
// CHECK: ]
diff --git a/test/ELF/mips-26.s b/test/ELF/mips-26.s
new file mode 100644
index 000000000000..b463c1ac2127
--- /dev/null
+++ b/test/ELF/mips-26.s
@@ -0,0 +1,95 @@
+# Check R_MIPS_26 relocation handling.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
+# RUN: ld.lld %t2.o -shared -o %t.so
+# RUN: ld.lld %t1.o %t.so -o %t.exe
+# RUN: llvm-objdump -d %t.exe | FileCheck %s
+# RUN: llvm-readobj -dynamic-table -s -r -mips-plt-got %t.exe \
+# RUN: | FileCheck -check-prefix=REL %s
+
+# REQUIRES: mips
+
+# CHECK: Disassembly of section .text:
+# CHECK-NEXT: bar:
+# CHECK-NEXT: 20000: 0c 00 80 06 jal 131096 <loc>
+# CHECK-NEXT: 20004: 00 00 00 00 nop
+#
+# CHECK: __start:
+# CHECK-NEXT: 20008: 0c 00 80 00 jal 131072 <bar>
+# CHECK-NEXT: 2000c: 00 00 00 00 nop
+# CHECK-NEXT: 20010: 0c 00 80 10 jal 131136
+# ^-- 0x20040 gotplt[foo0]
+# CHECK-NEXT: 20014: 00 00 00 00 nop
+#
+# CHECK: loc:
+# CHECK-NEXT: 20018: 00 00 00 00 nop
+# CHECK-NEXT: Disassembly of section .plt:
+# CHECK-NEXT: .plt:
+# CHECK-NEXT: 20020: 3c 1c 00 04 lui $gp, 4
+# CHECK-NEXT: 20024: 8f 99 00 04 lw $25, 4($gp)
+# CHECK-NEXT: 20028: 27 9c 00 04 addiu $gp, $gp, 4
+# CHECK-NEXT: 2002c: 03 1c c0 23 subu $24, $24, $gp
+# CHECK-NEXT: 20030: 03 e0 78 25 move $15, $ra
+# CHECK-NEXT: 20034: 00 18 c0 82 srl $24, $24, 2
+# CHECK-NEXT: 20038: 03 20 f8 09 jalr $25
+# CHECK-NEXT: 2003c: 27 18 ff fe addiu $24, $24, -2
+# CHECK-NEXT: 20040: 3c 0f 00 04 lui $15, 4
+# CHECK-NEXT: 20044: 8d f9 00 0c lw $25, 12($15)
+# CHECK-NEXT: 20048: 03 20 00 08 jr $25
+# CHECK-NEXT: 2004c: 25 f8 00 0c addiu $24, $15, 12
+
+# REL: Name: .plt
+# REL-NEXT: Type: SHT_PROGBITS
+# REL-NEXT: Flags [ (0x6)
+# REL-NEXT: SHF_ALLOC
+# REL-NEXT: SHF_EXECINSTR
+# REL-NEXT: ]
+# REL-NEXT: Address: 0x[[PLTADDR:[0-9A-F]+]]
+
+# REL: Name: .got.plt
+# REL-NEXT: Type: SHT_PROGBITS
+# REL-NEXT: Flags [ (0x3)
+# REL-NEXT: SHF_ALLOC
+# REL-NEXT: SHF_WRITE
+# REL-NEXT: ]
+# REL-NEXT: Address: 0x[[GOTPLTADDR:[0-9A-F]+]]
+
+# REL: Relocations [
+# REL-NEXT: Section (7) .rel.plt {
+# REL-NEXT: 0x[[PLTSLOT:[0-9A-F]+]] R_MIPS_JUMP_SLOT foo0 0x0
+# REL-NEXT: }
+# REL-NEXT: ]
+
+# REL: 0x70000032 MIPS_PLTGOT 0x[[GOTPLTADDR]]
+
+# REL: Primary GOT {
+# REL: Local entries [
+# REL-NEXT: ]
+# REL-NEXT: Global entries [
+# REL-NEXT: ]
+# REL: PLT GOT {
+# REL: Entries [
+# REL-NEXT: Entry {
+# REL-NEXT: Address: 0x[[PLTSLOT]]
+# REL-NEXT: Initial: 0x[[PLTADDR]]
+# REL-NEXT: Value: 0x0
+# REL-NEXT: Type: Function
+# REL-NEXT: Section: Undefined
+# REL-NEXT: Name: foo0
+# REL-NEXT: }
+# REL-NEXT: ]
+
+ .text
+ .globl bar
+bar:
+ jal loc # R_MIPS_26 against .text + offset
+
+ .globl __start
+__start:
+ jal bar # R_MIPS_26 against global 'bar' from object file
+ jal foo0 # R_MIPS_26 against 'foo0' from DSO
+
+loc:
+ nop
diff --git a/test/ELF/mips-32.s b/test/ELF/mips-32.s
new file mode 100644
index 000000000000..7875c48d64d7
--- /dev/null
+++ b/test/ELF/mips-32.s
@@ -0,0 +1,78 @@
+# Check R_MIPS_32 relocation calculation.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
+# RUN: ld.lld -shared %t-be.o -o %t-be.so
+# RUN: llvm-objdump -t -s %t-be.so \
+# RUN: | FileCheck -check-prefix=SYM -check-prefix=BE %s
+# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-be.so \
+# RUN: | FileCheck -check-prefix=REL %s
+
+# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
+# RUN: ld.lld -shared %t-el.o -o %t-el.so
+# RUN: llvm-objdump -t -s %t-el.so \
+# RUN: | FileCheck -check-prefix=SYM -check-prefix=EL %s
+# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-el.so \
+# RUN: | FileCheck -check-prefix=REL %s
+
+# REQUIRES: mips
+
+ .globl __start
+__start:
+ nop
+
+ .data
+ .type v1,@object
+ .size v1,4
+v1:
+ .word 0
+
+ .globl v2
+ .type v2,@object
+ .size v2,8
+v2:
+ .word v2+4 # R_MIPS_32 target v2 addend 4
+ .word v1 # R_MIPS_32 target v1 addend 0
+
+# BE: Contents of section .data:
+# BE-NEXT: 30000 00000000 00000004 00030000
+# ^-- v2+4 ^-- v1
+
+# EL: Contents of section .data:
+# EL-NEXT: 30000 00000000 04000000 00000300
+# ^-- v2+4 ^-- v1
+
+# SYM: SYMBOL TABLE:
+# SYM: 00030000 l .data 00000004 v1
+# SYM: 00030004 g .data 00000008 v2
+
+# REL: Relocations [
+# REL-NEXT: Section (7) .rel.dyn {
+# REL-NEXT: 0x30008 R_MIPS_REL32 - 0x0
+# REL-NEXT: 0x30004 R_MIPS_REL32 v2 0x0
+# REL-NEXT: }
+# REL-NEXT: ]
+
+# REL: DynamicSection [
+# REL: Tag Type Name/Value
+# REL: 0x00000012 RELSZ 16 (bytes)
+# REL: 0x00000013 RELENT 8 (bytes)
+
+# REL: Primary GOT {
+# REL-NEXT: Canonical gp value:
+# REL-NEXT: Reserved entries [
+# REL: ]
+# REL-NEXT: Local entries [
+# REL-NEXT: ]
+# REL-NEXT: Global entries [
+# REL-NEXT: Entry {
+# REL-NEXT: Address:
+# REL-NEXT: Access:
+# REL-NEXT: Initial: 0x30004
+# REL-NEXT: Value: 0x30004
+# REL-NEXT: Type: Object
+# REL-NEXT: Section: .data
+# REL-NEXT: Name: v2
+# REL-NEXT: }
+# REL-NEXT: ]
+# REL-NEXT: Number of TLS and multi-GOT entries: 0
+# REL-NEXT: }
diff --git a/test/ELF/mips-64-disp.s b/test/ELF/mips-64-disp.s
new file mode 100644
index 000000000000..1c66ba4fb9a1
--- /dev/null
+++ b/test/ELF/mips-64-disp.s
@@ -0,0 +1,89 @@
+# Check R_MIPS_GOT_DISP relocations against various kind of symbols.
+
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
+# RUN: %p/Inputs/mips-pic.s -o %t.so.o
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.exe.o
+# RUN: ld.lld %t.so.o -shared -o %t.so
+# RUN: ld.lld %t.exe.o %t.so -o %t.exe
+# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
+# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s
+
+# REQUIRES: mips
+
+# CHECK: __start:
+# CHECK-NEXT: 20000: 24 42 80 40 addiu $2, $2, -32704
+# CHECK-NEXT: 20004: 24 42 80 20 addiu $2, $2, -32736
+# CHECK-NEXT: 20008: 24 42 80 28 addiu $2, $2, -32728
+# CHECK-NEXT: 2000c: 24 42 80 30 addiu $2, $2, -32720
+# CHECK-NEXT: 20010: 24 42 80 38 addiu $2, $2, -32712
+
+# CHECK: 0000000000020014 .text 00000000 foo
+# CHECK: 0000000000037ff0 .got 00000000 .hidden _gp
+# CHECK: 0000000000020000 .text 00000000 __start
+# CHECK: 0000000000000000 g F *UND* 00000000 foo1a
+
+# GOT: Relocations [
+# GOT-NEXT: ]
+# GOT-NEXT: Primary GOT {
+# GOT-NEXT: Canonical gp value: 0x37FF0
+# GOT-NEXT: Reserved entries [
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30000
+# GOT-NEXT: Access: -32752
+# GOT-NEXT: Initial: 0x0
+# GOT-NEXT: Purpose: Lazy resolver
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30008
+# GOT-NEXT: Access: -32744
+# GOT-NEXT: Initial: 0x8000000000000000
+# GOT-NEXT: Purpose: Module pointer (GNU extension)
+# GOT-NEXT: }
+# GOT-NEXT: ]
+# GOT-NEXT: Local entries [
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30010
+# GOT-NEXT: Access: -32736
+# GOT-NEXT: Initial: 0x20014
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30018
+# GOT-NEXT: Access: -32728
+# GOT-NEXT: Initial: 0x20004
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30020
+# GOT-NEXT: Access: -32720
+# GOT-NEXT: Initial: 0x20008
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30028
+# GOT-NEXT: Access: -32712
+# GOT-NEXT: Initial: 0x2000C
+# GOT-NEXT: }
+# GOT-NEXT: ]
+# GOT-NEXT: Global entries [
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30030
+# GOT-NEXT: Access: -32704
+# GOT-NEXT: Initial: 0x0
+# GOT-NEXT: Value: 0x0
+# GOT-NEXT: Type: Function
+# GOT-NEXT: Section: Undefined
+# GOT-NEXT: Name: foo1a
+# GOT-NEXT: }
+# GOT-NEXT: ]
+# GOT-NEXT: Number of TLS and multi-GOT entries: 0
+# GOT-NEXT: }
+
+ .text
+ .global __start
+__start:
+ addiu $v0,$v0,%got_disp(foo1a) # R_MIPS_GOT_DISP
+ addiu $v0,$v0,%got_disp(foo) # R_MIPS_GOT_DISP
+ addiu $v0,$v0,%got_disp(.text+4) # R_MIPS_GOT_DISP
+ addiu $v0,$v0,%got_disp(.text+8) # R_MIPS_GOT_DISP
+ addiu $v0,$v0,%got_disp(.text+12) # R_MIPS_GOT_DISP
+
+foo:
+ nop
diff --git a/test/ELF/mips-64-got.s b/test/ELF/mips-64-got.s
new file mode 100644
index 000000000000..52ce6fb4d351
--- /dev/null
+++ b/test/ELF/mips-64-got.s
@@ -0,0 +1,87 @@
+# Check MIPS N64 ABI GOT relocations
+
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
+# RUN: %p/Inputs/mips-pic.s -o %t.so.o
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.exe.o
+# RUN: ld.lld %t.so.o -shared -o %t.so
+# RUN: ld.lld %t.exe.o %t.so -o %t.exe
+# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
+# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s
+
+# REQUIRES: mips
+
+# CHECK: __start:
+
+# CHECK-NEXT: 20000: df 82 80 20 ld $2, -32736($gp)
+# CHECK-NEXT: 20004: 64 42 00 18 daddiu $2, $2, 24
+# CHECK-NEXT: 20008: 24 42 80 38 addiu $2, $2, -32712
+# CHECK-NEXT: 2000c: 24 42 80 28 addiu $2, $2, -32728
+# CHECK-NEXT: 20010: 24 42 80 30 addiu $2, $2, -32720
+
+# CHECK: 0000000000020018 .text 00000000 foo
+# CHECK: 0000000000037ff0 .got 00000000 .hidden _gp
+# CHECK: 0000000000020000 .text 00000000 __start
+# CHECK: 0000000000020014 .text 00000000 bar
+
+# GOT: Relocations [
+# GOT-NEXT: ]
+# GOT-NEXT: Primary GOT {
+# GOT-NEXT: Canonical gp value: 0x37FF0
+# GOT-NEXT: Reserved entries [
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30000
+# GOT-NEXT: Access: -32752
+# GOT-NEXT: Initial: 0x0
+# GOT-NEXT: Purpose: Lazy resolver
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30008
+# GOT-NEXT: Access: -32744
+# GOT-NEXT: Initial: 0x8000000000000000
+# GOT-NEXT: Purpose: Module pointer (GNU extension)
+# GOT-NEXT: }
+# GOT-NEXT: ]
+# GOT-NEXT: Local entries [
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30010
+# GOT-NEXT: Access: -32736
+# GOT-NEXT: Initial: 0x20000
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30018
+# GOT-NEXT: Access: -32728
+# GOT-NEXT: Initial: 0x20014
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30020
+# GOT-NEXT: Access: -32720
+# GOT-NEXT: Initial: 0x20018
+# GOT-NEXT: }
+# GOT-NEXT: ]
+# GOT-NEXT: Global entries [
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x30028
+# GOT-NEXT: Access: -32712
+# GOT-NEXT: Initial: 0x0
+# GOT-NEXT: Value: 0x0
+# GOT-NEXT: Type: Function
+# GOT-NEXT: Section: Undefined
+# GOT-NEXT: Name: foo1a
+# GOT-NEXT: }
+# GOT-NEXT: ]
+# GOT-NEXT: Number of TLS and multi-GOT entries: 0
+# GOT-NEXT: }
+
+ .text
+ .global __start, bar
+__start:
+ ld $v0,%got_page(foo)($gp) # R_MIPS_GOT_PAGE
+ daddiu $v0,$v0,%got_ofst(foo) # R_MIPS_GOT_OFST
+ addiu $v0,$v0,%got_disp(foo1a) # R_MIPS_GOT_DISP
+ addiu $v0,$v0,%got_disp(bar) # R_MIPS_GOT_DISP
+ addiu $v0,$v0,%got_disp(foo) # R_MIPS_GOT_DISP
+
+bar:
+ nop
+foo:
+ nop
diff --git a/test/ELF/mips-64-gprel-so.s b/test/ELF/mips-64-gprel-so.s
new file mode 100644
index 000000000000..437238ef5f26
--- /dev/null
+++ b/test/ELF/mips-64-gprel-so.s
@@ -0,0 +1,23 @@
+# Check setup of GP relative offsets in a function's prologue.
+
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -shared -o %t.so
+# RUN: llvm-objdump -d -t %t.so | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Disassembly of section .text:
+# CHECK-NEXT: foo:
+# CHECK-NEXT: 10000: 3c 1c 00 01 lui $gp, 1
+# CHECK-NEXT: 10004: 03 99 e0 2d daddu $gp, $gp, $25
+# CHECK-NEXT: 10008: 67 9c 7f f0 daddiu $gp, $gp, 32752
+
+# CHECK: 0000000000027ff0 .got 00000000 .hidden _gp
+# CHECK: 0000000000010000 .text 00000000 foo
+
+ .text
+ .global foo
+foo:
+ lui $gp,%hi(%neg(%gp_rel(foo)))
+ daddu $gp,$gp,$t9
+ daddiu $gp,$gp,%lo(%neg(%gp_rel(foo)))
diff --git a/test/ELF/mips-64-rels.s b/test/ELF/mips-64-rels.s
new file mode 100644
index 000000000000..7126afc1e595
--- /dev/null
+++ b/test/ELF/mips-64-rels.s
@@ -0,0 +1,46 @@
+# Check handling multiple MIPS N64 ABI relocations packed
+# into the single relocation record.
+
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t.exe
+# RUN: llvm-objdump -d -s -t %t.exe | FileCheck %s
+# RUN: llvm-readobj -r %t.exe | FileCheck -check-prefix=REL %s
+
+# REQUIRES: mips
+
+# CHECK: __start:
+# CHECK-NEXT: 20000: 3c 1c 00 01 lui $gp, 1
+# ^-- 0x20000 - 0x37ff0
+# ^-- 0 - 0xfffffffffffe8010
+# ^-- %hi(0x17ff0)
+# CHECK: loc:
+# CHECK-NEXT: 20004: 67 9c 7f f0 daddiu $gp, $gp, 32752
+# ^-- 0x20000 - 0x37ff0
+# ^-- 0 - 0xfffffffffffe8010
+# ^-- %lo(0x17ff0)
+
+# CHECK: Contents of section .rodata:
+# CHECK-NEXT: 10190 ffffffff fffe8014
+# ^-- 0x20004 - 0x37ff0 = 0xfffffffffffe8014
+
+# CHECK: 0000000000020004 .text 00000000 loc
+# CHECK: 0000000000037ff0 .got 00000000 .hidden _gp
+# CHECK: 0000000000020000 .text 00000000 __start
+
+# REL: Relocations [
+# REL-NEXT: ]
+
+ .text
+ .global __start
+__start:
+ lui $gp,%hi(%neg(%gp_rel(__start))) # R_MIPS_GPREL16
+ # R_MIPS_SUB
+ # R_MIPS_HI16
+loc:
+ daddiu $gp,$gp,%lo(%neg(%gp_rel(__start))) # R_MIPS_GPREL16
+ # R_MIPS_SUB
+ # R_MIPS_LO16
+
+ .section .rodata,"a",@progbits
+ .gpdword(loc) # R_MIPS_GPREL32
+ # R_MIPS_64
diff --git a/test/ELF/mips-64.s b/test/ELF/mips-64.s
new file mode 100644
index 000000000000..689669e4b09f
--- /dev/null
+++ b/test/ELF/mips-64.s
@@ -0,0 +1,63 @@
+# Check R_MIPS_64 relocation calculation.
+
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t.so
+# RUN: llvm-objdump -t %t.so | FileCheck -check-prefix=SYM %s
+# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t.so | FileCheck %s
+
+# REQUIRES: mips
+
+ .global __start
+__start:
+ nop
+
+ .data
+ .type v1,@object
+ .size v1,4
+v1:
+ .quad 0
+
+ .globl v2
+ .type v2,@object
+ .size v2,8
+v2:
+ .quad v2+8 # R_MIPS_64 target v2 addend 8
+ .quad v1 # R_MIPS_64 target v1 addend 0
+
+
+# SYM: SYMBOL TABLE:
+# SYM: 00030000 l .data 00000004 v1
+# SYM: 00030008 g .data 00000008 v2
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section (7) .rela.dyn {
+# CHECK-NEXT: 0x30010 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE - 0x30000
+# ^-- v1
+# CHECK-NEXT: 0x30008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE v2 0x8
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# CHECK: DynamicSection [
+# CHECK: Tag Type Name/Value
+# CHECK: 0x0000000000000008 RELASZ 48 (bytes)
+# CHECK: 0x0000000000000009 RELAENT 24 (bytes)
+
+# CHECK: Primary GOT {
+# CHECK-NEXT: Canonical gp value:
+# CHECK-NEXT: Reserved entries [
+# CHECK: ]
+# CHECK-NEXT: Local entries [
+# CHECK-NEXT: ]
+# CHECK-NEXT: Global entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Access:
+# CHECK-NEXT: Initial: 0x30008
+# CHECK-NEXT: Value: 0x30008
+# CHECK-NEXT: Type: Object
+# CHECK-NEXT: Section: .data
+# CHECK-NEXT: Name: v2
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Number of TLS and multi-GOT entries: 0
+# CHECK-NEXT: }
diff --git a/test/ELF/mips-align-err.s b/test/ELF/mips-align-err.s
new file mode 100644
index 000000000000..28b192ac29f3
--- /dev/null
+++ b/test/ELF/mips-align-err.s
@@ -0,0 +1,12 @@
+# REQUIRES: mips
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o \
+# RUN: -mcpu=mips32r6
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: -mcpu=mips32r6 %S/Inputs/mips-align-err.s -o %t2.o
+# RUN: not ld.lld %t.o %t2.o -o %t.exe 2>&1 | FileCheck %s
+# CHECK: improper alignment for relocation R_MIPS_PC16
+
+ .globl __start
+__start:
+.zero 1
+ beqc $5, $6, _foo # R_MIPS_PC16
diff --git a/test/ELF/mips-dynamic.s b/test/ELF/mips-dynamic.s
index 626a3556d361..3cb5c63a49f2 100644
--- a/test/ELF/mips-dynamic.s
+++ b/test/ELF/mips-dynamic.s
@@ -8,6 +8,10 @@
# RUN: llvm-readobj -sections -dynamic-table %t.exe \
# RUN: | FileCheck -check-prefix=EXE %s
+# RUN: ld.lld %t.o --image-base=0x123000 %td.so -o %t.exe
+# RUN: llvm-readobj -sections -dynamic-table %t.exe \
+# RUN: | FileCheck -check-prefix=IMAGE_BASE %s
+
# RUN: ld.lld -shared %t.o %td.so -o %t.so
# RUN: llvm-readobj -sections -dyn-symbols -dynamic-table %t.so \
# RUN: | FileCheck -check-prefix=DSO %s
@@ -24,6 +28,7 @@
# EXE-NEXT: Type: SHT_PROGBITS
# EXE-NEXT: Flags [ (0x10000003)
# EXE-NEXT: SHF_ALLOC
+# EXE-NEXT: SHF_MIPS_GPREL
# EXE-NEXT: SHF_WRITE
# EXE-NEXT: ]
# EXE-NEXT: Address: [[GOTADDR:0x[0-9a-f]+]]
@@ -44,13 +49,15 @@
# EXE-DAG: 0x00000003 PLTGOT [[GOTADDR]]
# EXE-DAG: 0x70000001 MIPS_RLD_VERSION 1
# EXE-DAG: 0x70000005 MIPS_FLAGS NOTPOT
-# EXE-DAG: 0x70000006 MIPS_BASE_ADDRESS
+# EXE-DAG: 0x70000006 MIPS_BASE_ADDRESS 0x10000
# EXE-DAG: 0x7000000A MIPS_LOCAL_GOTNO 2
-# EXE-DAG: 0x70000011 MIPS_SYMTABNO 1
-# EXE-DAG: 0x70000013 MIPS_GOTSYM 0x1
+# EXE-DAG: 0x70000011 MIPS_SYMTABNO 2
+# EXE-DAG: 0x70000013 MIPS_GOTSYM 0x2
# EXE-DAG: 0x70000016 MIPS_RLD_MAP [[RLDMAPADDR]]
# EXE: ]
+# IMAGE_BASE: 0x70000006 MIPS_BASE_ADDRESS 0x123000
+
# DSO: Sections [
# DSO: Name: .dynamic
# DSO-NEXT: Type: SHT_DYNAMIC
@@ -61,6 +68,7 @@
# DSO-NEXT: Type: SHT_PROGBITS
# DSO-NEXT: Flags [ (0x10000003)
# DSO-NEXT: SHF_ALLOC
+# DSO-NEXT: SHF_MIPS_GPREL
# DSO-NEXT: SHF_WRITE
# DSO-NEXT: ]
# DSO-NEXT: Address: [[GOTADDR:0x[0-9a-f]+]]
@@ -69,7 +77,6 @@
# DSO: ]
# DSO: DynamicSymbols [
# DSO: Name: @
-# DSO: Name: _gp@
# DSO: Name: __start@
# DSO: Name: _foo@
# DSO: ]
@@ -80,8 +87,8 @@
# DSO-DAG: 0x70000005 MIPS_FLAGS NOTPOT
# DSO-DAG: 0x70000006 MIPS_BASE_ADDRESS 0x0
# DSO-DAG: 0x7000000A MIPS_LOCAL_GOTNO 2
-# DSO-DAG: 0x70000011 MIPS_SYMTABNO 4
-# DSO-DAG: 0x70000013 MIPS_GOTSYM 0x4
+# DSO-DAG: 0x70000011 MIPS_SYMTABNO 3
+# DSO-DAG: 0x70000013 MIPS_GOTSYM 0x3
# DSO: ]
.text
diff --git a/test/ELF/mips-gnu-hash.s b/test/ELF/mips-gnu-hash.s
index 4b11f213518c..288d54043fc1 100644
--- a/test/ELF/mips-gnu-hash.s
+++ b/test/ELF/mips-gnu-hash.s
@@ -6,7 +6,7 @@
# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
# RUN: not ld.lld -shared -hash-style=gnu %t-el.o -o %t-el.so 2>&1 | FileCheck %s
-# CHECK: The .gnu.hash section is not compatible with the MIPS target.
+# CHECK: the .gnu.hash section is not compatible with the MIPS target.
# REQUIRES: mips
diff --git a/test/ELF/mips-got-and-copy.s b/test/ELF/mips-got-and-copy.s
new file mode 100644
index 000000000000..453b8c957b56
--- /dev/null
+++ b/test/ELF/mips-got-and-copy.s
@@ -0,0 +1,57 @@
+# REQUIRES: mips
+
+# If there are two relocations such that the first one requires
+# dynamic COPY relocation, the second one requires GOT entry
+# creation, linker should create both - dynamic relocation
+# and GOT entry.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.so.o -shared -o %t.so
+# RUN: ld.lld %t.o %t.so -o %t.exe
+# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section (7) .rel.dyn {
+# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0
+# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data1
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Primary GOT {
+# CHECK-NEXT: Canonical gp value: 0x37FF0
+# CHECK-NEXT: Reserved entries [
+# CHECK: ]
+# CHECK-NEXT: Local entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x30008
+# CHECK-NEXT: Access: -32744
+# CHECK-NEXT: Initial: 0x40010
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Global entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x3000C
+# CHECK-NEXT: Access: -32740
+# CHECK-NEXT: Initial: 0x40014
+# CHECK-NEXT: Value: 0x40014
+# CHECK-NEXT: Type: Object (0x1)
+# CHECK-NEXT: Section: .bss (0xD)
+# CHECK-NEXT: Name: data1@ (7)
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Number of TLS and multi-GOT entries: 0
+# CHECK-NEXT: }
+
+ .text
+ .global __start
+__start:
+ # Case A: 'got' relocation goes before 'copy' relocation
+ lui $t0,%hi(data0) # R_MIPS_HI16 - requires R_MISP_COPY relocation
+ addi $t0,$t0,%lo(data0)
+ lw $t0,%got(data0)($gp) # R_MIPS_GOT16 - requires GOT entry
+
+ # Case B: 'copy' relocation goes before 'got' relocation
+ lw $t0,%got(data1)($gp) # R_MIPS_GOT16 - requires GOT entry
+ lui $t0,%hi(data1) # R_MIPS_HI16 - requires R_MISP_COPY relocation
+ addi $t0,$t0,%lo(data1)
diff --git a/test/ELF/mips-got-extsym.s b/test/ELF/mips-got-extsym.s
new file mode 100644
index 000000000000..1cf99aeed49b
--- /dev/null
+++ b/test/ELF/mips-got-extsym.s
@@ -0,0 +1,59 @@
+# Check creation of GOT entries for global symbols in case of executable
+# file linking. Symbols defined in DSO should get entries in the global part
+# of the GOT. Symbols defined in the executable itself should get local GOT
+# entries and does not need a row in .dynsym table.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
+# RUN: ld.lld -shared %t.so.o -o %t.so
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o %t.so -o %t.exe
+# RUN: llvm-readobj -dt -t -mips-plt-got %t.exe | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Symbols [
+# CHECK: Symbol {
+# CHECK: Name: _foo
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+
+# CHECK: Symbol {
+# CHECK: Name: bar
+# CHECK-NEXT: Value: 0x20008
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+
+# CHECK: DynamicSymbols [
+# CHECK-NOT: Name: bar
+
+# CHECK: Local entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x30008
+# CHECK-NEXT: Access: -32744
+# CHECK-NEXT: Initial: 0x20008
+# ^-- bar
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Global entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x3000C
+# CHECK-NEXT: Access: -32740
+# CHECK-NEXT: Initial: 0x0
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: Name: _foo@
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+ .text
+ .globl __start
+__start:
+ lw $t0,%got(bar)($gp)
+ lw $t0,%got(_foo)($gp)
+
+.global bar
+bar:
+ .word 0
diff --git a/test/ELF/mips-got-redundant.s b/test/ELF/mips-got-redundant.s
new file mode 100644
index 000000000000..07c3c249f4fa
--- /dev/null
+++ b/test/ELF/mips-got-redundant.s
@@ -0,0 +1,58 @@
+# Check number of redundant entries in the local part of MIPS GOT.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -shared -o %t.so
+# RUN: llvm-readobj -mips-plt-got %t.so | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Local entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x20008
+# CHECK-NEXT: Access: -32744
+# CHECK-NEXT: Initial: 0x30000
+# ^-- loc1
+# CHECK-NEXT: }
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x2000C
+# CHECK-NEXT: Access: -32740
+# CHECK-NEXT: Initial: 0x40000
+# ^-- loc2, loc3, loc4
+# CHECK-NEXT: }
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x20010
+# CHECK-NEXT: Access: -32736
+# CHECK-NEXT: Initial: 0x40008
+# ^-- glb1
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+ .text
+ .globl foo
+foo:
+ lw $t0, %got(loc1)($gp)
+ addi $t0, $t0, %lo(loc1)
+ lw $t0, %got(loc2)($gp)
+ addi $t0, $t0, %lo(loc2)
+ lw $t0, %got(loc3)($gp)
+ addi $t0, $t0, %lo(loc3)
+ lw $t0, %got(loc4)($gp)
+ addi $t0, $t0, %lo(loc4)
+ lw $t0, %got(glb1)($gp)
+ lw $t0, %got(glb1)($gp)
+
+ .section .data.1,"aw",%progbits
+loc1:
+ .space 0x10000
+loc2:
+ .word 0
+loc3:
+ .word 0
+ .global glb1
+ .hidden glb1
+glb1:
+ .word 0
+
+ .section .data.2,"aw",%progbits
+loc4:
+ .word 0
diff --git a/test/ELF/mips-got-relocs.s b/test/ELF/mips-got-relocs.s
index 27180fbf82ea..c44cf90b7be3 100644
--- a/test/ELF/mips-got-relocs.s
+++ b/test/ELF/mips-got-relocs.s
@@ -47,10 +47,11 @@ v1:
# EXE_SYM: Sections:
# EXE_SYM: .got 0000000c 0000000000030000 DATA
# EXE_SYM: SYMBOL TABLE:
-# EXE_SYM: 00037ff0 *ABS* 00000000 _gp
+# EXE_SYM: 00037ff0 .got 00000000 .hidden _gp
# ^-- .got + GP offset (0x7ff0)
# EXE_SYM: 00040000 g .data 00000004 v1
+
# EXE_GOT_BE: Contents of section .got:
# EXE_GOT_BE: 30000 00000000 80000000 00040000
# ^ ^ ^-- v1 (0x40000)
@@ -70,7 +71,7 @@ v1:
# DSO_SYM: Sections:
# DSO_SYM: .got 0000000c 0000000000020000 DATA
# DSO_SYM: SYMBOL TABLE:
-# DSO_SYM: 00027ff0 *ABS* 00000000 _gp
+# DSO_SYM: 00027ff0 .got 00000000 .hidden _gp
# ^-- .got + GP offset (0x7ff0)
# DSO_SYM: 00030000 g .data 00000004 v1
diff --git a/test/ELF/mips-got-weak.s b/test/ELF/mips-got-weak.s
new file mode 100644
index 000000000000..a77924692a10
--- /dev/null
+++ b/test/ELF/mips-got-weak.s
@@ -0,0 +1,172 @@
+# Check R_MIPS_GOT16 relocation against weak symbols.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -shared -o %t1.so
+# RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t1.so \
+# RUN: | FileCheck -check-prefix=NOSYM %s
+# RUN: ld.lld %t.o -shared -Bsymbolic -o %t2.so
+# RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t2.so \
+# RUN: | FileCheck -check-prefix=SYM %s
+
+# REQUIRES: mips
+
+# NOSYM: Relocations [
+# NOSYM-NEXT: ]
+
+# NOSYM: Symbol {
+# NOSYM: Name: foo
+# NOSYM-NEXT: Value: 0x30000
+# NOSYM-NEXT: Size: 0
+# NOSYM-NEXT: Binding: Weak
+# NOSYM-NEXT: Type: None
+# NOSYM-NEXT: Other: 0
+# NOSYM-NEXT: Section: .data
+# NOSYM-NEXT: }
+# NOSYM-NEXT: Symbol {
+# NOSYM-NEXT: Name: bar
+# NOSYM-NEXT: Value: 0x0
+# NOSYM-NEXT: Size: 0
+# NOSYM-NEXT: Binding: Weak
+# NOSYM-NEXT: Type: None
+# NOSYM-NEXT: Other: 0
+# NOSYM-NEXT: Section: Undefined
+# NOSYM-NEXT: }
+# NOSYM-NEXT: Symbol {
+# NOSYM-NEXT: Name: sym
+# NOSYM-NEXT: Value: 0x30004
+# NOSYM-NEXT: Size: 0
+# NOSYM-NEXT: Binding: Global
+# NOSYM-NEXT: Type: None
+# NOSYM-NEXT: Other: 0
+# NOSYM-NEXT: Section: .data
+# NOSYM-NEXT: }
+# NOSYM-NEXT: ]
+
+# NOSYM: 0x70000011 MIPS_SYMTABNO 4
+# NOSYM-NEXT: 0x7000000A MIPS_LOCAL_GOTNO 2
+# NOSYM-NEXT: 0x70000013 MIPS_GOTSYM 0x1
+
+# NOSYM: Primary GOT {
+# NOSYM-NEXT: Canonical gp value: 0x27FF0
+# NOSYM-NEXT: Reserved entries [
+# NOSYM-NEXT: Entry {
+# NOSYM-NEXT: Address: 0x20000
+# NOSYM-NEXT: Access: -32752
+# NOSYM-NEXT: Initial: 0x0
+# NOSYM-NEXT: Purpose: Lazy resolver
+# NOSYM-NEXT: }
+# NOSYM-NEXT: Entry {
+# NOSYM-NEXT: Address: 0x20004
+# NOSYM-NEXT: Access: -32748
+# NOSYM-NEXT: Initial: 0x80000000
+# NOSYM-NEXT: Purpose: Module pointer (GNU extension)
+# NOSYM-NEXT: }
+# NOSYM-NEXT: ]
+# NOSYM-NEXT: Local entries [
+# NOSYM-NEXT: ]
+# NOSYM-NEXT: Global entries [
+# NOSYM-NEXT: Entry {
+# NOSYM-NEXT: Address: 0x20008
+# NOSYM-NEXT: Access: -32744
+# NOSYM-NEXT: Initial: 0x30000
+# NOSYM-NEXT: Value: 0x30000
+# NOSYM-NEXT: Type: None
+# NOSYM-NEXT: Section: .data
+# NOSYM-NEXT: Name: foo
+# NOSYM-NEXT: }
+# NOSYM-NEXT: Entry {
+# NOSYM-NEXT: Address: 0x2000C
+# NOSYM-NEXT: Access: -32740
+# NOSYM-NEXT: Initial: 0x0
+# NOSYM-NEXT: Value: 0x0
+# NOSYM-NEXT: Type: None
+# NOSYM-NEXT: Section: Undefined
+# NOSYM-NEXT: Name: bar
+# NOSYM-NEXT: }
+# NOSYM-NEXT: Entry {
+# NOSYM-NEXT: Address: 0x20010
+# NOSYM-NEXT: Access: -32736
+# NOSYM-NEXT: Initial: 0x30004
+# NOSYM-NEXT: Value: 0x30004
+# NOSYM-NEXT: Type: None
+# NOSYM-NEXT: Section: .data
+# NOSYM-NEXT: Name: sym
+# NOSYM-NEXT: }
+# NOSYM-NEXT: ]
+# NOSYM-NEXT: Number of TLS and multi-GOT entries: 0
+# NOSYM-NEXT: }
+
+# SYM: Relocations [
+# SYM-NEXT: ]
+
+# SYM: Symbol {
+# SYM: Name: bar
+# SYM-NEXT: Value: 0x0
+# SYM-NEXT: Size: 0
+# SYM-NEXT: Binding: Weak
+# SYM-NEXT: Type: None
+# SYM-NEXT: Other: 0
+# SYM-NEXT: Section: Undefined
+# SYM-NEXT: }
+# SYM-NEXT: ]
+
+# SYM: 0x70000011 MIPS_SYMTABNO 4
+# SYM-NEXT: 0x7000000A MIPS_LOCAL_GOTNO 4
+# SYM-NEXT: 0x70000013 MIPS_GOTSYM 0x3
+
+# SYM: Primary GOT {
+# SYM-NEXT: Canonical gp value: 0x27FF0
+# SYM-NEXT: Reserved entries [
+# SYM-NEXT: Entry {
+# SYM-NEXT: Address: 0x20000
+# SYM-NEXT: Access: -32752
+# SYM-NEXT: Initial: 0x0
+# SYM-NEXT: Purpose: Lazy resolver
+# SYM-NEXT: }
+# SYM-NEXT: Entry {
+# SYM-NEXT: Address: 0x20004
+# SYM-NEXT: Access: -32748
+# SYM-NEXT: Initial: 0x80000000
+# SYM-NEXT: Purpose: Module pointer (GNU extension)
+# SYM-NEXT: }
+# SYM-NEXT: ]
+# SYM-NEXT: Local entries [
+# SYM-NEXT: Entry {
+# SYM-NEXT: Address: 0x20008
+# SYM-NEXT: Access: -32744
+# SYM-NEXT: Initial: 0x30000
+# SYM-NEXT: }
+# SYM-NEXT: Entry {
+# SYM-NEXT: Address: 0x2000C
+# SYM-NEXT: Access: -32740
+# SYM-NEXT: Initial: 0x30004
+# SYM-NEXT: }
+# SYM-NEXT: ]
+# SYM-NEXT: Global entries [
+# SYM-NEXT: Entry {
+# SYM-NEXT: Address: 0x20010
+# SYM-NEXT: Access: -32736
+# SYM-NEXT: Initial: 0x0
+# SYM-NEXT: Value: 0x0
+# SYM-NEXT: Type: None
+# SYM-NEXT: Section: Undefined
+# SYM-NEXT: Name: bar
+# SYM-NEXT: }
+# SYM-NEXT: ]
+# SYM-NEXT: Number of TLS and multi-GOT entries: 0
+# SYM-NEXT: }
+
+ .text
+ .global sym
+ .weak foo,bar
+func:
+ lw $t0,%got(foo)($gp)
+ lw $t0,%got(bar)($gp)
+ lw $t0,%got(sym)($gp)
+
+ .data
+ .weak foo
+foo:
+ .word 0
+sym:
+ .word 0
diff --git a/test/ELF/mips-got16.s b/test/ELF/mips-got16.s
new file mode 100644
index 000000000000..ef80418ef032
--- /dev/null
+++ b/test/ELF/mips-got16.s
@@ -0,0 +1,120 @@
+# Check R_MIPS_GOT16 relocation calculation.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -shared -o %t.so
+# RUN: llvm-objdump -d -t %t.so | FileCheck %s
+# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
+
+# REQUIRES: mips
+
+# CHECK: Disassembly of section .text:
+# CHECK-NEXT: __start:
+# CHECK-NEXT: 10000: 8f 88 80 18 lw $8, -32744($gp)
+# CHECK-NEXT: 10004: 21 08 00 2c addi $8, $8, 44
+# CHECK-NEXT: 10008: 8f 88 80 1c lw $8, -32740($gp)
+# CHECK-NEXT: 1000c: 21 08 90 00 addi $8, $8, -28672
+# CHECK-NEXT: 10010: 8f 88 80 20 lw $8, -32736($gp)
+# CHECK-NEXT: 10014: 21 08 90 04 addi $8, $8, -28668
+# CHECK-NEXT: 10018: 8f 88 80 20 lw $8, -32736($gp)
+# CHECK-NEXT: 1001c: 21 08 10 04 addi $8, $8, 4100
+# CHECK-NEXT: 10020: 8f 88 80 28 lw $8, -32728($gp)
+# CHECK-NEXT: 10024: 21 08 10 08 addi $8, $8, 4104
+# CHECK-NEXT: 10028: 8f 88 80 2c lw $8, -32724($gp)
+#
+# CHECK: SYMBOL TABLE:
+# CHECK: 00051008 .data 00000000 .hidden bar
+# CHECK: 00000000 *UND* 00000000 foo
+
+# GOT: Relocations [
+# GOT-NEXT: ]
+
+# GOT: Primary GOT {
+# GOT-NEXT: Canonical gp value: 0x27FF0
+# GOT-NEXT: Reserved entries [
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x20000
+# GOT-NEXT: Access: -32752
+# GOT-NEXT: Initial: 0x0
+# GOT-NEXT: Purpose: Lazy resolver
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x20004
+# GOT-NEXT: Access: -32748
+# GOT-NEXT: Initial: 0x80000000
+# GOT-NEXT: Purpose: Module pointer (GNU extension)
+# GOT-NEXT: }
+# GOT-NEXT: ]
+# GOT-NEXT: Local entries [
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x20008
+# GOT-NEXT: Access: -32744
+# GOT-NEXT: Initial: 0x10000
+# ^-- (0x1002c + 0x8000) & ~0xffff
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x2000C
+# GOT-NEXT: Access: -32740
+# GOT-NEXT: Initial: 0x40000
+# ^-- (0x39000 + 0x8000) & ~0xffff
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x20010
+# GOT-NEXT: Access: -32736
+# GOT-NEXT: Initial: 0x50000
+# ^-- (0x39000 + 0x10004 + 0x8000) & ~0xffff
+# ^-- (0x39000 + 0x18004 + 0x8000) & ~0xffff
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x20014
+# GOT-NEXT: Access: -32732
+# GOT-NEXT: Initial: 0x0
+# ^-- redundant unused entry
+# GOT-NEXT: }
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x20018
+# GOT-NEXT: Access: -327
+# GOT-NEXT: Initial: 0x51008
+# ^-- 'bar' address
+# GOT-NEXT: }
+# GOT-NEXT: ]
+# GOT-NEXT: Global entries [
+# GOT-NEXT: Entry {
+# GOT-NEXT: Address: 0x2001C
+# GOT-NEXT: Access: -32724
+# GOT-NEXT: Initial: 0x0
+# GOT-NEXT: Value: 0x0
+# GOT-NEXT: Type: None
+# GOT-NEXT: Section: Undefined
+# GOT-NEXT: Name: foo@
+# GOT-NEXT: }
+# GOT-NEXT: ]
+# GOT-NEXT: Number of TLS and multi-GOT entries: 0
+# GOT-NEXT: }
+
+ .text
+ .globl __start
+__start:
+ lw $t0,%got($LC0)($gp)
+ addi $t0,$t0,%lo($LC0)
+ lw $t0,%got($LC1)($gp)
+ addi $t0,$t0,%lo($LC1)
+ lw $t0,%got($LC1+0x10004)($gp)
+ addi $t0,$t0,%lo($LC1+0x10004)
+ lw $t0,%got($LC1+0x18004)($gp)
+ addi $t0,$t0,%lo($LC1+0x18004)
+ lw $t0,%got(bar)($gp)
+ addi $t0,$t0,%lo(bar)
+ lw $t0,%got(foo)($gp)
+$LC0:
+ nop
+
+ .data
+ .space 0x9000
+$LC1:
+ .word 0
+ .space 0x18000
+ .word 0
+.global bar
+.hidden bar
+bar:
+ .word 0
diff --git a/test/ELF/mips-gp-disp.s b/test/ELF/mips-gp-disp.s
index a08829c18bd4..7a0fd6409d18 100644
--- a/test/ELF/mips-gp-disp.s
+++ b/test/ELF/mips-gp-disp.s
@@ -11,17 +11,20 @@
# REQUIRES: mips
-# INT-SO-NOT: Name: _gp_disp
+# INT-SO: Name: _gp_disp
+# INT-SO-NEXT: Value:
+# INT-SO-NEXT: Size:
+# INT-SO-NEXT: Binding: Local
# EXT-SO: Name: _gp_disp
-# EXT-SO-NEXT: Value: 0x20010
+# EXT-SO-NEXT: Value: 0x20000
# DIS: Disassembly of section .text:
# DIS-NEXT: __start:
# DIS-NEXT: 10000: 3c 08 00 01 lui $8, 1
# DIS-NEXT: 10004: 21 08 7f f0 addi $8, $8, 32752
# ^-- 0x37ff0 & 0xffff
-# DIS: 00027ff0 *ABS* 00000000 _gp
+# DIS: 00027ff0 .got 00000000 .hidden _gp
# REL: Relocations [
# REL-NEXT: ]
diff --git a/test/ELF/mips-gp-local.s b/test/ELF/mips-gp-local.s
new file mode 100644
index 000000000000..8bb3c236edf0
--- /dev/null
+++ b/test/ELF/mips-gp-local.s
@@ -0,0 +1,20 @@
+# Check handling of relocations against __gnu_local_gp symbol.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld -o %t.exe %t.o
+# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Disassembly of section .text:
+# CHECK-NEXT: __start:
+# CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3
+# CHECK-NEXT: 20004: 21 08 7f f0 addi $8, $8, 32752
+
+# CHECK: 00037ff0 .got 00000000 .hidden _gp
+
+ .text
+ .globl __start
+__start:
+ lui $t0,%hi(__gnu_local_gp)
+ addi $t0,$t0,%lo(__gnu_local_gp)
diff --git a/test/ELF/mips-gprel32-relocs-gp0.test b/test/ELF/mips-gprel32-relocs-gp0.test
new file mode 100644
index 000000000000..6cc837ef7889
--- /dev/null
+++ b/test/ELF/mips-gprel32-relocs-gp0.test
@@ -0,0 +1,31 @@
+# Check R_MIPS_GPREL32 relocation calculation if input file conatins
+# non-zero GP0 value in the .reginfo section.
+# FIXME: The only way to get an object file with non-zero GP0 value
+# is to link multiple object files with GOT relocations using '-r'
+# option. LLD does not calculate and generate GP0 correctly so we
+# use a binary input in this test. The input object file is a result
+# of linking two object files with R_MIPS_GPREL32 relocations.
+
+# RUN: ld.lld -shared -o %t.so %S/Inputs/mips-gprel32-gp0.o
+# RUN: llvm-objdump -s %S/Inputs/mips-gprel32-gp0.o \
+# RUN: | FileCheck -check-prefix=OBJ %s
+# RUN: llvm-objdump -s -t %t.so | FileCheck %s
+
+# OBJ: Contents of section .reginfo:
+# OBJ-NEXT: 0000 00000001 00000000 00000000 00000000
+# OBJ-NEXT: 0010 00000000 00007fef
+# ^-- GP0 value
+# OBJ: Contents of section .rodata:
+# OBJ-NEXT: 0000 ffff8011 ffff8011
+# ^-- foo addend
+# ^-- bar addend
+
+# CHECK: Contents of section .rodata:
+# CHECK: 012c fffe8010 fffe8020
+# ^ 0x10000 + 0xffff8011 + 0x7fef - 0x27ff0
+# ^ 0x10010 + 0xffff8011 + 0x7fef - 0x27ff0
+
+# CHECK: SYMBOL TABLE:
+# CHECK: 00010000 .text 00000000 foo
+# CHECK: 00010010 .text 00000000 bar
+# CHECK: 00027ff0 .got 00000000 .hidden _gp
diff --git a/test/ELF/mips-gprel32-relocs.s b/test/ELF/mips-gprel32-relocs.s
index 4f93d50363c0..fa1c5cfe9956 100644
--- a/test/ELF/mips-gprel32-relocs.s
+++ b/test/ELF/mips-gprel32-relocs.s
@@ -28,4 +28,4 @@ v1:
# CHECK: SYMBOL TABLE:
# CHECK: 00010008 .text 00000000 bar
# CHECK: 00010004 .text 00000000 foo
-# CHECK: 00027ff0 *ABS* 00000000 _gp
+# CHECK: 00027ff0 .got 00000000 .hidden _gp
diff --git a/test/ELF/mips-hilo-gp-disp.s b/test/ELF/mips-hilo-gp-disp.s
index e2e9ae7bc2e2..37cf90d9728b 100644
--- a/test/ELF/mips-hilo-gp-disp.s
+++ b/test/ELF/mips-hilo-gp-disp.s
@@ -16,6 +16,9 @@ __start:
lui $t0,%hi(_gp_disp)
addi $t0,$t0,%lo(_gp_disp)
lw $v0,%call16(_foo)($gp)
+bar:
+ lui $t0,%hi(_gp_disp)
+ addi $t0,$t0,%lo(_gp_disp)
# EXE: Disassembly of section .text:
# EXE-NEXT: __start:
@@ -23,11 +26,16 @@ __start:
# ^-- %hi(0x37ff0-0x20000)
# EXE-NEXT: 20004: 21 08 7f f0 addi $8, $8, 32752
# ^-- %lo(0x37ff0-0x20004+4)
+# EXE: bar:
+# EXE-NEXT: 2000c: 3c 08 00 01 lui $8, 1
+# ^-- %hi(0x37ff0-0x2000c)
+# EXE-NEXT: 20010: 21 08 7f e4 addi $8, $8, 32740
+# ^-- %lo(0x37ff0-0x20010+4)
# EXE: SYMBOL TABLE:
-# EXE: 00037ff0 *ABS* 00000000 _gp
+# EXE: 0002000c .text 00000000 bar
+# EXE: 00037ff0 .got 00000000 .hidden _gp
# EXE: 00020000 .text 00000000 __start
-# EXE: 00020010 .text 00000000 _foo
# SO: Disassembly of section .text:
# SO-NEXT: __start:
@@ -35,8 +43,13 @@ __start:
# ^-- %hi(0x27ff0-0x10000)
# SO-NEXT: 10004: 21 08 7f f0 addi $8, $8, 32752
# ^-- %lo(0x27ff0-0x10004+4)
+# SO: bar:
+# SO-NEXT: 1000c: 3c 08 00 01 lui $8, 1
+# ^-- %hi(0x27ff0-0x1000c)
+# SO-NEXT: 10010: 21 08 7f e4 addi $8, $8, 32740
+# ^-- %lo(0x27ff0-0x10010+4)
# SO: SYMBOL TABLE:
-# SO: 00027ff0 *ABS* 00000000 _gp
+# SO: 0001000c .text 00000000 bar
+# SO: 00027ff0 .got 00000000 .hidden _gp
# SO: 00010000 .text 00000000 __start
-# SO: 00010010 .text 00000000 _foo
diff --git a/test/ELF/mips-hilo-hi-only.s b/test/ELF/mips-hilo-hi-only.s
index ad18a9f9161a..97808b515da5 100644
--- a/test/ELF/mips-hilo-hi-only.s
+++ b/test/ELF/mips-hilo-hi-only.s
@@ -14,7 +14,7 @@ __start:
_label:
nop
-# WARN: Can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16
+# WARN: can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16
# CHECK: Disassembly of section .text:
# CHECK-NEXT: __start:
diff --git a/test/ELF/mips-hilo.s b/test/ELF/mips-hilo.s
index d5de9422c427..4f1452831ae6 100644
--- a/test/ELF/mips-hilo.s
+++ b/test/ELF/mips-hilo.s
@@ -34,20 +34,20 @@ g1:
# CHECK-NEXT: __start:
# CHECK-NEXT: 20000: 3c 08 00 02 lui $8, 2
# ^-- %hi(__start+4)
-# CHECK-NEXT: 20004: 3c 09 00 03 lui $9, 3
+# CHECK-NEXT: 20004: 3c 09 00 04 lui $9, 4
# ^-- %hi(g1+8)
# CHECK-NEXT: 20008: 21 08 00 04 addi $8, $8, 4
# ^-- %lo(__start+4)
# CHECK-NEXT: 2000c: 21 08 00 0c addi $8, $8, 12
# ^-- %lo(g1+8)
-# CHECK-NEXT: 20010: 3c 08 00 04 lui $8, 4
+# CHECK-NEXT: 20010: 3c 08 00 05 lui $8, 5
# ^-- %hi(l1+0x10000-4)
-# CHECK-NEXT: 20014: 3c 09 00 05 lui $9, 5
+# CHECK-NEXT: 20014: 3c 09 00 06 lui $9, 6
# ^-- %hi(l1+0x20000-4)
# CHECK-NEXT: 20018: 21 08 ff fc addi $8, $8, -4
# ^-- %lo(l1-4)
# CHECK: SYMBOL TABLE:
-# CHECK: 0030000 l .data 00000004 l1
+# CHECK: 0040000 l .data 00000004 l1
# CHECK: 0020000 .text 00000000 __start
-# CHECK: 0030004 g .data 00000004 g1
+# CHECK: 0040004 g .data 00000004 g1
diff --git a/test/ELF/mips-jalr.test b/test/ELF/mips-jalr.test
index 4bdf8b6e7f00..c1b119c701b6 100644
--- a/test/ELF/mips-jalr.test
+++ b/test/ELF/mips-jalr.test
@@ -1,13 +1,18 @@
# Check that lld ignores R_MIPS_JALR relocation for now.
-# RUN: yaml2obj -format elf %s -o %t.o
+# RUN: yaml2obj %s -o %t.o
# RUN: ld.lld %t.o -o %t.so -shared
# RUN: llvm-objdump -d %t.so | FileCheck %s
+# RUN: llvm-readobj -relocations %t.so | FileCheck -check-prefix=REL %s
# REQUIRES: mips
# CHECK: 10000: 09 f8 20 03 jalr $25
+# REL: Relocations [
+# REL-NEXT: ]
+
+!ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
diff --git a/test/ELF/mips-lo16-not-relative.s b/test/ELF/mips-lo16-not-relative.s
new file mode 100644
index 000000000000..614e6396cc92
--- /dev/null
+++ b/test/ELF/mips-lo16-not-relative.s
@@ -0,0 +1,23 @@
+# Check that R_MIPS_LO16 relocation is handled as non-relative,
+# and if a target symbol is a DSO data symbol, LLD create a copy
+# relocation.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
+# RUN: ld.lld %t.so.o -shared -o %t.so
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o %t.so -o %t.exe
+# RUN: llvm-readobj -r %t.exe | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section (7) .rel.dyn {
+# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+ .text
+ .global __start
+__start:
+ addi $t0, $t0, %lo(data0)
diff --git a/test/ELF/mips-nonalloc.s b/test/ELF/mips-nonalloc.s
new file mode 100644
index 000000000000..7b0aa9469f9f
--- /dev/null
+++ b/test/ELF/mips-nonalloc.s
@@ -0,0 +1,21 @@
+# Check reading addends for relocations in non-allocatable sections.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %S/Inputs/mips-nonalloc.s -o %t2.o
+# RUN: ld.lld %t1.o %t2.o -o %t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Contents of section .debug_info:
+# CHECK-NEXT: 0000 ffffffff 00020000 00020000
+# ^--------^-- __start
+
+ .global __start
+__start:
+ nop
+
+.section .debug_info
+ .word 0xffffffff
+ .word __start
diff --git a/test/ELF/mips-npic-call-pic.s b/test/ELF/mips-npic-call-pic.s
new file mode 100644
index 000000000000..dbf053570bd9
--- /dev/null
+++ b/test/ELF/mips-npic-call-pic.s
@@ -0,0 +1,144 @@
+# REQUIRES: mips
+# Check LA25 stubs creation. This stub code is necessary when
+# non-PIC code calls PIC function.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %p/Inputs/mips-pic.s -o %t-pic.o
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o
+# RUN: ld.lld %t-npic.o %t-pic.o %p/Inputs/mips-sto-pic.o -o %t.exe
+# RUN: llvm-objdump -d %t.exe | FileCheck %s
+
+# CHECK: Disassembly of section .text:
+# CHECK-NEXT: __start:
+# CHECK-NEXT: 20000: 0c 00 80 0e jal 131128 <foo1b+0x4>
+# ^-- .pic.foo1a
+# CHECK-NEXT: 20004: 00 00 00 00 nop
+# CHECK-NEXT: 20008: 0c 00 80 19 jal 131172 <foo2+0x4>
+# ^-- .pic.foo2
+# CHECK-NEXT: 2000c: 00 00 00 00 nop
+# CHECK-NEXT: 20010: 0c 00 80 12 jal 131144 <foo1b+0x14>
+# ^-- .pic.foo1b
+# CHECK-NEXT: 20014: 00 00 00 00 nop
+# CHECK-NEXT: 20018: 0c 00 80 19 jal 131172 <foo2+0x4>
+# ^-- .pic.foo2
+# CHECK-NEXT: 2001c: 00 00 00 00 nop
+# CHECK-NEXT: 20020: 0c 00 80 28 jal 131232 <fnpic+0x10>
+# ^-- .pic.fpic
+# CHECK-NEXT: 20024: 00 00 00 00 nop
+# CHECK-NEXT: 20028: 0c 00 80 24 jal 131216 <fnpic>
+# CHECK-NEXT: 2002c: 00 00 00 00 nop
+#
+# CHECK: foo1a:
+# CHECK-NEXT: 20030: 00 00 00 00 nop
+#
+# CHECK: foo1b:
+# CHECK-NEXT: 20034: 00 00 00 00 nop
+#
+# CHECK-NEXT: 20038: 3c 19 00 02 lui $25, 2
+# CHECK-NEXT: 2003c: 08 00 80 0c j 131120 <foo1a>
+# CHECK-NEXT: 20040: 27 39 00 30 addiu $25, $25, 48
+# CHECK-NEXT: 20044: 00 00 00 00 nop
+# CHECK-NEXT: 20048: 3c 19 00 02 lui $25, 2
+# CHECK-NEXT: 2004c: 08 00 80 0d j 131124 <foo1b>
+# CHECK-NEXT: 20050: 27 39 00 34 addiu $25, $25, 52
+# CHECK-NEXT: 20054: 00 00 00 00 nop
+# CHECK-NEXT: 20058: 00 00 00 00 nop
+# CHECK-NEXT: 2005c: 00 00 00 00 nop
+#
+# CHECK: foo2:
+# CHECK-NEXT: 20060: 00 00 00 00 nop
+#
+# CHECK-NEXT: 20064: 3c 19 00 02 lui $25, 2
+# CHECK-NEXT: 20068: 08 00 80 18 j 131168 <foo2>
+# CHECK-NEXT: 2006c: 27 39 00 60 addiu $25, $25, 96
+# CHECK-NEXT: 20070: 00 00 00 00 nop
+# CHECK-NEXT: 20074: 00 00 00 00 nop
+# CHECK-NEXT: 20078: 00 00 00 00 nop
+# CHECK-NEXT: 2007c: 00 00 00 00 nop
+#
+# CHECK: fpic:
+# CHECK-NEXT: 20080: 00 00 00 00 nop
+# CHECK-NEXT: 20084: 00 00 00 00 nop
+# CHECK-NEXT: 20088: 00 00 00 00 nop
+# CHECK-NEXT: 2008c: 00 00 00 00 nop
+#
+# CHECK: fnpic:
+# CHECK-NEXT: 20090: 00 00 00 00 nop
+# CHECK-NEXT: 20094: 00 00 00 00 nop
+# CHECK-NEXT: 20098: 00 00 00 00 nop
+# CHECK-NEXT: 2009c: 00 00 00 00 nop
+# CHECK-NEXT: 200a0: 3c 19 00 02 lui $25, 2
+# CHECK-NEXT: 200a4: 08 00 80 20 j 131200 <fpic>
+# CHECK-NEXT: 200a8: 27 39 00 80 addiu $25, $25, 128
+
+# Make sure tha thunks are created properly no matter how
+# objects are laid out.
+#
+# RUN: ld.lld %t-pic.o %t-npic.o %p/Inputs/mips-sto-pic.o -o %t.exe
+# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s
+
+# REVERSE: foo1a:
+# REVERSE-NEXT: 20000: 00 00 00 00 nop
+#
+# REVERSE: foo1b:
+# REVERSE-NEXT: 20004: 00 00 00 00 nop
+# REVERSE-NEXT: 20008: 3c 19 00 02 lui $25, 2
+# REVERSE-NEXT: 2000c: 08 00 80 00 j 131072 <foo1a>
+# REVERSE-NEXT: 20010: 27 39 00 00 addiu $25, $25, 0
+# REVERSE-NEXT: 20014: 00 00 00 00 nop
+# REVERSE-NEXT: 20018: 3c 19 00 02 lui $25, 2
+# REVERSE-NEXT: 2001c: 08 00 80 01 j 131076 <foo1b>
+# REVERSE-NEXT: 20020: 27 39 00 04 addiu $25, $25, 4
+# REVERSE-NEXT: 20024: 00 00 00 00 nop
+# REVERSE-NEXT: 20028: 00 00 00 00 nop
+# REVERSE-NEXT: 2002c: 00 00 00 00 nop
+#
+# REVERSE: foo2:
+# REVERSE-NEXT: 20030: 00 00 00 00 nop
+# REVERSE-NEXT: 20034: 3c 19 00 02 lui $25, 2
+# REVERSE-NEXT: 20038: 08 00 80 0c j 131120 <foo2>
+# REVERSE-NEXT: 2003c: 27 39 00 30 addiu $25, $25, 48
+# REVERSE-NEXT: 20040: 00 00 00 00 nop
+# REVERSE-NEXT: 20044: 00 00 00 00 nop
+# REVERSE-NEXT: 20048: 00 00 00 00 nop
+# REVERSE-NEXT: 2004c: 00 00 00 00 nop
+#
+# REVERSE: __start:
+# REVERSE-NEXT: 20050: 0c 00 80 02 jal 131080 <foo1b+0x4>
+# REVERSE-NEXT: 20054: 00 00 00 00 nop
+# REVERSE-NEXT: 20058: 0c 00 80 0d jal 131124 <foo2+0x4>
+# REVERSE-NEXT: 2005c: 00 00 00 00 nop
+# REVERSE-NEXT: 20060: 0c 00 80 06 jal 131096 <foo1b+0x14>
+# REVERSE-NEXT: 20064: 00 00 00 00 nop
+# REVERSE-NEXT: 20068: 0c 00 80 0d jal 131124 <foo2+0x4>
+# REVERSE-NEXT: 2006c: 00 00 00 00 nop
+# REVERSE-NEXT: 20070: 0c 00 80 28 jal 131232 <fnpic+0x10>
+# REVERSE-NEXT: 20074: 00 00 00 00 nop
+# REVERSE-NEXT: 20078: 0c 00 80 24 jal 131216 <fnpic>
+# REVERSE-NEXT: 2007c: 00 00 00 00 nop
+#
+# REVERSE: fpic:
+# REVERSE-NEXT: 20080: 00 00 00 00 nop
+# REVERSE-NEXT: 20084: 00 00 00 00 nop
+# REVERSE-NEXT: 20088: 00 00 00 00 nop
+# REVERSE-NEXT: 2008c: 00 00 00 00 nop
+#
+# REVERSE: fnpic:
+# REVERSE-NEXT: 20090: 00 00 00 00 nop
+# REVERSE-NEXT: 20094: 00 00 00 00 nop
+# REVERSE-NEXT: 20098: 00 00 00 00 nop
+# REVERSE-NEXT: 2009c: 00 00 00 00 nop
+# REVERSE-NEXT: 200a0: 3c 19 00 02 lui $25, 2
+# REVERSE-NEXT: 200a4: 08 00 80 20 j 131200 <fpic>
+# REVERSE-NEXT: 200a8: 27 39 00 80 addiu $25, $25, 128
+# REVERSE-NEXT: 200ac: 00 00 00 00 nop
+
+ .text
+ .globl __start
+__start:
+ jal foo1a
+ jal foo2
+ jal foo1b
+ jal foo2
+ jal fpic
+ jal fnpic
diff --git a/test/ELF/mips-options-r.test b/test/ELF/mips-options-r.test
new file mode 100644
index 000000000000..c4144057e9ad
--- /dev/null
+++ b/test/ELF/mips-options-r.test
@@ -0,0 +1,19 @@
+# Check that if input file contains .MIPS.options section and symbol
+# points to the section and the linker generates a relocatable output,
+# LLD does not crash and write section symbols point to the output
+# .MIPS.options section.
+#
+# PR 27878
+#
+# Input object file created using the following script:
+# % cat t.s
+# .text
+# nop
+# % as -mabi=64 -mips64r2 t.s
+
+# RUN: ld.lld -r %p/Inputs/mips-options.o -o %t.o
+# RUN: llvm-readobj -t %t.o | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Section: .MIPS.options
diff --git a/test/ELF/mips-options.s b/test/ELF/mips-options.s
new file mode 100644
index 000000000000..30381ae55af7
--- /dev/null
+++ b/test/ELF/mips-options.s
@@ -0,0 +1,28 @@
+# Check MIPS .MIPS.options section generation.
+
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
+# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
+# RUN: ld.lld %t1.o %t2.o -shared -o %t.so
+# RUN: llvm-readobj -symbols -mips-options %t.so | FileCheck %s
+
+# REQUIRES: mips
+
+ .text
+ .globl __start
+__start:
+ lw $t0,%call16(g1)($gp)
+
+# CHECK: Name: _gp
+# CHECK-NEXT: Value: 0x[[GP:[0-9A-F]+]]
+
+# CHECK: MIPS Options {
+# CHECK-NEXT: ODK_REGINFO {
+# CHECK-NEXT: GP: 0x[[GP]]
+# CHECK-NEXT: General Mask: 0x10001001
+# CHECK-NEXT: Co-Proc Mask0: 0x0
+# CHECK-NEXT: Co-Proc Mask1: 0x0
+# CHECK-NEXT: Co-Proc Mask2: 0x0
+# CHECK-NEXT: Co-Proc Mask3: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: }
diff --git a/test/ELF/mips-pc-relocs.s b/test/ELF/mips-pc-relocs.s
index 631dd433925a..209d7d2971f5 100644
--- a/test/ELF/mips-pc-relocs.s
+++ b/test/ELF/mips-pc-relocs.s
@@ -5,7 +5,7 @@
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
# RUN: -mcpu=mips32r6 %S/Inputs/mips-dynamic.s -o %t2.o
# RUN: ld.lld %t1.o %t2.o -o %t.exe
-# RUN: llvm-objdump -mcpu=mips32r6 -d -t %t.exe | FileCheck %s
+# RUN: llvm-objdump -mcpu=mips32r6 -d -t -s %t.exe | FileCheck %s
# REQUIRES: mips
@@ -19,20 +19,27 @@ __start:
aluipc $2, %pcrel_hi(_foo) # R_MIPS_PCHI16
addiu $2, $2, %pcrel_lo(_foo) # R_MIPS_PCLO16
+ .data
+ .word _foo+8-. # R_MIPS_PC32
+
# CHECK: Disassembly of section .text:
# CHECK-NEXT: __start:
# CHECK-NEXT: 20000: ec c8 00 08 lwpc $6, 32
# ^-- (0x20020-0x20000)>>2
-# CHECK-NEXT: 20004: 20 a6 00 06 beqc $5, $6, 24
+# CHECK-NEXT: 20004: 20 a6 00 06 beqc $5, $6, 28
# ^-- (0x20020-4-0x20004)>>2
-# CHECK-NEXT: 20008: d9 20 00 05 beqzc $9, 20
+# CHECK-NEXT: 20008: d9 20 00 05 beqzc $9, 24
# ^-- (0x20020-4-0x20008)>>2
-# CHECK-NEXT: 2000c: c8 00 00 04 bc 16
+# CHECK-NEXT: 2000c: c8 00 00 04 bc 20
# ^-- (0x20020-4-0x2000c)>>2
# CHECK-NEXT: 20010: ec 5f 00 00 aluipc $2, 0
# ^-- %hi(0x20020-0x20010)
# CHECK-NEXT: 20014: 24 42 00 0c addiu $2, $2, 12
# ^-- %lo(0x20020-0x20014)
+# CHECK: Contents of section .data:
+# CHECK-NEXT: 40000 fffe0028 00000000 00000000 00000000
+# ^-- 0x20020 + 8 - 0x40000
+
# CHECK: 00020000 .text 00000000 __start
# CHECK: 00020020 .text 00000000 _foo
diff --git a/test/ELF/mips-plt-copy.s b/test/ELF/mips-plt-copy.s
new file mode 100644
index 000000000000..58883d884563
--- /dev/null
+++ b/test/ELF/mips-plt-copy.s
@@ -0,0 +1,85 @@
+# Check creating of R_MIPS_COPY and R_MIPS_JUMP_SLOT dynamic relocations
+# and corresponding PLT entries.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
+# RUN: ld.lld %t.so.o -shared -o %t.so
+# RUN: ld.lld %t.o %t.so -o %t.exe
+# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section ({{.*}}) .rel.dyn {
+# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0
+# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data1 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: Section ({{.*}}) .rel.plt {
+# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo0 0x0
+# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo1 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# CHECK: Primary GOT {
+# CHECK: Local entries [
+# CHECK-NEXT: ]
+# CHECK-NEXT: Global entries [
+# CHECK-NEXT: ]
+# CHECK-NEXT: Number of TLS and multi-GOT entries: 0
+# CHECK-NEXT: }
+
+# CHECK: PLT GOT {
+# CHECK: Entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x{{[0-9A-F]+}}
+# CHECK-NEXT: Initial: 0x{{[0-9A-F]+}}
+# CHECK-NEXT: Value: 0x{{[0-9A-F]+}}
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: Name: foo0
+# CHECK-NEXT: }
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x{{[0-9A-F]+}}
+# CHECK-NEXT: Initial: 0x{{[0-9A-F]+}}
+# CHECK-NEXT: Value: 0x{{[0-9A-F]+}}
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: Name: foo1
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+
+ .text
+ .globl __start
+__start:
+ lui $t0,%hi(foo0) # R_MIPS_HI16 requires JUMP_SLOT/PLT entry
+ # for DSO defined func.
+ addi $t0,$t0,%lo(foo0)
+ lui $t0,%hi(bar) # Does not require PLT for locally defined func.
+ addi $t0,$t0,%lo(bar)
+ lui $t0,%hi(loc) # Does not require PLT for local func.
+ addi $t0,$t0,%lo(loc)
+
+ lui $t0,%hi(data0) # R_MIPS_HI16 requires COPY rel for DSO defined data.
+ addi $t0,$t0,%lo(data0)
+ lui $t0,%hi(gd) # Does not require COPY rel for locally defined data.
+ addi $t0,$t0,%lo(gd)
+ lui $t0,%hi(ld) # Does not require COPY rel for local data.
+ addi $t0,$t0,%lo(ld)
+
+ .globl bar
+ .type bar, @function
+bar:
+ nop
+loc:
+ nop
+
+ .rodata
+ .globl gd
+gd:
+ .word 0
+ld:
+ .word data1+8 # R_MIPS_32 requires REL32 dnamic relocation
+ # for DSO defined data. For now we generate COPY one.
+ .word foo1+8 # R_MIPS_32 requires PLT entry for DSO defined func.
diff --git a/test/ELF/mips-relocs.s b/test/ELF/mips-relocs.s
deleted file mode 100644
index c05b8fd3bdd1..000000000000
--- a/test/ELF/mips-relocs.s
+++ /dev/null
@@ -1,42 +0,0 @@
-# Check R_MIPS_32 relocation calculation.
-
-# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
-# RUN: ld.lld %t-be.o -o %t-be.exe
-# RUN: llvm-objdump -t %t-be.exe | FileCheck %s
-# RUN: llvm-objdump -s %t-be.exe | FileCheck -check-prefix=BE %s
-
-# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
-# RUN: ld.lld %t-el.o -o %t-el.exe
-# RUN: llvm-objdump -t %t-el.exe | FileCheck %s
-# RUN: llvm-objdump -s %t-el.exe | FileCheck -check-prefix=EL %s
-
-# REQUIRES: mips
-
- .globl __start
-__start:
- nop
-
- .data
- .type v1,@object
- .size v1,4
-v1:
- .word 0
-
- .globl v2
- .type v2,@object
- .size v2,8
-v2:
- .word v2+4 # R_MIPS_32 target v2 addend 4
- .word v1 # R_MIPS_32 target v1 addend 0
-
-# CHECK: SYMBOL TABLE:
-# CHECK: 00030000 l .data 00000004 v1
-# CHECK: 00030004 g .data 00000008 v2
-
-# BE: Contents of section .data:
-# BE-NEXT: 30000 00000000 00030008 00030000
-# ^-- v2+4 ^-- v1
-
-# EL: Contents of section .data:
-# EL-NEXT: 30000 00000000 08000300 00000300
-# ^-- v2+4 ^-- v1
diff --git a/test/ELF/mips-sto-plt.s b/test/ELF/mips-sto-plt.s
new file mode 100644
index 000000000000..bd8de416680a
--- /dev/null
+++ b/test/ELF/mips-sto-plt.s
@@ -0,0 +1,66 @@
+# Check assigning STO_MIPS_PLT flag to symbol needs a pointer equality.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
+# RUN: ld.lld %t.so.o -shared -o %t.so
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o %t.so -o %t.exe
+# RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s
+
+# REQUIRES: mips
+
+# CHECK: Symbol {
+# CHECK: Name: foo0@
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: }
+# CHECK: Symbol {
+# CHECK: Name: foo1@
+# CHECK-NEXT: Value: 0x20050
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Other [ (0x8)
+# CHECK-NEXT: STO_MIPS_PLT
+# CHECK-NEXT: ]
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: }
+
+# CHECK: Primary GOT {
+# CHECK: Local entries [
+# CHECK-NEXT: ]
+# CHECK-NEXT: Global entries [
+# CHECK-NEXT: ]
+# CHECK: PLT GOT {
+# CHECK: Entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Initial:
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: Name: foo0
+# CHECK-NEXT: }
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Initial:
+# CHECK-NEXT: Value: 0x20050
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: Name: foo1
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+ .text
+ .globl __start
+__start:
+ jal foo0 # R_MIPS_26 against 'foo0' from DSO
+ lui $t0,%hi(foo1) # R_MIPS_HI16/LO16 against 'foo1' from DSO
+ addi $t0,$t0,%lo(foo1)
+
+loc:
+ nop
diff --git a/test/ELF/mips-tls-64.s b/test/ELF/mips-tls-64.s
new file mode 100644
index 000000000000..9c05e940b1c1
--- /dev/null
+++ b/test/ELF/mips-tls-64.s
@@ -0,0 +1,86 @@
+# Check MIPS TLS 64-bit relocations handling.
+
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
+# RUN: %p/Inputs/mips-dynamic.s -o %t.so.o
+# RUN: ld.lld -shared %t.so.o -o %t.so
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o %t.so -o %t.exe
+# RUN: llvm-objdump -d -s -t %t.exe | FileCheck -check-prefix=DIS %s
+# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
+
+# REQUIRES: mips
+
+# DIS: __start:
+# DIS-NEXT: 20000: 24 62 80 28 addiu $2, $3, -32728
+# DIS-NEXT: 20004: 24 62 80 38 addiu $2, $3, -32712
+# DIS-NEXT: 20008: 8f 82 80 20 lw $2, -32736($gp)
+# DIS-NEXT: 2000c: 24 62 80 48 addiu $2, $3, -32696
+
+# DIS: Contents of section .got:
+# DIS_NEXT: 30008 00000000 00000000 80000000 00000000
+# DIS_NEXT: 30018 00000000 00020000 00000000 00000000
+# DIS_NEXT: 30028 00000000 00000004 00000000 00000000
+# DIS_NEXT: 30038 00000000 00000000 00000000 00000004
+
+# DIS: 0000000000030000 l .tdata 00000000 .tdata
+# DIS: 0000000000030000 l .tdata 00000000 loc
+# DIS: 0000000000000004 g .tdata 00000000 foo
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section (7) .rela.dyn {
+# CHECK-NEXT: 0x30020 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE - 0x0
+# CHECK-NEXT: 0x30028 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE - 0x0
+# CHECK-NEXT: 0x30030 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE - 0x0
+# CHECK-NEXT: 0x30040 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE - 0x4
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Primary GOT {
+# CHECK-NEXT: Canonical gp value: 0x37FF8
+# CHECK-NEXT: Reserved entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x30008
+# CHECK-NEXT: Access: -32752
+# CHECK-NEXT: Initial: 0x0
+# CHECK-NEXT: Purpose: Lazy resolver
+# CHECK-NEXT: }
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x30010
+# CHECK-NEXT: Access: -32744
+# CHECK-NEXT: Initial: 0x80000000
+# CHECK-NEXT: Purpose: Module pointer (GNU extension)
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Local entries [
+# CHECK-NEXT: ]
+# CHECK-NEXT: Global entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x30018
+# CHECK-NEXT: Access: -32736
+# CHECK-NEXT: Initial: 0x0
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: Name: foo0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Number of TLS and multi-GOT entries: 5
+# ^-- 0x30020 / -32728 - R_MIPS_TLS_GD - R_MIPS_TLS_DTPMOD32 foo
+# ^-- 0x30028 / -32720 - R_MIPS_TLS_DTPREL32 foo
+# ^-- 0x30030 / -32712 - R_MIPS_TLS_LDM - R_MIPS_TLS_DTPMOD32 loc
+# ^-- 0x30038 / -32704
+# ^-- 0x30040 / -32696 - R_MIPS_TLS_GOTTPREL - R_MIPS_TLS_TPREL32
+
+ .text
+ .global __start
+__start:
+ addiu $2, $3, %tlsgd(foo) # R_MIPS_TLS_GD
+ addiu $2, $3, %tlsldm(loc) # R_MIPS_TLS_LDM
+ lw $2, %got(foo0)($gp)
+ addiu $2, $3, %gottprel(foo) # R_MIPS_TLS_GOTTPREL
+
+ .section .tdata,"awT",%progbits
+ .global foo
+loc:
+ .word 0
+foo:
+ .word 0
diff --git a/test/ELF/mips-tls-hilo.s b/test/ELF/mips-tls-hilo.s
new file mode 100644
index 000000000000..7628cb3a6ec6
--- /dev/null
+++ b/test/ELF/mips-tls-hilo.s
@@ -0,0 +1,52 @@
+# Check MIPS R_MIPS_TLS_DTPREL_HI16/LO16 and R_MIPS_TLS_TPREL_HI16/LO16
+# relocations handling.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t.exe
+# RUN: llvm-objdump -d -t %t.exe | FileCheck -check-prefix=DIS %s
+# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
+
+# RUN: ld.lld %t.o -shared -o %t.so
+# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=SO %s
+
+# REQUIRES: mips
+
+# DIS: __start:
+# DIS-NEXT: 20000: 24 62 00 00 addiu $2, $3, 0
+# %hi(loc0 - .tdata - 0x8000) --^
+# DIS-NEXT: 20004: 24 62 80 00 addiu $2, $3, -32768
+# %lo(loc0 - .tdata - 0x8000) --^
+# DIS-NEXT: 20008: 24 62 00 00 addiu $2, $3, 0
+# %hi(loc0 - .tdata - 0x7000) --^
+# DIS-NEXT: 2000c: 24 62 90 00 addiu $2, $3, -28672
+# %lo(loc0 - .tdata - 0x7000) --^
+
+# DIS: 00030000 l .tdata 00000000 .tdata
+# DIS: 00030000 l .tdata 00000000 loc0
+
+# CHECK: Relocations [
+# CHECK-NEXT: ]
+# CHECK-NOT: Primary GOT
+
+# SO: Relocations [
+# SO-NEXT: ]
+# SO: Primary GOT {
+# SO: Local entries [
+# SO-NEXT: ]
+# SO-NEXT: Global entries [
+# SO-NEXT: ]
+# SO-NEXT: Number of TLS and multi-GOT entries: 0
+# SO-NEXT: }
+
+ .text
+ .globl __start
+ .type __start,@function
+__start:
+ addiu $2, $3, %dtprel_hi(loc0) # R_MIPS_TLS_DTPREL_HI16
+ addiu $2, $3, %dtprel_lo(loc0) # R_MIPS_TLS_DTPREL_LO16
+ addiu $2, $3, %tprel_hi(loc0) # R_MIPS_TLS_TPREL_HI16
+ addiu $2, $3, %tprel_lo(loc0) # R_MIPS_TLS_TPREL_LO16
+
+ .section .tdata,"awT",%progbits
+loc0:
+ .word 0
diff --git a/test/ELF/mips-tls.s b/test/ELF/mips-tls.s
new file mode 100644
index 000000000000..9635558c2d95
--- /dev/null
+++ b/test/ELF/mips-tls.s
@@ -0,0 +1,77 @@
+# Check MIPS TLS relocations handling.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN: %p/Inputs/mips-tls.s -o %t.so.o
+# RUN: ld.lld -shared %t.so.o -o %t.so
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o %t.so -o %t.exe
+# RUN: llvm-objdump -d -s -t %t.exe | FileCheck -check-prefix=DIS %s
+# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
+
+# REQUIRES: mips
+
+# DIS: __start:
+# DIS-NEXT: 20000: 24 62 80 1c addiu $2, $3, -32740
+# DIS-NEXT: 20004: 24 62 80 24 addiu $2, $3, -32732
+# DIS-NEXT: 20008: 8f 82 80 18 lw $2, -32744($gp)
+# DIS-NEXT: 2000c: 24 62 80 2c addiu $2, $3, -32724
+
+# DIS: Contents of section .got:
+# DIS_NEXT: 30004 00000000 80000000 00020000 00000000
+# DIS_NEXT: 30014 00000000 00000000 00000000 00000000
+
+# DIS: 00030000 l .tdata 00000000 .tdata
+# DIS: 00030000 l .tdata 00000000 loc
+# DIS: 00000000 g *UND* 00000000 foo
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section (7) .rel.dyn {
+# CHECK-NEXT: 0x30018 R_MIPS_TLS_DTPMOD32 - 0x0
+# CHECK-NEXT: 0x30010 R_MIPS_TLS_DTPMOD32 foo 0x0
+# CHECK-NEXT: 0x30014 R_MIPS_TLS_DTPREL32 foo 0x0
+# CHECK-NEXT: 0x30020 R_MIPS_TLS_TPREL32 foo 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Primary GOT {
+# CHECK-NEXT: Canonical gp value: 0x37FF4
+# CHECK-NEXT: Reserved entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x30004
+# CHECK-NEXT: Access: -32752
+# CHECK-NEXT: Initial: 0x0
+# CHECK-NEXT: Purpose: Lazy resolver
+# CHECK-NEXT: }
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x30008
+# CHECK-NEXT: Access: -32748
+# CHECK-NEXT: Initial: 0x80000000
+# CHECK-NEXT: Purpose: Module pointer (GNU extension)
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Local entries [
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Address: 0x3000C
+# CHECK-NEXT: Access: -32744
+# CHECK-NEXT: Initial: 0x20000
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Global entries [
+# CHECK-NEXT: ]
+# CHECK-NEXT: Number of TLS and multi-GOT entries: 5
+# ^-- 0x30010 / -32740 - R_MIPS_TLS_GD - R_MIPS_TLS_DTPMOD32 foo
+# ^-- 0x30018 / -32736 - R_MIPS_TLS_DTPREL32 foo
+# ^-- 0x3001C / -32732 - R_MIPS_TLS_LDM - R_MIPS_TLS_DTPMOD32 loc
+# ^-- 0x30020 / -32728
+# ^-- 0x30024 / -32724 - R_MIPS_TLS_GOTTPREL - R_MIPS_TLS_TPREL32
+
+ .text
+ .global __start
+__start:
+ addiu $2, $3, %tlsgd(foo) # R_MIPS_TLS_GD
+ addiu $2, $3, %tlsldm(loc) # R_MIPS_TLS_LDM
+ lw $2, %got(__start)($gp)
+ addiu $2, $3, %gottprel(foo) # R_MIPS_TLS_GOTTPREL
+
+ .section .tdata,"awT",%progbits
+loc:
+ .word 0
diff --git a/test/ELF/no-augmentation.s b/test/ELF/no-augmentation.s
new file mode 100644
index 000000000000..31cd92e39b1c
--- /dev/null
+++ b/test/ELF/no-augmentation.s
@@ -0,0 +1,19 @@
+// RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o
+// RUN: ld.lld --eh-frame-hdr %t.o -o %t | FileCheck -allow-empty %s
+
+// REQUIRES: mips
+
+// CHECK-NOT: corrupted or unsupported CIE information
+// CHECK-NOT: corrupted CIE
+
+.global __start
+__start:
+
+.section .eh_frame,"aw",@progbits
+ .4byte 9
+ .4byte 0x0
+ .byte 0x1
+ .string ""
+ .uleb128 0x1
+ .sleb128 -4
+ .byte 0x1f
diff --git a/test/ELF/no-inhibit-exec.s b/test/ELF/no-inhibit-exec.s
index fe2240b731fe..31638fd92cc9 100644
--- a/test/ELF/no-inhibit-exec.s
+++ b/test/ELF/no-inhibit-exec.s
@@ -6,10 +6,10 @@
# CHECK: Disassembly of section .text:
# CHECK-NEXT: _start
-# CHECK-NEXT: 11000: e8 fb ef fe ff callq -69637
+# CHECK-NEXT: 11000: e8 fb ef fe ff callq -69637
# next code will not link without noinhibit-exec flag
# because of undefined symbol _bar
-.globl _start;
+.globl _start
_start:
call _bar
diff --git a/test/ELF/no-plt-shared.s b/test/ELF/no-plt-shared.s
new file mode 100644
index 000000000000..ac45ed502c38
--- /dev/null
+++ b/test/ELF/no-plt-shared.s
@@ -0,0 +1,17 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
+// RUN: ld.lld %t2.o %t.so -o %t2.so -shared
+// RUN: llvm-readobj -r %t2.so | FileCheck %s
+
+ .data
+fp:
+ .quad bar
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT: R_X86_64_64 bar 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/no-undefined.s b/test/ELF/no-undefined.s
index 94378bde40a2..fa4d5e928763 100644
--- a/test/ELF/no-undefined.s
+++ b/test/ELF/no-undefined.s
@@ -4,4 +4,4 @@
.globl _shared
_shared:
- call _unresolved
+ callq _unresolved@PLT
diff --git a/test/ELF/noplt-pie.s b/test/ELF/noplt-pie.s
new file mode 100644
index 000000000000..1eb84934184e
--- /dev/null
+++ b/test/ELF/noplt-pie.s
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -o %t2.so
+# RUN: ld.lld %t1.o %t2.so -o %t.out
+# RUN: llvm-readobj -s -r %t.out | FileCheck %s
+
+# CHECK: Section {
+# CHECK-NOT: Name: .plt
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
+# CHECK-NEXT: 0x120B0 R_X86_64_GLOB_DAT bar 0x0
+# CHECK-NEXT: 0x120B8 R_X86_64_GLOB_DAT zed 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+.global _start
+_start:
+ movq bar@GOTPCREL(%rip), %rcx
+ movq zed@GOTPCREL(%rip), %rcx
diff --git a/test/ELF/note.s b/test/ELF/note.s
new file mode 100644
index 000000000000..a383b95c9907
--- /dev/null
+++ b/test/ELF/note.s
@@ -0,0 +1,18 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t -shared
+// RUN: llvm-readobj -program-headers %t | FileCheck %s
+
+// CHECK: Type: PT_NOTE
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: VirtualAddress:
+// CHECK-NEXT: PhysicalAddress:
+// CHECK-NEXT: FileSize: 8
+// CHECK-NEXT: MemSize: 8
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: PF_R
+// CHECK-NEXT: ]
+// CHECK-NEXT: Alignment: 1
+
+ .section .note.test,"a",@note
+ .quad 42
diff --git a/test/ELF/phdr-align.s b/test/ELF/phdr-align.s
new file mode 100644
index 000000000000..58d537b46840
--- /dev/null
+++ b/test/ELF/phdr-align.s
@@ -0,0 +1,82 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+
+# RUN: echo "SECTIONS { \
+# RUN: .bss : { *(.bss) } \
+# RUN: .data : { *(.data) } \
+# RUN: .text : { *(.text) } }" > %t.script
+# RUN: ld.lld %t.o --script %t.script -o %t
+# RUN: llvm-readobj -sections -symbols %t | FileCheck %s
+
+# CHECK: Sections [
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 0
+# CHECK-NEXT: Name: (0)
+# CHECK-NEXT: Type: SHT_NULL
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x0
+# CHECK-NEXT: Offset: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 0
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 1
+# CHECK-NEXT: Name: .bss
+# CHECK-NEXT: Type: SHT_NOBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_WRITE
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x158
+# CHECK-NEXT: Offset: 0x158
+# CHECK-NEXT: Size: 6
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 1
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 2
+# CHECK-NEXT: Name: .data
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_WRITE
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x15E
+# CHECK-NEXT: Offset: 0x15E
+# CHECK-NEXT: Size: 2
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 1
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 3
+# CHECK-NEXT: Name: .text
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_EXECINSTR
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x160
+# CHECK-NEXT: Offset: 0x160
+# CHECK-NEXT: Size: 1
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 4
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+
+.global _start
+.text
+_start:
+ nop
+.data
+ .word 1
+.bss
+ .space 6
diff --git a/test/ELF/pie-weak.s b/test/ELF/pie-weak.s
new file mode 100644
index 000000000000..e74bcdfc09c0
--- /dev/null
+++ b/test/ELF/pie-weak.s
@@ -0,0 +1,16 @@
+# RUN: llvm-mc -filetype=obj -relax-relocations=false -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld -pie %t.o -o %t
+# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOCS %s
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
+
+# RELOCS: Relocations [
+# RELOCS-NEXT: ]
+
+.weak foo
+
+.globl _start
+_start:
+# DISASM: _start:
+# DISASM-NEXT: 1000: 48 8b 05 69 10 00 00 movq 4201(%rip), %rax
+# ^ .got - (.text + 7)
+mov foo@gotpcrel(%rip), %rax
diff --git a/test/ELF/pie.s b/test/ELF/pie.s
new file mode 100644
index 000000000000..4cf1743ee736
--- /dev/null
+++ b/test/ELF/pie.s
@@ -0,0 +1,102 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: ld.lld -pie %t1.o -o %t
+# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
+
+## Test --pic-executable alias
+# RUN: ld.lld --pic-executable %t1.o -o %t
+# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
+
+# CHECK: ElfHeader {
+# CHECK-NEXT: Ident {
+# CHECK-NEXT: Magic: (7F 45 4C 46)
+# CHECK-NEXT: Class: 64-bit
+# CHECK-NEXT: DataEncoding: LittleEndian
+# CHECK-NEXT: FileVersion: 1
+# CHECK-NEXT: OS/ABI: SystemV
+# CHECK-NEXT: ABIVersion: 0
+# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
+# CHECK-NEXT: }
+# CHECK-NEXT: Type: SharedObject
+# CHECK-NEXT: Machine: EM_X86_64
+# CHECK-NEXT: Version: 1
+# CHECK-NEXT: Entry: 0x1000
+# CHECK-NEXT: ProgramHeaderOffset: 0x40
+# CHECK-NEXT: SectionHeaderOffset: 0x1110
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: ]
+# CHECK-NEXT: HeaderSize: 64
+# CHECK-NEXT: ProgramHeaderEntrySize: 56
+# CHECK-NEXT: ProgramHeaderCount: 7
+# CHECK-NEXT: SectionHeaderEntrySize: 64
+# CHECK-NEXT: SectionHeaderCount: 9
+# CHECK-NEXT: StringTableSectionIndex: 7
+# CHECK-NEXT: }
+
+# CHECK: ProgramHeaders [
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_PHDR
+# CHECK-NEXT: Offset: 0x40
+# CHECK-NEXT: VirtualAddress: 0x40
+# CHECK-NEXT: PhysicalAddress: 0x40
+# CHECK-NEXT: FileSize: 392
+# CHECK-NEXT: MemSize: 392
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: PF_R
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 8
+# CHECK-NEXT: }
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_LOAD
+# CHECK-NEXT: Offset: 0x0
+# CHECK-NEXT: VirtualAddress: 0x0
+# CHECK-NEXT: PhysicalAddress: 0x0
+# CHECK-NEXT: FileSize: 497
+# CHECK-NEXT: MemSize: 497
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: PF_R
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 4096
+# CHECK-NEXT: }
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_LOAD
+# CHECK-NEXT: Offset: 0x1000
+# CHECK-NEXT: VirtualAddress: 0x1000
+# CHECK-NEXT: PhysicalAddress: 0x1000
+# CHECK-NEXT: FileSize: 0
+# CHECK-NEXT: MemSize: 0
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: PF_R
+# CHECK-NEXT: PF_X
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 4096
+# CHECK-NEXT: }
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_LOAD
+# CHECK-NEXT: Offset: 0x1000
+# CHECK-NEXT: VirtualAddress: 0x1000
+# CHECK-NEXT: PhysicalAddress: 0x1000
+# CHECK-NEXT: FileSize: 112
+# CHECK-NEXT: MemSize: 112
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: PF_R
+# CHECK-NEXT: PF_W
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 4096
+# CHECK-NEXT: }
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_DYNAMIC
+# CHECK-NEXT: Offset: 0x1000
+# CHECK-NEXT: VirtualAddress: 0x1000
+# CHECK-NEXT: PhysicalAddress: 0x1000
+# CHECK-NEXT: FileSize: 112
+# CHECK-NEXT: MemSize: 112
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: PF_R
+# CHECK-NEXT: PF_W
+# CHECK-NEXT: ]
+# CHECK-NEXT: Alignment: 8
+# CHECK-NEXT: }
+
+.globl _start
+_start:
diff --git a/test/ELF/plt-aarch64.s b/test/ELF/plt-aarch64.s
index 6ea732ec7c68..3f124b0af49c 100644
--- a/test/ELF/plt-aarch64.s
+++ b/test/ELF/plt-aarch64.s
@@ -1,5 +1,5 @@
// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t.o
-// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/shared.s -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/plt-aarch64.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld -shared %t.o %t2.so -o %t.so
// RUN: ld.lld %t.o %t2.so -o %t.exe
diff --git a/test/ELF/plt-i686.s b/test/ELF/plt-i686.s
index 4947e0e734fd..bf07fede7989 100644
--- a/test/ELF/plt-i686.s
+++ b/test/ELF/plt-i686.s
@@ -2,12 +2,13 @@
// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld %t.o %t2.so -o %t
-// RUN: llvm-readobj -s -r %t | FileCheck --check-prefix=CHECK %s
+// RUN: llvm-readobj -s -r %t | FileCheck %s
// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
// RUN: ld.lld -shared %t.o %t2.so -o %t
// RUN: llvm-readobj -s -r %t | FileCheck --check-prefix=CHECKSHARED %s
// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMSHARED %s
-
+// RUN: ld.lld -pie %t.o %t2.so -o %t
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMPIE %s
// REQUIRES: x86
// CHECK: Name: .plt
@@ -147,6 +148,21 @@
// DISASMSHARED-NEXT: 1046: 68 08 00 00 00 pushl $8
// DISASMSHARED-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
+// DISASMPIE: Disassembly of section .plt:
+// DISASMPIE-NEXT: .plt:
+// DISASMPIE-NEXT: 1020: ff b3 04 00 00 00 pushl 4(%ebx)
+// DISASMPIE-NEXT: 1026: ff a3 08 00 00 00 jmpl *8(%ebx)
+// DISASMPIE-NEXT: 102c: 90 nop
+// DISASMPIE-NEXT: 102d: 90 nop
+// DISASMPIE-NEXT: 102e: 90 nop
+// DISASMPIE-NEXT: 102f: 90 nop
+// DISASMPIE-NEXT: 1030: ff a3 0c 30 00 00 jmpl *12300(%ebx)
+// DISASMPIE-NEXT: 1036: 68 00 00 00 00 pushl $0
+// DISASMPIE-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
+// DISASMPIE-NEXT: 1040: ff a3 10 30 00 00 jmpl *12304(%ebx)
+// DISASMPIE-NEXT: 1046: 68 08 00 00 00 pushl $8
+// DISASMPIE-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
+
local:
.long 0
diff --git a/test/ELF/plt.s b/test/ELF/plt.s
index 1183d32c3ccc..60268a68195a 100644
--- a/test/ELF/plt.s
+++ b/test/ELF/plt.s
@@ -109,7 +109,7 @@
// DISASM2-NEXT: 11040: ff 25 da 1f 00 00 jmpq *8154(%rip)
// DISASM2-NEXT: 11046: 68 01 00 00 00 pushq $1
// DISASM2-NEXT: 1104b: e9 d0 ff ff ff jmp -48 <.plt>
-// DISASM2-NEXT-NOT: 110C0
+// DISASM2-NOT: 110C0
.global _start
_start:
diff --git a/test/ELF/ppc64-addr16-error.s b/test/ELF/ppc64-addr16-error.s
index 57a919a9b338..2bc8ef2ae4d7 100644
--- a/test/ELF/ppc64-addr16-error.s
+++ b/test/ELF/ppc64-addr16-error.s
@@ -1,7 +1,8 @@
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
-// RUN: not ld.lld -shared %t -o %t2 2>&1 | FileCheck %s
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2
+// RUN: not ld.lld -shared %t %t2 -o %t3 2>&1 | FileCheck %s
// REQUIRES: ppc
.short sym+65539
-// CHECK: Relocation R_PPC64_ADDR16 out of range
+// CHECK: relocation R_PPC64_ADDR16 out of range
diff --git a/test/ELF/ppc64-relocs.s b/test/ELF/ppc64-relocs.s
index 61f9a1eb3ce3..28902aed26df 100644
--- a/test/ELF/ppc64-relocs.s
+++ b/test/ELF/ppc64-relocs.s
@@ -43,7 +43,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_TOC16_HI:
# CHECK: .FR_PPC64_TOC16_HI:
-# CHECK: 10010014: 3c 22 10 01 addis 1, 2, 4097
+# CHECK: 10010014: 3c 22 ff ff addis 1, 2, -1
.section .R_PPC64_TOC16_HA,"ax",@progbits
.globl .FR_PPC64_TOC16_HA
@@ -52,7 +52,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_TOC16_HA:
# CHECK: .FR_PPC64_TOC16_HA:
-# CHECK: 10010018: 3c 22 10 02 addis 1, 2, 4098
+# CHECK: 10010018: 3c 22 00 00 addis 1, 2, 0
.section .R_PPC64_REL24,"ax",@progbits
.globl .FR_PPC64_REL24
diff --git a/test/ELF/ppc64-toc-restore.s b/test/ELF/ppc64-toc-restore.s
index cee105b35e64..dbfeaece7db4 100644
--- a/test/ELF/ppc64-toc-restore.s
+++ b/test/ELF/ppc64-toc-restore.s
@@ -53,8 +53,8 @@ last:
// CHECK: Disassembly of section .plt:
// CHECK: .plt:
// CHECK: 10010020: f8 41 00 28 std 2, 40(1)
-// CHECK: 10010024: 3d 62 00 00 addis 11, 2, 0
-// CHECK: 10010028: e9 8b 80 00 ld 12, -32768(11)
+// CHECK: 10010024: 3d 62 10 03 addis 11, 2, 4099
+// CHECK: 10010028: e9 8b 80 18 ld 12, -32744(11)
// CHECK: 1001002c: e9 6c 00 00 ld 11, 0(12)
// CHECK: 10010030: 7d 69 03 a6 mtctr 11
// CHECK: 10010034: e8 4c 00 08 ld 2, 8(12)
diff --git a/test/ELF/pre_init_fini_array.s b/test/ELF/pre_init_fini_array.s
index bf32283d2579..4ddcb6947e5b 100644
--- a/test/ELF/pre_init_fini_array.s
+++ b/test/ELF/pre_init_fini_array.s
@@ -67,7 +67,9 @@ _start:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .fini_array
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
@@ -76,7 +78,9 @@ _start:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .fini_array
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
@@ -85,7 +89,9 @@ _start:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .init_array
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
@@ -94,7 +100,9 @@ _start:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .init_array
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
@@ -103,7 +111,9 @@ _start:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .preinit_array
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
@@ -112,7 +122,9 @@ _start:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .preinit_array
// CHECK-NEXT: }
diff --git a/test/ELF/progname.s b/test/ELF/progname.s
index 5712b95d276d..10cbf177c69b 100644
--- a/test/ELF/progname.s
+++ b/test/ELF/progname.s
@@ -1,10 +1,29 @@
// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
-// RUN: echo '.global __progname' > %t2.s
+// RUN: echo .global __progname > %t2.s
// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %t2.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld -o %t %t.o %t2.so
// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
+
+// Inputs/progname-ver.so consists of the assembly file
+//
+// .global bar
+// bar:
+// .quad __progname
+//
+// linked into a library with the version script
+//
+// VER_1 {
+// global:
+// bar;
+// };
+//
+// We should create it with lld itself once we it supports that.
+
+// RUN: ld.lld -o %t %t.o %p/Inputs/progname-ver.so
+// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
+
// CHECK: Name: __progname@
// CHECK-NEXT: Value: 0x11000
// CHECK-NEXT: Size: 0
diff --git a/test/ELF/protected-shared.s b/test/ELF/protected-shared.s
new file mode 100644
index 000000000000..e69b10899dae
--- /dev/null
+++ b/test/ELF/protected-shared.s
@@ -0,0 +1,52 @@
+// 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 %p/Inputs/protected-shared.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: llvm-readobj -t --dyn-symbols %t | FileCheck %s
+
+ .global _start
+_start:
+
+ .global bar
+bar:
+
+ .data
+ .quad foo
+
+// CHECK: Name: bar
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+
+// CHECK: Name: foo
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+
+// CHECK: DynamicSymbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: @
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local (0x0)
+// CHECK-NEXT: Type: None (0x0)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined (0x0)
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo@
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/rel-offset.s b/test/ELF/rel-offset.s
new file mode 100644
index 000000000000..6f35bcebc4b0
--- /dev/null
+++ b/test/ELF/rel-offset.s
@@ -0,0 +1,15 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t -shared
+// RUN: llvm-readobj -r %t | FileCheck %s
+
+ .section .data.foo,"aw",@progbits
+ .quad foo
+
+ .section .data.zed,"aw",@progbits
+ .quad foo
+
+// CHECK: Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT: 0x2000 R_X86_64_64 foo 0x0
+// CHECK-NEXT: 0x2008 R_X86_64_64 foo 0x0
+// CHECK-NEXT: }
diff --git a/test/ELF/relative-dynamic-reloc-pie.s b/test/ELF/relative-dynamic-reloc-pie.s
new file mode 100644
index 000000000000..d9967af52eb6
--- /dev/null
+++ b/test/ELF/relative-dynamic-reloc-pie.s
@@ -0,0 +1,26 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld -pie %t.o -o %t.pie
+# RUN: llvm-readobj -r -dyn-symbols %t.pie | FileCheck %s
+
+## Test that we create R_X86_64_RELATIVE relocations with -pie.
+# CHECK: Relocations [
+# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
+# CHECK-NEXT: 0x3000 R_X86_64_RELATIVE - 0x3000
+# CHECK-NEXT: 0x3008 R_X86_64_RELATIVE - 0x3008
+# CHECK-NEXT: 0x3010 R_X86_64_RELATIVE - 0x3009
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+.globl _start
+_start:
+nop
+
+ .data
+foo:
+ .quad foo
+
+.hidden bar
+.global bar
+bar:
+ .quad bar
+ .quad bar + 1
diff --git a/test/ELF/relative-dynamic-reloc-ppc64.s b/test/ELF/relative-dynamic-reloc-ppc64.s
index b22b33f9f469..81a7a7027bb8 100644
--- a/test/ELF/relative-dynamic-reloc-ppc64.s
+++ b/test/ELF/relative-dynamic-reloc-ppc64.s
@@ -10,10 +10,10 @@
// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
// CHECK-NEXT: 0x[[FOO_ADDR:.*]] R_PPC64_RELATIVE - 0x[[FOO_ADDR]]
// CHECK-NEXT: 0x[[BAR_ADDR:.*]] R_PPC64_RELATIVE - 0x[[BAR_ADDR]]
-// CHECK-NEXT: 0x10010 R_PPC64_RELATIVE - 0x10009
+// CHECK-NEXT: 0x20010 R_PPC64_RELATIVE - 0x20009
// CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[ZED_ADDR:.*]]
// CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[FOO_ADDR]]
-// CHECK-NEXT: 0x1D0 R_PPC64_ADDR64 external 0x0
+// CHECK-NEXT: 0x20028 R_PPC64_ADDR64 external 0x0
// CHECK-NEXT: }
// CHECK-NEXT: ]
@@ -47,6 +47,7 @@
// CHECK-NEXT: }
// CHECK-NEXT: ]
+ .data
foo:
.quad foo
@@ -60,7 +61,7 @@ bar:
.comm zed,1
.quad zed
- .section abc,"a"
+ .section abc,"aw"
.quad foo
.quad external
diff --git a/test/ELF/relative-dynamic-reloc.s b/test/ELF/relative-dynamic-reloc.s
index 41fcd8a6a556..aac55669bb17 100644
--- a/test/ELF/relative-dynamic-reloc.s
+++ b/test/ELF/relative-dynamic-reloc.s
@@ -9,10 +9,10 @@
// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
// CHECK-NEXT: 0x[[FOO_ADDR:.*]] R_X86_64_RELATIVE - 0x[[FOO_ADDR]]
// CHECK-NEXT: 0x[[BAR_ADDR:.*]] R_X86_64_RELATIVE - 0x[[BAR_ADDR]]
-// CHECK-NEXT: 0x1010 R_X86_64_RELATIVE - 0x1009
+// CHECK-NEXT: 0x2010 R_X86_64_RELATIVE - 0x2009
// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[ZED_ADDR:.*]]
// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[FOO_ADDR]]
-// CHECK-NEXT: 0x1D0 R_X86_64_64 external 0x0
+// CHECK-NEXT: 0x2028 R_X86_64_64 external 0x0
// CHECK-NEXT: }
// CHECK-NEXT: ]
@@ -46,6 +46,7 @@
// CHECK-NEXT: }
// CHECK-NEXT: ]
+ .data
foo:
.quad foo
@@ -59,7 +60,7 @@ bar:
.comm zed,1
.quad zed
- .section abc,"a"
+ .section abc,"aw"
.quad foo
.quad external
diff --git a/test/ELF/relocatable-bss.s b/test/ELF/relocatable-bss.s
new file mode 100644
index 000000000000..0411bf339c43
--- /dev/null
+++ b/test/ELF/relocatable-bss.s
@@ -0,0 +1,40 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: ld.lld -r %t1.o -o %t
+# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
+
+## We check here that .bss does not occupy the space in file.
+## If it would, the SectionHeaderOffset would have offset about 5 megabytes.
+# CHECK: ElfHeader {
+# CHECK-NEXT: Ident {
+# CHECK-NEXT: Magic: (7F 45 4C 46)
+# CHECK-NEXT: Class: 64-bit
+# CHECK-NEXT: DataEncoding: LittleEndian
+# CHECK-NEXT: FileVersion: 1
+# CHECK-NEXT: OS/ABI: SystemV
+# CHECK-NEXT: ABIVersion: 0
+# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
+# CHECK-NEXT: }
+# CHECK-NEXT: Type: Relocatable
+# CHECK-NEXT: Machine: EM_X86_64
+# CHECK-NEXT: Version:
+# CHECK-NEXT: Entry:
+# CHECK-NEXT: ProgramHeaderOffset:
+# CHECK-NEXT: SectionHeaderOffset: 0xA8
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: ]
+# CHECK-NEXT: HeaderSize:
+# CHECK-NEXT: ProgramHeaderEntrySize:
+# CHECK-NEXT: ProgramHeaderCount:
+# CHECK-NEXT: SectionHeaderEntrySize:
+# CHECK-NEXT: SectionHeaderCount:
+# CHECK-NEXT: StringTableSectionIndex:
+# CHECK-NEXT: }
+
+.text
+.globl _start
+_start:
+ nop
+
+.bss
+ .space 5242880
diff --git a/test/ELF/relocatable-ehframe.s b/test/ELF/relocatable-ehframe.s
new file mode 100644
index 000000000000..d48402099c36
--- /dev/null
+++ b/test/ELF/relocatable-ehframe.s
@@ -0,0 +1,51 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable-ehframe.s -o %t2.o
+# RUN: ld.lld -r %t1.o %t2.o -o %t
+# RUN: llvm-readobj -r -s -section-data %t | FileCheck %s
+
+# CHECK: Name: .strtab
+# CHECK-NEXT: Type: SHT_STRTAB
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset
+# CHECK-NEXT: Size: 9
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 1
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: SectionData (
+# CHECK-NEXT: 0000: 00005F73 74617274 00 |.._start.|
+# CHECK-NEXT: )
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section {{.*}} .rela.eh_frame {
+# CHECK-NEXT: 0x20 R_X86_64_PC32 foo 0x0
+# CHECK-NEXT: 0x34 R_X86_64_PC32 bar 0x0
+# CHECK-NEXT: 0x48 R_X86_64_PC32 dah 0x0
+# CHECK-NEXT: 0x78 R_X86_64_PC32 foo1 0x0
+# CHECK-NEXT: 0x8C R_X86_64_PC32 bar1 0x0
+# CHECK-NEXT: 0xA0 R_X86_64_PC32 dah1 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+.section foo,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section bar,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section dah,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.text
+.globl _start
+_start:
+ nop
diff --git a/test/ELF/relocatable-reloc.s b/test/ELF/relocatable-reloc.s
new file mode 100644
index 000000000000..c576073a7510
--- /dev/null
+++ b/test/ELF/relocatable-reloc.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -filetype=obj %s -o %t.o -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o %t.o -r -o %t2.o
+// RUN: llvm-readobj -r %t2.o | FileCheck %s
+
+.weak foo
+foo:
+.quad foo
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rela.text {
+// CHECK-NEXT: 0x0 R_X86_64_64 foo 0x0
+// CHECK-NEXT: 0x8 R_X86_64_64 foo 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/relocatable-symbols.s b/test/ELF/relocatable-symbols.s
new file mode 100644
index 000000000000..75ed17ec5f6f
--- /dev/null
+++ b/test/ELF/relocatable-symbols.s
@@ -0,0 +1,183 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld -r %t -o %tout
+# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
+# RUN: llvm-readobj -symbols -r %tout | FileCheck -check-prefix=SYMBOL %s
+
+# DISASM: _start:
+# DISASM-NEXT: 0: {{.*}} callq 0
+# DISASM-NEXT: 5: {{.*}} callq 0
+# DISASM-NEXT: a: {{.*}} callq 0
+# DISASM-NEXT: f: {{.*}} callq 0
+# DISASM-NEXT: 14: {{.*}} callq 0
+# DISASM-NEXT: 19: {{.*}} callq 0
+# DISASM-NEXT: 1e: {{.*}} callq 0
+# DISASM-NEXT: 23: {{.*}} callq 0
+# DISASM-NEXT: 28: {{.*}} callq 0
+# DISASM-NEXT: 2d: {{.*}} callq 0
+# DISASM-NEXT: 32: {{.*}} callq 0
+# DISASM-NEXT: 37: {{.*}} callq 0
+# DISASM-NEXT: Disassembly of section foo:
+# DISASM-NEXT: foo:
+# DISASM-NEXT: 0: 90 nop
+# DISASM-NEXT: 1: 90 nop
+# DISASM-NEXT: 2: 90 nop
+# DISASM-NEXT: Disassembly of section bar:
+# DISASM-NEXT: bar:
+# DISASM-NEXT: 0: 90 nop
+# DISASM-NEXT: 1: 90 nop
+# DISASM-NEXT: 2: 90 nop
+
+# SYMBOL: Relocations [
+# SYMBOL-NEXT: Section ({{.*}}) .rela.text {
+# SYMBOL-NEXT: 0x1 R_X86_64_PC32 __start_foo 0x0
+# SYMBOL-NEXT: 0x6 R_X86_64_PC32 __stop_foo 0x0
+# SYMBOL-NEXT: 0xB R_X86_64_PC32 __start_bar 0x0
+# SYMBOL-NEXT: 0x10 R_X86_64_PC32 __stop_bar 0x0
+# SYMBOL-NEXT: 0x15 R_X86_64_PC32 __start_doo 0x0
+# SYMBOL-NEXT: 0x1A R_X86_64_PC32 __stop_doo 0x0
+# SYMBOL-NEXT: 0x1F R_X86_64_PC32 __preinit_array_start 0x0
+# SYMBOL-NEXT: 0x24 R_X86_64_PC32 __preinit_array_end 0x0
+# SYMBOL-NEXT: 0x29 R_X86_64_PC32 __init_array_start 0x0
+# SYMBOL-NEXT: 0x2E R_X86_64_PC32 __init_array_end 0x0
+# SYMBOL-NEXT: 0x33 R_X86_64_PC32 __fini_array_start 0x0
+# SYMBOL-NEXT: 0x38 R_X86_64_PC32 __fini_array_end 0x0
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: ]
+# SYMBOL: Symbol {
+# SYMBOL: Name: __fini_array_end
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __fini_array_start
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __init_array_end
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __init_array_start
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __preinit_array_end
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __preinit_array_start
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __start_bar
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __start_doo
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __start_foo
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __stop_bar
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __stop_doo
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+# SYMBOL-NEXT: Symbol {
+# SYMBOL-NEXT: Name: __stop_foo
+# SYMBOL-NEXT: Value: 0x0
+# SYMBOL-NEXT: Size: 0
+# SYMBOL-NEXT: Binding: Global
+# SYMBOL-NEXT: Type: None
+# SYMBOL-NEXT: Other: 0
+# SYMBOL-NEXT: Section: Undefined
+# SYMBOL-NEXT: }
+
+.global _start
+.text
+_start:
+ call __start_foo
+ call __stop_foo
+
+ call __start_bar
+ call __stop_bar
+
+ call __start_doo
+ call __stop_doo
+
+ call __preinit_array_start
+ call __preinit_array_end
+ call __init_array_start
+ call __init_array_end
+ call __fini_array_start
+ call __fini_array_end
+
+.section foo,"ax"
+ nop
+ nop
+ nop
+
+.section bar,"ax"
+ nop
+ nop
+ nop
diff --git a/test/ELF/relocatable.s b/test/ELF/relocatable.s
index 9fb171d4ed50..032cb6336c08 100644
--- a/test/ELF/relocatable.s
+++ b/test/ELF/relocatable.s
@@ -1,9 +1,120 @@
# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable.s -o %t2.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable2.s -o %t3.o
+# RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t
+# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
+# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
-# RUN: not ld.lld -r %t -o %t2 2>&1 | FileCheck %s
+## Test --relocatable alias
+# RUN: ld.lld --relocatable %t1.o %t2.o %t3.o -o %t
+# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
+# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
-# CHECK: -r option is not supported. Use 'ar' command instead.
+## Verify that we can use our relocation output as input to produce executable
+# RUN: ld.lld -e main %t -o %texec
+# RUN: llvm-readobj -file-headers %texec | FileCheck -check-prefix=CHECKEXE %s
-.globl _start;
-_start:
+# CHECK: ElfHeader {
+# CHECK-NEXT: Ident {
+# CHECK-NEXT: Magic: (7F 45 4C 46)
+# CHECK-NEXT: Class: 64-bit
+# CHECK-NEXT: DataEncoding: LittleEndian
+# CHECK-NEXT: FileVersion: 1
+# CHECK-NEXT: OS/ABI: SystemV
+# CHECK-NEXT: ABIVersion: 0
+# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
+# CHECK-NEXT: }
+# CHECK-NEXT: Type: Relocatable
+# CHECK-NEXT: Machine: EM_X86_64
+# CHECK-NEXT: Version: 1
+# CHECK-NEXT: Entry: 0x0
+# CHECK-NEXT: ProgramHeaderOffset: 0x0
+# CHECK-NEXT: SectionHeaderOffset: 0x2C0
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: ]
+# CHECK-NEXT: HeaderSize: 64
+# CHECK-NEXT: ProgramHeaderEntrySize: 0
+# CHECK-NEXT: ProgramHeaderCount: 0
+# CHECK-NEXT: SectionHeaderEntrySize: 64
+# CHECK-NEXT: SectionHeaderCount: 7
+# CHECK-NEXT: StringTableSectionIndex: 5
+# CHECK-NEXT: }
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section (3) .rela.text {
+# CHECK-NEXT: 0x3 R_X86_64_32S x 0x0
+# CHECK-NEXT: 0xE R_X86_64_32S y 0x0
+# CHECK-NEXT: 0x23 R_X86_64_32S xx 0x0
+# CHECK-NEXT: 0x2E R_X86_64_32S yy 0x0
+# CHECK-NEXT: 0x43 R_X86_64_32S xxx 0x0
+# CHECK-NEXT: 0x4E R_X86_64_32S yyy 0x0
+# CHECK-NEXT: }
+
+# CHECKTEXT: Disassembly of section .text:
+# CHECKTEXT-NEXT: main:
+# CHECKTEXT-NEXT: 0: c7 04 25 00 00 00 00 05 00 00 00 movl $5, 0
+# CHECKTEXT-NEXT: b: c7 04 25 00 00 00 00 07 00 00 00 movl $7, 0
+# CHECKTEXT: foo:
+# CHECKTEXT-NEXT: 20: c7 04 25 00 00 00 00 01 00 00 00 movl $1, 0
+# CHECKTEXT-NEXT: 2b: c7 04 25 00 00 00 00 02 00 00 00 movl $2, 0
+# CHECKTEXT: bar:
+# CHECKTEXT-NEXT: 40: c7 04 25 00 00 00 00 08 00 00 00 movl $8, 0
+# CHECKTEXT-NEXT: 4b: c7 04 25 00 00 00 00 09 00 00 00 movl $9, 0
+
+# CHECKEXE: Format: ELF64-x86-64
+# CHECKEXE-NEXT: Arch: x86_64
+# CHECKEXE-NEXT: AddressSize: 64bit
+# CHECKEXE-NEXT: LoadName:
+# CHECKEXE-NEXT: ElfHeader {
+# CHECKEXE-NEXT: Ident {
+# CHECKEXE-NEXT: Magic: (7F 45 4C 46)
+# CHECKEXE-NEXT: Class: 64-bit
+# CHECKEXE-NEXT: DataEncoding: LittleEndian
+# CHECKEXE-NEXT: FileVersion: 1
+# CHECKEXE-NEXT: OS/ABI: SystemV (0x0)
+# CHECKEXE-NEXT: ABIVersion: 0
+# CHECKEXE-NEXT: Unused: (00 00 00 00 00 00 00)
+# CHECKEXE-NEXT: }
+# CHECKEXE-NEXT: Type: Executable
+# CHECKEXE-NEXT: Machine: EM_X86_64
+# CHECKEXE-NEXT: Version: 1
+# CHECKEXE-NEXT: Entry: 0x11000
+# CHECKEXE-NEXT: ProgramHeaderOffset: 0x40
+# CHECKEXE-NEXT: SectionHeaderOffset: 0x11E8
+# CHECKEXE-NEXT: Flags [
+# CHECKEXE-NEXT: ]
+# CHECKEXE-NEXT: HeaderSize: 64
+# CHECKEXE-NEXT: ProgramHeaderEntrySize: 56
+# CHECKEXE-NEXT: ProgramHeaderCount: 5
+# CHECKEXE-NEXT: SectionHeaderEntrySize: 64
+# CHECKEXE-NEXT: SectionHeaderCount: 6
+# CHECKEXE-NEXT: StringTableSectionIndex: 4
+# CHECKEXE-NEXT: }
+
+.text
+.type x,@object
+.bss
+.globl x
+.align 4
+x:
+.long 0
+.size x, 4
+.type y,@object
+.globl y
+.align 4
+y:
+.long 0
+.size y, 4
+
+.text
+.globl main
+.align 16, 0x90
+.type main,@function
+main:
+movl $5, x
+movl $7, y
+
+blah:
+goo:
+abs = 42
diff --git a/test/ELF/relocation-copy-alias.s b/test/ELF/relocation-copy-alias.s
new file mode 100644
index 000000000000..15712e39bc93
--- /dev/null
+++ b/test/ELF/relocation-copy-alias.s
@@ -0,0 +1,67 @@
+// 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 %p/Inputs/relocation-copy-alias.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t.so
+// RUN: ld.lld %t.o %t.so -o %t3
+// RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t3 | FileCheck %s
+
+.global _start
+_start:
+movl $5, a1
+movl $5, b1
+movl $5, b2
+
+// CHECK: .rela.dyn {
+// CHECK-NEXT: Relocation {
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Type: R_X86_64_COPY
+// CHECK-NEXT: Symbol: a1
+// CHECK-NEXT: Addend: 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: Relocation {
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Type: R_X86_64_COPY
+// CHECK-NEXT: Symbol: b1
+// CHECK-NEXT: Addend: 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+
+// CHECK: Name: a1
+// CHECK-NEXT: Value: [[A:.*]]
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Binding: Global (0x1)
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss (0x7)
+
+// CHECK: Name: b1
+// CHECK-NEXT: Value: [[B:.*]]
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
+
+// CHECK: Name: b2
+// CHECK-NEXT: Value: [[B]]
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
+
+// CHECK: Name: a2
+// CHECK-NEXT: Value: [[A]]
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Binding: Weak
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
+
+// CHECK: Name: b3
+// CHECK-NEXT: Value: [[B]]
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Binding: Weak
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
diff --git a/test/ELF/relocation-copy-flags.s b/test/ELF/relocation-copy-flags.s
new file mode 100644
index 000000000000..50b4b15267e6
--- /dev/null
+++ b/test/ELF/relocation-copy-flags.s
@@ -0,0 +1,73 @@
+// 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 %p/Inputs/relocation-copy.s -o %t2.o
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t.exe
+// RUN: llvm-readobj -s -section-data -r %t.exe | FileCheck %s
+
+ .global _start
+_start:
+ .quad x
+
+ .section foo
+ .quad y
+
+ .section bar, "aw"
+ .quad z
+
+// CHECK: Name: .text
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x11000
+// CHECK-NEXT: Offset: 0x1000
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 4
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 10300100
+// CHECK-NEXT: )
+
+// CHECK: Name: bar
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x13000
+// CHECK-NEXT: Offset: 0x3000
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 00000000
+// CHECK-NEXT: )
+
+// CHECK: Name: foo
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x0
+// CHECK-NEXT: Offset: 0x3008
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 00000000
+// CHECK-NEXT: )
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section (4) .rela.dyn {
+// CHECK-NEXT: 0x13010 R_X86_64_COPY x 0x0
+// CHECK-NEXT: 0x13000 R_X86_64_64 z 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/relocation-copy-i686.s b/test/ELF/relocation-copy-i686.s
index d61f84783cb6..f9ee32e2b35e 100644
--- a/test/ELF/relocation-copy-i686.s
+++ b/test/ELF/relocation-copy-i686.s
@@ -22,7 +22,7 @@ movl $9, z
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x13000
-// CHECK-NEXT: Offset: 0x3000
+// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 24
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
diff --git a/test/ELF/relocation-copy.s b/test/ELF/relocation-copy.s
index 2e958ad5e955..9d13241f5496 100644
--- a/test/ELF/relocation-copy.s
+++ b/test/ELF/relocation-copy.s
@@ -23,7 +23,7 @@ movl $z, %edx
// CHECK-NEXT: SHF_WRITE (0x1)
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x13000
-// CHECK-NEXT: Offset: 0x3000
+// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 24
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
diff --git a/test/ELF/relocation-i686.s b/test/ELF/relocation-i686.s
index 529a35765f9e..96d760601127 100644
--- a/test/ELF/relocation-i686.s
+++ b/test/ELF/relocation-i686.s
@@ -45,8 +45,8 @@ movl bar@GOT, %eax
// ADDR-NEXT: SHF_ALLOC
// ADDR-NEXT: SHF_EXECINSTR
// ADDR-NEXT: ]
-// ADDR-NEXT: Address: 0x11030
-// ADDR-NEXT: Offset: 0x1030
+// ADDR-NEXT: Address: 0x11040
+// ADDR-NEXT: Offset: 0x1040
// ADDR-NEXT: Size: 32
// ADDR: Name: .got
@@ -69,16 +69,26 @@ R_386_GOTPC:
.section .dynamic_reloc, "ax",@progbits
call bar
-// 0x11030 - (0x11019 + 5) = 18
+// addr(.plt) + 16 - (0x11019 + 5) = 50
// CHECK: Disassembly of section .dynamic_reloc:
// CHECK-NEXT: .dynamic_reloc:
-// CHECK-NEXT: 11019: e8 22 00 00 00 calll 34
+// CHECK-NEXT: 11019: e8 32 00 00 00 calll 50
.section .R_386_GOT32,"ax",@progbits
.global R_386_GOT32
R_386_GOT32:
- movl zed@GOT, %eax
-// This is the second symbol in the got, so the offset is 4.
+ movl bar@GOT, %eax
+ movl zed@GOT, %eax
+ movl bar+8@GOT, %eax
+ movl zed+4@GOT, %eax
+
+// 4294967288 = 0xFFFFFFF8 = got[0](0x12070) - .got(0x12070) - sizeof(.got)(8)
+// 4294967292 = 0xFFFFFFFC = got[1](0x12074) - .got(0x12070) - sizeof(.got)(8)
+// 0xFFFFFFF8 + 8 = 0
+// 0xFFFFFFFC + 4 = 0
// CHECK: Disassembly of section .R_386_GOT32:
// CHECK-NEXT: R_386_GOT32:
-// CHECK-NEXT: 1101e: {{.*}} movl 4, %eax
+// CHECK-NEXT: 1101e: a1 f8 ff ff ff movl 4294967288, %eax
+// CHECK-NEXT: 11023: a1 fc ff ff ff movl 4294967292, %eax
+// CHECK-NEXT: 11028: a1 00 00 00 00 movl 0, %eax
+// CHECK-NEXT: 1102d: a1 00 00 00 00 movl 0, %eax
diff --git a/test/ELF/relocation-in-merge.s b/test/ELF/relocation-in-merge.s
index 820208a2cafe..9ce2e4f79150 100644
--- a/test/ELF/relocation-in-merge.s
+++ b/test/ELF/relocation-in-merge.s
@@ -1,7 +1,7 @@
// REQUIRES: x86
// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
// RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
-// CHECK: Relocations pointing to SHF_MERGE are not supported
+// CHECK: relocations pointing to SHF_MERGE are not supported
.section .foo,"aM",@progbits,4
.long bar
diff --git a/test/ELF/relocation-non-alloc.s b/test/ELF/relocation-non-alloc.s
new file mode 100644
index 000000000000..43f6f5ff1e4b
--- /dev/null
+++ b/test/ELF/relocation-non-alloc.s
@@ -0,0 +1,60 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+// RUN: ld.lld %t -o %t2 -shared
+// RUN: llvm-readobj -s -section-data -r %t2 | FileCheck %s
+
+// CHECK: Name: .data
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x2000
+// CHECK-NEXT: Offset: 0x2000
+// CHECK-NEXT: Size: 16
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000
+// CHECK-NEXT: )
+
+// CHECK: Name: foo
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x0
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 32
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 00200000 00000000 00200000 00000000
+// CHECK-NEXT: 0010: 00200000 00000000 00200000 00000000
+// CHECK-NEXT: )
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.}}) .rela.dyn {
+// CHECK-NEXT: 0x2000 R_X86_64_RELATIVE - 0x2000
+// CHECK-NEXT: 0x2008 R_X86_64_64 zed 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+.data
+ .global zed
+zed:
+bar:
+ .quad bar
+ .quad zed
+
+ .section foo
+ .quad bar
+ .quad zed
+
+ .section foo
+ .quad bar
+ .quad zed
diff --git a/test/ELF/relocation-past-merge-end.s b/test/ELF/relocation-past-merge-end.s
index 4dadea1e7acd..993b071f62d2 100644
--- a/test/ELF/relocation-past-merge-end.s
+++ b/test/ELF/relocation-past-merge-end.s
@@ -1,7 +1,8 @@
// REQUIRES: x86
// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
-// CHECK: Entry is past the end of the section
+// CHECK: entry is past the end of the section
+ .data
.long .foo + 1
.section .foo,"aM",@progbits,4
diff --git a/test/ELF/relocation-relative-absolute.s b/test/ELF/relocation-relative-absolute.s
new file mode 100644
index 000000000000..5253191331cc
--- /dev/null
+++ b/test/ELF/relocation-relative-absolute.s
@@ -0,0 +1,12 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s
+
+.globl _start
+_start:
+
+# CHECK: relocation R_X86_64_PLT32 cannot refer to absolute symbol answer
+call answer@PLT
+
+.globl answer
+answer = 42
diff --git a/test/ELF/relocation-relative-synthetic.s b/test/ELF/relocation-relative-synthetic.s
new file mode 100644
index 000000000000..f4d449b844e4
--- /dev/null
+++ b/test/ELF/relocation-relative-synthetic.s
@@ -0,0 +1,11 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t -pie
+# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
+
+# CHECK: Dynamic Relocations {
+# CHECK-NEXT: }
+
+.globl _start
+_start:
+call __init_array_start@PLT
diff --git a/test/ELF/relocation-relative-weak.s b/test/ELF/relocation-relative-weak.s
new file mode 100644
index 000000000000..c525012acf67
--- /dev/null
+++ b/test/ELF/relocation-relative-weak.s
@@ -0,0 +1,14 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t -pie
+# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
+
+# CHECK: Dynamic Relocations {
+# CHECK-NEXT: }
+
+.globl _start
+_start:
+
+.globl w
+.weak w
+call w@PLT
diff --git a/test/ELF/relocation-shared.s b/test/ELF/relocation-shared.s
new file mode 100644
index 000000000000..e1850944c459
--- /dev/null
+++ b/test/ELF/relocation-shared.s
@@ -0,0 +1,35 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -shared -o %t.so
+// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
+
+// CHECK: Name: foo
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x1C8
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 380E0000 00000000
+// 0x1000 - 0x1C8 = 0xE38
+// CHECK-NEXT: )
+
+// CHECK: Name: .text
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x1000
+
+// CHECK: Relocations [
+// CHECK-NEXT: ]
+
+bar:
+ .section foo,"a",@progbits
+ .quad bar - .
diff --git a/test/ELF/relocation-size-shared.s b/test/ELF/relocation-size-shared.s
index 1b52e77b7d5f..d6274e9ae12e 100644
--- a/test/ELF/relocation-size-shared.s
+++ b/test/ELF/relocation-size-shared.s
@@ -7,48 +7,48 @@
// RELOCSHARED: Relocations [
// RELOCSHARED-NEXT: Section ({{.*}}) .rela.dyn {
-// RELOCSHARED-NEXT: 0x11018 R_X86_64_SIZE64 fooshared 0xFFFFFFFFFFFFFFFF
-// RELOCSHARED-NEXT: 0x11020 R_X86_64_SIZE64 fooshared 0x0
-// RELOCSHARED-NEXT: 0x11028 R_X86_64_SIZE64 fooshared 0x1
-// RELOCSHARED-NEXT: 0x11048 R_X86_64_SIZE32 fooshared 0xFFFFFFFFFFFFFFFF
-// RELOCSHARED-NEXT: 0x1104F R_X86_64_SIZE32 fooshared 0x0
-// RELOCSHARED-NEXT: 0x11056 R_X86_64_SIZE32 fooshared 0x1
+// RELOCSHARED-NEXT: 0x13018 R_X86_64_SIZE64 fooshared 0xFFFFFFFFFFFFFFFF
+// RELOCSHARED-NEXT: 0x13020 R_X86_64_SIZE64 fooshared 0x0
+// RELOCSHARED-NEXT: 0x13028 R_X86_64_SIZE64 fooshared 0x1
+// RELOCSHARED-NEXT: 0x13048 R_X86_64_SIZE32 fooshared 0xFFFFFFFFFFFFFFFF
+// RELOCSHARED-NEXT: 0x1304F R_X86_64_SIZE32 fooshared 0x0
+// RELOCSHARED-NEXT: 0x13056 R_X86_64_SIZE32 fooshared 0x1
// RELOCSHARED-NEXT: }
// RELOCSHARED-NEXT:]
-// DISASM: Disassembly of section .text:
+// DISASM: Disassembly of section test
// DISASM: _data:
-// DISASM-NEXT: 11000: 19 00
-// DISASM-NEXT: 11002: 00 00
-// DISASM-NEXT: 11004: 00 00
-// DISASM-NEXT: 11006: 00 00
-// DISASM-NEXT: 11008: 1a 00
-// DISASM-NEXT: 1100a: 00 00
-// DISASM-NEXT: 1100c: 00 00
-// DISASM-NEXT: 1100e: 00 00
-// DISASM-NEXT: 11010: 1b 00
-// DISASM-NEXT: 11012: 00 00
-// DISASM-NEXT: 11014: 00 00
-// DISASM-NEXT: 11016: 00 00
-// DISASM-NEXT: 11018: 00 00
-// DISASM-NEXT: 1101a: 00 00
-// DISASM-NEXT: 1101c: 00 00
-// DISASM-NEXT: 1101e: 00 00
-// DISASM-NEXT: 11020: 00 00
-// DISASM-NEXT: 11022: 00 00
-// DISASM-NEXT: 11024: 00 00
-// DISASM-NEXT: 11026: 00 00
-// DISASM-NEXT: 11028: 00 00
-// DISASM-NEXT: 1102a: 00 00
-// DISASM-NEXT: 1102c: 00 00
-// DISASM-NEXT: 1102e: 00 00
+// DISASM-NEXT: 13000: 19 00
+// DISASM-NEXT: 13002: 00 00
+// DISASM-NEXT: 13004: 00 00
+// DISASM-NEXT: 13006: 00 00
+// DISASM-NEXT: 13008: 1a 00
+// DISASM-NEXT: 1300a: 00 00
+// DISASM-NEXT: 1300c: 00 00
+// DISASM-NEXT: 1300e: 00 00
+// DISASM-NEXT: 13010: 1b 00
+// DISASM-NEXT: 13012: 00 00
+// DISASM-NEXT: 13014: 00 00
+// DISASM-NEXT: 13016: 00 00
+// DISASM-NEXT: 13018: 00 00
+// DISASM-NEXT: 1301a: 00 00
+// DISASM-NEXT: 1301c: 00 00
+// DISASM-NEXT: 1301e: 00 00
+// DISASM-NEXT: 13020: 00 00
+// DISASM-NEXT: 13022: 00 00
+// DISASM-NEXT: 13024: 00 00
+// DISASM-NEXT: 13026: 00 00
+// DISASM-NEXT: 13028: 00 00
+// DISASM-NEXT: 1302a: 00 00
+// DISASM-NEXT: 1302c: 00 00
+// DISASM-NEXT: 1302e: 00 00
// DISASM: _start:
-// DISASM-NEXT: 11030: 8b 04 25 19 00 00 00 movl 25, %eax
-// DISASM-NEXT: 11037: 8b 04 25 1a 00 00 00 movl 26, %eax
-// DISASM-NEXT: 1103e: 8b 04 25 1b 00 00 00 movl 27, %eax
-// DISASM-NEXT: 11045: 8b 04 25 00 00 00 00 movl 0, %eax
-// DISASM-NEXT: 1104c: 8b 04 25 00 00 00 00 movl 0, %eax
-// DISASM-NEXT: 11053: 8b 04 25 00 00 00 00 movl 0, %eax
+// DISASM-NEXT: 13030: 8b 04 25 19 00 00 00 movl 25, %eax
+// DISASM-NEXT: 13037: 8b 04 25 1a 00 00 00 movl 26, %eax
+// DISASM-NEXT: 1303e: 8b 04 25 1b 00 00 00 movl 27, %eax
+// DISASM-NEXT: 13045: 8b 04 25 00 00 00 00 movl 0, %eax
+// DISASM-NEXT: 1304c: 8b 04 25 00 00 00 00 movl 0, %eax
+// DISASM-NEXT: 13053: 8b 04 25 00 00 00 00 movl 0, %eax
.data
.global foo
@@ -57,7 +57,7 @@
foo:
.zero 26
-.text
+.section test, "awx"
_data:
// R_X86_64_SIZE64:
.quad foo@SIZE-1
diff --git a/test/ELF/relocation-size.s b/test/ELF/relocation-size.s
index aea3dafea071..58604dbcb4e4 100644
--- a/test/ELF/relocation-size.s
+++ b/test/ELF/relocation-size.s
@@ -9,84 +9,84 @@
// NORELOC: Relocations [
// NORELOC-NEXT: ]
-// DISASM: Disassembly of section .text:
+// DISASM: Disassembly of section test:
// DISASM-NEXT: _data:
-// DISASM-NEXT: 11000: 19 00
-// DISASM-NEXT: 11002: 00 00
-// DISASM-NEXT: 11004: 00 00
-// DISASM-NEXT: 11006: 00 00
-// DISASM-NEXT: 11008: 1a 00
-// DISASM-NEXT: 1100a: 00 00
-// DISASM-NEXT: 1100c: 00 00
-// DISASM-NEXT: 1100e: 00 00
-// DISASM-NEXT: 11010: 1b 00
-// DISASM-NEXT: 11012: 00 00
-// DISASM-NEXT: 11014: 00 00
-// DISASM-NEXT: 11016: 00 00
-// DISASM-NEXT: 11018: 19 00
-// DISASM-NEXT: 1101a: 00 00
-// DISASM-NEXT: 1101c: 00 00
-// DISASM-NEXT: 1101e: 00 00
-// DISASM-NEXT: 11020: 1a 00
-// DISASM-NEXT: 11022: 00 00
-// DISASM-NEXT: 11024: 00 00
-// DISASM-NEXT: 11026: 00 00
-// DISASM-NEXT: 11028: 1b 00
-// DISASM-NEXT: 1102a: 00 00
-// DISASM-NEXT: 1102c: 00 00
-// DISASM-NEXT: 1102e: 00 00
+// DISASM-NEXT: 12000: 19 00
+// DISASM-NEXT: 12002: 00 00
+// DISASM-NEXT: 12004: 00 00
+// DISASM-NEXT: 12006: 00 00
+// DISASM-NEXT: 12008: 1a 00
+// DISASM-NEXT: 1200a: 00 00
+// DISASM-NEXT: 1200c: 00 00
+// DISASM-NEXT: 1200e: 00 00
+// DISASM-NEXT: 12010: 1b 00
+// DISASM-NEXT: 12012: 00 00
+// DISASM-NEXT: 12014: 00 00
+// DISASM-NEXT: 12016: 00 00
+// DISASM-NEXT: 12018: 19 00
+// DISASM-NEXT: 1201a: 00 00
+// DISASM-NEXT: 1201c: 00 00
+// DISASM-NEXT: 1201e: 00 00
+// DISASM-NEXT: 12020: 1a 00
+// DISASM-NEXT: 12022: 00 00
+// DISASM-NEXT: 12024: 00 00
+// DISASM-NEXT: 12026: 00 00
+// DISASM-NEXT: 12028: 1b 00
+// DISASM-NEXT: 1202a: 00 00
+// DISASM-NEXT: 1202c: 00 00
+// DISASM-NEXT: 1202e: 00 00
// DISASM: _start:
-// DISASM-NEXT: 11030: 8b 04 25 19 00 00 00 movl 25, %eax
-// DISASM-NEXT: 11037: 8b 04 25 1a 00 00 00 movl 26, %eax
-// DISASM-NEXT: 1103e: 8b 04 25 1b 00 00 00 movl 27, %eax
-// DISASM-NEXT: 11045: 8b 04 25 19 00 00 00 movl 25, %eax
-// DISASM-NEXT: 1104c: 8b 04 25 1a 00 00 00 movl 26, %eax
-// DISASM-NEXT: 11053: 8b 04 25 1b 00 00 00 movl 27, %eax
+// DISASM-NEXT: 12030: 8b 04 25 19 00 00 00 movl 25, %eax
+// DISASM-NEXT: 12037: 8b 04 25 1a 00 00 00 movl 26, %eax
+// DISASM-NEXT: 1203e: 8b 04 25 1b 00 00 00 movl 27, %eax
+// DISASM-NEXT: 12045: 8b 04 25 19 00 00 00 movl 25, %eax
+// DISASM-NEXT: 1204c: 8b 04 25 1a 00 00 00 movl 26, %eax
+// DISASM-NEXT: 12053: 8b 04 25 1b 00 00 00 movl 27, %eax
// RELOCSHARED: Relocations [
// RELOCSHARED-NEXT: Section ({{.*}}) .rela.dyn {
-// RELOCSHARED-NEXT: 0x1000 R_X86_64_SIZE64 foo 0xFFFFFFFFFFFFFFFF
-// RELOCSHARED-NEXT: 0x1008 R_X86_64_SIZE64 foo 0x0
-// RELOCSHARED-NEXT: 0x1010 R_X86_64_SIZE64 foo 0x1
-// RELOCSHARED-NEXT: 0x1033 R_X86_64_SIZE32 foo 0xFFFFFFFFFFFFFFFF
-// RELOCSHARED-NEXT: 0x103A R_X86_64_SIZE32 foo 0x0
-// RELOCSHARED-NEXT: 0x1041 R_X86_64_SIZE32 foo 0x1
+// RELOCSHARED-NEXT: 0x3000 R_X86_64_SIZE64 foo 0xFFFFFFFFFFFFFFFF
+// RELOCSHARED-NEXT: 0x3008 R_X86_64_SIZE64 foo 0x0
+// RELOCSHARED-NEXT: 0x3010 R_X86_64_SIZE64 foo 0x1
+// RELOCSHARED-NEXT: 0x3033 R_X86_64_SIZE32 foo 0xFFFFFFFFFFFFFFFF
+// RELOCSHARED-NEXT: 0x303A R_X86_64_SIZE32 foo 0x0
+// RELOCSHARED-NEXT: 0x3041 R_X86_64_SIZE32 foo 0x1
// RELOCSHARED-NEXT: }
// RELOCSHARED-NEXT: ]
-// DISASMSHARED: Disassembly of section .text:
+// 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: 1018: 19 00
-// DISASMSHARED-NEXT: 101a: 00 00
-// DISASMSHARED-NEXT: 101c: 00 00
-// DISASMSHARED-NEXT: 101e: 00 00
-// DISASMSHARED-NEXT: 1020: 1a 00
-// DISASMSHARED-NEXT: 1022: 00 00
-// DISASMSHARED-NEXT: 1024: 00 00
-// DISASMSHARED-NEXT: 1026: 00 00
-// DISASMSHARED-NEXT: 1028: 1b 00
-// DISASMSHARED-NEXT: 102a: 00 00
-// DISASMSHARED-NEXT: 102c: 00 00
-// DISASMSHARED-NEXT: 102e: 00 00
+// DISASMSHARED-NEXT: 3000: 00 00
+// DISASMSHARED-NEXT: 3002: 00 00
+// DISASMSHARED-NEXT: 3004: 00 00
+// DISASMSHARED-NEXT: 3006: 00 00
+// DISASMSHARED-NEXT: 3008: 00 00
+// DISASMSHARED-NEXT: 300a: 00 00
+// DISASMSHARED-NEXT: 300c: 00 00
+// DISASMSHARED-NEXT: 300e: 00 00
+// DISASMSHARED-NEXT: 3010: 00 00
+// DISASMSHARED-NEXT: 3012: 00 00
+// DISASMSHARED-NEXT: 3014: 00 00
+// DISASMSHARED-NEXT: 3016: 00 00
+// DISASMSHARED-NEXT: 3018: 19 00
+// DISASMSHARED-NEXT: 301a: 00 00
+// DISASMSHARED-NEXT: 301c: 00 00
+// DISASMSHARED-NEXT: 301e: 00 00
+// DISASMSHARED-NEXT: 3020: 1a 00
+// DISASMSHARED-NEXT: 3022: 00 00
+// DISASMSHARED-NEXT: 3024: 00 00
+// DISASMSHARED-NEXT: 3026: 00 00
+// DISASMSHARED-NEXT: 3028: 1b 00
+// DISASMSHARED-NEXT: 302a: 00 00
+// DISASMSHARED-NEXT: 302c: 00 00
+// DISASMSHARED-NEXT: 302e: 00 00
// DISASMSHARED: _start:
-// DISASMSHARED-NEXT: 1030: 8b 04 25 00 00 00 00 movl 0, %eax
-// DISASMSHARED-NEXT: 1037: 8b 04 25 00 00 00 00 movl 0, %eax
-// DISASMSHARED-NEXT: 103e: 8b 04 25 00 00 00 00 movl 0, %eax
-// DISASMSHARED-NEXT: 1045: 8b 04 25 19 00 00 00 movl 25, %eax
-// DISASMSHARED-NEXT: 104c: 8b 04 25 1a 00 00 00 movl 26, %eax
-// DISASMSHARED-NEXT: 1053: 8b 04 25 1b 00 00 00 movl 27, %eax
+// DISASMSHARED-NEXT: 3030: 8b 04 25 00 00 00 00 movl 0, %eax
+// DISASMSHARED-NEXT: 3037: 8b 04 25 00 00 00 00 movl 0, %eax
+// DISASMSHARED-NEXT: 303e: 8b 04 25 00 00 00 00 movl 0, %eax
+// DISASMSHARED-NEXT: 3045: 8b 04 25 19 00 00 00 movl 25, %eax
+// DISASMSHARED-NEXT: 304c: 8b 04 25 1a 00 00 00 movl 26, %eax
+// DISASMSHARED-NEXT: 3053: 8b 04 25 1b 00 00 00 movl 27, %eax
.data
.global foo
@@ -103,7 +103,7 @@ foo:
foohidden:
.zero 26
-.text
+.section test,"axw"
_data:
// R_X86_64_SIZE64:
.quad foo@SIZE-1
diff --git a/test/ELF/relocation.s b/test/ELF/relocation.s
index 33b0e23ee972..11832683d9be 100644
--- a/test/ELF/relocation.s
+++ b/test/ELF/relocation.s
@@ -14,7 +14,7 @@
// SEC-NEXT: ]
// SEC-NEXT: Address: 0x11030
// SEC-NEXT: Offset: 0x1030
-// SEC-NEXT: Size: 32
+// SEC-NEXT: Size: 48
// SEC: Name: .got
// SEC-NEXT: Type: SHT_PROGBITS
@@ -39,7 +39,7 @@
// SEC-NEXT: ]
// SEC-NEXT: Address: 0x13000
// SEC-NEXT: Offset: 0x3000
-// SEC-NEXT: Size: 32
+// SEC-NEXT: Size: 40
// SEC-NEXT: Link: 0
// SEC-NEXT: Info: 0
// SEC-NEXT: AddressAlignment: 8
@@ -98,6 +98,15 @@ R_X86_64_PC32:
// CHECK-NEXT: 11017: {{.*}} callq 36
// CHECK-NEXT: 1101c: {{.*}} movl $69696, %eax
+.section .R_X86_64_32S_2,"ax",@progbits
+.global R_X86_64_32S_2
+R_X86_64_32S_2:
+ mov bar2, %eax
+// plt is at 0x11030. The second plt entry is at 0x11050 == 69712
+// CHECK: Disassembly of section .R_X86_64_32S_2:
+// CHECK-NEXT: R_X86_64_32S_2:
+// CHECK-NEXT: 11021: {{.*}} movl 69712, %eax
+
.section .R_X86_64_64,"a",@progbits
.global R_X86_64_64
R_X86_64_64:
@@ -115,3 +124,11 @@ R_X86_64_GOTPCREL:
// 7952 = 0x101f0000 in little endian
// CHECK: Contents of section .R_X86_64_GOTPCREL
// CHECK-NEXT: 101d0 201f0000
+
+.section .R_X86_64_GOT32,"a",@progbits
+.global R_X86_64_GOT32
+R_X86_64_GOT32:
+ .long zed@got
+
+// CHECK: Contents of section .R_X86_64_GOT32:
+// CHECK-NEXT: f8ffffff
diff --git a/test/ELF/relro-tls.s b/test/ELF/relro-tls.s
new file mode 100644
index 000000000000..0ee5b6d328c2
--- /dev/null
+++ b/test/ELF/relro-tls.s
@@ -0,0 +1,23 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+// RUN: ld.lld %t -o %tout
+// RUN: llvm-readobj -program-headers %tout | FileCheck %s
+
+// CHECK: Type: PT_GNU_RELRO
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: VirtualAddress:
+// CHECK-NEXT: PhysicalAddress:
+// CHECK-NEXT: FileSize: 4
+// CHECK-NEXT: MemSize: 4
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: PF_R
+// CHECK-NEXT: ]
+// CHECK-NEXT: Alignment: 1
+
+.global _start
+_start:
+
+.global d
+.section .foo,"awT",@progbits
+d:
+.long 2
diff --git a/test/ELF/relro.s b/test/ELF/relro.s
index 692d6b271cf8..d35548740001 100644
--- a/test/ELF/relro.s
+++ b/test/ELF/relro.s
@@ -232,7 +232,7 @@
.global _start
_start:
.long bar
- jmp *bar@GOTPCREL(%rip)
+ jmp *bar2@GOTPCREL(%rip)
.section .data,"aw"
.quad 0
diff --git a/test/ELF/reproduce-error.s b/test/ELF/reproduce-error.s
new file mode 100644
index 000000000000..c66132c4bd01
--- /dev/null
+++ b/test/ELF/reproduce-error.s
@@ -0,0 +1,15 @@
+# Extracting the cpio archive can get over the path limit on windows.
+# REQUIRES: shell
+
+# RUN: rm -rf %t.dir
+# RUN: mkdir -p %t.dir
+# RUN: cd %t.dir
+
+# RUN: not ld.lld --reproduce repro abc -o t 2>&1 | FileCheck %s
+# CHECK: cannot open abc: {{N|n}}o such file or directory
+
+# RUN: grep TRAILER repro.cpio
+# RUN: cpio -id < repro.cpio
+# RUN: FileCheck --check-prefix=RSP %s < repro/response.txt
+# RSP: abc
+# RSP: -o t
diff --git a/test/ELF/reproduce-linkerscript.s b/test/ELF/reproduce-linkerscript.s
new file mode 100644
index 000000000000..a020fcc9a4f1
--- /dev/null
+++ b/test/ELF/reproduce-linkerscript.s
@@ -0,0 +1,17 @@
+# REQUIRES: x86, shell
+
+# RUN: rm -rf %t.dir
+# RUN: mkdir -p %t.dir/build
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build/foo.o
+# RUN: echo "INPUT(\"%t.dir/build/foo.o\")" > %t.dir/build/foo.script
+# RUN: cd %t.dir
+# RUN: ld.lld build/foo.script -o bar --reproduce repro
+# RUN: cpio -id < repro.cpio
+# RUN: diff build/foo.script repro/%:t.dir/build/foo.script
+# RUN: diff build/foo.o repro/%:t.dir/build/foo.o
+
+.globl _start
+_start:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
diff --git a/test/ELF/reproduce-thin-archive.s b/test/ELF/reproduce-thin-archive.s
new file mode 100644
index 000000000000..0797b6c67e9c
--- /dev/null
+++ b/test/ELF/reproduce-thin-archive.s
@@ -0,0 +1,15 @@
+# REQUIRES: x86, shell
+
+# RUN: rm -rf %t.dir
+# RUN: mkdir -p %t.dir
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.dir/foo.o
+# RUN: cd %t.dir
+# RUN: llvm-ar --format=gnu rcT foo.a foo.o
+# RUN: ld.lld -m elf_x86_64 foo.a -o bar --reproduce repro
+# RUN: cpio -id < repro.cpio
+# RUN: diff foo.a repro/%:t.dir/foo.a
+# RUN: diff foo.o repro/%:t.dir/foo.o
+
+.globl _start
+_start:
+ nop
diff --git a/test/ELF/reproduce-windows.s b/test/ELF/reproduce-windows.s
new file mode 100644
index 000000000000..464b27098694
--- /dev/null
+++ b/test/ELF/reproduce-windows.s
@@ -0,0 +1,12 @@
+# REQUIRES: x86
+
+# Test that a repro archive always uses / instead of \.
+# RUN: rm -rf %t.dir
+# RUN: mkdir -p %t.dir/build
+# RUN: llvm-mc %s -o %t.dir/build/foo.o -filetype=obj -triple=x86_64-pc-linux
+# RUN: cd %t.dir
+# RUN: not ld.lld build/foo.o --reproduce repro
+# RUN: cpio -t < repro.cpio | FileCheck %s
+
+# CHECK: repro/response.txt
+# CHECK: repro/{{.*}}/build/foo.o
diff --git a/test/ELF/reproduce.s b/test/ELF/reproduce.s
new file mode 100644
index 000000000000..9d256c12d827
--- /dev/null
+++ b/test/ELF/reproduce.s
@@ -0,0 +1,67 @@
+# REQUIRES: x86
+
+# Extracting the cpio archive can get over the path limit on windows.
+# REQUIRES: shell
+
+# RUN: rm -rf %t.dir
+# RUN: mkdir -p %t.dir/build1
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build1/foo.o
+# RUN: cd %t.dir
+# RUN: ld.lld --hash-style=gnu build1/foo.o -o bar -shared --as-needed --reproduce repro
+# RUN: cpio -id < repro.cpio
+# RUN: diff build1/foo.o repro/%:t.dir/build1/foo.o
+
+# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt
+# RSP: {{^}}--hash-style gnu{{$}}
+# RSP-NOT: repro{{[/\\]}}
+# RSP-NEXT: {{[/\\]}}foo.o
+# RSP-NEXT: -o bar
+# RSP-NEXT: -shared
+# RSP-NEXT: --as-needed
+
+# RUN: FileCheck %s --check-prefix=VERSION < repro/version.txt
+# VERSION: LLD
+
+# RUN: mkdir -p %t.dir/build2/a/b/c
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build2/foo.o
+# RUN: cd %t.dir/build2/a/b/c
+# RUN: env LLD_REPRODUCE=repro ld.lld ./../../../foo.o -o bar -shared --as-needed
+# RUN: cpio -id < repro.cpio
+# RUN: diff %t.dir/build2/foo.o repro/%:t.dir/build2/foo.o
+
+# RUN: echo "{ local: *; };" > ver
+# RUN: echo > dyn
+# RUN: echo > file
+# RUN: echo > file2
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o 'foo bar'
+# RUN: ld.lld --reproduce repro2 'foo bar' -L"foo bar" -Lfile -Tfile2 \
+# RUN: --dynamic-list dyn -rpath file --script file --version-script ver \
+# RUN: --dynamic-linker "some unusual/path" -soname 'foo bar' -soname='foo bar'
+# RUN: cpio -id < repro2.cpio
+# RUN: FileCheck %s --check-prefix=RSP2 < repro2/response.txt
+# RSP2: "{{.*}}foo bar"
+# RSP2-NEXT: -L "{{.*}}foo bar"
+# RSP2-NEXT: -L {{.+}}file
+# RSP2-NEXT: --script {{.+}}file2
+# RSP2-NEXT: --dynamic-list {{.+}}dyn
+# RSP2-NEXT: -rpath {{.+}}file
+# RSP2-NEXT: --script {{.+}}file
+# RSP2-NEXT: --version-script [[PATH:.*]]ver
+# RSP2-NEXT: --dynamic-linker "some unusual/path"
+# RSP2-NEXT: -soname="foo bar"
+# RSP2-NEXT: -soname="foo bar"
+
+# RUN: cpio -t < repro2.cpio | FileCheck %s
+# CHECK: repro2/response.txt
+# CHECK-NEXT: repro2/version.txt
+# CHECK-NEXT: repro2/{{.*}}/dyn
+# CHECK-NEXT: repro2/{{.*}}/ver
+# CHECK-NEXT: repro2/{{.*}}/foo bar
+# CHECK-NEXT: repro2/{{.*}}/file2
+# CHECK-NEXT: repro2/{{.*}}/file
+
+.globl _start
+_start:
+ mov $60, %rax
+ mov $42, %rdi
+ syscall
diff --git a/test/ELF/resolution-shared.s b/test/ELF/resolution-shared.s
new file mode 100644
index 000000000000..e1eac070e5af
--- /dev/null
+++ b/test/ELF/resolution-shared.s
@@ -0,0 +1,15 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-shared.s -o %t2.o
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t3 -shared
+// RUN: llvm-readobj -t %t3 | FileCheck %s
+// REQUIRES: x86
+
+ .weak foo
+foo:
+
+// CHECK: Symbol {
+// CHECK: Name: foo
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding: Weak
diff --git a/test/ELF/resolution.s b/test/ELF/resolution.s
index ce275c2934a4..5596212b3bac 100644
--- a/test/ELF/resolution.s
+++ b/test/ELF/resolution.s
@@ -309,7 +309,7 @@
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: UndefWeak_with_UndefWeak
// CHECK-NEXT: Value: 0x0
-// CHECK-NEXT: Size: 15
+// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Weak
// CHECK-NEXT: Type: None
// CHECK-NEXT: Other: 0
diff --git a/test/ELF/section-align-0.test b/test/ELF/section-align-0.test
index fc27ee95fd4b..35783f5a894b 100644
--- a/test/ELF/section-align-0.test
+++ b/test/ELF/section-align-0.test
@@ -1,8 +1,9 @@
-# RUN: yaml2obj -format elf %s -o %t
+# RUN: yaml2obj %s -o %t
# RUN: ld.lld %t -o %tout
# Verify that lld can handle sections with an alignment of zero.
+!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
diff --git a/test/ELF/section-name.s b/test/ELF/section-name.s
index 2d7ed4e63717..f470c48c6a37 100644
--- a/test/ELF/section-name.s
+++ b/test/ELF/section-name.s
@@ -21,11 +21,17 @@ _start:
.section .data.rel.ro.a,"aw",%progbits
.section .data.rel.ro.local,"aw",%progbits
.section .data.rel.ro.local.a,"aw",%progbits
+.section .tbss.foo,"aGwT",@nobits,foo,comdat
+.section .gcc_except_table.foo,"aG",@progbits,foo,comdat
+.section .tdata.foo,"aGwT",@progbits,foo,comdat
// CHECK-NOT: Name: .rodata.a
// CHECK: Name: .rodata
+// CHECK: Name: .gcc_except_table ({{.*}})
// CHECK-NOT: Name: .text.a
// CHECK: Name: .text
+// CHECK: Name: .tdata ({{.*}})
+// CHECK: Name: .tbss ({{.*}})
// CHECK-NOT: Name: .data.rel.ro.a
// CHECK-NOT: Name: .data.rel.ro.local.a
// CHECK: Name: .data.rel.ro
diff --git a/test/ELF/section-symbol.s b/test/ELF/section-symbol.s
index 5f04606914fb..5cf71aceec72 100644
--- a/test/ELF/section-symbol.s
+++ b/test/ELF/section-symbol.s
@@ -23,7 +23,18 @@
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _DYNAMIC
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .dynamic
+// CHECK-NEXT: }
// CHECK-NEXT: ]
foo:
- .quad foo
+ .quad foo - .
diff --git a/test/ELF/shared-be.s b/test/ELF/shared-be.s
index 0f57a4b7f0c3..12eb3131050a 100644
--- a/test/ELF/shared-be.s
+++ b/test/ELF/shared-be.s
@@ -20,17 +20,18 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
+// CHECK-NEXT: 0x000000000000001D RUNPATH foo:bar
+// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x0000000000000007 RELA [[RELADDR]]
// CHECK-NEXT: 0x0000000000000008 RELASZ [[RELSIZE]] (bytes)
// CHECK-NEXT: 0x0000000000000009 RELAENT [[RELENT]] (bytes)
-// CHECK: 0x000000000000001D RUNPATH foo:bar
-// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
-// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
+// CHECK: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000000 NULL 0x0
// CHECK-NEXT: ]
.global _start
_start:
+.data
.long bar
.long zed
diff --git a/test/ELF/shared.s b/test/ELF/shared.s
index 1bf5bd1795bc..a81a09370999 100644
--- a/test/ELF/shared.s
+++ b/test/ELF/shared.s
@@ -144,6 +144,17 @@
// CHECK-NEXT: Section: Undefined
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _DYNAMIC
+// CHECK-NEXT: Value: 0x12000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .dynamic
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: _start
// CHECK-NEXT: Value: 0x11000
// CHECK-NEXT: Size: 0
@@ -243,6 +254,8 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
+// CHECK-NEXT: 0x0000001D RUNPATH foo:bar
+// CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x00000011 REL [[RELADDR]]
// CHECK-NEXT: 0x00000012 RELSZ [[RELSIZE]] (bytes)
// CHECK-NEXT: 0x00000013 RELENT [[RELENT]] (bytes)
@@ -251,8 +264,6 @@
// CHECK-NEXT: 0x00000005 STRTAB [[DYNSTRADDR]]
// CHECK-NEXT: 0x0000000A STRSZ
// CHECK-NEXT: 0x00000004 HASH [[HASHADDR]]
-// CHECK-NEXT: 0x0000001D RUNPATH foo:bar
-// CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x00000015 DEBUG 0x0
// CHECK-NEXT: 0x00000000 NULL 0x0
// CHECK-NEXT: ]
@@ -291,5 +302,5 @@
.global _start
_start:
-.long bar
-.long zed
+.long bar@GOT
+.long zed@GOT
diff --git a/test/ELF/soname.s b/test/ELF/soname.s
index 9d6fe7681dac..65e95ce85add 100644
--- a/test/ELF/soname.s
+++ b/test/ELF/soname.s
@@ -1,6 +1,6 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: ld.lld %t.o -shared -soname=bar -o %t.so
-// RUN: ld.lld %t.o -shared -soname=bar -o %t2.so
+// RUN: ld.lld %t.o -shared --soname=bar -o %t2.so
// RUN: ld.lld %t.o %t.so %t2.so -o %t
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s
diff --git a/test/ELF/splitstacks.s b/test/ELF/splitstacks.s
new file mode 100644
index 000000000000..6506b48a2513
--- /dev/null
+++ b/test/ELF/splitstacks.s
@@ -0,0 +1,11 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+
+# RUN: not ld.lld %t1.o -o %t 2>&1 | FileCheck %s
+# CHECK: objects using splitstacks are not supported
+
+.globl _start
+_start:
+ nop
+
+.section .note.GNU-split-stack,"",@progbits
diff --git a/test/ELF/start-lib-comdat.s b/test/ELF/start-lib-comdat.s
new file mode 100644
index 000000000000..ce03959fd74b
--- /dev/null
+++ b/test/ELF/start-lib-comdat.s
@@ -0,0 +1,23 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
+// RUN: %p/Inputs/start-lib-comdat.s -o %t2.o
+// RUN: ld.lld -shared -o %t3 %t1.o --start-lib %t2.o --end-lib
+// RUN: llvm-readobj -t %t3 | FileCheck %s
+// RUN: ld.lld -shared -o %t3 --start-lib %t2.o --end-lib %t1.o
+// RUN: llvm-readobj -t %t3 | FileCheck %s
+
+// CHECK: Name: zed
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Other:
+// CHECK-NEXT: Section: Undefined
+
+ call bar@plt
+// The other file also has a section in the zed comdat, but it defines the
+// symbol zed. That means that we will have a lazy symbol zed, but when adding
+// the actual file zed will be undefined.
+ .section .sec,"aG",@progbits,zed,comdat
diff --git a/test/ELF/start-lib.s b/test/ELF/start-lib.s
new file mode 100644
index 000000000000..013a2b206a1f
--- /dev/null
+++ b/test/ELF/start-lib.s
@@ -0,0 +1,25 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+// RUN: %p/Inputs/start-lib1.s -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+// RUN: %p/Inputs/start-lib2.s -o %t3.o
+
+// RUN: ld.lld -o %t3 %t1.o %t2.o %t3.o
+// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST1 %s
+// TEST1: Name: bar
+// TEST1: Name: foo
+
+// RUN: ld.lld -o %t3 %t1.o -u bar --start-lib %t2.o %t3.o
+// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST2 %s
+// TEST2: Name: bar
+// TEST2-NOT: Name: foo
+
+// RUN: ld.lld -o %t3 %t1.o --start-lib %t2.o %t3.o
+// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST3 %s
+// TEST3-NOT: Name: bar
+// TEST3-NOT: Name: foo
+
+.globl _start
+_start:
diff --git a/test/ELF/startstop-gccollect.s b/test/ELF/startstop-gccollect.s
new file mode 100644
index 000000000000..b0cd41337e34
--- /dev/null
+++ b/test/ELF/startstop-gccollect.s
@@ -0,0 +1,32 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+## Default run: sections foo and bar exist in output
+# RUN: ld.lld %t -o %tout
+# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
+
+## Check that foo and bar sections are not garbage collected,
+## we do not want to reclaim sections if they can be referred
+## by __start_* and __stop_* symbols.
+# RUN: ld.lld %t --gc-sections -o %tout
+# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
+
+# DISASM: _start:
+# DISASM-NEXT: 11000: 90 nop
+# DISASM-NEXT: Disassembly of section foo:
+# DISASM-NEXT: foo:
+# DISASM-NEXT: 11001: 90 nop
+# DISASM-NEXT: Disassembly of section bar:
+# DISASM-NEXT: bar:
+# DISASM-NEXT: 11002: 90 nop
+
+.global _start
+.text
+_start:
+ nop
+
+.section foo,"ax"
+ nop
+
+.section bar,"ax"
+ nop
diff --git a/test/ELF/startstop-shared.s b/test/ELF/startstop-shared.s
index 108184648f97..77411f3f25c9 100644
--- a/test/ELF/startstop-shared.s
+++ b/test/ELF/startstop-shared.s
@@ -3,16 +3,24 @@
// RUN: ld.lld %t.o -o %t.so -shared
// RUN: llvm-readobj -r -t %t.so | FileCheck %s
+ .data
.quad __start_foo
- .section foo,"a"
-// By default the symbol is visible and we need a dynamic reloc.
-// CHECK: R_X86_64_64 __start_foo 0x0
+ .section foo,"aw"
+// By default the symbol is hidden.
+// CHECK: R_X86_64_RELATIVE - 0x[[ADDR1:.*]]
.hidden __start_bar
.quad __start_bar
.section bar,"a"
-// Test that we are able to hide the symbol.
-// CHECK: R_X86_64_RELATIVE - 0x[[ADDR:.*]]
+// References do not affect the visibility.
+// CHECK: R_X86_64_RELATIVE - 0x[[ADDR2:.*]]
// CHECK: Name: __start_bar
-// CHECK-NEXT: Value: 0x[[ADDR]]
+// CHECK-NEXT: Value: 0x[[ADDR2]]
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding: Local
+
+// CHECK: Name: __start_foo
+// CHECK-NEXT: Value: 0x[[ADDR1]]
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding: Local
diff --git a/test/ELF/startstop.s b/test/ELF/startstop.s
index d0e88df4e7eb..a7b2e43e6a5f 100644
--- a/test/ELF/startstop.s
+++ b/test/ELF/startstop.s
@@ -20,7 +20,13 @@
// DISASM: 1014: 90 nop
-// SYMBOL: Relocations [
+// SYMBOL: Relocations [
+// SYMBOL-NEXT: Section ({{.*}}) .rela.dyn {
+// SYMBOL-NEXT: 0x3000 R_X86_64_RELATIVE - 0x3020
+// SYMBOL-NEXT: 0x3008 R_X86_64_RELATIVE - 0x3021
+// SYMBOL-NEXT: 0x3010 R_X86_64_RELATIVE - 0x3010
+// SYMBOL-NEXT: 0x3018 R_X86_64_RELATIVE - 0x3011
+// SYMBOL-NEXT: }
// SYMBOL-NEXT: ]
// SYMBOL: Symbol {
@@ -59,3 +65,11 @@ _start:
nop
nop
nop
+
+.section zed1, "aw"
+ .quad __stop_zed2
+ .quad __stop_zed2 + 1
+
+.section zed2, "aw"
+ .quad __stop_zed1
+ .quad __stop_zed1 + 1
diff --git a/test/ELF/string-gc.s b/test/ELF/string-gc.s
new file mode 100644
index 000000000000..e7f86a1c6077
--- /dev/null
+++ b/test/ELF/string-gc.s
@@ -0,0 +1,73 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t --gc-sections
+// RUN: llvm-readobj -symbols %t | FileCheck %s
+
+// CHECK: Symbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: (0)
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local (0x0)
+// CHECK-NEXT: Type: None (0x0)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined (0x0)
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: s3
+// CHECK-NEXT: Value: 0x10125
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local (0x0)
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .rodata (0x1)
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: s1
+// CHECK-NEXT: Value: 0x10120
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local (0x0)
+// CHECK-NEXT: Type: Object (0x1)
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN (0x2)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .rodata (0x1)
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _start
+// CHECK-NEXT: Value: 0x11000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global (0x1)
+// CHECK-NEXT: Type: Function (0x2)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text (0x2)
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+.text
+.globl _start
+.type _start,@function
+_start:
+movl $s1, %eax
+movl $s3, %eax
+
+.hidden s1
+.type s1,@object
+.section .rodata.str1.1,"aMS",@progbits,1
+.globl s1
+s1:
+.asciz "abcd"
+
+.hidden s2
+.type s2,@object
+.globl s2
+s2:
+.asciz "efgh"
+
+.type s3,@object
+s3:
+.asciz "ijkl"
+
+.type s4,@object
+.globl s4
+s4:
+.asciz "mnop"
diff --git a/test/ELF/string-table.s b/test/ELF/string-table.s
index 8393d6de6cc5..892c348f6fd0 100644
--- a/test/ELF/string-table.s
+++ b/test/ELF/string-table.s
@@ -59,9 +59,8 @@ _start:
// CHECK-NEXT: EntrySize: 0
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 00626172 002E7465 78740066 6F6F6261 |.bar..text.fooba|
-// CHECK-NEXT: 0010: 7200666F 6F626172 00666F6F 62617200 |r.foobar.foobar.|
-// CHECK-NEXT: 0020: 2E73796D 74616200 2E736873 74727461 |.symtab..shstrta|
-// CHECK-NEXT: 0030: 62002E73 74727461 6200 |b..strtab.|
+// CHECK-NEXT: 0010: 72002E73 796D7461 62002E73 68737472 |r..symtab..shstr|
+// CHECK-NEXT: 0020: 74616200 2E737472 74616200 |tab..strtab.|
// CHECK-NEXT: )
// CHECK-NEXT:}
// CHECK: Name: .strtab
diff --git a/test/ELF/strip-all.s b/test/ELF/strip-all.s
index 6d18431668ae..f322119b0dbb 100644
--- a/test/ELF/strip-all.s
+++ b/test/ELF/strip-all.s
@@ -13,12 +13,16 @@
#AFTER: .shstrtab
#AFTER-NOT: .strtab
+# Ignore --strip-all if -r is specified
+#RUN: ld.lld %t.o --strip-all -r -o %t1
+#RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix BEFORE
+
# Test alias -s
#RUN: ld.lld %t.o -s -o %t1
#RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix AFTER
# exits with return code 42 on linux
-.globl _start;
+.globl _start
_start:
mov $60, %rax
mov $42, %rdi
diff --git a/test/ELF/strip-debug.s b/test/ELF/strip-debug.s
new file mode 100644
index 000000000000..81f7572aa7c5
--- /dev/null
+++ b/test/ELF/strip-debug.s
@@ -0,0 +1,25 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -g %s -o %t
+# RUN: ld.lld %t -o %t2
+# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=DEFAULT %s
+# RUN: ld.lld %t -o %t2 --strip-debug
+# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s
+# RUN: ld.lld %t -o %t2 -S
+# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s
+# RUN: ld.lld %t -o %t2 --strip-all
+# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s
+
+# DEFAULT: Name: .debug_info
+# DEFAULT: Name: .debug_abbrev
+# DEFAULT: Name: .debug_aranges
+# DEFAULT: Name: .debug_line
+
+# STRIP-NOT: Name: .debug_info
+# STRIP-NOT: Name: .debug_abbrev
+# STRIP-NOT: Name: .debug_aranges
+# STRIP-NOT: Name: .debug_line
+
+.globl _start
+_start:
+ ret
diff --git a/test/ELF/symbol-override.s b/test/ELF/symbol-override.s
new file mode 100644
index 000000000000..487885b75b36
--- /dev/null
+++ b/test/ELF/symbol-override.s
@@ -0,0 +1,46 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/symbol-override.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t1.o %t2.so -o %t
+// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
+
+// CHECK: DynamicSymbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name:
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: do
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Function
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo
+// CHECK-NEXT: Value: 0x11000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Function
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+.text
+.globl foo
+.type foo,@function
+foo:
+nop
+
+.text
+.globl _start
+_start:
+callq do@plt
diff --git a/test/ELF/symbols.s b/test/ELF/symbols.s
index ccf83afdf567..a6c838cf0b74 100644
--- a/test/ELF/symbols.s
+++ b/test/ELF/symbols.s
@@ -67,7 +67,7 @@ internal:
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x12000
-// CHECK-NEXT: Offset: 0x2000
+// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 4
// CHECK: Symbols [
@@ -86,7 +86,9 @@ internal:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 2
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: foobar
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
@@ -95,7 +97,9 @@ internal:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 1
+// CHECK-NEXT: Other [ (0x1)
+// CHECK-NEXT: STV_INTERNAL
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: foobar
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
@@ -149,7 +153,9 @@ internal:
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 3
+// CHECK-NEXT: Other [ (0x3)
+// CHECK-NEXT: STV_PROTECTED
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: foobar
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
diff --git a/test/ELF/sysroot.s b/test/ELF/sysroot.s
index 35154be125a3..38fd8cdde402 100644
--- a/test/ELF/sysroot.s
+++ b/test/ELF/sysroot.s
@@ -14,7 +14,7 @@
// We need to be sure that there is no suitable library in the /lib directory
// RUN: not ld.lld -o %t/r %t/m.o -L/lib -l:libls.a 2>&1 \
// RUN: | FileCheck --check-prefix=NOLIB %s
-// NOLIB: Unable to find library -l:libls.a
+// NOLIB: unable to find library -l:libls.a
// Should just remove the '=' symbol if --sysroot is not specified.
// Case 1: relative path
@@ -32,5 +32,5 @@
// RUN: not ld.lld -o %t/r %r/m.o --sysroot=%t -Llib -l:libls.a
// RUN: not ld.lld -o %t/r %r/m.o --sysroot=%t -L/lib -l:libls.a
-.globl _start,_bar;
+.globl _start,_bar
_start:
diff --git a/test/ELF/tail-merge-string-align.s b/test/ELF/tail-merge-string-align.s
new file mode 100644
index 000000000000..a5d4603b6f8b
--- /dev/null
+++ b/test/ELF/tail-merge-string-align.s
@@ -0,0 +1,35 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared -O3
+// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
+
+ .section .rodata.4a,"aMS",@progbits,1
+ .align 4
+ .asciz "abcdef"
+
+ .section .rodata.4b,"aMS",@progbits,1
+ .align 4
+ .asciz "ef"
+
+ .section .rodata.4c,"aMS",@progbits,1
+ .align 4
+ .asciz "f"
+
+
+// CHECK: Name: .rodata
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_MERGE
+// CHECK-NEXT: SHF_STRINGS
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 1
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 4
+// CHECK-NEXT: EntrySize:
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 61626364 65660000 6600 |abcdef..f.|
+// CHECK-NEXT: )
diff --git a/test/ELF/tls-archive.s b/test/ELF/tls-archive.s
new file mode 100644
index 000000000000..9a88fddffd36
--- /dev/null
+++ b/test/ELF/tls-archive.s
@@ -0,0 +1,10 @@
+// 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/tls-mismatch.s -o %t2
+// RUN: rm -f %t.a
+// RUN: llvm-ar cru %t.a %t2
+// RUN: ld.lld %t.a %t -o %t3
+
+.globl _start,tlsvar
+_start:
+ movq tlsvar@GOTTPOFF(%rip),%rdx
diff --git a/test/ELF/tls-dynamic-i686.s b/test/ELF/tls-dynamic-i686.s
index b2620d048864..4db6278ca21b 100644
--- a/test/ELF/tls-dynamic-i686.s
+++ b/test/ELF/tls-dynamic-i686.s
@@ -19,6 +19,14 @@ tls1:
.long 0
.size tls1, 4
+.type tls2,@object
+.globl tls2
+.hidden tls2
+.align 4
+tls2:
+ .long 0
+ .size tls2, 4
+
.section .text
.globl _start
_start:
@@ -28,13 +36,13 @@ call __tls_get_addr@plt
leal tls1@tlsgd(,%ebx,1),%eax
call __tls_get_addr@plt
-leal tls0@tlsldm(%ebx),%eax
+leal tls2@tlsldm(%ebx),%eax
call __tls_get_addr@plt
-leal tls0@dtpoff(%eax),%edx
+leal tls2@dtpoff(%eax),%edx
-leal tls1@tlsldm(%ebx),%eax
+leal tls2@tlsldm(%ebx),%eax
call __tls_get_addr@plt
-leal tls1@dtpoff(%eax),%edx
+leal tls2@dtpoff(%eax),%edx
movl %gs:0,%eax
addl tls0@gotntpoff(%ebx),%eax
@@ -59,12 +67,12 @@ addl tls1@gotntpoff(%ebx),%eax
// CHECK: Relocations [
// CHECK: Section ({{.+}}) .rel.dyn {
+// CHECK-NEXT: 0x2078 R_386_TLS_DTPMOD32 - 0x0
// CHECK-NEXT: 0x2068 R_386_TLS_DTPMOD32 tls0 0x0
// CHECK-NEXT: 0x206C R_386_TLS_DTPOFF32 tls0 0x0
+// CHECK-NEXT: 0x2080 R_386_TLS_TPOFF tls0 0x0
// CHECK-NEXT: 0x2070 R_386_TLS_DTPMOD32 tls1 0x0
// CHECK-NEXT: 0x2074 R_386_TLS_DTPOFF32 tls1 0x0
-// CHECK-NEXT: 0x2078 R_386_TLS_DTPMOD32 - 0x0
-// CHECK-NEXT: 0x2080 R_386_TLS_TPOFF tls0 0x0
// CHECK-NEXT: 0x2084 R_386_TLS_TPOFF tls1 0x0
// CHECK-NEXT: }
@@ -81,10 +89,10 @@ addl tls1@gotntpoff(%ebx),%eax
// -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 00 00 00 00 leal (%eax), %edx
+// 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 04 00 00 00 leal 4(%eax), %edx
+// DIS-NEXT: 1034: 8d 90 08 00 00 00 leal 8(%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
diff --git a/test/ELF/tls-dynamic.s b/test/ELF/tls-dynamic.s
index b6ae6da61bb2..b627977e3c6f 100644
--- a/test/ELF/tls-dynamic.s
+++ b/test/ELF/tls-dynamic.s
@@ -14,10 +14,13 @@
leaq c@tlsgd(%rip), %rdi
rex64
callq __tls_get_addr@PLT
- leaq c@dtpoff(%rax), %rcx
+ leaq a@dtpoff(%rax), %rcx
// Initial Exec Model Code Sequence, II
movq c@gottpoff(%rip),%rax
movq %fs:(%rax),%rax
+ movabs $a@dtpoff, %rax
+ movabs $b@dtpoff, %rax
+ movabs $a@dtpoff, %rax
.global a
.hidden a
@@ -76,6 +79,9 @@ c:
// DIS-NEXT: 102c: 00 00
// DIS-NEXT: 102e: {{.+}} leaq 4267(%rip), %rdi
// DIS-NEXT: 1035: {{.+}} callq
-// DIS-NEXT: 103b: {{.+}} leaq 8(%rax), %rcx
+// DIS-NEXT: 103b: {{.+}} leaq (%rax), %rcx
// DIS-NEXT: 1042: {{.+}} movq 4263(%rip), %rax
// DIS-NEXT: 1049: {{.+}} movq %fs:(%rax), %rax
+// DIS-NEXT: 104d: {{.+}} movabsq $0, %rax
+// DIS-NEXT: 1057: {{.+}} movabsq $4, %rax
+// DIS-NEXT: 1061: {{.+}} movabsq $0, %rax
diff --git a/test/ELF/tls-got-entry.s b/test/ELF/tls-got-entry.s
new file mode 100644
index 000000000000..c7b96697ab30
--- /dev/null
+++ b/test/ELF/tls-got-entry.s
@@ -0,0 +1,25 @@
+// REQUIRES: x86
+// 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-got-entry.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 %s
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT: R_X86_64_TPOFF64 tlsshared0 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+.globl _start
+_start:
+ .byte 0x66
+ leaq tlsshared0@tlsgd(%rip),%rdi
+ .word 0x6666
+ rex64
+ call __tls_get_addr@plt
+ .byte 0x66
+ leaq tlsshared0@tlsgd(%rip),%rdi
+ .word 0x6666
+ rex64
+ call __tls_get_addr@plt
diff --git a/test/ELF/tls-got.s b/test/ELF/tls-got.s
index aa024519a64a..f36d94e40cb1 100644
--- a/test/ELF/tls-got.s
+++ b/test/ELF/tls-got.s
@@ -24,8 +24,8 @@
// CHECK: Relocations [
// CHECK-NEXT: Section (4) .rela.dyn {
-// CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0
// CHECK-NEXT: 0x120B8 R_X86_64_TPOFF64 tls0 0x0
+// CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0
// CHECK-NEXT: }
// CHECK-NEXT: ]
diff --git a/test/ELF/tls-i686.s b/test/ELF/tls-i686.s
index 62940d6cd164..e0a1007fde16 100644
--- a/test/ELF/tls-i686.s
+++ b/test/ELF/tls-i686.s
@@ -15,7 +15,7 @@ var:
var1:
.long 1
-.text
+.section test, "awx"
.global _start
_start:
movl $var@tpoff, %edx
@@ -30,40 +30,40 @@ _start:
movl %gs:0, %ecx
leal var1@ntpoff(%ecx), %eax
-// DIS: Disassembly of section .text:
+// DIS: Disassembly of section test:
// DIS-NEXT: _start:
-// DIS-NEXT: 11000: ba 08 00 00 00 movl $8, %edx
-// DIS-NEXT: 11005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DIS-NEXT: 1100c: 29 d0 subl %edx, %eax
-// DIS-NEXT: 1100e: ba 04 00 00 00 movl $4, %edx
-// DIS-NEXT: 11013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DIS-NEXT: 1101a: 29 d0 subl %edx, %eax
-// DIS-NEXT: 1101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DIS-NEXT: 11023: 8d 81 f8 ff ff ff leal -8(%ecx), %eax
-// DIS-NEXT: 11029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DIS-NEXT: 11030: 8d 81 fc ff ff ff leal -4(%ecx), %eax
+// DIS-NEXT: 12000: ba 08 00 00 00 movl $8, %edx
+// DIS-NEXT: 12005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 1200c: 29 d0 subl %edx, %eax
+// DIS-NEXT: 1200e: ba 04 00 00 00 movl $4, %edx
+// DIS-NEXT: 12013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 1201a: 29 d0 subl %edx, %eax
+// DIS-NEXT: 1201c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 12023: 8d 81 f8 ff ff ff leal -8(%ecx), %eax
+// DIS-NEXT: 12029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DIS-NEXT: 12030: 8d 81 fc ff ff ff leal -4(%ecx), %eax
// RELOC: Relocations [
// RELOC-NEXT: ]
-// DISSHARED: Disassembly of section .text:
+// DISSHARED: Disassembly of section test:
// DISSHARED-NEXT: _start:
-// DISSHARED-NEXT: 1000: ba 00 00 00 00 movl $0, %edx
-// DISSHARED-NEXT: 1005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DISSHARED-NEXT: 100c: 29 d0 subl %edx, %eax
-// DISSHARED-NEXT: 100e: ba 00 00 00 00 movl $0, %edx
-// DISSHARED-NEXT: 1013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DISSHARED-NEXT: 101a: 29 d0 subl %edx, %eax
-// DISSHARED-NEXT: 101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DISSHARED-NEXT: 1023: 8d 81 00 00 00 00 leal (%ecx), %eax
-// DISSHARED-NEXT: 1029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
-// DISSHARED-NEXT: 1030: 8d 81 00 00 00 00 leal (%ecx), %eax
+// DISSHARED-NEXT: 2000: ba 00 00 00 00 movl $0, %edx
+// DISSHARED-NEXT: 2005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DISSHARED-NEXT: 200c: 29 d0 subl %edx, %eax
+// DISSHARED-NEXT: 200e: ba 00 00 00 00 movl $0, %edx
+// DISSHARED-NEXT: 2013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DISSHARED-NEXT: 201a: 29 d0 subl %edx, %eax
+// DISSHARED-NEXT: 201c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DISSHARED-NEXT: 2023: 8d 81 00 00 00 00 leal (%ecx), %eax
+// DISSHARED-NEXT: 2029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
+// DISSHARED-NEXT: 2030: 8d 81 00 00 00 00 leal (%ecx), %eax
// RELOCSHARED: Relocations [
// RELOCSHARED-NEXT: Section (4) .rel.dyn {
-// RELOCSHARED-NEXT: 0x1001 R_386_TLS_TPOFF32 var 0x0
-// RELOCSHARED-NEXT: 0x100F R_386_TLS_TPOFF32 var1 0x0
-// RELOCSHARED-NEXT: 0x1025 R_386_TLS_TPOFF var 0x0
-// RELOCSHARED-NEXT: 0x1032 R_386_TLS_TPOFF var1 0x0
+// RELOCSHARED-NEXT: 0x2001 R_386_TLS_TPOFF32 var 0x0
+// RELOCSHARED-NEXT: 0x2025 R_386_TLS_TPOFF var 0x0
+// RELOCSHARED-NEXT: 0x200F R_386_TLS_TPOFF32 var1 0x0
+// RELOCSHARED-NEXT: 0x2032 R_386_TLS_TPOFF var1 0x0
// RELOCSHARED-NEXT: }
// RELOCSHARED-NEXT: ]
diff --git a/test/ELF/tls-in-archive.s b/test/ELF/tls-in-archive.s
new file mode 100644
index 000000000000..71f60e380f33
--- /dev/null
+++ b/test/ELF/tls-in-archive.s
@@ -0,0 +1,11 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-in-archive.s -o %t1.o
+// RUN: llvm-ar cru %t.a %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
+// RUN: ld.lld %t2.o %t.a -o %tout
+
+ .globl _start
+_start:
+ movq foo@gottpoff(%rip), %rax
+ .section .tbss,"awT",@nobits
+ .weak foo
diff --git a/test/ELF/tls-initial-exec-local.s b/test/ELF/tls-initial-exec-local.s
new file mode 100644
index 000000000000..0aef3c8237b6
--- /dev/null
+++ b/test/ELF/tls-initial-exec-local.s
@@ -0,0 +1,36 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t
+// RUN: llvm-readobj -r -s %t | FileCheck %s
+// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
+
+// CHECK: Name: .got
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC (0x2)
+// CHECK-NEXT: SHF_WRITE (0x1)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x2090
+
+// 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: }
+// CHECK-NEXT: ]
+
+// 0x1007 + 4233 = 0x2090
+// 0x100e + 4234 = 0x2098
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: .text:
+// DISASM-NEXT: 1000: {{.*}} addq 4233(%rip), %rax
+// DISASM-NEXT: 1007: {{.*}} addq 4234(%rip), %rax
+
+ addq foo@GOTTPOFF(%rip), %rax
+ addq bar@GOTTPOFF(%rip), %rax
+
+ .section .tbss,"awT",@nobits
+foo:
+ .long 0
+bar:
+ .long 0
diff --git a/test/ELF/tls-offset.s b/test/ELF/tls-offset.s
new file mode 100644
index 000000000000..8f5a46d988da
--- /dev/null
+++ b/test/ELF/tls-offset.s
@@ -0,0 +1,56 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+// RUN: ld.lld %t -o %tout
+// RUN: llvm-readobj -s %tout | FileCheck %s
+
+ .global _start
+_start:
+ retq
+
+ .section .tdata,"awT",@progbits
+ .align 4
+ .long 42
+
+ .section .tbss,"awT",@nobits
+ .align 16
+ .zero 16
+
+ .data
+ .long 1
+
+
+// Test that .tbss doesn't show up in the offset or in the address. If this
+// gets out of sync what we get a runtime is different from what the section
+// table says.
+
+// CHECK: Name: .tdata
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_TLS
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x12000
+// CHECK-NEXT: Offset: 0x2000
+// CHECK-NEXT: Size: 4
+
+// CHECK: Name: .tbss
+// CHECK-NEXT: Type: SHT_NOBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_TLS
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x12010
+// CHECK-NEXT: Offset: 0x2004
+// CHECK-NEXT: Size: 16
+
+// CHECK: Name: .data
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x12004
+// CHECK-NEXT: Offset: 0x2004
+// CHECK-NEXT: Size: 4
diff --git a/test/ELF/tls-opt-gdie.s b/test/ELF/tls-opt-gdie.s
index 3f83157086e7..6ed370e3f0b2 100644
--- a/test/ELF/tls-opt-gdie.s
+++ b/test/ELF/tls-opt-gdie.s
@@ -6,15 +6,15 @@
// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
//RELOC: Section {
-//RELOC: Index: 9
-//RELOC-NEXT: Name: .got
+//RELOC: Index:
+//RELOC: Name: .got
//RELOC-NEXT: Type: SHT_PROGBITS
//RELOC-NEXT: Flags [
//RELOC-NEXT: SHF_ALLOC
//RELOC-NEXT: SHF_WRITE
//RELOC-NEXT: ]
-//RELOC-NEXT: Address: 0x120F0
-//RELOC-NEXT: Offset: 0x20F0
+//RELOC-NEXT: Address: 0x120B0
+//RELOC-NEXT: Offset: 0x20B0
//RELOC-NEXT: Size: 16
//RELOC-NEXT: Link: 0
//RELOC-NEXT: Info: 0
@@ -23,22 +23,19 @@
//RELOC-NEXT: }
//RELOC: Relocations [
//RELOC-NEXT: Section (4) .rela.dyn {
-//RELOC-NEXT: 0x120F0 R_X86_64_TPOFF64 tlsshared0 0x0
-//RELOC-NEXT: 0x120F8 R_X86_64_TPOFF64 tlsshared1 0x0
-//RELOC-NEXT: }
-//RELOC-NEXT: Section (5) .rela.plt {
-//RELOC-NEXT: 0x13018 R_X86_64_JUMP_SLOT __tls_get_addr 0x0
+//RELOC-NEXT: 0x120B0 R_X86_64_TPOFF64 tlsshared0 0x0
+//RELOC-NEXT: 0x120B8 R_X86_64_TPOFF64 tlsshared1 0x0
//RELOC-NEXT: }
//RELOC-NEXT: ]
-//0x11009 + (4304 + 7) = 0x120F0
-//0x11019 + (4296 + 7) = 0x120F8
+//0x11009 + (4256 + 7) = 0x120B0
+//0x11019 + (4248 + 7) = 0x120B8
// DISASM: Disassembly of section .text:
// DISASM-NEXT: _start:
-// DISASM-NEXT: 11000: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
-// DISASM-NEXT: 11009: 48 03 05 e0 10 00 00 addq 4320(%rip), %rax
-// DISASM-NEXT: 11010: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
-// DISASM-NEXT: 11019: 48 03 05 d8 10 00 00 addq 4312(%rip), %rax
+// DISASM-NEXT: 11000: {{.*}} movq %fs:0, %rax
+// DISASM-NEXT: 11009: {{.*}} addq 4256(%rip), %rax
+// DISASM-NEXT: 11010: {{.*}} movq %fs:0, %rax
+// DISASM-NEXT: 11019: {{.*}} addq 4248(%rip), %rax
.section .text
.globl _start
diff --git a/test/ELF/tls-opt-iele-i686-nopic.s b/test/ELF/tls-opt-iele-i686-nopic.s
index 50ade0fc76cc..b6608c16551c 100644
--- a/test/ELF/tls-opt-iele-i686-nopic.s
+++ b/test/ELF/tls-opt-iele-i686-nopic.s
@@ -4,9 +4,6 @@
// RUN: ld.lld %t.o %tso -o %t1
// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTREL %s
// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
-// RUN: ld.lld -shared %t.o %tso -o %t1
-// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTRELSHARED %s
-// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s
// GOTREL: Section {
// GOTREL: Index:
@@ -54,62 +51,6 @@
// DISASM-NEXT: 1103d: 03 0d 5c 20 01 00 addl 73820, %ecx
// DISASM-NEXT: 11043: 65 8b 01 movl %gs:(%ecx), %eax
-// GOTRELSHARED: Section {
-// GOTRELSHARED: Index: 8
-// GOTRELSHARED: Name: .got
-// GOTRELSHARED-NEXT: Type: SHT_PROGBITS
-// GOTRELSHARED-NEXT: Flags [
-// GOTRELSHARED-NEXT: SHF_ALLOC
-// GOTRELSHARED-NEXT: SHF_WRITE
-// GOTRELSHARED-NEXT: ]
-// GOTRELSHARED-NEXT: Address: 0x2050
-// GOTRELSHARED-NEXT: Offset: 0x2050
-// GOTRELSHARED-NEXT: Size: 16
-// GOTRELSHARED-NEXT: Link: 0
-// GOTRELSHARED-NEXT: Info: 0
-// GOTRELSHARED-NEXT: AddressAlignment: 4
-// GOTRELSHARED-NEXT: EntrySize: 0
-// GOTRELSHARED-NEXT: }
-// GOTRELSHARED: Relocations [
-// GOTRELSHARED-NEXT: Section ({{.*}}) .rel.dyn {
-// GOTRELSHARED-NEXT: 0x1002 R_386_RELATIVE - 0x0
-// GOTRELSHARED-NEXT: 0x2050 R_386_TLS_TPOFF tlslocal0 0x0
-// GOTRELSHARED-NEXT: 0x100A R_386_RELATIVE - 0x0
-// GOTRELSHARED-NEXT: 0x1013 R_386_RELATIVE - 0x0
-// GOTRELSHARED-NEXT: 0x101C R_386_RELATIVE - 0x0
-// GOTRELSHARED-NEXT: 0x2054 R_386_TLS_TPOFF tlslocal1 0x0
-// GOTRELSHARED-NEXT: 0x1024 R_386_RELATIVE - 0x0
-// GOTRELSHARED-NEXT: 0x102D R_386_RELATIVE - 0x0
-// GOTRELSHARED-NEXT: 0x1036 R_386_RELATIVE - 0x0
-// GOTRELSHARED-NEXT: 0x2058 R_386_TLS_TPOFF tlsshared0 0x0
-// GOTRELSHARED-NEXT: 0x103F R_386_RELATIVE - 0x0
-// GOTRELSHARED-NEXT: 0x205C R_386_TLS_TPOFF tlsshared1 0x0
-// GOTRELSHARED-NEXT: }
-// GOTRELSHARED-NEXT: ]
-
-// DISASMSHARED: Disassembly of section .text:
-// DISASMSHARED-NEXT: _start:
-// (.got)[0] = 0x2050 = 8272
-// (.got)[1] = 0x2054 = 8276
-// (.got)[2] = 0x2058 = 8280
-// (.got)[3] = 0x205C = 8284
-// DISASMSHARED-NEXT: 1000: 8b 0d 50 20 00 00 movl 8272, %ecx
-// DISASMSHARED-NEXT: 1006: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASMSHARED-NEXT: 1009: a1 50 20 00 00 movl 8272, %eax
-// DISASMSHARED-NEXT: 100e: 65 8b 00 movl %gs:(%eax), %eax
-// DISASMSHARED-NEXT: 1011: 03 0d 50 20 00 00 addl 8272, %ecx
-// DISASMSHARED-NEXT: 1017: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASMSHARED-NEXT: 101a: 8b 0d 54 20 00 00 movl 8276, %ecx
-// DISASMSHARED-NEXT: 1020: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASMSHARED-NEXT: 1023: a1 54 20 00 00 movl 8276, %eax
-// DISASMSHARED-NEXT: 1028: 65 8b 00 movl %gs:(%eax), %eax
-// DISASMSHARED-NEXT: 102b: 03 0d 54 20 00 00 addl 8276, %ecx
-// DISASMSHARED-NEXT: 1031: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASMSHARED-NEXT: 1034: 8b 0d 58 20 00 00 movl 8280, %ecx
-// DISASMSHARED-NEXT: 103a: 65 8b 01 movl %gs:(%ecx), %eax
-// DISASMSHARED-NEXT: 103d: 03 0d 5c 20 00 00 addl 8284, %ecx
-// DISASMSHARED-NEXT: 1043: 65 8b 01 movl %gs:(%ecx), %eax
-
.type tlslocal0,@object
.section .tbss,"awT",@nobits
.globl tlslocal0
diff --git a/test/ELF/tls-opt-no-plt.s b/test/ELF/tls-opt-no-plt.s
new file mode 100644
index 000000000000..53655d0934d5
--- /dev/null
+++ b/test/ELF/tls-opt-no-plt.s
@@ -0,0 +1,34 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-opt-gdie.s -o %t2.o
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t.exe
+// RUN: llvm-readobj -s %t.exe | FileCheck %s
+
+// CHECK-NOT: .plt
+
+ .global _start
+_start:
+ data16
+ leaq foo@TLSGD(%rip), %rdi
+ data16
+ data16
+ rex64
+ callq __tls_get_addr@PLT
+
+ leaq bar@TLSLD(%rip), %rdi
+ callq __tls_get_addr@PLT
+ leaq bar@DTPOFF(%rax), %rax
+
+ .type bar,@object
+ .section .tdata,"awT",@progbits
+ .align 8
+bar:
+ .long 42
+
+
+ .type foo,@object
+ .section .tdata,"awT",@progbits
+ .globl foo
+ .align 8
+foo:
+ .long 42
diff --git a/test/ELF/tls-opt.s b/test/ELF/tls-opt.s
index 06577d7e1021..52468f16b09d 100644
--- a/test/ELF/tls-opt.s
+++ b/test/ELF/tls-opt.s
@@ -6,35 +6,37 @@
// NORELOC: Relocations [
// NORELOC-NEXT: ]
-// DISASM: Disassembly of section .text:
-// DISASM-NEXT: _start:
-// DISASM-NEXT: 11000: 48 c7 c0 f8 ff ff ff movq $-8, %rax
-// DISASM-NEXT: 11007: 49 c7 c7 f8 ff ff ff movq $-8, %r15
-// DISASM-NEXT: 1100e: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax
-// DISASM-NEXT: 11015: 4d 8d bf f8 ff ff ff leaq -8(%r15), %r15
-// DISASM-NEXT: 1101c: 48 81 c4 f8 ff ff ff addq $-8, %rsp
-// DISASM-NEXT: 11023: 49 81 c4 f8 ff ff ff addq $-8, %r12
-// DISASM-NEXT: 1102a: 48 c7 c0 fc ff ff ff movq $-4, %rax
-// DISASM-NEXT: 11031: 49 c7 c7 fc ff ff ff movq $-4, %r15
-// DISASM-NEXT: 11038: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax
-// DISASM-NEXT: 1103f: 4d 8d bf fc ff ff ff leaq -4(%r15), %r15
-// DISASM-NEXT: 11046: 48 81 c4 fc ff ff ff addq $-4, %rsp
-// DISASM-NEXT: 1104d: 49 81 c4 fc ff ff ff addq $-4, %r12
-// Corrupred output:
-// DISASM-NEXT: 11054: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax
-// DISASM-NEXT: 1105b: 48 d1 81 c4 f8 ff ff rolq -1852(%rcx)
-// DISASM-NEXT: 11062: ff 48 d1 decl -47(%rax)
-// DISASM-NEXT: 11065: 81 c4 f8 ff ff ff addl $4294967288, %esp
+// DISASM: _start:
+// DISASM-NEXT: 11000: 48 c7 c0 f8 ff ff ff movq $-8, %rax
+// DISASM-NEXT: 11007: 49 c7 c7 f8 ff ff ff movq $-8, %r15
+// DISASM-NEXT: 1100e: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax
+// DISASM-NEXT: 11015: 4d 8d bf f8 ff ff ff leaq -8(%r15), %r15
+// DISASM-NEXT: 1101c: 48 81 c4 f8 ff ff ff addq $-8, %rsp
+// DISASM-NEXT: 11023: 49 81 c4 f8 ff ff ff addq $-8, %r12
+// DISASM-NEXT: 1102a: 48 c7 c0 fc ff ff ff movq $-4, %rax
+// DISASM-NEXT: 11031: 49 c7 c7 fc ff ff ff movq $-4, %r15
+// DISASM-NEXT: 11038: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax
+// DISASM-NEXT: 1103f: 4d 8d bf fc ff ff ff leaq -4(%r15), %r15
+// DISASM-NEXT: 11046: 48 81 c4 fc ff ff ff addq $-4, %rsp
+// DISASM-NEXT: 1104d: 49 81 c4 fc ff ff ff addq $-4, %r12
+
// LD to LE:
-// DISASM-NEXT: 1106b: 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
-// DISASM-NEXT: 11077: 48 8d 88 f8 ff ff ff leaq -8(%rax), %rcx
-// DISASM-NEXT: 1107e: 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
-// DISASM-NEXT: 1108a: 48 8d 88 fc ff ff ff leaq -4(%rax), %rcx
+// DISASM-NEXT: 11054: 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
+// DISASM-NEXT: 11060: 48 8d 88 f8 ff ff ff leaq -8(%rax), %rcx
+// DISASM-NEXT: 11067: 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
+// DISASM-NEXT: 11073: 48 8d 88 fc ff ff ff leaq -4(%rax), %rcx
+
// GD to LE:
-// DISASM-NEXT: 11091: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
-// DISASM-NEXT: 1109a: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax
-// DISASM-NEXT: 110a1: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
-// DISASM-NEXT: 110aa: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax
+// DISASM-NEXT: 1107a: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
+// DISASM-NEXT: 11083: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax
+// DISASM-NEXT: 1108a: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
+// DISASM-NEXT: 11093: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax
+
+// LD to LE:
+// DISASM: _DTPOFF64_1:
+// DISASM-NEXT: 1109a: f8 clc
+// DISASM: _DTPOFF64_2:
+// DISASM-NEXT: 110a3: fc cld
.type tls0,@object
.section .tbss,"awT",@nobits
@@ -67,12 +69,7 @@ _start:
addq tls1@GOTTPOFF(%rip), %rsp
addq tls1@GOTTPOFF(%rip), %r12
- //Invalid input case:
- xchgq tls0@gottpoff(%rip),%rax
- shlq tls0@gottpoff
- rolq tls0@gottpoff
-
- //LD to LE:
+ // LD to LE
leaq tls0@tlsld(%rip), %rdi
callq __tls_get_addr@PLT
leaq tls0@dtpoff(%rax),%rcx
@@ -80,7 +77,7 @@ _start:
callq __tls_get_addr@PLT
leaq tls1@dtpoff(%rax),%rcx
- //GD to LE:
+ // GD to LE
.byte 0x66
leaq tls0@tlsgd(%rip),%rdi
.word 0x6666
@@ -91,3 +88,12 @@ _start:
.word 0x6666
rex64
call __tls_get_addr@plt
+
+ // LD to LE
+_DTPOFF64_1:
+ .quad tls0@DTPOFF
+ nop
+
+_DTPOFF64_2:
+ .quad tls1@DTPOFF
+ nop
diff --git a/test/ELF/tls-two-relocs.s b/test/ELF/tls-two-relocs.s
new file mode 100644
index 000000000000..7c5d6abf77f4
--- /dev/null
+++ b/test/ELF/tls-two-relocs.s
@@ -0,0 +1,30 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+// RUN: ld.lld %t -o %tout -shared
+// RUN: llvm-readobj -r %tout | FileCheck %s
+
+ data16
+ leaq g_tls_s@TLSGD(%rip), %rdi
+ data16
+ data16
+ rex64
+ callq __tls_get_addr@PLT
+
+ data16
+ leaq g_tls_s@TLSGD(%rip), %rdi
+ data16
+ data16
+ rex64
+ callq __tls_get_addr@PLT
+
+// Check that we handle two gd relocations to the same symbol.
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section (4) .rela.dyn {
+// CHECK-NEXT: R_X86_64_DTPMOD64 g_tls_s 0x0
+// CHECK-NEXT: R_X86_64_DTPOFF64 g_tls_s 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: Section (5) .rela.plt {
+// CHECK-NEXT: R_X86_64_JUMP_SLOT __tls_get_addr 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/trace-ar.s b/test/ELF/trace-ar.s
new file mode 100644
index 000000000000..1d178dc9dd37
--- /dev/null
+++ b/test/ELF/trace-ar.s
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.foo.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar1.s -o %t.obj1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar2.s -o %t.obj2.o
+# RUN: llvm-ar rcs %t.boo.a %t.obj1.o %t.obj2.o
+
+## Check how -t works with achieves
+# RUN: ld.lld %t.foo.o %t.boo.a -o %t.out -t 2>&1 | FileCheck %s
+# CHECK: {{.*}}.foo.o
+# CHECK-NEXT: {{.*}}.boo.a({{.*}}.obj1.o)
+# CHECK-NOT: {{.*}}.boo.a({{.*}}.obj2.o)
+
+## Test output with --start-lib
+# RUN: ld.lld %t.foo.o --start-lib %t.obj1.o %t.obj2.o -o %t.out -t 2>&1 | FileCheck --check-prefix=STARTLIB %s
+# STARTLIB: {{.*}}.foo.o
+# STARTLIB-NEXT: {{.*}}.obj1.o
+# STARTLIB-NOT: {{.*}}.obj2.o
+
+.globl _start, _used
+_start:
+ call _used
diff --git a/test/ELF/trace-symbols.s b/test/ELF/trace-symbols.s
new file mode 100644
index 000000000000..7f6bca8be216
--- /dev/null
+++ b/test/ELF/trace-symbols.s
@@ -0,0 +1,78 @@
+# Test -y symbol and -trace-symbol=symbol
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+# RUN: %p/Inputs/trace-symbols-foo-weak.s -o %t1
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+# RUN: %p/Inputs/trace-symbols-foo-strong.s -o %t2
+# RUN: ld.lld -shared %t1 -o %t1.so
+# RUN: ld.lld -shared %t2 -o %t2.so
+# RUN: llvm-ar rcs %t1.a %t1
+# RUN: llvm-ar rcs %t2.a %t2
+
+# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
+# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTRFOO %s
+# OBJECTRFOO: trace-symbols.s.tmp: reference to foo
+
+# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
+# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTDCOMMON %s
+# OBJECTDCOMMON: trace-symbols.s.tmp1: common definition of common
+
+# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
+# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD1FOO %s
+# OBJECTD1FOO: trace-symbols.s.tmp: reference to foo
+# OBJECTD1FOO: trace-symbols.s.tmp1: common definition of common
+# OBJECTD1FOO: trace-symbols.s.tmp1: definition of foo
+# OBJECTD1FOO: trace-symbols.s.tmp2: definition of foo
+
+# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
+# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s
+# RUN: ld.lld -y foo -y common --trace-symbol=hsymbol \
+# RUN: %t %t2 %t1 -o %t4 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s
+# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \
+# RUN: FileCheck -check-prefix=OBJECTD2FOO %s
+# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \
+# RUN: FileCheck -check-prefix=OBJECTD2FOO %s
+# OBJECTD2FOO: trace-symbols.s.tmp2: definition of foo
+
+# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \
+# RUN: FileCheck -check-prefix=SHLIBDCOMMON %s
+# SHLIBDCOMMON: trace-symbols.s.tmp1.so: definition of common
+
+# RUN: ld.lld -y foo -y common %t %t2.so %t1.so -o %t3 2>&1 | \
+# RUN: FileCheck -check-prefix=SHLIBD2FOO %s
+# RUN: ld.lld -y foo %t %t1.a %t2.so -o %t3 | \
+# RUN: FileCheck -check-prefix=NO-SHLIBD2FOO %s
+# SHLIBD2FOO: trace-symbols.s.tmp2.so: definition of foo
+# NO-SHLIBD2FOO-NOT: trace-symbols.s.tmp2.so: definition of foo
+
+# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \
+# RUN: FileCheck -check-prefix=ARCHIVEDCOMMON %s
+# ARCHIVEDCOMMON-NOT: trace-symbols.s.tmp1.a(trace-symbols.s.tmp1): definition of \
+# common
+
+# RUN: ld.lld -y foo %t %t1.a %t2.so -o %t3 | \
+# RUN: FileCheck -check-prefix=ARCHIVED1FOO %s
+# ARCHIVED1FOO: trace-symbols.s.tmp1.a(trace-symbols.s.tmp1): definition of foo
+
+# RUN: ld.lld -y foo %t %t1.a %t2.a -o %t3 | \
+# RUN: FileCheck -check-prefix=ARCHIVED2FOO %s
+# ARCHIVED2FOO: trace-symbols.s.tmp2.a(trace-symbols.s.tmp2): definition of foo
+
+# RUN: ld.lld -y bar %t %t1.so %t2.so -o %t3 | \
+# RUN: FileCheck -check-prefix=SHLIBDBAR %s
+# SHLIBDBAR: trace-symbols.s.tmp2.so: definition of bar
+
+# RUN: ld.lld -y foo -y bar %t %t1.so %t2.so -o %t3 | \
+# RUN: FileCheck -check-prefix=SHLIBRBAR %s
+# SHLIBRBAR-NOT: trace-symbols.s.tmp1.so: reference to bar
+
+# RUN: ld.lld -y foo -y bar %t -u bar --start-lib %t1 %t2 --end-lib -o %t3 | \
+# RUN: FileCheck -check-prefix=STARTLIB %s
+# STARTLIB: trace-symbols.s.tmp1: reference to bar
+
+.hidden hsymbol
+.globl _start
+.type _start, @function
+_start:
+call foo
diff --git a/test/ELF/trace.s b/test/ELF/trace.s
new file mode 100644
index 000000000000..4374d93da648
--- /dev/null
+++ b/test/ELF/trace.s
@@ -0,0 +1,9 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.foo.o
+
+## Check -t
+# RUN: ld.lld -shared %t.foo.o -o %t.so -t 2>&1 | FileCheck %s
+# CHECK: {{.*}}.foo.o
+
+## Check --trace alias
+# RUN: ld.lld -shared %t.foo.o -o %t.so -t 2>&1 | FileCheck %s
diff --git a/test/ELF/undef-shared.s b/test/ELF/undef-shared.s
new file mode 100644
index 000000000000..ed9103571443
--- /dev/null
+++ b/test/ELF/undef-shared.s
@@ -0,0 +1,14 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
+
+# CHECK: undefined symbol: hidden in {{.*}}
+.global hidden
+.hidden hidden
+
+# CHECK: undefined symbol: internal in {{.*}}
+.global internal
+.internal internal
+
+# CHECK: undefined symbol: protected in {{.*}}
+.global protected
+.protected protected
diff --git a/test/ELF/undef-version-script.s b/test/ELF/undef-version-script.s
new file mode 100644
index 000000000000..9f0a5a49e72e
--- /dev/null
+++ b/test/ELF/undef-version-script.s
@@ -0,0 +1,40 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "{ local: *; };" > %t.script
+# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
+
+# This does not match gold's behavior because gold does not create undefined
+# symbols in dynsym without an appropriate (e.g. PLT) relocation in the input.
+
+# CHECK: DynamicSymbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: @ (0)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local (0x0)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined (0x0)
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: bar@ (1)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Weak (0x2)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined (0x0)
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: foo@ (5)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global (0x1)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined (0x0)
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+.global foo
+.weak bar
diff --git a/test/ELF/undef-with-plt-addr-i686.s b/test/ELF/undef-with-plt-addr-i686.s
new file mode 100644
index 000000000000..755f0daced2e
--- /dev/null
+++ b/test/ELF/undef-with-plt-addr-i686.s
@@ -0,0 +1,23 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/undef-with-plt-addr.s -o %t2.o
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t3
+// RUN: llvm-readobj -t -s %t3 | FileCheck %s
+
+.globl _start
+_start:
+mov $set_data, %eax
+
+// Test that set_data has an address in the .plt
+
+// CHECK: Name: .plt
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x11010
+
+// CHECK: Name: set_data
+// CHECK-NEXT: Value: 0x11020
diff --git a/test/ELF/undef-with-plt-addr.s b/test/ELF/undef-with-plt-addr.s
new file mode 100644
index 000000000000..792d85f3da61
--- /dev/null
+++ b/test/ELF/undef-with-plt-addr.s
@@ -0,0 +1,45 @@
+// REQUIRES: x86
+// 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/undef-with-plt-addr.s -o %t2.o
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t3
+// RUN: llvm-readobj -t -s -r %t3 | FileCheck %s
+
+.globl _start
+_start:
+movabsq $set_data, %rax
+
+.data
+.quad foo
+// Test that set_data has an address in the .plt, but foo is not
+
+// CHECK: Name: .plt
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x11010
+
+// CHECK: Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT: 0x13000 R_X86_64_64 foo 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: Section ({{.*}}) .rela.plt {
+// CHECK-NEXT: 0x13020 R_X86_64_JUMP_SLOT set_data 0x0
+// CHECK-NEXT: }
+
+// CHECK: Name: foo
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Function
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+
+// CHECK: Name: set_data
+// CHECK-NEXT: Value: 0x11020
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Function
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
diff --git a/test/ELF/undef.s b/test/ELF/undef.s
index 374c9c884d5f..c8211c73866f 100644
--- a/test/ELF/undef.s
+++ b/test/ELF/undef.s
@@ -1,8 +1,15 @@
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
-# RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
-# CHECK: undefined symbol: foo in {{.*}}
# 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 %p/Inputs/undef.s -o %t2.o
+# RUN: llvm-ar rc %t2.a %t2.o
+# RUN: not ld.lld %t.o %t2.a -o %t.exe 2>&1 | FileCheck %s
+# RUN: not ld.lld -pie %t.o %t2.a -o %t.exe 2>&1 | FileCheck %s
+# CHECK: undefined symbol: bar in {{.*}}
+# CHECK: undefined symbol: foo in {{.*}}
+# CHECK: undefined symbol: zed2 in {{.*}}2.a({{.*}}.o)
- .globl _start;
+ .globl _start
_start:
call foo
+ call bar
+ call zed1
diff --git a/test/ELF/undefined-opt.s b/test/ELF/undefined-opt.s
index 97ab5a63490a..ddd34f49b748 100644
--- a/test/ELF/undefined-opt.s
+++ b/test/ELF/undefined-opt.s
@@ -51,5 +51,16 @@
# UNK-UNDEFINED-SO-NOT: Name: unknown
# UNK-UNDEFINED-SO: ]
-.globl _start;
+# Added undefined symbols should appear in the dynamic table if necessary.
+# RUN: ld.lld -shared -o %t5 %t.o -u export
+# RUN: llvm-readobj --dyn-symbols %t5 | \
+# RUN: FileCheck --check-prefix=EXPORT-SO %s
+# EXPORT-SO: DynamicSymbols [
+# EXPORT-SO: Name: export
+# EXPORT-SO: ]
+
+.globl _start
_start:
+
+.globl export
+export:
diff --git a/test/ELF/unresolved-symbols.s b/test/ELF/unresolved-symbols.s
new file mode 100644
index 000000000000..2fa59cb0ffd7
--- /dev/null
+++ b/test/ELF/unresolved-symbols.s
@@ -0,0 +1,63 @@
+# REQUIRES: x86
+# 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/unresolved-symbols.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -o %t.so
+
+## Check that %t2.o contains undefined symbol undef.
+# RUN: not ld.lld %t1.o %t2.o -o %t 2>&1 | \
+# RUN: FileCheck -check-prefix=UNDCHECK %s
+# UNDCHECK: undefined symbol: undef in {{.*}}2.o
+
+## Error out if unknown option value was set.
+# RUN: not ld.lld %t1.o %t2.o -o %t --unresolved-symbols=xxx 2>&1 | \
+# RUN: FileCheck -check-prefix=ERR1 %s
+# ERR1: unknown --unresolved-symbols value: xxx
+
+## Ignore all should not produce error for symbols from object except
+## case when --no-undefined specified.
+# RUN: ld.lld %t2.o -o %t1_1 --unresolved-symbols=ignore-all
+# RUN: llvm-readobj %t1_1 > /dev/null 2>&1
+# RUN: not ld.lld %t2.o -o %t1_2 --unresolved-symbols=ignore-all --no-undefined 2>&1 | \
+# RUN: FileCheck -check-prefix=ERRUND %s
+# ERRUND: undefined symbol: undef
+## 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: 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 %t2_1 --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 %t3 --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: llvm-readobj %t3_1 > /dev/null 2>&1
+
+## Ignoring undefines in shared libs should not produce error for symbol from object
+## if we are linking DSO.
+# RUN: ld.lld -shared %t1.o -o %t4 --unresolved-symbols=ignore-in-shared-libs
+# RUN: llvm-readobj %t4 > /dev/null 2>&1
+
+## Do not report undefines if linking relocatable.
+# RUN: ld.lld -r %t1.o %t2.o -o %t5 --unresolved-symbols=report-all
+# RUN: llvm-readobj %t5 > /dev/null 2>&1
+
+## report-all is the default one. Check that we do not report
+## undefines from DSO and do report undefines from object. With
+## report-all specified and without.
+# RUN: ld.lld -shared %t1.o %t.so -o %t6 --unresolved-symbols=report-all
+# RUN: llvm-readobj %t6 > /dev/null 2>&1
+# RUN: ld.lld -shared %t1.o %t.so -o %t6_1
+# RUN: llvm-readobj %t6_1 > /dev/null 2>&1
+# RUN: not ld.lld %t2.o -o %t7 --unresolved-symbols=report-all 2>&1 | \
+# RUN: FileCheck -check-prefix=ERRUND %s
+# RUN: not ld.lld %t2.o -o %t7_1 2>&1 | \
+# RUN: FileCheck -check-prefix=ERRUND %s
+
+.globl _start
+_start:
diff --git a/test/ELF/user_def_init_array_start.s b/test/ELF/user_def_init_array_start.s
new file mode 100644
index 000000000000..6c33166d1d4e
--- /dev/null
+++ b/test/ELF/user_def_init_array_start.s
@@ -0,0 +1,10 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t2.so -shared
+// Allow user defined __init_array_start. This is used by musl because of the
+// the bfd linker not handling these properly. We always create them as
+// hidden, musl should not have problems with lld.
+
+ .hidden __init_array_start
+ .globl __init_array_start
+__init_array_start:
+ .zero 8
diff --git a/test/ELF/valid-cie-length-dw64.s b/test/ELF/valid-cie-length-dw64.s
deleted file mode 100644
index 65d6952448a2..000000000000
--- a/test/ELF/valid-cie-length-dw64.s
+++ /dev/null
@@ -1,13 +0,0 @@
-// REQUIRES: x86
-
-// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
-// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
-
- .section .eh_frame
- .long 0xFFFFFFFF
- .quad 1
- nop
-
-// CHECK-NOT: Truncated CIE/FDE length
-// CHECK-NOT: CIE/FIE size is too large
-// CHECK-NOT: CIE/FIE ends past the end of the section
diff --git a/test/ELF/verdef-defaultver.s b/test/ELF/verdef-defaultver.s
new file mode 100644
index 000000000000..4d847344f996
--- /dev/null
+++ b/test/ELF/verdef-defaultver.s
@@ -0,0 +1,205 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/verdef-defaultver.s -o %t1
+# RUN: echo "LIBSAMPLE_1.0{ \
+# RUN: global: a; \
+# RUN: local: *; }; \
+# RUN: LIBSAMPLE_2.0{ \
+# RUN: global: b; c; \
+# RUN: }LIBSAMPLE_1.0;" > %t.script
+# RUN: ld.lld -shared -soname shared %t1 --version-script %t.script -o %t.so
+# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
+
+# DSO: DynamicSymbols [
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: @
+# DSO-NEXT: Value: 0x0
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Local
+# DSO-NEXT: Type: None
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: Undefined
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: a@@LIBSAMPLE_1.0
+# DSO-NEXT: Value: 0x1000
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global
+# DSO-NEXT: Type: Function
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: .text
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: b@@LIBSAMPLE_2.0
+# DSO-NEXT: Value: 0x1002
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global
+# DSO-NEXT: Type: Function
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: .text
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: b@LIBSAMPLE_1.0
+# DSO-NEXT: Value: 0x1001
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global
+# DSO-NEXT: Type: Function
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: .text
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: c@@LIBSAMPLE_2.0
+# DSO-NEXT: Value: 0x1003
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global
+# DSO-NEXT: Type: Function
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: .text
+# DSO-NEXT: }
+# DSO-NEXT: ]
+# DSO-NEXT: Version symbols {
+# DSO-NEXT: Section Name: .gnu.version
+# DSO-NEXT: Address: 0x240
+# DSO-NEXT: Offset: 0x240
+# DSO-NEXT: Link: 1
+# DSO-NEXT: Symbols [
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 0
+# DSO-NEXT: Name: @
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 2
+# DSO-NEXT: Name: a@@LIBSAMPLE_1.0
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 3
+# DSO-NEXT: Name: b@@LIBSAMPLE_2.0
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 2
+# DSO-NEXT: Name: b@LIBSAMPLE_1.0
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 3
+# DSO-NEXT: Name: c@@LIBSAMPLE_2.0
+# DSO-NEXT: }
+# DSO-NEXT: ]
+# DSO-NEXT: }
+# DSO-NEXT: SHT_GNU_verdef {
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: Base
+# DSO-NEXT: Index: 1
+# DSO-NEXT: Hash: 127830196
+# DSO-NEXT: Name: shared
+# DSO-NEXT: }
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: 0x0
+# DSO-NEXT: Index: 2
+# DSO-NEXT: Hash: 98457184
+# DSO-NEXT: Name: LIBSAMPLE_1.0
+# DSO-NEXT: }
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: 0x0
+# DSO-NEXT: Index: 3
+# DSO-NEXT: Hash: 98456416
+# DSO-NEXT: Name: LIBSAMPLE_2.0
+# DSO-NEXT: }
+# DSO-NEXT: }
+
+## Check that we can link against DSO produced.
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
+# RUN: ld.lld %t2 %t.so -o %t3
+# RUN: llvm-readobj -V -dyn-symbols %t3 | FileCheck --check-prefix=EXE %s
+
+# EXE: DynamicSymbols [
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: @
+# EXE-NEXT: Value: 0x0
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Local
+# EXE-NEXT: Type: None
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: Undefined
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: a@LIBSAMPLE_1.0
+# EXE-NEXT: Value: 0x11020
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global
+# EXE-NEXT: Type: Function
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: Undefined
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: b@LIBSAMPLE_2.0
+# EXE-NEXT: Value: 0x11030
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global
+# EXE-NEXT: Type: Function
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: Undefined
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: c@LIBSAMPLE_2.0
+# EXE-NEXT: Value: 0x11040
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global
+# EXE-NEXT: Type: Function
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: Undefined
+# EXE-NEXT: }
+# EXE-NEXT: ]
+# EXE-NEXT: Version symbols {
+# EXE-NEXT: Section Name: .gnu.version
+# EXE-NEXT: Address: 0x10228
+# EXE-NEXT: Offset: 0x228
+# EXE-NEXT: Link: 1
+# EXE-NEXT: Symbols [
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Version: 0
+# EXE-NEXT: Name: @
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Version: 2
+# EXE-NEXT: Name: a@LIBSAMPLE_1.0
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Version: 3
+# EXE-NEXT: Name: b@LIBSAMPLE_2.0
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Version: 3
+# EXE-NEXT: Name: c@LIBSAMPLE_2.0
+# EXE-NEXT: }
+# EXE-NEXT: ]
+# EXE-NEXT: }
+# EXE-NEXT: SHT_GNU_verdef {
+# EXE-NEXT: }
+# EXE-NEXT: SHT_GNU_verneed {
+# EXE-NEXT: Dependency {
+# EXE-NEXT: Version: 1
+# EXE-NEXT: Count: 2
+# EXE-NEXT: FileName: shared
+# EXE-NEXT: Entry {
+# EXE-NEXT: Hash: 98457184
+# EXE-NEXT: Flags: 0x0
+# EXE-NEXT: Index: 2
+# EXE-NEXT: Name: LIBSAMPLE_1.0
+# EXE-NEXT: }
+# EXE-NEXT: Entry {
+# EXE-NEXT: Hash: 98456416
+# EXE-NEXT: Flags: 0x0
+# EXE-NEXT: Index: 3
+# EXE-NEXT: Name: LIBSAMPLE_2.0
+# EXE-NEXT: }
+# EXE-NEXT: }
+# EXE-NEXT: }
+
+.globl _start
+_start:
+ callq a
+ callq b
+ callq c
diff --git a/test/ELF/verdef-dependency.s b/test/ELF/verdef-dependency.s
new file mode 100644
index 000000000000..92627ddc5c0f
--- /dev/null
+++ b/test/ELF/verdef-dependency.s
@@ -0,0 +1,44 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "LIBSAMPLE_1.0{ \
+# RUN: global: a; \
+# RUN: local: *; }; \
+# RUN: LIBSAMPLE_2.0{ \
+# RUN: global: b; \
+# RUN: local: *; }LIBSAMPLE_1.0; \
+# RUN: LIBSAMPLE_3.0{ \
+# RUN: global: c; \
+# RUN: }LIBSAMPLE_2.0;" > %t.script
+# RUN: ld.lld --version-script %t.script -shared -soname shared %t.o -o %t.so
+# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
+
+# DSO: SHT_GNU_verdef {
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: Base
+# DSO-NEXT: Index: 1
+# DSO-NEXT: Hash: 127830196
+# DSO-NEXT: Name: shared
+# DSO-NEXT: }
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: 0x0
+# DSO-NEXT: Index: 2
+# DSO-NEXT: Hash: 98457184
+# DSO-NEXT: Name: LIBSAMPLE_1.0
+# DSO-NEXT: }
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: 0x0
+# DSO-NEXT: Index: 3
+# DSO-NEXT: Hash: 98456416
+# DSO-NEXT: Name: LIBSAMPLE_2.0
+# DSO-NEXT: }
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: 0x0
+# DSO-NEXT: Index: 4
+# DSO-NEXT: Hash: 98456672
+# DSO-NEXT: Name: LIBSAMPLE_3.0
+# DSO-NEXT: }
+# DSO-NEXT: }
diff --git a/test/ELF/verdef.s b/test/ELF/verdef.s
new file mode 100644
index 000000000000..9463de0c0a0c
--- /dev/null
+++ b/test/ELF/verdef.s
@@ -0,0 +1,117 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "LIBSAMPLE_1.0{ \
+# RUN: global: a; \
+# RUN: local: *; }; \
+# RUN: LIBSAMPLE_2.0{ \
+# RUN: global: b; \
+# RUN: local: *; }; \
+# RUN: LIBSAMPLE_3.0{ \
+# RUN: global: c; \
+# RUN: local: *; };" > %t.script
+# RUN: ld.lld --version-script %t.script -shared -soname shared %t.o -o %t.so
+# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
+
+# DSO: Version symbols {
+# DSO-NEXT: Section Name: .gnu.version
+# DSO-NEXT: Address: 0x228
+# DSO-NEXT: Offset: 0x228
+# DSO-NEXT: Link: 1
+# DSO-NEXT: Symbols [
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 0
+# DSO-NEXT: Name: @
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 2
+# DSO-NEXT: Name: a@@LIBSAMPLE_1.0
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 3
+# DSO-NEXT: Name: b@@LIBSAMPLE_2.0
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 4
+# DSO-NEXT: Name: c@@LIBSAMPLE_3.0
+# DSO-NEXT: }
+# DSO-NEXT: ]
+# DSO-NEXT: }
+# DSO-NEXT: SHT_GNU_verdef {
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: Base
+# DSO-NEXT: Index: 1
+# DSO-NEXT: Hash: 127830196
+# DSO-NEXT: Name: shared
+# DSO-NEXT: }
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: 0x0
+# DSO-NEXT: Index: 2
+# DSO-NEXT: Hash: 98457184
+# DSO-NEXT: Name: LIBSAMPLE_1.0
+# DSO-NEXT: }
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: 0x0
+# DSO-NEXT: Index: 3
+# DSO-NEXT: Hash: 98456416
+# DSO-NEXT: Name: LIBSAMPLE_2.0
+# DSO-NEXT: }
+# DSO-NEXT: Definition {
+# DSO-NEXT: Version: 1
+# DSO-NEXT: Flags: 0x0
+# DSO-NEXT: Index: 4
+# DSO-NEXT: Hash: 98456672
+# DSO-NEXT: Name: LIBSAMPLE_3.0
+# DSO-NEXT: }
+# DSO-NEXT: }
+# DSO-NEXT: SHT_GNU_verneed {
+# DSO-NEXT: }
+
+## Check that we can link agains DSO we produced.
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/verdef.s -o %tmain.o
+# RUN: ld.lld %tmain.o %t.so -o %tout
+# RUN: llvm-readobj -V %tout | FileCheck --check-prefix=MAIN %s
+
+# MAIN: Version symbols {
+# MAIN-NEXT: Section Name: .gnu.version
+# MAIN-NEXT: Address: 0x10228
+# MAIN-NEXT: Offset: 0x228
+# MAIN-NEXT: Link: 1
+# MAIN-NEXT: Symbols [
+# MAIN-NEXT: Symbol {
+# MAIN-NEXT: Version: 0
+# MAIN-NEXT: Name: @
+# MAIN-NEXT: }
+# MAIN-NEXT: Symbol {
+# MAIN-NEXT: Version: 2
+# MAIN-NEXT: Name: a@LIBSAMPLE_1.0
+# MAIN-NEXT: }
+# MAIN-NEXT: Symbol {
+# MAIN-NEXT: Version: 3
+# MAIN-NEXT: Name: b@LIBSAMPLE_2.0
+# MAIN-NEXT: }
+# MAIN-NEXT: Symbol {
+# MAIN-NEXT: Version: 4
+# MAIN-NEXT: Name: c@LIBSAMPLE_3.0
+# MAIN-NEXT: }
+# MAIN-NEXT: ]
+# MAIN-NEXT: }
+# MAIN-NEXT: SHT_GNU_verdef {
+# MAIN-NEXT: }
+
+.globl a
+.type a,@function
+a:
+retq
+
+.globl b
+.type b,@function
+b:
+retq
+
+.globl c
+.type c,@function
+c:
+retq
diff --git a/test/ELF/verneed-as-needed-weak.s b/test/ELF/verneed-as-needed-weak.s
new file mode 100644
index 000000000000..a8efdc42d6d4
--- /dev/null
+++ b/test/ELF/verneed-as-needed-weak.s
@@ -0,0 +1,14 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o --as-needed %S/Inputs/verneed1.so -o %t
+# RUN: llvm-readobj -V %t | FileCheck %s
+
+# CHECK: SHT_GNU_verneed {
+# CHECK-NEXT: }
+
+.weak f1
+
+.globl _start
+_start:
+.data
+.quad f1
diff --git a/test/ELF/verneed-local.s b/test/ELF/verneed-local.s
new file mode 100644
index 000000000000..a50f670ed7bd
--- /dev/null
+++ b/test/ELF/verneed-local.s
@@ -0,0 +1,8 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: not ld.lld %t.o %S/Inputs/verneed1.so -o %t 2>&1 | FileCheck %s
+
+# CHECK: undefined symbol: f3 in
+.globl _start
+_start:
+call f3
diff --git a/test/ELF/verneed.s b/test/ELF/verneed.s
new file mode 100644
index 000000000000..e9d7c53ba334
--- /dev/null
+++ b/test/ELF/verneed.s
@@ -0,0 +1,173 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o %S/Inputs/verneed1.so %S/Inputs/verneed2.so -o %t
+# RUN: llvm-readobj -V -sections -section-data -dyn-symbols -dynamic-table %t | FileCheck %s
+
+# CHECK: Section {
+# CHECK: Index: 1
+# CHECK-NEXT: Name: .dynsym (1)
+# CHECK-NEXT: Type: SHT_DYNSYM (0xB)
+# CHECK-NEXT: Flags [ (0x2)
+# CHECK-NEXT: SHF_ALLOC (0x2)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x101C8
+# CHECK-NEXT: Offset: 0x1C8
+# CHECK-NEXT: Size: 96
+# CHECK-NEXT: Link: 5
+# CHECK-NEXT: Info: 1
+# CHECK-NEXT: AddressAlignment: 8
+# CHECK-NEXT: EntrySize: 24
+# CHECK: Section {
+# CHECK-NEXT: Index: 2
+# CHECK-NEXT: Name: .gnu.version (9)
+# CHECK-NEXT: Type: SHT_GNU_versym (0x6FFFFFFF)
+# CHECK-NEXT: Flags [ (0x2)
+# CHECK-NEXT: SHF_ALLOC (0x2)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x10228
+# CHECK-NEXT: Offset: 0x228
+# CHECK-NEXT: Size: 8
+# CHECK-NEXT: Link: 1
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 2
+# CHECK-NEXT: EntrySize: 2
+# CHECK: Section {
+# CHECK-NEXT: Index: 3
+# CHECK-NEXT: Name: .gnu.version_r (22)
+# CHECK-NEXT: Type: SHT_GNU_verneed (0x6FFFFFFE)
+# CHECK-NEXT: Flags [ (0x2)
+# CHECK-NEXT: SHF_ALLOC (0x2)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x10230
+# CHECK-NEXT: Offset: 0x230
+# CHECK-NEXT: Size: 80
+# CHECK-NEXT: Link: 5
+# CHECK-NEXT: Info: 2
+# CHECK-NEXT: AddressAlignment: 4
+# CHECK-NEXT: EntrySize: 0
+# CHECK: Section {
+# CHECK: Index: 5
+# CHECK-NEXT: Name: .dynstr
+# CHECK-NEXT: Type: SHT_STRTAB
+# CHECK-NEXT: Flags [ (0x2)
+# CHECK-NEXT: SHF_ALLOC (0x2)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x102A8
+# CHECK-NEXT: Offset: 0x2A8
+# CHECK-NEXT: Size: 47
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 1
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: SectionData (
+# CHECK-NEXT: 0000: 00663100 7665726E 65656431 2E736F2E |.f1.verneed1.so.|
+# CHECK-NEXT: 0010: 30007633 00663200 76320067 31007665 |0.v3.f2.v2.g1.ve|
+# CHECK-NEXT: 0020: 726E6565 64322E73 6F2E3000 763100 |rneed2.so.0.v1.|
+# CHECK-NEXT: )
+# CHECK-NEXT: }
+
+# CHECK: DynamicSymbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: @ (0)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local (0x0)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined (0x0)
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: f1@v3 (1)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global (0x1)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined (0x0)
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: f2@v2 (21)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global (0x1)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined (0x0)
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: g1@v1 (27)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global (0x1)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined (0x0)
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# CHECK: 0x000000006FFFFFF0 VERSYM 0x10228
+# CHECK-NEXT: 0x000000006FFFFFFE VERNEED 0x10230
+# CHECK-NEXT: 0x000000006FFFFFFF VERNEEDNUM 2
+
+# CHECK: Version symbols {
+# CHECK-NEXT: Section Name: .gnu.version
+# CHECK-NEXT: Address: 0x10228
+# CHECK-NEXT: Offset: 0x228
+# CHECK-NEXT: Link: 1
+# CHECK-NEXT: Symbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Version: 0
+# CHECK-NEXT: Name: @
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Version: 2
+# CHECK-NEXT: Name: f1@v3
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Version: 3
+# CHECK-NEXT: Name: f2@v2
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Version: 4
+# CHECK-NEXT: Name: g1@v1
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: SHT_GNU_verdef {
+# CHECK-NEXT: }
+# CHECK-NEXT: SHT_GNU_verneed {
+# CHECK-NEXT: Dependency {
+# CHECK-NEXT: Version: 1
+# CHECK-NEXT: Count: 2
+# CHECK-NEXT: FileName: verneed1.so.0
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Hash: 1938
+# CHECK-NEXT: Flags: 0x0
+# CHECK-NEXT: Index: 3
+# CHECK-NEXT: Name: v2
+# CHECK-NEXT: }
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Hash: 1939
+# CHECK-NEXT: Flags: 0x0
+# CHECK-NEXT: Index: 2
+# CHECK-NEXT: Name: v3
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: Dependency {
+# CHECK-NEXT: Version: 1
+# CHECK-NEXT: Count: 1
+# CHECK-NEXT: FileName: verneed2.so.0
+# CHECK-NEXT: Entry {
+# CHECK-NEXT: Hash: 1937
+# CHECK-NEXT: Flags: 0x0
+# CHECK-NEXT: Index: 4
+# CHECK-NEXT: Name: v1
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+
+.globl _start
+_start:
+call f1@plt
+call f2@plt
+call g1@plt
diff --git a/test/ELF/version-script-err.s b/test/ELF/version-script-err.s
new file mode 100644
index 000000000000..15b69e98505b
--- /dev/null
+++ b/test/ELF/version-script-err.s
@@ -0,0 +1,10 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: not ld.lld -shared %t.o -o %t.so --version-script %p/Inputs/version-script-err.script 2>&1 | FileCheck %s
+// CHECK: ; expected, but got }
+
+// RUN: echo "\"" > %terr1.script
+// RUN: not ld.lld --version-script %terr1.script -shared %t.o -o %t.so 2>&1 | \
+// RUN: FileCheck -check-prefix=ERR1 %s
+// ERR1: unclosed quote
diff --git a/test/ELF/version-script-extern.s b/test/ELF/version-script-extern.s
new file mode 100644
index 000000000000..439653487bc0
--- /dev/null
+++ b/test/ELF/version-script-extern.s
@@ -0,0 +1,97 @@
+# REQUIRES: shell
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "LIBSAMPLE_1.0 { \
+# RUN: global: \
+# RUN: extern "C++" { \
+# RUN: \"foo(int)\"; \
+# RUN: \"zed(int)\"; \
+# RUN: }; \
+# RUN: }; \
+# RUN: LIBSAMPLE_2.0 { \
+# RUN: global: \
+# RUN: extern "C++" { \
+# RUN: \"bar(int)\"; \
+# RUN: }; \
+# RUN: }; " > %t.script
+# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
+# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
+
+# DSO: DynamicSymbols [
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: @
+# DSO-NEXT: Value: 0x0
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Local
+# DSO-NEXT: Type: None
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: Undefined
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: _Z3bari@@LIBSAMPLE_2.0
+# DSO-NEXT: Value: 0x1001
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global
+# DSO-NEXT: Type: Function
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: .text
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: _Z3fooi@@LIBSAMPLE_1.0
+# DSO-NEXT: Value: 0x1000
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global
+# DSO-NEXT: Type: Function
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: .text
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: _Z3zedi@@LIBSAMPLE_1.0
+# DSO-NEXT: Value: 0x1002
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global (0x1)
+# DSO-NEXT: Type: Function (0x2)
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: .text (0x6)
+# DSO-NEXT: }
+# DSO-NEXT: ]
+# DSO-NEXT: Version symbols {
+# DSO-NEXT: Section Name: .gnu.version
+# DSO-NEXT: Address: 0x228
+# DSO-NEXT: Offset: 0x228
+# DSO-NEXT: Link: 1
+# DSO-NEXT: Symbols [
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 0
+# DSO-NEXT: Name: @
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 3
+# DSO-NEXT: Name: _Z3bari@@LIBSAMPLE_2.0
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 2
+# DSO-NEXT: Name: _Z3fooi@@LIBSAMPLE_1.0
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Version: 2
+# DSO-NEXT: Name: _Z3zedi@@LIBSAMPLE_1.0
+# DSO-NEXT: }
+# DSO-NEXT: ]
+# DSO-NEXT: }
+
+.text
+.globl _Z3fooi
+.type _Z3fooi,@function
+_Z3fooi:
+retq
+
+.globl _Z3bari
+.type _Z3bari,@function
+_Z3bari:
+retq
+
+.globl _Z3zedi
+.type _Z3zedi,@function
+_Z3zedi:
+retq
diff --git a/test/ELF/version-script-noundef.s b/test/ELF/version-script-noundef.s
new file mode 100644
index 000000000000..4a251d6172da
--- /dev/null
+++ b/test/ELF/version-script-noundef.s
@@ -0,0 +1,22 @@
+# REQUIRES: x86
+
+# RUN: echo "VERSION_1.0{ \
+# RUN: global: bar; \
+# RUN: };" > %t.script
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: not ld.lld --version-script %t.script -shared --no-undefined-version \
+# RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR1 %s
+# ERR1: version script assignment of VERSION_1.0 to symbol bar failed: symbol not defined
+
+# RUN: echo "VERSION_1.0{ \
+# RUN: global: und; \
+# RUN: };" > %t2.script
+# RUN: not ld.lld --version-script %t2.script -shared --no-undefined-version \
+# RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR2 %s
+# ERR2: version script assignment of VERSION_1.0 to symbol und failed: symbol not defined
+
+.text
+.globl foo
+.type foo,@function
+foo:
+callq und@PLT
diff --git a/test/ELF/version-script.s b/test/ELF/version-script.s
new file mode 100644
index 000000000000..ba9c95a96fc3
--- /dev/null
+++ b/test/ELF/version-script.s
@@ -0,0 +1,274 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -soname shared -o %t2.so
+
+# RUN: echo "{ global: foo1; foo3; local: *; };" > %t.script
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld --version-script %t.script -shared %t.o %t2.so -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
+
+# RUN: echo "# comment" > %t3.script
+# RUN: echo "{ local: *; # comment" >> %t3.script
+# RUN: echo -n "}; # comment" >> %t3.script
+# RUN: ld.lld --version-script %t3.script -shared %t.o %t2.so -o %t3.so
+# RUN: llvm-readobj -dyn-symbols %t3.so | FileCheck --check-prefix=DSO2 %s
+
+# --version-script filters --dynamic-list.
+# RUN: echo "{ foo1; foo2; };" > %t.list
+# RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t
+# RUN: llvm-readobj -dyn-symbols %t | FileCheck --check-prefix=EXE %s
+
+# RUN: echo "VERSION_1.0{ \
+# RUN: global: foo1; \
+# RUN: local: *; }; \
+# RUN: VERSION_2.0{ \
+# RUN: global: foo3; \
+# RUN: local: *; }; " > %t4.script
+# RUN: ld.lld --version-script %t4.script -shared %t.o %t2.so -o %t4.so
+# RUN: llvm-readobj -dyn-symbols %t4.so | FileCheck --check-prefix=VERDSO %s
+
+# RUN: echo "VERSION_1.0{ \
+# RUN: global: foo1; \
+# RUN: local: *; }; \
+# RUN: { \
+# RUN: global: foo3; \
+# RUN: local: *; }; " > %t5.script
+# RUN: not ld.lld --version-script %t5.script -shared %t.o %t2.so -o %t5.so 2>&1 | \
+# RUN: FileCheck -check-prefix=ERR %s
+# ERR: anonymous version definition is used in combination with other version definitions
+
+# RUN: echo "{ \
+# RUN: global: foo1; \
+# RUN: local: *; }; \
+# RUN: VERSION_2.0 { \
+# RUN: global: foo3; \
+# RUN: local: *; }; " > %t5.script
+# RUN: not ld.lld --version-script %t5.script -shared %t.o %t2.so -o %t5.so 2>&1 | \
+# RUN: FileCheck -check-prefix=ERR %s
+
+# RUN: echo "VERSION_1.0{ \
+# RUN: global: foo1; \
+# RUN: local: *; }; \
+# RUN: VERSION_2.0 { \
+# RUN: global: foo1; \
+# RUN: local: *; }; " > %t6.script
+# RUN: ld.lld --version-script %t6.script -shared %t.o %t2.so -o %t6.so 2>&1 | \
+# RUN: FileCheck -check-prefix=WARN2 %s
+# WARN2: duplicate symbol foo1 in version script
+
+# RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t2
+# RUN: llvm-readobj %t2 > /dev/null
+
+# DSO: DynamicSymbols [
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: @ (0)
+# DSO-NEXT: Value: 0x0
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Local (0x0)
+# DSO-NEXT: Type: None (0x0)
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: Undefined (0x0)
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: bar@ (1)
+# DSO-NEXT: Value: 0x0
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global (0x1)
+# DSO-NEXT: Type: Function (0x2)
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: Undefined (0x0)
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: foo1@ (5)
+# DSO-NEXT: Value: 0x1000
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global (0x1)
+# DSO-NEXT: Type: None (0x0)
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: .text
+# DSO-NEXT: }
+# DSO-NEXT: Symbol {
+# DSO-NEXT: Name: foo3@ (10)
+# DSO-NEXT: Value: 0x1007
+# DSO-NEXT: Size: 0
+# DSO-NEXT: Binding: Global (0x1)
+# DSO-NEXT: Type: None (0x0)
+# DSO-NEXT: Other: 0
+# DSO-NEXT: Section: .text
+# DSO-NEXT: }
+# DSO-NEXT: ]
+
+# DSO2: DynamicSymbols [
+# DSO2-NEXT: Symbol {
+# DSO2-NEXT: Name: @ (0)
+# DSO2-NEXT: Value: 0x0
+# DSO2-NEXT: Size: 0
+# DSO2-NEXT: Binding: Local (0x0)
+# DSO2-NEXT: Type: None (0x0)
+# DSO2-NEXT: Other: 0
+# DSO2-NEXT: Section: Undefined (0x0)
+# DSO2-NEXT: }
+# DSO2-NEXT: Symbol {
+# DSO2-NEXT: Name: bar@ (1)
+# DSO2-NEXT: Value: 0x0
+# DSO2-NEXT: Size: 0
+# DSO2-NEXT: Binding: Global (0x1)
+# DSO2-NEXT: Type: Function (0x2)
+# DSO2-NEXT: Other: 0
+# DSO2-NEXT: Section: Undefined (0x0)
+# DSO2-NEXT: }
+# DSO2-NEXT: ]
+
+# EXE: DynamicSymbols [
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: @ (0)
+# EXE-NEXT: Value: 0x0
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Local (0x0)
+# EXE-NEXT: Type: None (0x0)
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: Undefined (0x0)
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: bar@ (1)
+# EXE-NEXT: Value: 0x0
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global (0x1)
+# EXE-NEXT: Type: Function (0x2)
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: Undefined (0x0)
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: foo1@ (5)
+# EXE-NEXT: Value: 0x11000
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global (0x1)
+# EXE-NEXT: Type: None (0x0)
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: .text
+# EXE-NEXT: }
+# EXE-NEXT: ]
+
+# VERDSO: DynamicSymbols [
+# VERDSO-NEXT: Symbol {
+# VERDSO-NEXT: Name: @
+# VERDSO-NEXT: Value: 0x0
+# VERDSO-NEXT: Size: 0
+# VERDSO-NEXT: Binding: Local
+# VERDSO-NEXT: Type: None
+# VERDSO-NEXT: Other: 0
+# VERDSO-NEXT: Section: Undefined
+# VERDSO-NEXT: }
+# VERDSO-NEXT: Symbol {
+# VERDSO-NEXT: Name: bar@
+# VERDSO-NEXT: Value: 0x0
+# VERDSO-NEXT: Size: 0
+# VERDSO-NEXT: Binding: Global
+# VERDSO-NEXT: Type: Function
+# VERDSO-NEXT: Other: 0
+# VERDSO-NEXT: Section: Undefined
+# VERDSO-NEXT: }
+# VERDSO-NEXT: Symbol {
+# VERDSO-NEXT: Name: foo1@@VERSION_1.0
+# VERDSO-NEXT: Value: 0x1000
+# VERDSO-NEXT: Size: 0
+# VERDSO-NEXT: Binding: Global
+# VERDSO-NEXT: Type: None
+# VERDSO-NEXT: Other: 0
+# VERDSO-NEXT: Section: .text
+# VERDSO-NEXT: }
+# VERDSO-NEXT: Symbol {
+# VERDSO-NEXT: Name: foo3@@VERSION_2.0
+# VERDSO-NEXT: Value: 0x1007
+# VERDSO-NEXT: Size: 0
+# VERDSO-NEXT: Binding: Global
+# VERDSO-NEXT: Type: None
+# VERDSO-NEXT: Other: 0
+# VERDSO-NEXT: Section: .text
+# VERDSO-NEXT: }
+# VERDSO-NEXT: ]
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o %t2.so -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s
+
+# RUN: echo "{ global: foo1; foo3; };" > %t2.script
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld --version-script %t2.script -shared %t.o %t2.so -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s
+
+# ALL: DynamicSymbols [
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: @
+# ALL-NEXT: Value: 0x0
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Local
+# ALL-NEXT: Type: None
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: Undefined
+# ALL-NEXT: }
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: _start@
+# ALL-NEXT: Value:
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Global
+# ALL-NEXT: Type: None
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: .text
+# ALL-NEXT: }
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: bar@
+# ALL-NEXT: Value:
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Global
+# ALL-NEXT: Type: Function
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: Undefined
+# ALL-NEXT: }
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: foo1@
+# ALL-NEXT: Value:
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Global
+# ALL-NEXT: Type: None
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: .text
+# ALL-NEXT: }
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: foo2@
+# ALL-NEXT: Value:
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Global
+# ALL-NEXT: Type: None
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: .text
+# ALL-NEXT: }
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: foo3@
+# ALL-NEXT: Value:
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Global
+# ALL-NEXT: Type: None
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: .text
+# ALL-NEXT: }
+# ALL-NEXT: ]
+
+.globl foo1
+foo1:
+ call bar@PLT
+ ret
+
+.globl foo2
+foo2:
+ ret
+
+.globl foo3
+foo3:
+ call foo2@PLT
+ ret
+
+.globl _start
+_start:
+ ret
diff --git a/test/ELF/version-undef-sym.s b/test/ELF/version-undef-sym.s
new file mode 100644
index 000000000000..20e92e61f647
--- /dev/null
+++ b/test/ELF/version-undef-sym.s
@@ -0,0 +1,42 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-readobj --dyn-symbols %p/Inputs/version-undef-sym.so | FileCheck %s
+
+
+// Inputs/version-undef-sym.so consists of the assembly file
+//
+// .global bar
+// bar:
+// .weak abc1
+// .weak abc2
+// .weak abc3
+// .weak abc4
+// .weak abc5
+//
+// linked into a shared library with the version script
+//
+// VER_1 {
+// global:
+// bar;
+// };
+//
+// Assuming we can reproduce the desired property (a few undefined symbols
+// before bar) we should create it with lld itself once it supports that.
+
+
+// Show that the input .so has undefined symbols before bar. That is what would
+// get our version parsing out of sync.
+
+// CHECK: Section: Undefined
+// CHECK: Section: Undefined
+// CHECK: Section: Undefined
+// CHECK: Section: Undefined
+// CHECK: Section: Undefined
+// CHECK: Name: bar
+
+// But now we can successfully find bar.
+// RUN: ld.lld %t.o %p/Inputs/version-undef-sym.so -o %t.exe
+
+ .global _start
+_start:
+ call bar@plt
diff --git a/test/ELF/version-use.s b/test/ELF/version-use.s
new file mode 100644
index 000000000000..7ef12bc04536
--- /dev/null
+++ b/test/ELF/version-use.s
@@ -0,0 +1,9 @@
+// REQUIRES: x86
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o %p/Inputs/version-use.so -o %t.so -shared -z defs
+// RUN: llvm-readobj -s %t.so | FileCheck %s
+
+
+ call bar@PLT
+
+// CHECK-NOT: SHT_GNU_versym
diff --git a/test/ELF/version-wildcard.test b/test/ELF/version-wildcard.test
new file mode 100644
index 000000000000..80cb9cadf159
--- /dev/null
+++ b/test/ELF/version-wildcard.test
@@ -0,0 +1,114 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "VERSION_1.0{ \
+# RUN: global: foo*; \
+# RUN: local: *; };" > %t.script
+# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
+
+# CHECK: DynamicSymbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: @
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: foo1@@VERSION_1.0
+# CHECK-NEXT: Value: 0x1000
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: foo2@@VERSION_1.0
+# CHECK-NEXT: Value: 0x1001
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: foo3@@VERSION_1.0
+# CHECK-NEXT: Value: 0x1007
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "VERSION_1.0{ \
+# RUN: global: foo2; \
+# RUN: local: *; }; \
+# RUN: VERSION_2.0{ \
+# RUN: global: foo*; \
+# RUN: }; " > %t2.script
+# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
+# RUN: llvm-readobj -dyn-symbols %t2.so | FileCheck --check-prefix=MIX %s
+
+# MIX: DynamicSymbols [
+# MIX-NEXT: Symbol {
+# MIX-NEXT: Name: @
+# MIX-NEXT: Value: 0x0
+# MIX-NEXT: Size: 0
+# MIX-NEXT: Binding: Local
+# MIX-NEXT: Type: None
+# MIX-NEXT: Other: 0
+# MIX-NEXT: Section: Undefined
+# MIX-NEXT: }
+# MIX-NEXT: Symbol {
+# MIX-NEXT: Name: foo1@@VERSION_2.0
+# MIX-NEXT: Value: 0x1000
+# MIX-NEXT: Size: 0
+# MIX-NEXT: Binding: Global
+# MIX-NEXT: Type: None
+# MIX-NEXT: Other: 0
+# MIX-NEXT: Section: .text
+# MIX-NEXT: }
+# MIX-NEXT: Symbol {
+# MIX-NEXT: Name: foo2@@VERSION_1.0
+# MIX-NEXT: Value: 0x1001
+# MIX-NEXT: Size: 0
+# MIX-NEXT: Binding: Global
+# MIX-NEXT: Type: None
+# MIX-NEXT: Other: 0
+# MIX-NEXT: Section: .text
+# MIX-NEXT: }
+# MIX-NEXT: Symbol {
+# MIX-NEXT: Name: foo3@@VERSION_2.0
+# MIX-NEXT: Value: 0x1007
+# MIX-NEXT: Size: 0
+# MIX-NEXT: Binding: Global
+# MIX-NEXT: Type: None
+# MIX-NEXT: Other: 0
+# MIX-NEXT: Section: .text
+# MIX-NEXT: }
+# MIX-NEXT: ]
+
+.globl foo1
+foo1:
+ ret
+
+.globl foo2
+foo2:
+ call foo1@PLT
+ ret
+
+.globl foo3
+foo3:
+ call foo2@PLT
+ ret
+
+.globl _start
+_start:
+ ret
diff --git a/test/ELF/visibility.s b/test/ELF/visibility.s
index d76ed0793eb1..2043894d3d3d 100644
--- a/test/ELF/visibility.s
+++ b/test/ELF/visibility.s
@@ -20,7 +20,9 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 2
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
@@ -29,7 +31,9 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 1
+// CHECK-NEXT: Other [ (0x1)
+// CHECK-NEXT: STV_INTERNAL
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
@@ -38,10 +42,23 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 2
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _DYNAMIC
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .dynamic
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: default
// CHECK-NEXT: Value:
// CHECK-NEXT: Size: 0
@@ -56,7 +73,9 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 3
+// CHECK-NEXT: Other [ (0x3)
+// CHECK-NEXT: STV_PROTECTED
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: ]
@@ -86,7 +105,9 @@
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: None
-// CHECK-NEXT: Other: 3
+// CHECK-NEXT: Other [ (0x3)
+// CHECK-NEXT: STV_PROTECTED
+// CHECK-NEXT: ]
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: ]
diff --git a/test/ELF/warn-common.s b/test/ELF/warn-common.s
new file mode 100644
index 000000000000..783a9ab77b56
--- /dev/null
+++ b/test/ELF/warn-common.s
@@ -0,0 +1,25 @@
+# REQUIRES: x86
+# 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/warn-common.s -o %t2.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common2.s -o %t3.o
+
+## Report multiple commons if warn-common is specified
+# RUN: ld.lld --warn-common %t1.o %t2.o -o %t.out 2>&1 | FileCheck %s --check-prefix=WARN
+# WARN: multiple common of arr
+
+## no-warn-common is ignored
+# RUN: ld.lld --no-warn-common %t1.o %t2.o -o %t.out
+# RUN: llvm-readobj %t.out > /dev/null
+
+## Report if common is overridden
+# RUN: ld.lld --warn-common %t1.o %t3.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER
+# OVER: common arr is overridden
+
+## Report if common is overridden, but in different order
+# RUN: ld.lld --warn-common %t3.o %t1.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER
+
+.globl _start
+_start:
+
+.type arr,@object
+.comm arr,4,4
diff --git a/test/ELF/weak-undef-hidden.s b/test/ELF/weak-undef-hidden.s
new file mode 100644
index 000000000000..70b951bf0596
--- /dev/null
+++ b/test/ELF/weak-undef-hidden.s
@@ -0,0 +1,29 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
+
+.data
+.weak g
+.hidden g
+.quad g
+
+// CHECK: Name: .data
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 00000000 00000000
+// CHECK-NEXT: )
+
+// CHECK: Relocations [
+// CHECK-NEXT: ]
diff --git a/test/ELF/weak-undef-shared.s b/test/ELF/weak-undef-shared.s
new file mode 100644
index 000000000000..862a08632e26
--- /dev/null
+++ b/test/ELF/weak-undef-shared.s
@@ -0,0 +1,19 @@
+// REQUIRES: x86
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: llvm-mc %p/Inputs/shared.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t.exe
+// RUN: llvm-readobj -t %t.exe | FileCheck %s
+
+// CHECK: Name: bar
+// CHECK-NEXT: Value: 0x11020
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Weak
+// CHECK-NEXT: Type: Function
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+
+.global _start
+_start:
+ .weak bar
+ .quad bar
diff --git a/test/ELF/weak-undef.s b/test/ELF/weak-undef.s
new file mode 100644
index 000000000000..02555535927e
--- /dev/null
+++ b/test/ELF/weak-undef.s
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t -pie
+# RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
+
+# CHECK: DynamicSymbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: @ (0)
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local (0x0)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined (0x0)
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+.weak foo
+
+.globl _start
+_start:
diff --git a/test/ELF/whole-archive.s b/test/ELF/whole-archive.s
index 0a6b30fd171e..c65f116965f7 100644
--- a/test/ELF/whole-archive.s
+++ b/test/ELF/whole-archive.s
@@ -30,5 +30,11 @@
// RUN: ld.lld -o %t3 %t.o --whole-archive %t.a --no-whole-archive
// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=ADDED %s
-.globl _start;
+// --whole-archive should also work with thin archives
+// RUN: rm -f %tthin.a
+// RUN: llvm-ar --format=gnu rcsT %tthin.a %ta.o
+// RUN: ld.lld -o %t3 %t.o --whole-archive %tthin.a
+// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=ADDED %s
+
+.globl _start
_start:
diff --git a/test/ELF/wildcards.s b/test/ELF/wildcards.s
new file mode 100644
index 000000000000..2fe0f881bf46
--- /dev/null
+++ b/test/ELF/wildcards.s
@@ -0,0 +1,80 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+## Default case: abc and abx included in text.
+# RUN: echo "SECTIONS { \
+# RUN: .text : { *(.abc .abx) } }" > %t.script
+# RUN: ld.lld -o %t.out --script %t.script %t
+# RUN: llvm-objdump -section-headers %t.out | \
+# RUN: FileCheck -check-prefix=SEC-DEFAULT %s
+# SEC-DEFAULT: Sections:
+# SEC-DEFAULT-NEXT: Idx Name Size Address Type
+# SEC-DEFAULT-NEXT: 0 00000000 0000000000000000
+# SEC-DEFAULT-NEXT: 1 .text 00000008 0000000000000120 TEXT DATA
+# SEC-DEFAULT-NEXT: 2 .abcd 00000004 0000000000000128 TEXT DATA
+# SEC-DEFAULT-NEXT: 3 .ad 00000004 000000000000012c TEXT DATA
+# SEC-DEFAULT-NEXT: 4 .ag 00000004 0000000000000130 TEXT DATA
+# SEC-DEFAULT-NEXT: 5 .symtab 00000030 0000000000000000
+# SEC-DEFAULT-NEXT: 6 .shstrtab 0000002f 0000000000000000
+# SEC-DEFAULT-NEXT: 7 .strtab 00000008 0000000000000000
+
+## Now replace the symbol with '?' and check that results are the same.
+# RUN: echo "SECTIONS { \
+# RUN: .text : { *(.abc .ab?) } }" > %t.script
+# RUN: ld.lld -o %t.out --script %t.script %t
+# RUN: llvm-objdump -section-headers %t.out | \
+# RUN: FileCheck -check-prefix=SEC-DEFAULT %s
+
+## Now see how replacing '?' with '*' will consume whole abcd.
+# RUN: echo "SECTIONS { \
+# RUN: .text : { *(.abc .ab*) } }" > %t.script
+# RUN: ld.lld -o %t.out --script %t.script %t
+# RUN: llvm-objdump -section-headers %t.out | \
+# RUN: FileCheck -check-prefix=SEC-ALL %s
+# SEC-ALL: Sections:
+# SEC-ALL-NEXT: Idx Name Size Address Type
+# SEC-ALL-NEXT: 0 00000000 0000000000000000
+# SEC-ALL-NEXT: 1 .text 0000000c 0000000000000120 TEXT DATA
+# SEC-ALL-NEXT: 2 .ad 00000004 000000000000012c TEXT DATA
+# SEC-ALL-NEXT: 3 .ag 00000004 0000000000000130 TEXT DATA
+# SEC-ALL-NEXT: 4 .symtab 00000030 0000000000000000
+# SEC-ALL-NEXT: 5 .shstrtab 00000029 0000000000000000
+# SEC-ALL-NEXT: 6 .strtab 00000008 0000000000000000
+
+## All sections started with .a are merged.
+# RUN: echo "SECTIONS { \
+# RUN: .text : { *(.a*) } }" > %t.script
+# RUN: ld.lld -o %t.out --script %t.script %t
+# RUN: llvm-objdump -section-headers %t.out | \
+# RUN: FileCheck -check-prefix=SEC-NO %s
+# SEC-NO: Sections:
+# SEC-NO-NEXT: Idx Name Size Address Type
+# SEC-NO-NEXT: 0 00000000 0000000000000000
+# SEC-NO-NEXT: 1 .text 00000014 0000000000000120 TEXT DATA
+# SEC-NO-NEXT: 2 .symtab 00000030 0000000000000000
+# SEC-NO-NEXT: 3 .shstrtab 00000021 0000000000000000
+# SEC-NO-NEXT: 4 .strtab 00000008 0000000000000000
+
+.text
+.section .abc,"ax",@progbits
+.long 0
+
+.text
+.section .abx,"ax",@progbits
+.long 0
+
+.text
+.section .abcd,"ax",@progbits
+.long 0
+
+.text
+.section .ad,"ax",@progbits
+.long 0
+
+.text
+.section .ag,"ax",@progbits
+.long 0
+
+
+.globl _start
+_start:
diff --git a/test/ELF/writable-merge.s b/test/ELF/writable-merge.s
index dd7b8538e57a..431cb6282d91 100644
--- a/test/ELF/writable-merge.s
+++ b/test/ELF/writable-merge.s
@@ -1,6 +1,6 @@
// REQUIRES: x86
// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
// RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
-// CHECK: Writable SHF_MERGE sections are not supported
+// CHECK: writable SHF_MERGE section is not supported
- .section .foo,"awM",@progbits,4
+.section .foo,"awM",@progbits,4
diff --git a/test/ELF/x86-64-dyn-rel-error.s b/test/ELF/x86-64-dyn-rel-error.s
new file mode 100644
index 000000000000..c814fbeb1d9a
--- /dev/null
+++ b/test/ELF/x86-64-dyn-rel-error.s
@@ -0,0 +1,12 @@
+// 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 %p/Inputs/shared.s -o %t2.o
+// RUN: ld.lld %t2.o -shared -o %t2.so
+// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
+
+ .global _start
+_start:
+ .data
+ .long bar
+
+// CHECK: R_X86_64_32 cannot be used against shared object; recompile with -fPIC.
diff --git a/test/ELF/x86-64-dyn-rel-error2.s b/test/ELF/x86-64-dyn-rel-error2.s
new file mode 100644
index 000000000000..c1d3da3ae2ae
--- /dev/null
+++ b/test/ELF/x86-64-dyn-rel-error2.s
@@ -0,0 +1,12 @@
+// 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 %p/Inputs/shared.s -o %t2.o
+// RUN: ld.lld %t2.o -shared -o %t2.so
+// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
+
+ .global _start
+_start:
+ .data
+ .long bar - .
+
+// CHECK: R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC.
diff --git a/test/ELF/x86-64-rela.s b/test/ELF/x86-64-rela.s
new file mode 100644
index 000000000000..41bdd76de4ca
--- /dev/null
+++ b/test/ELF/x86-64-rela.s
@@ -0,0 +1,11 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -dynamic-table %t.so | FileCheck %s
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux-gnux32 %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -dynamic-table %t.so | FileCheck %s
+
+ call foo@plt
+
+// CHECK: 0x{{0+}}14 PLTREL{{ +}}RELA
diff --git a/test/ELF/x86-64-relax-offset.s b/test/ELF/x86-64-relax-offset.s
new file mode 100644
index 000000000000..a7c7ce6f6271
--- /dev/null
+++ b/test/ELF/x86-64-relax-offset.s
@@ -0,0 +1,13 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %s \
+// RUN: -o %t.o
+// RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux \
+// RUN: %p/Inputs/x86-64-relax-offset.s -o %t2.o
+// RUN: ld.lld %t2.o %t.o -o %t.so -shared
+// RUN: llvm-objdump -d %t.so | FileCheck %s
+
+ mov foo@gotpcrel(%rip), %rax
+ nop
+
+// CHECK: 1004: {{.*}} leaq -11(%rip), %rax
+// CHECK-NEXT: 100b: {{.*}} nop
diff --git a/test/ELF/x86-64-reloc-32-fpic.s b/test/ELF/x86-64-reloc-32-fpic.s
new file mode 100644
index 000000000000..0a0f1a09fda8
--- /dev/null
+++ b/test/ELF/x86-64-reloc-32-fpic.s
@@ -0,0 +1,7 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
+# CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC.
+
+.data
+.long _shared
diff --git a/test/ELF/x86-64-reloc-32S-error.s b/test/ELF/x86-64-reloc-32S-error.s
deleted file mode 100644
index aa19c2c32e93..000000000000
--- a/test/ELF/x86-64-reloc-32S-error.s
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
-// RUN: not ld.lld -shared %t -o %t2 2>&1 | FileCheck %s
-// REQUIRES: x86
-
- movq _start - 0x1000000000000, %rdx
-
-#CHECK: R_X86_64_32S out of range
diff --git a/test/ELF/x86-64-reloc-32-error.s b/test/ELF/x86-64-reloc-error.s
index b5d476bcf082..9b7e17de793b 100644
--- a/test/ELF/x86-64-reloc-32-error.s
+++ b/test/ELF/x86-64-reloc-error.s
@@ -1,8 +1,10 @@
-// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/abs.s -o %tabs
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-error.s -o %tabs
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
// RUN: not ld.lld -shared %tabs %t -o %t2 2>&1 | FileCheck %s
// REQUIRES: x86
movl $big, %edx
+ movq $foo - 0x1000000000000, %rdx
-#CHECK: R_X86_64_32 out of range
+# CHECK: R_X86_64_32 out of range
+# CHECK: R_X86_64_32S out of range
diff --git a/test/ELF/x86-64-reloc-pc32-fpic.s b/test/ELF/x86-64-reloc-pc32-fpic.s
new file mode 100644
index 000000000000..ed9121583c18
--- /dev/null
+++ b/test/ELF/x86-64-reloc-pc32-fpic.s
@@ -0,0 +1,7 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
+# CHECK: relocation R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC.
+
+.data
+call _shared
diff --git a/test/ELF/x86-64-reloc-range.s b/test/ELF/x86-64-reloc-range.s
new file mode 100644
index 000000000000..8319eaafa0ce
--- /dev/null
+++ b/test/ELF/x86-64-reloc-range.s
@@ -0,0 +1,13 @@
+// RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj
+// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
+
+// CHECK: relocation R_X86_64_PC32 out of range
+// CHECK-NOT: relocation
+
+ lea foo(%rip), %rax
+ lea foo(%rip), %rax
+
+ .hidden foo
+ .bss
+ .zero 0x7fffe007
+foo:
diff --git a/test/ELF/x86-64-tls-gd-got.s b/test/ELF/x86-64-tls-gd-got.s
new file mode 100644
index 000000000000..f86c3aa14f08
--- /dev/null
+++ b/test/ELF/x86-64-tls-gd-got.s
@@ -0,0 +1,19 @@
+# REQUIRES: x86
+# 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-tls-gd-got.s -o %t2.o
+# RUN: ld.lld %t1.o %t2.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck %s
+
+ .globl _start
+_start:
+ .byte 0x66
+ leaq bar@tlsgd(%rip), %rdi
+ .byte 0x66
+ rex64
+ call *__tls_get_addr@GOTPCREL(%rip)
+ ret
+
+// CHECK: _start:
+// CHECK-NEXT: movq %fs:0, %rax
+// CHECK-NEXT: leaq -4(%rax), %rax
+// CHECK-NEXT: retq
diff --git a/test/ELF/x86-64-tls-gd-local.s b/test/ELF/x86-64-tls-gd-local.s
new file mode 100644
index 000000000000..843b891be56b
--- /dev/null
+++ b/test/ELF/x86-64-tls-gd-local.s
@@ -0,0 +1,52 @@
+// REQUIRES: x86
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
+
+ .byte 0x66
+ leaq foo@tlsgd(%rip), %rdi
+ .value 0x6666
+ rex64
+ call __tls_get_addr@PLT
+
+ .byte 0x66
+ leaq bar@tlsgd(%rip), %rdi
+ .value 0x6666
+ rex64
+ call __tls_get_addr@PLT
+
+ .section .tbss,"awT",@nobits
+
+ .hidden foo
+ .globl foo
+foo:
+ .zero 4
+
+ .hidden bar
+ .globl bar
+bar:
+ .zero 4
+
+
+// CHECK: Name: .got
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC (0x2)
+// CHECK-NEXT: SHF_WRITE (0x1)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x20D0
+// CHECK-NEXT: Offset: 0x20D0
+// CHECK-NEXT: Size: 32
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 8
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
+// CHECK-NEXT: 0010: 00000000 00000000 04000000 00000000 |................|
+// CHECK-NEXT: )
+
+// CHECK: Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT: 0x20D0 R_X86_64_DTPMOD64 - 0x0
+// CHECK-NEXT: 0x20E0 R_X86_64_DTPMOD64 - 0x0
+// CHECK-NEXT: }
diff --git a/test/ELF/x86-64-tls-pie.s b/test/ELF/x86-64-tls-pie.s
new file mode 100644
index 000000000000..5ef0f54f435d
--- /dev/null
+++ b/test/ELF/x86-64-tls-pie.s
@@ -0,0 +1,26 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-cloudabi %s -o %t1.o
+# RUN: ld.lld -pie %t1.o -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+
+# Bug 27174: R_X86_64_TPOFF32 and R_X86_64_GOTTPOFF relocations should
+# be eliminated when building a PIE executable, as the static TLS layout
+# is fixed.
+#
+# CHECK: Relocations [
+# CHECK-NEXT: ]
+
+ .globl _start
+_start:
+ movq %fs:0, %rax
+ movl $3, i@TPOFF(%rax)
+
+ movq %fs:0, %rdx
+ movq i@GOTTPOFF(%rip), %rcx
+ movl $3, (%rdx,%rcx)
+
+ .section .tbss.i,"awT",@nobits
+ .globl i
+i:
+ .long 0
+ .size i, 4
diff --git a/test/ELF/zdefs.s b/test/ELF/zdefs.s
new file mode 100644
index 000000000000..410da1812db9
--- /dev/null
+++ b/test/ELF/zdefs.s
@@ -0,0 +1,7 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t1.so
+
+# RUN: not ld.lld -z defs -shared %t.o -o %t1.so 2>&1 | FileCheck -check-prefix=ERR %s
+# ERR: undefined symbol: foo
+
+callq foo@PLT