blob: 81924cd35cb1604f9baa4cd26044b74f128ccd63 [file]
# 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" \
] \
]
}