| # Expect script for RISC-V ELF linker tests |
| # Copyright (C) 2017-2021 Free Software Foundation, Inc. |
| # |
| # This file is part of the GNU Binutils. |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program; if not, write to the Free Software |
| # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| # MA 02110-1301, USA. |
| # |
| |
| proc riscv_choose_ilp32_emul {} { |
| if { [istarget "riscvbe-*"] \ |
| || [istarget "riscv32be-*"] \ |
| || [istarget "riscv64be-*"] } { |
| return "elf32briscv" |
| } |
| return "elf32lriscv" |
| } |
| |
| proc riscv_choose_lp64_emul {} { |
| if { [istarget "riscvbe-*"] \ |
| || [istarget "riscv32be-*"] \ |
| || [istarget "riscv64be-*"] } { |
| return "elf64briscv" |
| } |
| return "elf64lriscv" |
| } |
| |
| # target: rv32 or rv64. |
| # output: Which output you want? (exe, pie, .so) |
| proc run_dump_test_ifunc { name target output} { |
| set asflags "" |
| set ldflags "-z nocombreloc" |
| |
| switch -- $output { |
| exe { |
| set ext "exe" |
| } |
| pie { |
| set ext "pie" |
| set ldflags "$ldflags -pie" |
| } |
| pic { |
| set ext "so" |
| set ldflags "$ldflags -shared" |
| } |
| } |
| |
| switch -- $target { |
| rv32 { |
| set asflags "$asflags -march=rv32i -mabi=ilp32" |
| set ldflags "$ldflags -m[riscv_choose_ilp32_emul]" |
| } |
| rv64 { |
| set asflags "$asflags -march=rv64i -mabi=lp64 -defsym __64_bit__=1" |
| set ldflags "$ldflags -m[riscv_choose_lp64_emul]" |
| } |
| } |
| |
| run_ld_link_tests [list \ |
| [list "$name ($target-$output)" \ |
| "$ldflags" "" \ |
| "$asflags" \ |
| [list "$name.s"] \ |
| [concat [list "readelf -rW $name-$output.rd"] \ |
| [list "objdump -dw $name.d"]] \ |
| "$name-$target.$ext"]] |
| } |
| |
| proc run_relax_twice_test {} { |
| global as |
| global ld |
| global nm |
| global nm_output |
| global srcdir |
| global subdir |
| global runtests |
| |
| set testname "relax-twice" |
| if ![runtest_file_p $runtests $testname] then { |
| return |
| } |
| |
| # assemble and link the two input files with a version script, then |
| # capture output of nm and compare addresses of the two symbols |
| # 'foobar_new' and 'foobar@@New'. They must be equal. |
| # Bitness doesn't matter so we simply force 64bit. |
| if { ![ld_assemble_flags $as "-march=rv64i" $srcdir/$subdir/relax-twice-1.s tmpdir/relax-twice-1.o ] |
| || ![ld_assemble_flags $as "-march=rv64i" $srcdir/$subdir/relax-twice-2.s tmpdir/relax-twice-2.o] |
| || ![ld_link $ld tmpdir/relax-twice.so "-m[riscv_choose_lp64_emul] -shared --relax --version-script $srcdir/$subdir/relax-twice.ver tmpdir/relax-twice-1.o tmpdir/relax-twice-2.o"] } { |
| fail $testname |
| } elseif { ![ld_nm $nm "" tmpdir/relax-twice.so] } { |
| fail $testname |
| } elseif { ![info exists nm_output(foobar_new)] |
| || ![info exists nm_output(foobar@@New)]} { |
| send_log "bad output from nm\n" |
| verbose "bad output from nm" |
| fail $testname |
| } elseif {$nm_output(foobar_new) != $nm_output(foobar@@New)} { |
| send_log "foobar_new == $nm_output(foobar_new)\n" |
| verbose "foobar_new == $nm_output(foobar_new)" |
| send_log "foobar@@New == $nm_output(foobar@@New)\n" |
| verbose "foobar@@New == $nm_output(foobar@@New)" |
| fail $testname |
| } else { |
| pass $testname |
| } |
| } |
| |
| if [istarget "riscv*-*-*"] { |
| run_dump_test "call-relax" |
| run_dump_test "pcgp-relax" |
| run_dump_test "c-lui" |
| run_dump_test "c-lui-2" |
| run_dump_test "disas-jalr" |
| run_dump_test "pcrel-lo-addend" |
| run_dump_test "pcrel-lo-addend-2a" |
| run_dump_test "pcrel-lo-addend-2b" |
| run_dump_test "pcrel-lo-addend-3a" |
| run_dump_test "pcrel-lo-addend-3b" |
| run_dump_test "pcrel-lo-addend-3c" |
| run_dump_test "restart-relax" |
| run_dump_test "attr-merge-arch-01" |
| run_dump_test "attr-merge-arch-02" |
| run_dump_test "attr-merge-arch-03" |
| run_dump_test "attr-merge-strict-align-01" |
| run_dump_test "attr-merge-strict-align-02" |
| run_dump_test "attr-merge-strict-align-03" |
| run_dump_test "attr-merge-strict-align-04" |
| run_dump_test "attr-merge-strict-align-05" |
| run_dump_test "attr-merge-stack-align" |
| run_dump_test "attr-merge-priv-spec-01" |
| run_dump_test "attr-merge-priv-spec-02" |
| run_dump_test "attr-merge-priv-spec-03" |
| run_dump_test "attr-merge-arch-failed-01" |
| run_dump_test "attr-merge-arch-failed-02" |
| run_dump_test "attr-merge-stack-align-failed" |
| run_dump_test "attr-merge-priv-spec-failed-01" |
| run_dump_test "attr-merge-priv-spec-failed-02" |
| run_dump_test "attr-merge-priv-spec-failed-03" |
| run_dump_test "attr-merge-priv-spec-failed-04" |
| run_dump_test "attr-merge-priv-spec-failed-05" |
| run_dump_test "attr-merge-priv-spec-failed-06" |
| run_dump_test "attr-phdr" |
| run_ld_link_tests [list \ |
| [list "Weak reference 32" "-T weakref.ld -m[riscv_choose_ilp32_emul]" "" \ |
| "-march=rv32i -mabi=ilp32" {weakref32.s} \ |
| {{objdump -d weakref32.d}} "weakref32"] \ |
| [list "Weak reference 64" "-T weakref.ld -m[riscv_choose_lp64_emul]" "" \ |
| "-march=rv64i -mabi=lp64" {weakref64.s} \ |
| {{objdump -d weakref64.d}} "weakref64"]] |
| |
| # The following tests require shared library support. |
| if ![check_shared_lib_support] { |
| return |
| } |
| |
| run_dump_test "relro-relax-lui" |
| run_dump_test "relro-relax-pcrel" |
| run_relax_twice_test |
| |
| set abis [list rv32gc ilp32 [riscv_choose_ilp32_emul] rv64gc lp64 [riscv_choose_lp64_emul]] |
| foreach { arch abi emul } $abis { |
| # This checks whether our linker scripts handle __global_pointer$ |
| # correctly. It should be defined in executables and PIE, but not |
| # in shared libraries. |
| set suff64 [string map {ilp32 "" lp64 -64} $abi] |
| run_ld_link_tests [list \ |
| [list "gp test ($abi shared library)" \ |
| "-m$emul -shared" "" \ |
| "-march=$arch -mabi=$abi -fpic" \ |
| { gp-test.s } \ |
| [list "readelf --syms gp-test-lib.sd"] \ |
| "gp-test-lib-${abi}.so"] \ |
| [list "gp test ($abi executable)" \ |
| "-m$emul" "" \ |
| "-march=$arch -mabi=$abi" \ |
| { gp-test.s } \ |
| [list "readelf --syms gp-test.sd"] \ |
| "gp-test-${abi}"]] |
| } |
| |
| run_ld_link_tests { |
| { "Link non-pic code into a shared library (setup)" |
| "-shared" "" "" {lib-nopic-01a.s} |
| {} "lib-nopic-01a.so" } |
| } |
| run_dump_test "lib-nopic-01b" |
| |
| # IFUNC testcases. |
| # Check IFUNC by single type relocs. |
| run_dump_test_ifunc "ifunc-reloc-call-01" rv32 exe |
| run_dump_test_ifunc "ifunc-reloc-call-01" rv32 pie |
| run_dump_test_ifunc "ifunc-reloc-call-01" rv32 pic |
| run_dump_test_ifunc "ifunc-reloc-call-02" rv32 exe |
| run_dump_test_ifunc "ifunc-reloc-call-02" rv32 pie |
| run_dump_test_ifunc "ifunc-reloc-call-02" rv32 pic |
| run_dump_test_ifunc "ifunc-reloc-pcrel" rv32 exe |
| run_dump_test_ifunc "ifunc-reloc-pcrel" rv32 pie |
| run_dump_test_ifunc "ifunc-reloc-pcrel" rv32 pic |
| run_dump_test_ifunc "ifunc-reloc-data" rv32 exe |
| run_dump_test_ifunc "ifunc-reloc-data" rv32 pie |
| run_dump_test_ifunc "ifunc-reloc-data" rv32 pic |
| run_dump_test_ifunc "ifunc-reloc-got" rv32 exe |
| run_dump_test_ifunc "ifunc-reloc-got" rv32 pie |
| run_dump_test_ifunc "ifunc-reloc-got" rv32 pic |
| run_dump_test_ifunc "ifunc-reloc-pcrel" rv64 exe |
| run_dump_test_ifunc "ifunc-reloc-pcrel" rv64 pie |
| run_dump_test_ifunc "ifunc-reloc-pcrel" rv64 pic |
| run_dump_test_ifunc "ifunc-reloc-data" rv64 exe |
| run_dump_test_ifunc "ifunc-reloc-data" rv64 pie |
| run_dump_test_ifunc "ifunc-reloc-data" rv64 pic |
| run_dump_test_ifunc "ifunc-reloc-got" rv64 exe |
| run_dump_test_ifunc "ifunc-reloc-got" rv64 pie |
| run_dump_test_ifunc "ifunc-reloc-got" rv64 pic |
| # Check the IFUNC PLT and non-PLT relocs. |
| run_dump_test_ifunc "ifunc-nonplt" rv32 exe |
| run_dump_test_ifunc "ifunc-nonplt" rv32 pie |
| run_dump_test_ifunc "ifunc-nonplt" rv32 pic |
| run_dump_test_ifunc "ifunc-plt-01" rv32 exe |
| run_dump_test_ifunc "ifunc-plt-01" rv32 pie |
| run_dump_test_ifunc "ifunc-plt-01" rv32 pic |
| run_dump_test_ifunc "ifunc-plt-02" rv32 exe |
| run_dump_test_ifunc "ifunc-plt-02" rv32 pie |
| run_dump_test_ifunc "ifunc-plt-02" rv32 pic |
| run_dump_test_ifunc "ifunc-nonplt" rv64 exe |
| run_dump_test_ifunc "ifunc-nonplt" rv64 pie |
| run_dump_test_ifunc "ifunc-nonplt" rv64 pic |
| run_dump_test_ifunc "ifunc-plt-01" rv64 exe |
| run_dump_test_ifunc "ifunc-plt-01" rv64 pie |
| run_dump_test_ifunc "ifunc-plt-01" rv64 pic |
| run_dump_test_ifunc "ifunc-plt-02" rv64 exe |
| run_dump_test_ifunc "ifunc-plt-02" rv64 pie |
| run_dump_test_ifunc "ifunc-plt-02" rv64 pic |
| # Check the .rela.iplt overwrite issue. |
| run_dump_test_ifunc "ifunc-plt-got-overwrite" rv32 exe |
| run_dump_test_ifunc "ifunc-plt-got-overwrite" rv32 pie |
| run_dump_test_ifunc "ifunc-plt-got-overwrite" rv32 pic |
| run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 exe |
| run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pie |
| run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pic |
| |
| # Setup shared libraries. |
| run_ld_link_tests { |
| { "Build shared library for IFUNC non-PLT caller" |
| "-shared" "" "" {ifunc-seperate-caller-nonplt.s} |
| {} "ifunc-seperate-caller.so" } |
| { "Build shared library for IFUNC PLT caller" |
| "-shared" "" "" {ifunc-seperate-caller-plt.s} |
| {} "ifunc-seperate-caller.so" } |
| { "Build shared library for IFUNC resolver" |
| "-shared" "" "" {ifunc-seperate-resolver.s} |
| {} "ifunc-seperate-resolver.so" } |
| } |
| # The IFUNC resolver and caller are in the seperate modules. |
| # If IFUNC resolver and caller are linked to the same module, |
| # then the result are the same as the run_dump_test_ifunc. |
| run_dump_test "ifunc-seperate-nonplt-exe" |
| run_dump_test "ifunc-seperate-nonplt-pie" |
| run_dump_test "ifunc-seperate-nonplt-pic" |
| run_dump_test "ifunc-seperate-plt-exe" |
| run_dump_test "ifunc-seperate-plt-pie" |
| run_dump_test "ifunc-seperate-plt-pic" |
| run_dump_test "ifunc-seperate-pcrel-pie" |
| run_dump_test "ifunc-seperate-pcrel-pic" |
| } |