diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2025-08-07 18:04:47 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2025-08-09 08:56:43 -0700 |
commit | ff3b64d944d711a306232928ebd3d049a8c70d65 (patch) | |
tree | 41905b8d89e031733981e86093d7ecdb6f232d87 | |
parent | a65d0a432567c62618fc83b9d9647e4868d6f08d (diff) | |
download | binutils-ff3b64d944d711a306232928ebd3d049a8c70d65.zip binutils-ff3b64d944d711a306232928ebd3d049a8c70d65.tar.gz binutils-ff3b64d944d711a306232928ebd3d049a8c70d65.tar.bz2 |
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>
-rw-r--r-- | bfd/elfxx-x86.h | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/i386.exp | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr33260.d | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr33260.s | 46 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr33260-x32.d | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr33260.d | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr33260.s | 40 | ||||
-rw-r--r-- | 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 88bfa05..05c416f 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 6366457..0d653e9 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 0000000..4b1755d --- /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 0000000..9d779f2 --- /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 0000000..d45e42d --- /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 0000000..d98c165 --- /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 0000000..e48c3ce --- /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 3d873a7..f3fdf02 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" |