aboutsummaryrefslogtreecommitdiff
path: root/binutils/readelf.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2022-11-01 11:36:04 -0700
committerH.J. Lu <hjl.tools@gmail.com>2023-09-29 07:58:53 -0700
commit832ca732b8a96ff9a3e7c4abf24098bf2a59a96d (patch)
tree5ee140bdc26d1d37696b865c80becee32ecde8c6 /binutils/readelf.c
parenta78c3c9717e8fa98b11482f948e71c6d1d9d0e44 (diff)
downloadbinutils-832ca732b8a96ff9a3e7c4abf24098bf2a59a96d.zip
binutils-832ca732b8a96ff9a3e7c4abf24098bf2a59a96d.tar.gz
binutils-832ca732b8a96ff9a3e7c4abf24098bf2a59a96d.tar.bz2
x86-64: Add -z mark-plt and -z nomark-plt
The PLT entry in executables and shared libraries contains an indirect branch, like jmp *foo@GOTPCREL(%rip) push $index_foo jmp .PLT0 or endbr64 jmp *foo@GOTPCREL(%rip) NOP padding which is used to branch to the function, foo, defined in another object. Each R_X86_64_JUMP_SLOT relocation has a corresponding PLT entry. The dynamic tags have been added to the x86-64 psABI to mark such PLT entries: https://gitlab.com/x86-psABIs/x86-64-ABI/-/commit/6d824a52a42d173eb838b879616c1be5870b593e Add an x86-64 linker option, -z mark-plt, to mark PLT entries with #define DT_X86_64_PLT (DT_LOPROC + 0) #define DT_X86_64_PLTSZ (DT_LOPROC + 1) #define DT_X86_64_PLTENT (DT_LOPROC + 3) 1. DT_X86_64_PLT: The address of the procedure linkage table. 2. DT_X86_64_PLTSZ: The total size, in bytes, of the procedure linkage table. 3. DT_X86_64_PLTENT: The size, in bytes, of a procedure linkage table entry. and set the r_addend field of the R_X86_64_JUMP_SLOT relocation to the memory offset of the indirect branch instruction. The dynamic linker can use these tags to update the PLT section to direct branch. bfd/ * elf-linker-x86.h (elf_linker_x86_params): Add mark_plt. * elf64-x86-64.c (elf_x86_64_finish_dynamic_symbol): Set the r_addend of R_X86_64_JUMP_SLOT to the indirect branch offset in PLT entry for -z mark-plt. * elfxx-x86.c (_bfd_x86_elf_size_dynamic_sections): Add DT_X86_64_PLT, DT_X86_64_PLTSZ and DT_X86_64_PLTENT for -z mark-plt. (_bfd_x86_elf_finish_dynamic_sections): Set DT_X86_64_PLT, DT_X86_64_PLTSZ and DT_X86_64_PLTENT. (_bfd_x86_elf_get_synthetic_symtab): Ignore addend for JUMP_SLOT relocation. (_bfd_x86_elf_link_setup_gnu_properties): Set plt_indirect_branch_offset. * elfxx-x86.h (elf_x86_plt_layout): Add plt_indirect_branch_offset. binutils/ * readelf.c (get_x86_64_dynamic_type): New function. (get_dynamic_type): Call get_x86_64_dynamic_type. include/ * elf/x86-64.h (DT_X86_64_PLT): New. (DT_X86_64_PLTSZ): Likewise. (DT_X86_64_PLTENT): Likewise. ld/ * ld.texi: Document -z mark-plt and -z nomark-plt. * emulparams/elf32_x86_64.sh: Source x86-64-plt.sh. * emulparams/elf_x86_64.sh: Likewise. * emulparams/x86-64-plt.sh: New file. * testsuite/ld-x86-64/mark-plt-1.s: Likewise. * testsuite/ld-x86-64/mark-plt-1a-x32.d: Likewise. * testsuite/ld-x86-64/mark-plt-1a.d: Likewise. * testsuite/ld-x86-64/mark-plt-1b-x32.d: Likewise. * testsuite/ld-x86-64/mark-plt-1b.d: Likewise. * testsuite/ld-x86-64/mark-plt-1c-x32.d: Likewise. * testsuite/ld-x86-64/mark-plt-1c.d: Likewise. * testsuite/ld-x86-64/mark-plt-1d-x32.d: Likewise. * testsuite/ld-x86-64/mark-plt-1d.d: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run -z mark-plt tests.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r--binutils/readelf.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c
index be2f385..c9b6210 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -2523,6 +2523,22 @@ get_riscv_dynamic_type (unsigned long type)
}
static const char *
+get_x86_64_dynamic_type (unsigned long type)
+{
+ switch (type)
+ {
+ case DT_X86_64_PLT:
+ return "DT_X86_64_PLT";
+ case DT_X86_64_PLTSZ:
+ return "DT_X86_64_PLTSZ";
+ case DT_X86_64_PLTENT:
+ return "DT_X86_64_PLTENT";
+ default:
+ return NULL;
+ }
+}
+
+static const char *
get_dynamic_type (Filedata * filedata, unsigned long type)
{
static char buff[64];
@@ -2650,6 +2666,9 @@ get_dynamic_type (Filedata * filedata, unsigned long type)
case EM_RISCV:
result = get_riscv_dynamic_type (type);
break;
+ case EM_X86_64:
+ result = get_x86_64_dynamic_type (type);
+ break;
default:
if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
result = get_solaris_dynamic_type (type);