[PATCH] x86: Treat protected symbols with indirect external access as local
H.J. Lu
hjl.tools@gmail.com
Fri Aug 8 01:04:47 GMT 2025
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>
---
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(-)
create mode 100644 ld/testsuite/ld-i386/pr33260.d
create mode 100644 ld/testsuite/ld-i386/pr33260.s
create mode 100644 ld/testsuite/ld-x86-64/pr33260-x32.d
create mode 100644 ld/testsuite/ld-x86-64/pr33260.d
create mode 100644 ld/testsuite/ld-x86-64/pr33260.s
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"
--
2.50.1
More information about the Binutils
mailing list