[binutils-gdb] x86: Treat protected symbols with indirect external access as local

H.J. Lu hjl@sourceware.org
Sat Aug 9 16:01:37 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ff3b64d944d711a306232928ebd3d049a8c70d65

commit ff3b64d944d711a306232928ebd3d049a8c70d65
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 7 18:04:47 2025 -0700

    x86: Treat protected symbols with indirect external access as local
    
    If all external symbol accesses are indirect, we can treat protected
    symbols as local since there will be no copy relocation for data and
    external function pointer access will go through GOT, instead of PLT.
    No PLT slot should be used for external function pointer in executable.
    
    bfd/
    
            PR ld/33260
            * elfxx-x86.h (COPY_INPUT_RELOC_P): Treat protected symbols with
            indirect external access as local.
    
    ld/
    
            PR ld/33260
            * testsuite/ld-i386/i386.exp: Run PR ld/33260 test.
            * testsuite/ld-x86-64/x86-64.exp: Likewise.
            * testsuite/ld-i386/pr33260.d: New file.
            * testsuite/ld-i386/pr33260.s: Likewise.
            * testsuite/ld-x86-64/pr33260-x32.d: Likewise.
            * testsuite/ld-x86-64/pr33260.d: Likewise.
            * testsuite/ld-x86-64/pr33260.s: Likewise.
    
    Signed-off-by: H.J. Lu <hjl.tools@gmail.com>

Diff:
---
 bfd/elfxx-x86.h                      |  8 +++++--
 ld/testsuite/ld-i386/i386.exp        |  1 +
 ld/testsuite/ld-i386/pr33260.d       |  9 +++++++
 ld/testsuite/ld-i386/pr33260.s       | 46 ++++++++++++++++++++++++++++++++++++
 ld/testsuite/ld-x86-64/pr33260-x32.d |  9 +++++++
 ld/testsuite/ld-x86-64/pr33260.d     |  9 +++++++
 ld/testsuite/ld-x86-64/pr33260.s     | 40 +++++++++++++++++++++++++++++++
 ld/testsuite/ld-x86-64/x86-64.exp    |  2 ++
 8 files changed, 122 insertions(+), 2 deletions(-)

diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index 88bfa05bce2..05c416fdf26 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -224,12 +224,16 @@
 		   || (EH)->elf.root.type == bfd_link_hash_undefined)))
 
 /* TRUE if this input relocation should be copied to output.  H->dynindx
-   may be -1 if this symbol was marked to become local.  */
+   may be -1 if this symbol was marked to become local.  STV_PROTECTED
+   symbols with indirect external access are local. */
 #define COPY_INPUT_RELOC_P(IS_X86_64, INFO, H, R_TYPE) \
   ((H) != NULL \
    && (H)->dynindx != -1 \
    && (X86_PCREL_TYPE_P (IS_X86_64, R_TYPE) \
-       || !(bfd_link_executable (INFO) || SYMBOLIC_BIND ((INFO), (H))) \
+       || !(bfd_link_executable (INFO) \
+	    || SYMBOLIC_BIND ((INFO), (H)) \
+	    || ((INFO)->indirect_extern_access > 0 \
+		&& ELF_ST_VISIBILITY ((H)->other) == STV_PROTECTED)) \
        || !(H)->def_regular))
 
 /* TRUE if this is actually a static link, or it is a -Bsymbolic link
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 6366457cd08..0d653e90627 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -520,6 +520,7 @@ run_dump_test "pr28894"
 run_dump_test "pr30787"
 run_dump_test "pr31047"
 run_dump_test "pr32191"
+run_dump_test "pr33260"
 
 if { !([istarget "i?86-*-linux*"]
        || [istarget "i?86-*-gnu*"]
diff --git a/ld/testsuite/ld-i386/pr33260.d b/ld/testsuite/ld-i386/pr33260.d
new file mode 100644
index 00000000000..4b1755d9938
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr33260.d
@@ -0,0 +1,9 @@
+#source: pr33260.s
+#as: -mrelax-relocations=yes --32
+#ld: -melf_i386 -shared -z indirect-extern-access
+#readelf: -r --wide
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_RELATIVE +
+[0-9a-f]+ +[0-9a-f]+ +R_386_RELATIVE +
diff --git a/ld/testsuite/ld-i386/pr33260.s b/ld/testsuite/ld-i386/pr33260.s
new file mode 100644
index 00000000000..9d779f20f26
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr33260.s
@@ -0,0 +1,46 @@
+	.text
+	.p2align 4
+	.globl	my_func
+	.protected	my_func
+	.type	my_func, @function
+my_func:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+	.size	my_func, .-my_func
+	.p2align 4
+	.globl	f
+	.type	f, @function
+f:
+	.cfi_startproc
+	call	__x86.get_pc_thunk.ax
+	addl	$_GLOBAL_OFFSET_TABLE_, %eax
+	leal	vtable@GOTOFF(%eax), %eax
+	ret
+	.cfi_endproc
+	.size	f, .-f
+	.section	.data.rel,"aw"
+	.align 4
+	.type	vtable, @object
+	.size	vtable, 8
+vtable:
+	.long	my_func
+	.long	my_data
+	.protected	my_data
+	.globl	my_data
+	.bss
+	.align 4
+	.type	my_data, @object
+	.size	my_data, 4
+my_data:
+	.zero	4
+	.section	.text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
+	.globl	__x86.get_pc_thunk.ax
+	.hidden	__x86.get_pc_thunk.ax
+	.type	__x86.get_pc_thunk.ax, @function
+__x86.get_pc_thunk.ax:
+	.cfi_startproc
+	movl	(%esp), %eax
+	ret
+	.cfi_endproc
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/pr33260-x32.d b/ld/testsuite/ld-x86-64/pr33260-x32.d
new file mode 100644
index 00000000000..d45e42dca3d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr33260-x32.d
@@ -0,0 +1,9 @@
+#source: pr33260.s
+#as: -mrelax-relocations=yes --x32
+#ld: -melf32_x86_64 -shared -z indirect-extern-access
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr33260.d b/ld/testsuite/ld-x86-64/pr33260.d
new file mode 100644
index 00000000000..d98c1658fa1
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr33260.d
@@ -0,0 +1,9 @@
+#source: pr33260.s
+#as: -mrelax-relocations=yes --64 -defsym __x86_64__=1
+#ld: -melf_x86_64 -shared -z indirect-extern-access
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Sym.* Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-x86-64/pr33260.s b/ld/testsuite/ld-x86-64/pr33260.s
new file mode 100644
index 00000000000..e48c3cee25a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr33260.s
@@ -0,0 +1,40 @@
+	.text
+	.p2align 4
+	.globl	my_func
+	.protected	my_func
+	.type	my_func, @function
+my_func:
+	.cfi_startproc
+	ret
+	.cfi_endproc
+	.size	my_func, .-my_func
+	.p2align 4
+	.globl	f
+	.type	f, @function
+f:
+	.cfi_startproc
+	leaq	vtable(%rip), %rax
+	ret
+	.cfi_endproc
+	.size	f, .-f
+	.section	.data.rel,"aw"
+	.type	vtable, @object
+.ifdef __x86_64__
+	.align 16
+	.size	vtable, 16
+.else
+	.align 8
+	.size	vtable, 8
+.endif
+vtable:
+	.dc.a	my_func
+	.dc.a	my_data
+	.protected	my_data
+	.globl	my_data
+	.bss
+	.align 4
+	.type	my_data, @object
+	.size	my_data, 4
+my_data:
+	.zero	4
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 3d873a79b78..f3fdf023cb2 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -564,6 +564,8 @@ run_dump_test "pr32591-3-x32"
 run_dump_test "pr32591-4"
 run_dump_test "pr32591-4-x32"
 run_dump_test "pr32809"
+run_dump_test "pr33260"
+run_dump_test "pr33260-x32"
 
 if { ![skip_sframe_tests] } {
     run_dump_test "sframe-simple-1"


More information about the Binutils-cvs mailing list