# Expect script for LoongArch ELF linker tests # Copyright (C) 2022-2024 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 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" \ ] \ ] }