]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86: Treat protected symbols with indirect external access as local
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 8 Aug 2025 01:04:47 +0000 (18:04 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Sat, 9 Aug 2025 15:56:43 +0000 (08:56 -0700)
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
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/pr33260.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr33260.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr33260-x32.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr33260.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr33260.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 88bfa05bce20cf8e140db54239d92060e80b135e..05c416fdf26cf104525e3d313f1c60fac6f80c51 100644 (file)
                   || (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
index 6366457cd08fe6c628b0f7775895cc1a72fcdd07..0d653e90627444ce1164a3f92c34ea00135fede1 100644 (file)
@@ -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 (file)
index 0000000..4b1755d
--- /dev/null
@@ -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 (file)
index 0000000..9d779f2
--- /dev/null
@@ -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 (file)
index 0000000..d45e42d
--- /dev/null
@@ -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 (file)
index 0000000..d98c165
--- /dev/null
@@ -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 (file)
index 0000000..e48c3ce
--- /dev/null
@@ -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
index 3d873a79b789d9f0e01a3cb15fd74568d7f3278d..f3fdf023cb2ec3b20e7edfa779206c90f5b9c72b 100644 (file)
@@ -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"