public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2] x86-64: Add -z mark-plt and -z nomark-plt
@ 2023-09-27 17:19 H.J. Lu
  2023-09-28  6:00 ` Jan Beulich
  2023-09-28  6:07 ` Jan Beulich
  0 siblings, 2 replies; 6+ messages in thread
From: H.J. Lu @ 2023-09-27 17:19 UTC (permalink / raw)
  To: binutils

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.
---
 bfd/elf-linker-x86.h                     |  3 ++
 bfd/elf64-x86-64.c                       |  7 +++-
 bfd/elfxx-x86.c                          | 47 +++++++++++++++++++++++-
 bfd/elfxx-x86.h                          |  3 ++
 binutils/readelf.c                       | 19 ++++++++++
 include/elf/x86-64.h                     |  5 +++
 ld/emulparams/elf32_x86_64.sh            |  1 +
 ld/emulparams/elf_x86_64.sh              |  1 +
 ld/emulparams/x86-64-plt.sh              | 14 +++++++
 ld/ld.texi                               |  5 +++
 ld/testsuite/ld-x86-64/mark-plt-1.s      |  7 ++++
 ld/testsuite/ld-x86-64/mark-plt-1a-x32.d | 12 ++++++
 ld/testsuite/ld-x86-64/mark-plt-1a.d     | 12 ++++++
 ld/testsuite/ld-x86-64/mark-plt-1b-x32.d | 16 ++++++++
 ld/testsuite/ld-x86-64/mark-plt-1b.d     | 16 ++++++++
 ld/testsuite/ld-x86-64/mark-plt-1c-x32.d | 12 ++++++
 ld/testsuite/ld-x86-64/mark-plt-1c.d     | 12 ++++++
 ld/testsuite/ld-x86-64/mark-plt-1d-x32.d | 16 ++++++++
 ld/testsuite/ld-x86-64/mark-plt-1d.d     | 16 ++++++++
 ld/testsuite/ld-x86-64/x86-64.exp        |  8 ++++
 20 files changed, 230 insertions(+), 2 deletions(-)
 create mode 100644 ld/emulparams/x86-64-plt.sh
 create mode 100644 ld/testsuite/ld-x86-64/mark-plt-1.s
 create mode 100644 ld/testsuite/ld-x86-64/mark-plt-1a-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/mark-plt-1a.d
 create mode 100644 ld/testsuite/ld-x86-64/mark-plt-1b-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/mark-plt-1b.d
 create mode 100644 ld/testsuite/ld-x86-64/mark-plt-1c-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/mark-plt-1c.d
 create mode 100644 ld/testsuite/ld-x86-64/mark-plt-1d-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/mark-plt-1d.d

diff --git a/bfd/elf-linker-x86.h b/bfd/elf-linker-x86.h
index e39dbf21a4f..1e6ecb1bd3b 100644
--- a/bfd/elf-linker-x86.h
+++ b/bfd/elf-linker-x86.h
@@ -61,6 +61,9 @@ struct elf_linker_x86_params
   /* Report relative relocations.  */
   unsigned int report_relative_reloc : 1;
 
+  /* Mark PLT with dynamic tags.  */
+  unsigned int mark_plt : 1;
+
   /* X86-64 ISA level needed.  */
   unsigned int isa_level;
 
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index e7a0a9166f5..3b7a8aeee11 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -4455,7 +4455,12 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
 	  else
 	    {
 	      rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT);
-	      rela.r_addend = 0;
+	      if (htab->params->mark_plt)
+		rela.r_addend = (resolved_plt->output_section->vma
+				 + plt_offset
+				 + htab->plt.plt_indirect_branch_offset);
+	      else
+		rela.r_addend = 0;
 	      plt_index = htab->next_jump_slot_index++;
 	    }
 
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 103559d77ec..58bd76dc6fc 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -2525,6 +2525,19 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
 	}
     }
 
+  asection *resolved_plt = NULL;
+
+  if (htab->params->mark_plt && htab->elf.dynamic_sections_created)
+    {
+      if (htab->plt_second != NULL)
+	resolved_plt = htab->plt_second;
+      else
+	resolved_plt = htab->elf.splt;
+
+      if (resolved_plt != NULL && resolved_plt->size == 0)
+	resolved_plt = NULL;
+    }
+
   /* We now have determined the sizes of the various dynamic sections.
      Allocate memory for them.  */
   relocs = false;
@@ -2673,6 +2686,12 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
 	_bfd_x86_elf_write_sframe_plt (output_bfd, info, SFRAME_PLT_SEC);
     }
 
+  if (resolved_plt != NULL
+      && (!_bfd_elf_add_dynamic_entry (info, DT_X86_64_PLT, 0)
+	  || !_bfd_elf_add_dynamic_entry (info, DT_X86_64_PLTSZ, 0)
+	  || !_bfd_elf_add_dynamic_entry (info, DT_X86_64_PLTENT, 0)))
+    return false;
+
   return _bfd_elf_maybe_vxworks_add_dynamic_tags (output_bfd, info,
 						  relocs);
 }
@@ -2747,6 +2766,12 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
   if (sdyn == NULL || htab->elf.sgot == NULL)
     abort ();
 
+  asection *resolved_plt;
+  if (htab->plt_second != NULL)
+    resolved_plt = htab->plt_second;
+  else
+    resolved_plt = htab->elf.splt;
+
   sizeof_dyn = bed->s->sizeof_dyn;
   dyncon = sdyn->contents;
   dynconend = sdyn->contents + sdyn->size;
@@ -2791,6 +2816,19 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
 	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
 	    + htab->elf.tlsdesc_got;
 	  break;
+
+	case DT_X86_64_PLT:
+	  s = resolved_plt->output_section;
+	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+	  break;
+
+	case DT_X86_64_PLTSZ:
+	  dyn.d_un.d_val = resolved_plt->size;
+	  break;
+
+	case DT_X86_64_PLTENT:
+	  dyn.d_un.d_ptr = htab->plt.plt_entry_size;
+	  break;
 	}
 
       (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon);
@@ -3561,6 +3599,7 @@ _bfd_x86_elf_get_synthetic_symtab (bfd *abfd,
   bfd_vma (*get_plt_got_vma) (struct elf_x86_plt *, bfd_vma, bfd_vma,
 			      bfd_vma);
   bool (*valid_plt_reloc_p) (unsigned int);
+  unsigned int jump_slot_reloc;
 
   dynrelbuf = NULL;
   if (count == 0)
@@ -3601,11 +3640,13 @@ _bfd_x86_elf_get_synthetic_symtab (bfd *abfd,
     {
       get_plt_got_vma = elf_x86_64_get_plt_got_vma;
       valid_plt_reloc_p = elf_x86_64_valid_plt_reloc_p;
+      jump_slot_reloc = R_X86_64_JUMP_SLOT;
     }
   else
     {
       get_plt_got_vma = elf_i386_get_plt_got_vma;
       valid_plt_reloc_p = elf_i386_valid_plt_reloc_p;
+      jump_slot_reloc = R_386_JUMP_SLOT;
       if (got_addr)
 	{
 	  /* Check .got.plt and then .got to get the _GLOBAL_OFFSET_TABLE_
@@ -3710,7 +3751,9 @@ _bfd_x86_elf_get_synthetic_symtab (bfd *abfd,
 		len = strlen ((*p->sym_ptr_ptr)->name);
 		memcpy (names, (*p->sym_ptr_ptr)->name, len);
 		names += len;
-		if (p->addend != 0)
+		/* There may be JUMP_SLOT and IRELATIVE relocations.
+		   JUMP_SLOT r_addend should be ignored.  */
+		if (p->addend != 0 && p->howto->type != jump_slot_reloc)
 		  {
 		    char buf[30], *a;
 
@@ -4275,6 +4318,7 @@ _bfd_x86_elf_link_setup_gnu_properties
      still be used with LD_AUDIT or LD_PROFILE if PLT entry is used for
      canonical function address.  */
   htab->plt.has_plt0 = 1;
+  htab->plt.plt_indirect_branch_offset = 0;
   normal_target = htab->elf.target_os == is_normal;
 
   if (normal_target)
@@ -4283,6 +4327,7 @@ _bfd_x86_elf_link_setup_gnu_properties
 	{
 	  htab->lazy_plt = init_table->lazy_ibt_plt;
 	  htab->non_lazy_plt = init_table->non_lazy_ibt_plt;
+	  htab->plt.plt_indirect_branch_offset = 4;
 	}
       else
 	{
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index 3b4644ca478..0bc966b1274 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -502,6 +502,9 @@ struct elf_x86_plt_layout
   /* 1 has PLT0.  */
   unsigned int has_plt0;
 
+  /* Offset of indirect branch in plt_entry.  */
+  unsigned int plt_indirect_branch_offset;
+
   /* Offsets into plt_entry that are to be replaced with...  */
   unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
 
diff --git a/binutils/readelf.c b/binutils/readelf.c
index e9935c010cf..34ac6b62443 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -2522,6 +2522,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)
 {
@@ -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);
diff --git a/include/elf/x86-64.h b/include/elf/x86-64.h
index 60b3c2ad10e..1b87beef41a 100644
--- a/include/elf/x86-64.h
+++ b/include/elf/x86-64.h
@@ -95,4 +95,9 @@ END_RELOC_NUMBERS (R_X86_64_max)
 #define SHN_X86_64_LCOMMON 	(SHN_LORESERVE + 2)
 
 #define SHF_X86_64_LARGE	0x10000000
+
+#define DT_X86_64_PLT		(DT_LOPROC + 0)
+#define DT_X86_64_PLTSZ		(DT_LOPROC + 1)
+#define DT_X86_64_PLTENT	(DT_LOPROC + 3)
+
 #endif
diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh
index 4bff41287c1..f6c6de9cc9e 100644
--- a/ld/emulparams/elf32_x86_64.sh
+++ b/ld/emulparams/elf32_x86_64.sh
@@ -6,6 +6,7 @@ source_sh ${srcdir}/emulparams/call_nop.sh
 source_sh ${srcdir}/emulparams/cet.sh
 source_sh ${srcdir}/emulparams/x86-report-relative.sh
 source_sh ${srcdir}/emulparams/x86-64-level.sh
+source_sh ${srcdir}/emulparams/x86-64-plt.sh
 source_sh ${srcdir}/emulparams/static.sh
 source_sh ${srcdir}/emulparams/dt-relr.sh
 SCRIPT_NAME=elf
diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh
index a689a7b6dc4..466da2c48ca 100644
--- a/ld/emulparams/elf_x86_64.sh
+++ b/ld/emulparams/elf_x86_64.sh
@@ -7,6 +7,7 @@ source_sh ${srcdir}/emulparams/cet.sh
 source_sh ${srcdir}/emulparams/x86-report-relative.sh
 source_sh ${srcdir}/emulparams/x86-64-level.sh
 source_sh ${srcdir}/emulparams/x86-64-lam.sh
+source_sh ${srcdir}/emulparams/x86-64-plt.sh
 source_sh ${srcdir}/emulparams/static.sh
 source_sh ${srcdir}/emulparams/dt-relr.sh
 SCRIPT_NAME=elf
diff --git a/ld/emulparams/x86-64-plt.sh b/ld/emulparams/x86-64-plt.sh
new file mode 100644
index 00000000000..92732401dc7
--- /dev/null
+++ b/ld/emulparams/x86-64-plt.sh
@@ -0,0 +1,14 @@
+PARSE_AND_LIST_OPTIONS_X86_64_PLT='
+  fprintf (file, _("\
+  -z mark-plt                 Mark PLT with dynamic tags\n\
+  -z nomark-plt               Do not mark PLT with dynamic tags (default)\n"));
+'
+PARSE_AND_LIST_ARGS_CASE_Z_X86_64_PLT='
+      else if (strcmp (optarg, "mark-plt") == 0)
+	params.mark_plt = 1;
+      else if (strcmp (optarg, "nomark-plt") == 0)
+	params.mark_plt = 0;
+'
+
+PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_X86_64_PLT"
+PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_X86_64_PLT"
diff --git a/ld/ld.texi b/ld/ld.texi
index 24e9debfb5f..15e4ae34dbf 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -1475,6 +1475,11 @@ Specify that the object's filters be processed immediately at runtime.
 @item max-page-size=@var{value}
 Set the maximum memory page size supported to @var{value}.
 
+@item mark-plt
+@itemx nomark-plt
+Mark PLT entries with dynamic tags, DT_X86_64_PLT, DT_X86_64_PLTSZ and
+DT_X86_64_PLTENT.  Supported for x86_64.
+
 @item muldefs
 Allow multiple definitions.
 
diff --git a/ld/testsuite/ld-x86-64/mark-plt-1.s b/ld/testsuite/ld-x86-64/mark-plt-1.s
new file mode 100644
index 00000000000..e3f03c89b51
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-1.s
@@ -0,0 +1,7 @@
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	call	bar@PLT
+	ret
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/mark-plt-1a-x32.d b/ld/testsuite/ld-x86-64/mark-plt-1a-x32.d
new file mode 100644
index 00000000000..2051356be73
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-1a-x32.d
@@ -0,0 +1,12 @@
+#source: mark-plt-1.s
+#as: --x32
+#ld: -melf32_x86_64 -shared -z mark-plt
+#readelf: -drW
+
+#...
+ 0x70000000 \(DT_X86_64_PLT\)              0x1000
+ 0x70000001 \(DT_X86_64_PLTSZ\)            0x20
+ 0x70000003 \(DT_X86_64_PLTENT\)           0x10
+#...
+[0-9a-f ]+R_X86_64_JUMP_SLOT +0+ +bar \+ 1010
+#pass
diff --git a/ld/testsuite/ld-x86-64/mark-plt-1a.d b/ld/testsuite/ld-x86-64/mark-plt-1a.d
new file mode 100644
index 00000000000..a252e95e759
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-1a.d
@@ -0,0 +1,12 @@
+#source: mark-plt-1.s
+#as: --64
+#ld: -melf_x86_64 -shared -z mark-plt
+#readelf: -drW
+
+#...
+ 0x0000000070000000 \(DT_X86_64_PLT\)      0x1000
+ 0x0000000070000001 \(DT_X86_64_PLTSZ\)    0x20
+ 0x0000000070000003 \(DT_X86_64_PLTENT\)   0x10
+#...
+[0-9a-f ]+R_X86_64_JUMP_SLOT +0+ +bar \+ 1010
+#pass
diff --git a/ld/testsuite/ld-x86-64/mark-plt-1b-x32.d b/ld/testsuite/ld-x86-64/mark-plt-1b-x32.d
new file mode 100644
index 00000000000..74306a0d8d7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-1b-x32.d
@@ -0,0 +1,16 @@
+#source: mark-plt-1.s
+#as: --x32
+#ld: -melf32_x86_64 -shared -z mark-plt
+#objdump: -dw
+
+#...
+0+1010 <bar@plt>:
+ +1010:	ff 25 9a 10 00 00    	jmp    \*0x109a\(%rip\)        # 20b0 <bar>
+ +1016:	68 00 00 00 00       	push   \$0x0
+ +101b:	e9 e0 ff ff ff       	jmp    1000 <bar@plt-0x10>
+
+Disassembly of section .text:
+
+0+1020 <foo>:
+ +1020:	e8 eb ff ff ff       	call   1010 <bar@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/mark-plt-1b.d b/ld/testsuite/ld-x86-64/mark-plt-1b.d
new file mode 100644
index 00000000000..dc046c031eb
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-1b.d
@@ -0,0 +1,16 @@
+#source: mark-plt-1.s
+#as: --64
+#ld: -melf_x86_64 -shared -z mark-plt
+#objdump: -dw
+
+#...
+0+1010 <bar@plt>:
+ +1010:	ff 25 32 11 00 00    	jmp    \*0x1132\(%rip\)        # 2148 <bar>
+ +1016:	68 00 00 00 00       	push   \$0x0
+ +101b:	e9 e0 ff ff ff       	jmp    1000 <bar@plt-0x10>
+
+Disassembly of section .text:
+
+0+1020 <foo>:
+ +1020:	e8 eb ff ff ff       	call   1010 <bar@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/mark-plt-1c-x32.d b/ld/testsuite/ld-x86-64/mark-plt-1c-x32.d
new file mode 100644
index 00000000000..6354dc3bd95
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-1c-x32.d
@@ -0,0 +1,12 @@
+#source: mark-plt-1.s
+#as: --x32
+#ld: -melf32_x86_64 -shared -z mark-plt -z ibtplt
+#readelf: -drW
+
+#...
+ 0x70000000 \(DT_X86_64_PLT\)              0x1020
+ 0x70000001 \(DT_X86_64_PLTSZ\)            0x10
+ 0x70000003 \(DT_X86_64_PLTENT\)           0x10
+#...
+[0-9a-f ]+R_X86_64_JUMP_SLOT +0+ +bar \+ 1024
+#pass
diff --git a/ld/testsuite/ld-x86-64/mark-plt-1c.d b/ld/testsuite/ld-x86-64/mark-plt-1c.d
new file mode 100644
index 00000000000..e11e0b7a758
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-1c.d
@@ -0,0 +1,12 @@
+#source: mark-plt-1.s
+#as: --64
+#ld: -melf_x86_64 -shared -z mark-plt -z ibtplt
+#readelf: -drW
+
+#...
+ 0x0000000070000000 \(DT_X86_64_PLT\)      0x1020
+ 0x0000000070000001 \(DT_X86_64_PLTSZ\)    0x10
+ 0x0000000070000003 \(DT_X86_64_PLTENT\)   0x10
+#...
+[0-9a-f ]+R_X86_64_JUMP_SLOT +0+ +bar \+ 1024
+#pass
diff --git a/ld/testsuite/ld-x86-64/mark-plt-1d-x32.d b/ld/testsuite/ld-x86-64/mark-plt-1d-x32.d
new file mode 100644
index 00000000000..318ca1f0931
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-1d-x32.d
@@ -0,0 +1,16 @@
+#source: mark-plt-1.s
+#as: --x32
+#ld: -melf32_x86_64 -shared -z mark-plt -z ibtplt
+#objdump: -dw
+
+#...
+0+1020 <bar@plt>:
+ +1020:	f3 0f 1e fa          	endbr64
+ +1024:	ff 25 86 10 00 00    	jmp    \*0x1086\(%rip\)        # 20b0 <bar>
+ +102a:	66 0f 1f 44 00 00    	nopw   0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+1030 <foo>:
+ +1030:	e8 eb ff ff ff       	call   1020 <bar@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/mark-plt-1d.d b/ld/testsuite/ld-x86-64/mark-plt-1d.d
new file mode 100644
index 00000000000..2dd63bc10b7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mark-plt-1d.d
@@ -0,0 +1,16 @@
+#source: mark-plt-1.s
+#as: --64
+#ld: -melf_x86_64 -shared -z mark-plt -z ibtplt
+#objdump: -dw
+
+#...
+0+1020 <bar@plt>:
+ +1020:	f3 0f 1e fa          	endbr64
+ +1024:	ff 25 1e 11 00 00    	jmp    \*0x111e\(%rip\)        # 2148 <bar>
+ +102a:	66 0f 1f 44 00 00    	nopw   0x0\(%rax,%rax,1\)
+
+Disassembly of section .text:
+
+0+1030 <foo>:
+ +1030:	e8 eb ff ff ff       	call   1020 <bar@plt>
+#pass
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index f94284b079c..3dc8cb47192 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -2228,5 +2228,13 @@ run_dump_test "ibt-plt-3a-x32"
 run_dump_test "ibt-plt-3b-x32"
 run_dump_test "ibt-plt-3c-x32"
 run_dump_test "ibt-plt-3d-x32"
+run_dump_test "mark-plt-1a"
+run_dump_test "mark-plt-1b"
+run_dump_test "mark-plt-1c"
+run_dump_test "mark-plt-1d"
+run_dump_test "mark-plt-1a-x32"
+run_dump_test "mark-plt-1b-x32"
+run_dump_test "mark-plt-1c-x32"
+run_dump_test "mark-plt-1d-x32"
 
 set ASFLAGS "$saved_ASFLAGS"
-- 
2.41.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] x86-64: Add -z mark-plt and -z nomark-plt
  2023-09-27 17:19 [PATCH v2] x86-64: Add -z mark-plt and -z nomark-plt H.J. Lu
@ 2023-09-28  6:00 ` Jan Beulich
  2023-09-28  6:07 ` Jan Beulich
  1 sibling, 0 replies; 6+ messages in thread
From: Jan Beulich @ 2023-09-28  6:00 UTC (permalink / raw)
  To: H.J. Lu

On 27.09.2023 19:19, H.J. Lu via Binutils wrote:
> --- a/ld/ld.texi
> +++ b/ld/ld.texi
> @@ -1475,6 +1475,11 @@ Specify that the object's filters be processed immediately at runtime.
>  @item max-page-size=@var{value}
>  Set the maximum memory page size supported to @var{value}.
>  
> +@item mark-plt
> +@itemx nomark-plt
> +Mark PLT entries with dynamic tags, DT_X86_64_PLT, DT_X86_64_PLTSZ and
> +DT_X86_64_PLTENT.  Supported for x86_64.

Hmm, you use backwards compatibility issues as justification for not having
a configure time way to default the new behavior to enabled, and then you
don't mention the backwards compatibility aspect here?

Jan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] x86-64: Add -z mark-plt and -z nomark-plt
  2023-09-27 17:19 [PATCH v2] x86-64: Add -z mark-plt and -z nomark-plt H.J. Lu
  2023-09-28  6:00 ` Jan Beulich
@ 2023-09-28  6:07 ` Jan Beulich
  2023-09-28  7:02   ` Fangrui Song
  2023-09-28 14:52   ` H.J. Lu
  1 sibling, 2 replies; 6+ messages in thread
From: Jan Beulich @ 2023-09-28  6:07 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

On 27.09.2023 19:19, H.J. Lu via Binutils wrote:
> --- a/ld/ld.texi
> +++ b/ld/ld.texi
> @@ -1475,6 +1475,11 @@ Specify that the object's filters be processed immediately at runtime.
>  @item max-page-size=@var{value}
>  Set the maximum memory page size supported to @var{value}.
>  
> +@item mark-plt
> +@itemx nomark-plt
> +Mark PLT entries with dynamic tags, DT_X86_64_PLT, DT_X86_64_PLTSZ and
> +DT_X86_64_PLTENT.  Supported for x86_64.

Hmm, you use backwards compatibility issues as justification for not having
a configure time way to default the new behavior to enabled, and then you
don't mention the backwards compatibility aspect here?

Jan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] x86-64: Add -z mark-plt and -z nomark-plt
  2023-09-28  6:07 ` Jan Beulich
@ 2023-09-28  7:02   ` Fangrui Song
  2023-09-28 14:52   ` H.J. Lu
  1 sibling, 0 replies; 6+ messages in thread
From: Fangrui Song @ 2023-09-28  7:02 UTC (permalink / raw)
  To: Jan Beulich; +Cc: H.J. Lu, binutils

On Wed, Sep 27, 2023 at 11:07 PM Jan Beulich via Binutils
<binutils@sourceware.org> wrote:
>
> On 27.09.2023 19:19, H.J. Lu via Binutils wrote:
> > --- a/ld/ld.texi
> > +++ b/ld/ld.texi
> > @@ -1475,6 +1475,11 @@ Specify that the object's filters be processed immediately at runtime.
> >  @item max-page-size=@var{value}
> >  Set the maximum memory page size supported to @var{value}.
> >
> > +@item mark-plt
> > +@itemx nomark-plt
> > +Mark PLT entries with dynamic tags, DT_X86_64_PLT, DT_X86_64_PLTSZ and
> > +DT_X86_64_PLTENT.  Supported for x86_64.
>
> Hmm, you use backwards compatibility issues as justification for not having
> a configure time way to default the new behavior to enabled, and then you
> don't mention the backwards compatibility aspect here?
>
> Jan

For linker defaults, they can be performed either on the linker side
or on the compiler driver side.
If GCC specifies an extra option to ld (like -z relro -z now), I think
it is fine for ld not to have a configure-time option.
(I understand that someone may argue that patching ld has a greater
coverage... I typically refute such arguments. This mark-plt is for a
rtld optimization that unlikely applies to the programs that directly
use ld anyway.)

At least for LLD that I maintain, we prefer not to have
target-specific differences and prefer that the compiler drivers pass
relevant options to the linker.
Linker not having to deal with too many defaults allows testing more
address-related properties in the output, which I find valuable to
catch many bugs without doing distribution testing.
(https://sourceware.org/bugzilla/show_bug.cgi?id=28602)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] x86-64: Add -z mark-plt and -z nomark-plt
  2023-09-28  6:07 ` Jan Beulich
  2023-09-28  7:02   ` Fangrui Song
@ 2023-09-28 14:52   ` H.J. Lu
  2023-09-28 14:54     ` Jan Beulich
  1 sibling, 1 reply; 6+ messages in thread
From: H.J. Lu @ 2023-09-28 14:52 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Wed, Sep 27, 2023 at 11:07 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 27.09.2023 19:19, H.J. Lu via Binutils wrote:
> > --- a/ld/ld.texi
> > +++ b/ld/ld.texi
> > @@ -1475,6 +1475,11 @@ Specify that the object's filters be processed immediately at runtime.
> >  @item max-page-size=@var{value}
> >  Set the maximum memory page size supported to @var{value}.
> >
> > +@item mark-plt
> > +@itemx nomark-plt
> > +Mark PLT entries with dynamic tags, DT_X86_64_PLT, DT_X86_64_PLTSZ and
> > +DT_X86_64_PLTENT.  Supported for x86_64.
>
> Hmm, you use backwards compatibility issues as justification for not having
> a configure time way to default the new behavior to enabled, and then you
> don't mention the backwards compatibility aspect here?
>

How about this:

@item mark-plt
@itemx nomark-plt
Mark PLT entries with dynamic tags, DT_X86_64_PLT, DT_X86_64_PLTSZ and
DT_X86_64_PLTENT.  Since this option stores a non-zero value in the
r_addend field of R_X86_64_JUMP_SLOT relocations, the resulting
executables and shared libraries are incompatible with dynamic linkers,
such as those in older versions of glibc without the change to ignore
r_addend in R_X86_64_GLOB_DAT and R_X86_64_JUMP_SLOT relocations, which
don't ignore the r_addend field of R_X86_64_JUMP_SLOT relocations.
Supported for x86_64.

-- 
H.J.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] x86-64: Add -z mark-plt and -z nomark-plt
  2023-09-28 14:52   ` H.J. Lu
@ 2023-09-28 14:54     ` Jan Beulich
  0 siblings, 0 replies; 6+ messages in thread
From: Jan Beulich @ 2023-09-28 14:54 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

On 28.09.2023 16:52, H.J. Lu wrote:
> On Wed, Sep 27, 2023 at 11:07 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 27.09.2023 19:19, H.J. Lu via Binutils wrote:
>>> --- a/ld/ld.texi
>>> +++ b/ld/ld.texi
>>> @@ -1475,6 +1475,11 @@ Specify that the object's filters be processed immediately at runtime.
>>>  @item max-page-size=@var{value}
>>>  Set the maximum memory page size supported to @var{value}.
>>>
>>> +@item mark-plt
>>> +@itemx nomark-plt
>>> +Mark PLT entries with dynamic tags, DT_X86_64_PLT, DT_X86_64_PLTSZ and
>>> +DT_X86_64_PLTENT.  Supported for x86_64.
>>
>> Hmm, you use backwards compatibility issues as justification for not having
>> a configure time way to default the new behavior to enabled, and then you
>> don't mention the backwards compatibility aspect here?
>>
> 
> How about this:
> 
> @item mark-plt
> @itemx nomark-plt
> Mark PLT entries with dynamic tags, DT_X86_64_PLT, DT_X86_64_PLTSZ and
> DT_X86_64_PLTENT.  Since this option stores a non-zero value in the
> r_addend field of R_X86_64_JUMP_SLOT relocations, the resulting
> executables and shared libraries are incompatible with dynamic linkers,
> such as those in older versions of glibc without the change to ignore
> r_addend in R_X86_64_GLOB_DAT and R_X86_64_JUMP_SLOT relocations, which
> don't ignore the r_addend field of R_X86_64_JUMP_SLOT relocations.
> Supported for x86_64.

Reads okay to me, thanks.

Jan

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-09-28 14:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-27 17:19 [PATCH v2] x86-64: Add -z mark-plt and -z nomark-plt H.J. Lu
2023-09-28  6:00 ` Jan Beulich
2023-09-28  6:07 ` Jan Beulich
2023-09-28  7:02   ` Fangrui Song
2023-09-28 14:52   ` H.J. Lu
2023-09-28 14:54     ` Jan Beulich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).