mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-12 12:16:04 +08:00
9181724704
Linker plugin_object_p opens the IR archive for each IR archive member. For GCC plugin, plugin_object_p closes the archive file descriptor. But for LLVM plugin, the archive file descriptor remains open. If there are 3000 IR archive members, there are 3000 file descriptors for them. We can run out of file descriptors petty easily. 1. Add archive_plugin_fd and archive_plugin_fd_open_count to bfd so that we can cache and reuse the IR archive file descriptor for all IR archive members in the archive. 2. Add bfd_plugin_close_file_descriptor to properly close the IR archive file descriptor. bfd/ PR ld/28040 * archive.c (_bfd_archive_close_and_cleanup): Close the archive plugin file descriptor if needed. * bfd.c (bfd): Add archive_plugin_fd and archive_plugin_fd_open_count. * opncls.c (_bfd_new_bfd): Initialize to -1. * plugin.c (bfd_plugin_open_input): Cache and reuse the archive plugin file descriptor. (bfd_plugin_close_file_descriptor): New function. (try_claim): Call bfd_plugin_close_file_descriptor. * plugin.h (bfd_plugin_close_file_descriptor): New. * bfd-in2.h: Regenerated. ld/ PR ld/28040 * plugin.c (plugin_input_file): Add ibfd. (release_plugin_file_descriptor): New function. (release_input_file): Call release_plugin_file_descriptor to close input->fd. (plugin_object_p): Call release_plugin_file_descriptor to close input->fd. Also call release_plugin_file_descriptor if not claimed. * testsuite/config/default.exp (RANLIB): New. * testsuite/ld-plugin/lto.exp: Run ranlib test.
463 lines
12 KiB
Plaintext
463 lines
12 KiB
Plaintext
# Basic expect script for LD Regression Tests
|
|
# Copyright (C) 1993-2021 Free Software Foundation, Inc.
|
|
#
|
|
# This file is part of the GNU Binutils.
|
|
#
|
|
# This file 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.
|
|
#
|
|
# Written by Jeffrey Wheat (cassidy@cygnus.com)
|
|
#
|
|
|
|
if ![info exists ld] then {
|
|
set ld [findfile $base_dir/ld-new $base_dir/ld-new [transform ld]]
|
|
}
|
|
|
|
if ![info exists as] then {
|
|
set as [findfile $base_dir/../gas/as-new $base_dir/../gas/as-new [transform as]]
|
|
}
|
|
|
|
if ![info exists nm] then {
|
|
set nm [findfile $base_dir/../binutils/nm-new $base_dir/../binutils/nm-new [transform nm]]
|
|
}
|
|
|
|
if ![info exists objdump] then {
|
|
set objdump [findfile $base_dir/../binutils/objdump]
|
|
}
|
|
|
|
if ![info exists objcopy] then {
|
|
set objcopy [findfile $base_dir/../binutils/objcopy]
|
|
}
|
|
|
|
if ![info exists ar] then {
|
|
set ar [findfile $base_dir/../binutils/ar]
|
|
}
|
|
|
|
if ![info exists strip] then {
|
|
set strip [findfile $base_dir/../binutils/strip-new $base_dir/../binutils/strip-new [transform strip]]
|
|
}
|
|
|
|
if ![info exists size] then {
|
|
set size [findfile $base_dir/../binutils/size]
|
|
}
|
|
|
|
remote_exec host "mkdir -p tmpdir"
|
|
|
|
# Make symlinks from tmpdir/ld to the linker and assembler in the
|
|
# build tree, so that we can use a -B option to gcc to force it to use
|
|
# the newly built linker and assembler.
|
|
if {![file isdirectory tmpdir/ld]} then {
|
|
catch "exec mkdir tmpdir/ld" status
|
|
catch "exec ln -s ../../ld-new tmpdir/ld/ld" status
|
|
catch "exec ln -s ld tmpdir/ld/collect-ld" status
|
|
catch "exec ln -s ../../../gas/as-new tmpdir/ld/as" status
|
|
}
|
|
set gcc_B_opt "-B[pwd]/tmpdir/ld/"
|
|
|
|
# load the linker path
|
|
set ld_L_opt ""
|
|
if {[file exists tmpdir/libpath.exp]} {
|
|
load_lib tmpdir/libpath.exp
|
|
|
|
foreach dir $libpath {
|
|
append ld_L_opt " -L$dir"
|
|
}
|
|
}
|
|
|
|
# The "make check" target in the Makefile passes in
|
|
# "CC=$(CC_FOR_TARGET)". But, if the user invokes runtest directly
|
|
# (as when testing an installed linker), these flags may not be set.
|
|
if {![info exists CC]} {
|
|
set CC [find_gcc]
|
|
}
|
|
if {![info exists CFLAGS]} {
|
|
set CFLAGS "-g -O2"
|
|
}
|
|
if {![info exists CXX]} {
|
|
set CXX [find_g++]
|
|
}
|
|
if {![info exists CXXFLAGS]} {
|
|
set CXXFLAGS ""
|
|
}
|
|
|
|
# This allows us to run the linker testsuite with clang as the compilation
|
|
# driver instead of gcc. The syntax of the overrides are as follows, one
|
|
# per line:
|
|
#
|
|
# '#': Silence information about the changes to the command line arguments.
|
|
#
|
|
# '^': Add FOO as a new argument at the beginning of the command line.
|
|
#
|
|
# '+': Add FOO as a new argument at the end of the command line.
|
|
#
|
|
# 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command
|
|
# line.
|
|
#
|
|
# 'xOPTION': Removes all instances of the literal argument OPTION.
|
|
#
|
|
# 'XOPTION': Removes all instances of the literal argument OPTION,
|
|
# and the following argument.
|
|
#
|
|
# 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
|
|
# at the end of the command line.
|
|
#
|
|
# \param OS - The stream to write edit information to.
|
|
# \param Args - The vector of command line arguments.
|
|
# \param Edit - The override command to perform.
|
|
# \param SavedStrings - Set to use for storing string representations.
|
|
|
|
# Only set up the environment variable if the user has not already provided one.
|
|
if {! [info exists env(CCC_OVERRIDE_OPTIONS)]} {
|
|
set env(CCC_OVERRIDE_OPTIONS) "#\
|
|
+-Wno-unused-command-line-argument \
|
|
+-Wno-unknown-attributes \
|
|
+-Wno-tautological-compare \
|
|
+-Wno-ignored-optimization-argument \
|
|
+-Wno-deprecated \
|
|
+-fuse-ld=$ld \
|
|
x-Wa,--elf-stt-common=yes \
|
|
x-Wa,-mx86-used-note=no \
|
|
x-Wa,-mx86-used-note=yes \
|
|
x-Wa,-madd-bnd-prefix \
|
|
x-fno-early-inlining \
|
|
x-fno-toplevel-reorder \
|
|
x-flto-partition=none \
|
|
x-feliminate-dwarf2-dups \
|
|
s/-Wa,-mrelax-relocations=yes,-mx86-used-note=yes/-Wa,-mrelax-relocations=yes/ \
|
|
s/-Wa,--compress-debug-sections=zlib/-Wa,-compress-debug-sections=zlib/ \
|
|
s/-Wa,--compress-debug-sections=zlib-gabi/-Wa,-compress-debug-sections=zlib-gabi/ \
|
|
"
|
|
}
|
|
|
|
# The mips64-*-linux-gnu compiler defaults to the N32 ABI after
|
|
# installed, but to the O32 ABI in the build tree, because of some
|
|
# specs-file hacks. Make sure we use an ABI that is compatible with
|
|
# the one we expect.
|
|
if {[istarget mips64*-*-linux*] &&
|
|
(![board_info [target_info name] exists multilib_flags] ||
|
|
![string match "*-mabi" [board_info [target_info name] multilib_flags]])
|
|
} {
|
|
append gcc_B_opt " -mabi=n32"
|
|
}
|
|
|
|
if { [istarget rx-*-*] } {
|
|
global ASFLAGS
|
|
set ASFLAGS "-muse-conventional-section-names"
|
|
}
|
|
|
|
# Blackfin ELF targets require selection of an explicit CPU. Use the sim.
|
|
if {[istarget bfin*-elf*]} {
|
|
append gcc_B_opt " -msim"
|
|
}
|
|
|
|
# load the utility procedures
|
|
load_lib ld-lib.exp
|
|
|
|
proc get_target_emul {} {
|
|
global target_triplet
|
|
global srcdir
|
|
set status [catch "exec sh -c \"targ='$target_triplet' && . $srcdir/../configure.tgt && echo \\\$targ_emul\"" result]
|
|
if $status { error "Error getting emulation name: $result" }
|
|
return $result
|
|
}
|
|
|
|
if ![info exists HOSTING_EMU] { set HOSTING_EMU "-m [get_target_emul]" }
|
|
|
|
#
|
|
# ld_version -- extract and print the version number of ld compiler (GCC)
|
|
#
|
|
proc ld_version {} {
|
|
global ld
|
|
default_ld_version $ld
|
|
}
|
|
|
|
#
|
|
# ld_exit -- just a stub for ld
|
|
#
|
|
proc ld_exit {} {
|
|
}
|
|
|
|
#
|
|
# ld_start
|
|
# relink the linker
|
|
#
|
|
proc ld_start { ld target } {
|
|
#
|
|
}
|
|
|
|
#
|
|
# ld_relocate
|
|
# link an object using relocation
|
|
#
|
|
proc ld_relocate { ld target objects } {
|
|
default_ld_relocate $ld $target $objects
|
|
}
|
|
|
|
#
|
|
# ld_link
|
|
# link a program using ld
|
|
#
|
|
proc ld_link { ld target objects } {
|
|
default_ld_link $ld $target $objects
|
|
}
|
|
|
|
#
|
|
# ld_compile
|
|
# compile an object using $cc
|
|
#
|
|
proc ld_compile { cc source object } {
|
|
default_ld_compile $cc $source $object
|
|
}
|
|
|
|
#
|
|
# ld_assemble
|
|
# assemble a file
|
|
#
|
|
proc ld_assemble { as source object } {
|
|
default_ld_assemble $as "" $source $object
|
|
}
|
|
|
|
#
|
|
# ld_assemble_flags
|
|
# assemble a file with extra flags
|
|
#
|
|
proc ld_assemble_flags { as flags source object } {
|
|
default_ld_assemble $as $flags $source $object
|
|
}
|
|
|
|
#
|
|
# ld_nm
|
|
# run nm on a file
|
|
#
|
|
proc ld_nm { nm nmflags object } {
|
|
default_ld_nm $nm $nmflags $object
|
|
}
|
|
|
|
#
|
|
# ld_exec
|
|
# execute ithe target
|
|
#
|
|
proc ld_exec { target output } {
|
|
default_ld_exec $target $output
|
|
}
|
|
|
|
# From gas-defs.exp, to support run_dump_test.
|
|
if ![info exists AS] then {
|
|
set AS $as
|
|
}
|
|
|
|
if ![info exists ASFLAGS] then {
|
|
set ASFLAGS ""
|
|
}
|
|
|
|
if ![info exists OBJDUMP] then {
|
|
set OBJDUMP $objdump
|
|
}
|
|
|
|
if ![info exists OBJDUMPFLAGS] then {
|
|
set OBJDUMPFLAGS {}
|
|
}
|
|
|
|
if ![info exists NM] then {
|
|
set NM $nm
|
|
}
|
|
|
|
if ![info exists NMFLAGS] then {
|
|
set NMFLAGS {}
|
|
}
|
|
|
|
if ![info exists OBJCOPY] then {
|
|
set OBJCOPY $objcopy
|
|
}
|
|
|
|
if ![info exists OBJCOPYFLAGS] then {
|
|
set OBJCOPYFLAGS {}
|
|
}
|
|
|
|
if ![info exists RANLIB] then {
|
|
set RANLIB [findfile $base_dir/../binutils/ranlib]
|
|
}
|
|
|
|
if ![info exists READELF] then {
|
|
set READELF [findfile $base_dir/../binutils/readelf]
|
|
}
|
|
|
|
if ![info exists READELFFLAGS] then {
|
|
set READELFFLAGS {}
|
|
}
|
|
|
|
if ![info exists ELFEDIT] then {
|
|
set ELFEDIT [findfile $base_dir/../binutils/elfedit]
|
|
}
|
|
|
|
if ![info exists LD] then {
|
|
set LD [findfile $base_dir/ld-new ./ld-new [transform ld]]
|
|
}
|
|
|
|
if ![info exists LDFLAGS] then {
|
|
set LDFLAGS {}
|
|
}
|
|
|
|
# Set LD_CLASS to "64bit" for a 64-bit *host* linker.
|
|
if { ![info exists LD_CLASS] } then {
|
|
set REAL_LD [findfile $base_dir/.libs/ld-new .libs/ld-new $LD [transform ld]]
|
|
set readelf_output [run_host_cmd "$READELF" "-h $REAL_LD"]
|
|
if { [regexp {[ \t]+Class:[ \t]+ELF64} $readelf_output] } then {
|
|
set LD_CLASS "64bit"
|
|
} else {
|
|
set LD_CLASS "32bit"
|
|
}
|
|
}
|
|
|
|
# Compiler tests
|
|
proc compiler_supports { flag args } {
|
|
if { [check_compiler_available] } {
|
|
global CC
|
|
set flags ""
|
|
if [board_info [target_info name] exists cflags] {
|
|
append flags " [board_info [target_info name] cflags]"
|
|
}
|
|
if [board_info [target_info name] exists ldflags] {
|
|
append flags " [board_info [target_info name] ldflags]"
|
|
}
|
|
set fn "cs[pid].c"
|
|
set f [open $fn "w"]
|
|
if { [llength $args] > 0 } {
|
|
puts $f [lindex $args 0]
|
|
} else {
|
|
puts $f "int main (void) { return 0; }"
|
|
}
|
|
close $f
|
|
set rfn [remote_download host $fn]
|
|
set avail [run_host_cmd_yesno "$CC" "$flags $flag $rfn -o /dev/null"]
|
|
remote_file host delete $rfn
|
|
file delete $fn
|
|
return $avail
|
|
}
|
|
return 0
|
|
}
|
|
|
|
if { ![info exists PLT_CFLAGS] } then {
|
|
set PLT_CFLAGS ""
|
|
if [compiler_supports "-c -fplt"] {
|
|
set PLT_CFLAGS "-fplt"
|
|
}
|
|
}
|
|
|
|
if { ![info exists NOPIE_CFLAGS] || ![info exists NOPIE_LDFLAGS] } then {
|
|
set NOPIE_CFLAGS ""
|
|
set NOPIE_LDFLAGS ""
|
|
if [compiler_supports "-fno-PIE -no-pie"] {
|
|
set NOPIE_CFLAGS "-fno-PIE"
|
|
set NOPIE_LDFLAGS "-no-pie"
|
|
}
|
|
}
|
|
|
|
if { ![info exists NOCF_PROTECTION_CFLAGS] } then {
|
|
set NOCF_PROTECTION_CFLAGS ""
|
|
if [compiler_supports "-fcf-protection=none"] {
|
|
set NOCF_PROTECTION_CFLAGS "-fcf-protection=none"
|
|
}
|
|
}
|
|
|
|
if { ![info exists GNU2_CFLAGS] } then {
|
|
set GNU2_CFLAGS ""
|
|
if [compiler_supports "-c -mtls-dialect=gnu2" "__thread int y = 1;"] {
|
|
set GNU2_CFLAGS "-mtls-dialect=gnu2"
|
|
}
|
|
}
|
|
|
|
if { ![info exists INT128_CFLAGS] } then {
|
|
set INT128_CFLAGS ""
|
|
if [compiler_supports "-c" "__int128 a = 42;"] {
|
|
set INT128_CFLAGS "-DHAS_INT128"
|
|
}
|
|
}
|
|
|
|
if { ![info exists STATIC_LDFLAGS] } then {
|
|
set STATIC_LDFLAGS ""
|
|
if [compiler_supports "-static"] {
|
|
set STATIC_LDFLAGS "-static"
|
|
}
|
|
}
|
|
|
|
if { ![info exists STATIC_PIE_LDFLAGS] } then {
|
|
set STATIC_PIE_LDFLAGS ""
|
|
if [compiler_supports "-static-pie"] {
|
|
set STATIC_PIE_LDFLAGS "-static-pie"
|
|
}
|
|
}
|
|
|
|
if { ![info exists NOSANITIZE_CFLAGS] } then {
|
|
set NOSANITIZE_CFLAGS ""
|
|
if [compiler_supports "-fno-sanitize=all"] {
|
|
set NOSANITIZE_CFLAGS "-fno-sanitize=all"
|
|
}
|
|
}
|
|
|
|
if { ![info exists NOLTO_CFLAGS] } then {
|
|
set NOLTO_CFLAGS ""
|
|
if [compiler_supports "-fno-lto"] {
|
|
set NOLTO_CFLAGS "-fno-lto"
|
|
}
|
|
}
|
|
|
|
# Provide dummy libraries that alpha-vms-ld always loads
|
|
if { [istarget alpha*-*-*vms*] } {
|
|
set src tmpdir/empty.s
|
|
set f [open $src "w"]
|
|
close $f
|
|
if { [ld_assemble $as $src tmpdir/empty.o]
|
|
&& ![ld_link $LD tmpdir/empty tmpdir/empty.o]
|
|
&& [regsub -all {[^\n]*: cannot find -l([^\n]*)} $exec_output {tmpdir/lib\1.a } missing_libs] } {
|
|
regsub -all {\$} $missing_libs {\\\$} missing_libs
|
|
for { set i 0 } { $i < [llength $missing_libs] } { incr i } {
|
|
set f [lindex $missing_libs $i]
|
|
verbose -log "creating dummy $f"
|
|
ar_simple_create $ar {} $f tmpdir/empty.o
|
|
}
|
|
append LDFLAGS " -Ltmpdir"
|
|
unset i missing_libs
|
|
}
|
|
unset f src
|
|
}
|
|
|
|
set plug_opt ""
|
|
if { [check_compiler_available] } {
|
|
set plugin_names {
|
|
liblto_plugin.so
|
|
liblto_plugin-0.dll
|
|
cyglto_plugin-0.dll
|
|
}
|
|
foreach plug $plugin_names {
|
|
set plug_so [run_host_cmd $CC "--print-prog-name $plug"]
|
|
if { $plug_so eq $plug } then {
|
|
set plug_so [run_host_cmd $CC "--print-file-name $plug"]
|
|
}
|
|
if { $plug_so ne $plug } then {
|
|
set plug_opt "--plugin $plug_so"
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if {[file exists .libs/libdep.so]} {
|
|
set dep_plug_opt "--plugin .libs/libdep.so"
|
|
} elseif {[file exists .libs/libdep.dll]} {
|
|
set dep_plug_opt "--plugin .libs/libdep.dll"
|
|
} else {
|
|
set dep_plug_opt ""
|
|
}
|