diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2022-11-01 11:36:04 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2023-09-29 07:58:53 -0700 |
commit | 832ca732b8a96ff9a3e7c4abf24098bf2a59a96d (patch) | |
tree | 5ee140bdc26d1d37696b865c80becee32ecde8c6 /binutils | |
parent | a78c3c9717e8fa98b11482f948e71c6d1d9d0e44 (diff) | |
download | gdb-832ca732b8a96ff9a3e7c4abf24098bf2a59a96d.zip gdb-832ca732b8a96ff9a3e7c4abf24098bf2a59a96d.tar.gz gdb-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')
-rw-r--r-- | binutils/readelf.c | 19 |
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); |