| # Expect script for LoongArch ELF linker tests |
| # Copyright (C) 2022-2025 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 run_partial_linking_align_test {} { |
| global as |
| global ld |
| global srcdir |
| global subdir |
| global runtests |
| |
| set testname "partial-link-align" |
| if ![runtest_file_p $runtests $testname] then { |
| return |
| } |
| |
| if { ![ld_assemble $as "$srcdir/$subdir/$testname-a.s" tmpdir/a.o] |
| || ![ld_assemble $as "$srcdir/$subdir/$testname-b.s" tmpdir/b.o] |
| || ![ld_link $ld tmpdir/$testname.os "tmpdir/a.o tmpdir/b.o -r"] |
| || ![ld_link $ld tmpdir/$testname "tmpdir/$testname.os -e0 -Ttext 0x1000"] } { |
| fail $testname |
| } else { |
| set objdump_output [run_host_cmd "objdump" "-d -M no-aliases tmpdir/$testname"] |
| if { [ regexp ".*1010:\\s*4c000020\\s*jirl.*" $objdump_output ] } { |
| pass $testname |
| } else { |
| fail $testname |
| } |
| } |
| } |
| |
| if [istarget loongarch64-*-*] { |
| if [isbuild loongarch64-*-*] { |
| run_dump_test "relax-align-ignore-start" |
| run_partial_linking_align_test |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax call36 .so build" \ |
| "-shared" "" \ |
| "" \ |
| {relax-call36-so.s} \ |
| {} \ |
| "relax-call36.so" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/relax-call36.so"] { |
| set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-call36.so"] |
| if { [ regexp "pcaddu18i" $objdump_output] } { |
| fail "loongarch relax call36 so" |
| } { |
| pass "loongarch relax call36 so" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax call36 dyn exe build" \ |
| "-pie -e 0" "" \ |
| "" \ |
| {relax-call36-exe.s} \ |
| {} \ |
| "relax-call36-d.exe" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/relax-call36-d.exe"] { |
| set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-call36-d.exe"] |
| if { [ regexp "pcaddu18i" $objdump_output] } { |
| fail "loongarch relax call36 dyn exe" |
| } { |
| pass "loongarch relax call36 dyn exe" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax call36 dyn-pie exe build" \ |
| "-pie -e 0" "" \ |
| "" \ |
| {relax-call36-exe.s} \ |
| {} \ |
| "relax-call36-dp.exe" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/relax-call36-dp.exe"] { |
| set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-call36-dp.exe"] |
| if { [ regexp "pcaddu18i" $objdump_output] } { |
| fail "loongarch relax call36 dyn-pie exe" |
| } { |
| pass "loongarch relax call36 dyn-pie exe" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax call36 static exe build" \ |
| "-static -e 0" "" \ |
| "" \ |
| {relax-call36-exe.s} \ |
| {} \ |
| "relax-call36-s.exe" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/relax-call36-s.exe"] { |
| set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-call36-s.exe"] |
| if { [ regexp "pcaddu18i" $objdump_output] } { |
| fail "loongarch relax call36 static exe" |
| } { |
| pass "loongarch relax call36 static exe" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax call36 static-pie exe build" \ |
| "-static -pie --no-dynamic-linker -e 0" "" \ |
| "" \ |
| {relax-call36-exe.s} \ |
| {} \ |
| "relax-call36-sp.exe" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/relax-call36-sp.exe"] { |
| set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-call36-sp.exe"] |
| if { [ regexp "pcaddu18i" $objdump_output] } { |
| fail "loongarch relax call36 static-pie exe" |
| } { |
| pass "loongarch relax call36 static-pie exe" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax ttext" \ |
| "" "" \ |
| "" \ |
| {relax-ttext.s} \ |
| {} \ |
| "relax-ttext" \ |
| ] \ |
| ] |
| |
| set testname "loongarch relax .exe build" |
| set pre_builds [list \ |
| [list \ |
| "$testname" \ |
| "" \ |
| "" \ |
| {relax.s} \ |
| {} \ |
| "relax" \ |
| ] \ |
| ] |
| |
| run_cc_link_tests $pre_builds |
| |
| if [file exist "tmpdir/relax"] { |
| set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax"] |
| if { [ regexp ".*pcaddi.*pcaddi.*" $objdump_output] } { |
| pass "loongarch relax .exe" |
| } { |
| fail "loongarch relax .exe" |
| } |
| } |
| |
| set testname "loongarch ld --no-relax build" |
| set pre_builds [list \ |
| [list \ |
| "$testname" \ |
| "-Wl,--no-relax" \ |
| "" \ |
| {relax.s} \ |
| {} \ |
| "norelax" \ |
| ] \ |
| ] |
| |
| run_cc_link_tests $pre_builds |
| |
| if [file exist "tmpdir/norelax"] { |
| set objdump_output [run_host_cmd "objdump" "-d tmpdir/norelax"] |
| if { [ regexp ".*pcaddi.*" $objdump_output] } { |
| fail "loongarch ld --no-relax" |
| } { |
| pass "loongarch ld --no-relax" |
| } |
| } |
| |
| if [check_shared_lib_support] { |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax .so build" \ |
| "-shared -e 0x0" "" \ |
| "" \ |
| {relax-so.s} \ |
| {} \ |
| "relax-so" \ |
| ] \ |
| ] |
| } |
| |
| if [file exist "tmpdir/relax-so"] { |
| set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-so"] |
| if { [ regexp ".*pcaddi.*" $objdump_output] } { |
| pass "loongarch relax .so" |
| } { |
| fail "loongarch relax .so" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch tls le relax .exe build" \ |
| "" "" \ |
| "" \ |
| {relax-tls-le.s} \ |
| {} \ |
| "relax-tls-le" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/relax-tls-le"] { |
| set objdump_output1 [run_host_cmd "objdump" "-d tmpdir/relax-tls-le -M no-aliases"] |
| if { [ regexp ".addi.*st.*" $objdump_output1] } { |
| pass "loongarch relax success" |
| } { |
| fail "loongarch relax fail" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch tls le no relax .exe build" \ |
| "--no-relax" "" \ |
| "" \ |
| {relax-tls-le.s} \ |
| {} \ |
| "no-relax-tls-le" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/no-relax-tls-le"] { |
| set objdump_output2 [run_host_cmd "objdump" "-d tmpdir/no-relax-tls-le -M no-aliases"] |
| if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output2] } { |
| pass "loongarch no-relax success" |
| } { |
| fail "loongarch no-relax fail" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch old tls le .exe build" \ |
| "--no-relax" "" \ |
| "" \ |
| {old-tls-le.s} \ |
| {} \ |
| "old-tls-le" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/old-tls-le"] { |
| set objdump_output3 [run_host_cmd "objdump" "-d tmpdir/old-tls-le -M no-aliases"] |
| if { [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output3] } { |
| pass "loongarch old tls le success" |
| } { |
| fail "loongarch old tls le fail" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch tls le realx compatible .exe build" \ |
| "--no-relax" "" \ |
| "" \ |
| {tls-relax-compatible-check-new.s tls-relax-compatible-check-old.s} \ |
| {} \ |
| "realx-compatible" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/realx-compatible"] { |
| set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/realx-compatible -M no-aliases"] |
| if { [ regexp ".addi.*st.*" $objdump_output4] && \ |
| [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output4] } { |
| pass "loongarch tls le relax compatible check success" |
| } { |
| fail "loongarch tls le relax compatible check fail" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch tls le no realx compatible .exe build" \ |
| "--no-relax" "" \ |
| "" \ |
| {tls-relax-compatible-check-new.s tls-relax-compatible-check-old.s} \ |
| {} \ |
| "no-realx-compatible" \ |
| ] \ |
| ] |
| if [file exist "tmpdir/no-realx-compatible"] { |
| set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/no-realx-compatible -M no-aliases"] |
| if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output4] && \ |
| [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output4] } { |
| pass "loongarch tls le no-relax compatible check success" |
| } { |
| fail "loongarch tls le no-relax compatible check fail" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch tls le realx bound-check .exe build" \ |
| "--no-relax" "" \ |
| "" \ |
| {relax-bound-check-tls-le.s} \ |
| {} \ |
| "relax-bound-check-tls-le" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/relax-bound-check-tls-le"] { |
| set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/relax-bound-check-tls-le -M no-aliases"] |
| if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output5] && \ |
| [ regexp ".addi.*st.*" $objdump_output5] } { |
| pass "loongarch no-relax success" |
| } { |
| fail "loongarch no-relax fail" |
| } |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch tls le no realx bound-check .exe build" \ |
| "--no-relax" "" \ |
| "" \ |
| {relax-bound-check-tls-le.s} \ |
| {} \ |
| "no-relax-bound-check-tls-le" \ |
| ] \ |
| ] |
| |
| if [file exist "tmpdir/no-relax-bound-check-tls-le"] { |
| set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/no-relax-bound-check-tls-le -M no-aliases"] |
| if { [ regexp ".*addi.*st.*" $objdump_output5] } { |
| pass "loongarch no-relax success" |
| } { |
| fail "loongarch no-relax fail" |
| } |
| } |
| |
| # If symbol in data segment, offset need to sub segment align to prevent |
| # overflow. |
| if [check_pie_support] { |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax segment alignment min" \ |
| "-e0 -Ttext 0x120004000 -pie -z relro" "" \ |
| "" \ |
| {relax-segment-min.s} \ |
| {} \ |
| "relax-segment-min" \ |
| ] \ |
| ] |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax segment alignment max" \ |
| "-e0 -Ttext 0x120004000 -pie -z relro" "" \ |
| "" \ |
| {relax-segment-max.s} \ |
| {} \ |
| "relax-segment-max" \ |
| ] \ |
| ] |
| } |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax section align overflow" \ |
| "-e0 -Ttext 0x120000000" "" \ |
| "" \ |
| {relax-section-align-overflow.s} \ |
| {} \ |
| "relax-section-align-overflow" \ |
| ] \ |
| ] |
| |
| # # loongarch*-elf target do not support -z separate-code |
| if [check_shared_lib_support] { |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax separate code overflow" \ |
| "-e0 -z separate-code" "" \ |
| "" \ |
| {relax-separate-code-overflow.s} \ |
| {} \ |
| "relax-separate-code-overflow" \ |
| ] \ |
| ] |
| } |
| } |
| |
| if [check_shared_lib_support] { |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax-align" \ |
| "-e 0x0 -z relro" "" \ |
| "--no-warn" \ |
| {relax-align.s} \ |
| [list \ |
| [list objdump -d relax-align.dd] \ |
| ] \ |
| "relax-align" \ |
| ] \ |
| ] |
| |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch relax align discard" \ |
| "-e 0x0 -T relax-align-discard.lds -r" "" \ |
| "" \ |
| {relax-align-discard.s} \ |
| {} \ |
| "relax-align-discard" \ |
| ] \ |
| ] |
| } |
| |
| set objdump_flags "-s -j .data" |
| run_ld_link_tests \ |
| [list \ |
| [list \ |
| "loongarch uleb128" \ |
| "-e 0x0" "" \ |
| "" \ |
| {uleb128.s} \ |
| [list \ |
| [list objdump $objdump_flags uleb128.dd] \ |
| ] \ |
| "uleb128" \ |
| ] \ |
| ] |
| } |