mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-21 04:42:53 +08:00
38b123494b
On x86-64, the procedure linkage table (PLT) is used to 1. Call external function. 2. Call internal IFUNC function. The best implementation is selected for the target processor at run-time. 3. Act as the canonical function address. 4. Support LD_AUDIT to audit external function calls. 5. Support LD_PROFILE to profile external function calls. PLT looks like: PLT0: push GOT[1] jmp *GOT[2] nop PLT1: jmp *GOT[name1_index] push name1_reloc_index jmp PLT0 GOT is an array of addresses. Initially the GOT entry of name1 is filled with the address of the "push name1_reloc_index" instruction. The function, name1, is called via "jmp *GOT[name1]" in the PLT entry. Even when lazy binding is disabled by "-z now", the PLT0 entry may still be used with LD_AUDIT or LD_PROFILE if PLT entry is used for canonical function address. When linker is invoked with "-z bndplt", a different PLT layout in .plt is used: PLT0: push GOT[1] bnd jmp *GOT[2] nop PLT1: push name1_reloc_index bnd jmp PLT0 nop together with a second PLT section, .pl.bnd: PLT1: bnd jmp *GOT[name1_index] nop where the GOT entry of name1 is filled with the address of the push instruction of the corresponding entry in .plt. 1. With lazy binding, when the external function, name1, is called the first time, dynamic linker is called via PLT0 to update GOT[name1_index] with the actual address of name1 and transfers control to name1 afterwards. 2. PLT is also used to call a local IFUNC function, name1, run-time loader updates GOT[name1_index] when loading the module. This patch 1. Remove PLT layout configurations from x86-64 backend_data. 2. Add generic, lay and non-lazy PLT layout configurations to x86-64 link_hash_table. Generic PLT layout includes the PLT entry templates, information how to update the first instruction in PLT and PLT eh_frame informaton, which are initialized in x86-64 setup_gnu_properties, based on "-z bndplt" and target selection. PLT section alignment is also set to PLT entry size for non-NaCl target. 3. Remove elf_x86_64_create_dynamic_sections. create_dynamic_sections isn't always called, but GOT relocations need GOT relocations. Instead, create all x86-64 specific dynamic sections with alignment to their entry size in x86-64 setup_gnu_properties, which initializes elf.dynobj, so that x86-64 check_relocs can be simplified. 4. Rewrite elf_x86_64_get_synthetic_symtab to check PLT sections against all dynamic relocations to support both lazy and non-lazy PLTs. There is no change in PLT. The only externally visible change is the improvement of synthetic PLT symbols for .plt.got. bfd/ * elf64-x86-64.c (PLT_ENTRY_SIZE): Renamed to ... (LAZY_PLT_ENTRY_SIZE): This. (NON_LAZY_PLT_ENTRY_SIZE): New. (elf_x86_64_plt0_entry): Renamed to ... (elf_x86_64_lazy_plt0_entry): This. (elf_x86_64_plt_entry): Renamed to ... (elf_x86_64_lazy_plt_entry): This. (elf_x86_64_bnd_plt0_entry): Renamed to ... (elf_x86_64_lazy_bnd_plt0_entry): This. (elf_x86_64_legacy_plt_entry): Removed. (elf_x86_64_bnd_plt_entry): Renamed to ... (elf_x86_64_lazy_bnd_plt_entry): This. (elf_x86_64_legacy_plt2_entry): Renamed to ... (elf_x86_64_non_lazy_plt_entry): This. (elf_x86_64_bnd_plt2_entry): Renamed to ... (elf_x86_64_non_lazy_bnd_plt_entry): This. (elf_x86_64_eh_frame_plt): Renamed to ... (elf_x86_64_eh_frame_lazy_plt): This. (elf_x86_64_eh_frame_bnd_plt): Renamed to ... (elf_x86_64_eh_frame_lazy_bnd_plt): This. (elf_x86_64_eh_frame_plt_got): Renamed to ... (elf_x86_64_eh_frame_non_lazy_plt): This. (elf_x86_64_lazy_plt_layout): New. (elf_x86_64_non_lazy_plt_layout): Likewise. (elf_x86_64_plt_layout): Likewise. (elf_x86_64_backend_data): Remove PLT layout information. Add os for target system. (GET_PLT_ENTRY_SIZE): Removed. (elf_x86_64_lazy_plt): New. (elf_x86_64_non_lazy_plt): Likewise. (elf_x86_64_lazy_bnd_plt): Likewise. (elf_x86_64_non_lazy_bnd_plt): Likewise. (elf_x86-64_arch_bed): Updated. (elf_x86_64_link_hash_table): Add plt, lazy_plt and non_lazy_plt. (elf_x86_64_create_dynamic_sections): Removed. (elf_x86_64_check_relocs): Don't check elf.dynobj. Don't call _bfd_elf_create_ifunc_sections nor _bfd_elf_create_got_section. (elf_x86-64_adjust_dynamic_symbol): Updated. (elf_x86_64_allocate_dynrelocs): Updated. Pass 0 as PLT header size to _bfd_elf_allocate_ifunc_dyn_relocs and don't allocate size for PLT0 if there is no PLT0. Get plt_entry_size from non_lazy_plt for non-lazy PLT entries. (elf_x86_64_size_dynamic_sections): Updated. Get plt_entry_size from non_lazy_plt for non-lazy PLT entries. (elf_x86-64_relocate_section): Updated. Properly get PLT index if there is no PLT0. (elf_x86_64_finish_dynamic_symbol): Updated. Fill the first slot in the PLT entry with generic PLT layout. Fill the non-lazy PLT entries with non-lazy PLT layout. Don't fill the second and third slots in the PLT entry if there is no PLT0. (elf_x86_64_finish_dynamic_sections): Updated. Don't fill PLT0 if there is no PLT0. Set sh_entsize on the .plt.got section. (compare_relocs): New. (elf_x86_64_plt_type): Likewise. (elf_x86_64_plt): Likewise. (elf_x86_64_nacl_plt): New. Forward declaration. (elf_x86_64_get_plt_sym_val): Removed. (elf_x86_64_get_synthetic_symtab): Rewrite to check PLT sections against all dynamic relocations. (elf_x86_64_link_setup_gnu_properties): New function. (elf_backend_create_dynamic_sections): Updated. (elf_backend_setup_gnu_properties): New. (elf_x86_64_nacl_plt): New. (elf_x86_64_nacl_arch_bed): Updated. ld/ * testsuite/ld-ifunc/ifunc-16-x86-64-now.d: New file. * testsuite/ld-ifunc/ifunc-2-local-x86-64-now.d: Likewise. * testsuite/ld-ifunc/ifunc-2-x86-64-now.d: Likewise. * testsuite/ld-ifunc/pr17154-x86-64-now.d: Likewise. * testsuite/ld-x86-64/bnd-branch-1-now.d: Likewise. * testsuite/ld-x86-64/bnd-ifunc-1-now.d: Likewise. * testsuite/ld-x86-64/bnd-ifunc-2-now.d: Likewise. * testsuite/ld-x86-64/bnd-plt-1-now.d: Likewise. * testsuite/ld-x86-64/mpx3n.dd: Likewise. * testsuite/ld-x86-64/mpx4n.dd: Likewise. * testsuite/ld-x86-64/plt-main-bnd-now.rd: Likewise. * testsuite/ld-x86-64/plt2.dd: Likewise. * testsuite/ld-x86-64/plt2.rd: Likewise. * testsuite/ld-x86-64/plt2.s: Likewise. * testsuite/ld-x86-64/pr20830a-now.d: Likewise. * testsuite/ld-x86-64/pr20830b-now.d: Likewise. * testsuite/ld-x86-64/pr21038a-now.d: Likewise. * testsuite/ld-x86-64/pr21038b-now.d: Likewise. * testsuite/ld-x86-64/pr21038c-now.d: Likewise. * testsuite/ld-x86-64/load1b-nacl.d: Updated. * testsuite/ld-x86-64/load1b.d: Likewise. * testsuite/ld-x86-64/plt-main-bnd.dd: Likewise. * testsuite/ld-x86-64/pr20253-1h.d: Likewise. * testsuite/ld-x86-64/pr20830a.d: Update the .plt.got section with func@plt. * testsuite/ld-x86-64/pr20830b.d: Likewise. * testsuite/ld-x86-64/pr21038a.d: Likewise. * testsuite/ld-x86-64/pr21038c.d: Likewise. * testsuite/ld-x86-64/mpx.exp: Add some -z now tests. * testsuite/ld-x86-64/x86-64.exp: Likewise.
139 lines
3.6 KiB
Plaintext
139 lines
3.6 KiB
Plaintext
# Expect script for ELF MPX tests.
|
|
# Copyright (C) 2013-2017 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.
|
|
#
|
|
|
|
# The following tests require running the executable generated by ld,
|
|
# or enough of a build environment to create a fully linked executable.
|
|
# This is not commonly available when testing a cross-built linker.
|
|
if ![isnative] {
|
|
return
|
|
}
|
|
|
|
# Only on Linux for now.
|
|
if ![istarget "x86_64-*-linux*"] {
|
|
return
|
|
}
|
|
|
|
# Check to see if the C compiler works
|
|
if { [which $CC] == 0 } {
|
|
return
|
|
}
|
|
|
|
# Add $PLT_CFLAGS if PLT is expected.
|
|
global PLT_CFLAGS
|
|
|
|
run_cc_link_tests [list \
|
|
[list \
|
|
"Build libmpx1a.a" \
|
|
"" \
|
|
"-Wa,-madd-bnd-prefix -fPIC $PLT_CFLAGS" \
|
|
{mpx1a.c} \
|
|
{{readelf {-r --wide} mpx1a.rd}} \
|
|
"libmpx1a.a" \
|
|
] \
|
|
[list \
|
|
"Build libmpx1b.a" \
|
|
"" \
|
|
"" \
|
|
{mpx1b.c} \
|
|
{} \
|
|
"libmpx1b.a" \
|
|
] \
|
|
[list \
|
|
"Build libmpx1c.a" \
|
|
"" \
|
|
"-Wa,-madd-bnd-prefix" \
|
|
{mpx1c.c} \
|
|
{{readelf {-r --wide} mpx1c.rd}} \
|
|
"libmpx1c.a" \
|
|
] \
|
|
[list \
|
|
"Build libmpx2a.a" \
|
|
"" \
|
|
"-Wa,-madd-bnd-prefix -fPIE $PLT_CFLAGS" \
|
|
{mpx2a.c} \
|
|
{{readelf {-r --wide} mpx2a.rd}} \
|
|
"libmpx2a.a" \
|
|
] \
|
|
[list \
|
|
"Build libmpx2b.a" \
|
|
"" \
|
|
"-fPIE" \
|
|
{mpx2b.c} \
|
|
{} \
|
|
"libmpx2b.a" \
|
|
] \
|
|
[list \
|
|
"Build libmpx2c.a" \
|
|
"" \
|
|
"-Wa,-madd-bnd-prefix -fPIE $PLT_CFLAGS" \
|
|
{mpx2c.c} \
|
|
{{readelf {-r --wide} mpx2c.rd}} \
|
|
"libmpx2c.a" \
|
|
] \
|
|
]
|
|
|
|
set run_tests {
|
|
{"Run mpx1"
|
|
"tmpdir/mpx1a.o tmpdir/mpx1b.o tmpdir/mpx1c.o" ""
|
|
{dummy.s} "mpx1" "mpx1.out"}
|
|
{"Run mpx1 with -static"
|
|
"tmpdir/mpx1a.o tmpdir/mpx1b.o tmpdir/mpx1c.o -static" ""
|
|
{dummy.s} "mpx1static" "mpx1.out"}
|
|
{"Run mpx2"
|
|
"tmpdir/mpx2a.o tmpdir/mpx2b.o tmpdir/mpx2c.o -pie" ""
|
|
{dummy.s} "mpx2" "mpx2.out"}
|
|
{"Run mpx2 with -static"
|
|
"tmpdir/mpx2a.o tmpdir/mpx2b.o tmpdir/mpx2c.o -static" ""
|
|
{dummy.s} "mpx2static" "mpx2.out"}
|
|
}
|
|
|
|
run_ld_link_tests {
|
|
{"Build libcall.so"
|
|
"-m elf_x86_64 -shared -z bndplt" "" "--64"
|
|
{mpx3b.s} {} "libcall.so"}
|
|
{"Build mpx3"
|
|
"-m elf_x86_64 -z bndplt tmpdir/libcall.so" "" "--64"
|
|
{mpx3a.s} {{objdump -dw mpx3.dd}} "mpx3"}
|
|
{"Build libcall1.so"
|
|
"-m elf_x86_64 -shared -z bndplt" "" "--64"
|
|
{mpx4b.s} {} "libcall1.so"}
|
|
{"Build mpx4"
|
|
"-m elf_x86_64 -z bndplt tmpdir/libcall1.so" "" "--64"
|
|
{mpx4a.s} {{objdump -dw mpx4.dd}} "mpx4"}
|
|
{"Build mpx3 (-z now)"
|
|
"-z now -m elf_x86_64 -z bndplt tmpdir/libcall.so" "" "--64"
|
|
{mpx3a.s} {{objdump -dw mpx3n.dd}} "mpx3n"}
|
|
{"Build mpx4 (-z now)"
|
|
"-z now -m elf_x86_64 -z bndplt tmpdir/libcall1.so" "" "--64"
|
|
{mpx4a.s} {{objdump -dw mpx4n.dd}} "mpx4n"}
|
|
}
|
|
|
|
run_ld_link_exec_tests $run_tests
|
|
|
|
run_dump_test "bnd-branch-1"
|
|
run_dump_test "bnd-ifunc-1"
|
|
run_dump_test "bnd-ifunc-2"
|
|
run_dump_test "bnd-plt-1"
|
|
run_dump_test "bnd-branch-1-now"
|
|
run_dump_test "bnd-ifunc-1-now"
|
|
run_dump_test "bnd-ifunc-2-now"
|
|
run_dump_test "bnd-plt-1-now"
|