[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