[PATCH] x86: Treat protected symbols with indirect external access as local
H.J. Lu
hjl.tools@gmail.com
Sat Aug 9 15:56:13 GMT 2025
On Thu, Aug 7, 2025 at 6:04 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> 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.
I am checking it in.
> 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
>
--
H.J.
More information about the Binutils
mailing list