From 1d68a49ac5d71b648304f69af978fce0f4413800 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 23 Jul 2024 23:39:50 -0700 Subject: x86: Improve TLS transition error check Provide detailed TLS transition errors when unsupported instructions are used. Treat R_X86_64_CODE_4_GOTTPOFF and R_X86_64_CODE_6_GOTTPOFF as R_X86_64_GOTTPOFF when performing TLS transition. bfd/ PR ld/32017 * elf32-i386.c (elf_i386_check_tls_transition): Return different enums for different errors. (elf_i386_tls_transition): Change argument from r_symndx to sym. Call _bfd_x86_elf_link_report_tls_transition_error to report TLS transition errors. (elf_i386_scan_relocs): Pass isym instead of r_symndx to elf_i386_tls_transition. (elf_i386_relocate_section): Pass sym instead of r_symndx to elf_i386_tls_transition. * elf64-x86-64.c (elf_x86_64_check_tls_transition): Return different enums for different errors. (elf_x86_64_tls_transition): Change argument from r_symndx to sym. Treat R_X86_64_CODE_4_GOTTPOFF and R_X86_64_CODE_6_GOTTPOFF as R_X86_64_GOTTPOFF. Call _bfd_x86_elf_link_report_tls_transition_error to report TLS transition errors. (elf_x86_64_scan_relocs): Pass isym instead of r_symndx to elf_x86_64_tls_transition. (elf_x86_64_relocate_section): Pass sym instead of r_symndx to elf_x86_64_tls_transition. * elfxx-x86.c (_bfd_x86_elf_link_report_tls_transition_error): New. * elfxx-x86.h (elf_x86_tls_error_type): Likewise. (_bfd_x86_elf_link_report_tls_transition_error): Likewise. ld/ PR ld/32017 * testsuite/ld-i386/i386.exp: Run tlsgdesc1 and tlsgdesc2. * testsuite/ld-i386/tlsie2.d: Updated. * testsuite/ld-i386/tlsie3.d: Likewise. * testsuite/ld-i386/tlsie4.d: Likewise. * testsuite/ld-i386/tlsie5.d: Likewise. * testsuite/ld-x86-64/tlsie2.d: Likewise. * testsuite/ld-x86-64/tlsie3.d: Likewise. * testsuite/ld-i386/tlsgdesc1.d: New file. * testsuite/ld-i386/tlsgdesc1.s: Likewise. * testsuite/ld-i386/tlsgdesc2.d: Likewise. * testsuite/ld-i386/tlsgdesc2.s: Likewise. * testsuite/ld-x86-64/tlsdesc3.d: Likewise. * testsuite/ld-x86-64/tlsdesc3.s: Likewise. * testsuite/ld-x86-64/tlsdesc4.d: Likewise. * testsuite/ld-x86-64/tlsdesc4.s: Likewise. * testsuite/ld-x86-64/tlsie5.d: Likewise. * testsuite/ld-x86-64/tlsie5.s: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run tlsie5, tlsdesc3 and tlsdesc4. Signed-off-by: H.J. Lu --- ld/testsuite/ld-i386/i386.exp | 2 ++ ld/testsuite/ld-i386/tlsgdesc1.d | 4 ++++ ld/testsuite/ld-i386/tlsgdesc1.s | 11 +++++++++++ ld/testsuite/ld-i386/tlsgdesc2.d | 4 ++++ ld/testsuite/ld-i386/tlsgdesc2.s | 11 +++++++++++ ld/testsuite/ld-i386/tlsie2.d | 2 +- ld/testsuite/ld-i386/tlsie3.d | 2 +- ld/testsuite/ld-i386/tlsie4.d | 2 +- ld/testsuite/ld-i386/tlsie5.d | 2 +- ld/testsuite/ld-x86-64/tlsdesc3.d | 4 ++++ ld/testsuite/ld-x86-64/tlsdesc3.s | 13 +++++++++++++ ld/testsuite/ld-x86-64/tlsdesc4.d | 4 ++++ ld/testsuite/ld-x86-64/tlsdesc4.s | 13 +++++++++++++ ld/testsuite/ld-x86-64/tlsie2.d | 2 +- ld/testsuite/ld-x86-64/tlsie3.d | 2 +- ld/testsuite/ld-x86-64/tlsie5.d | 4 ++++ ld/testsuite/ld-x86-64/tlsie5.s | 12 ++++++++++++ ld/testsuite/ld-x86-64/x86-64.exp | 3 +++ 18 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 ld/testsuite/ld-i386/tlsgdesc1.d create mode 100644 ld/testsuite/ld-i386/tlsgdesc1.s create mode 100644 ld/testsuite/ld-i386/tlsgdesc2.d create mode 100644 ld/testsuite/ld-i386/tlsgdesc2.s create mode 100644 ld/testsuite/ld-x86-64/tlsdesc3.d create mode 100644 ld/testsuite/ld-x86-64/tlsdesc3.s create mode 100644 ld/testsuite/ld-x86-64/tlsdesc4.d create mode 100644 ld/testsuite/ld-x86-64/tlsdesc4.s create mode 100644 ld/testsuite/ld-x86-64/tlsie5.d create mode 100644 ld/testsuite/ld-x86-64/tlsie5.s (limited to 'ld') diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 5c9153f..d5f322d 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -544,6 +544,8 @@ run_dump_test "pr27998b" run_dump_test "pr31868a" run_dump_test "pr31868b" run_dump_test "pr31868c" +run_dump_test "tlsgdesc1" +run_dump_test "tlsgdesc2" proc undefined_weak {cflags ldflags} { set testname "Undefined weak symbol" diff --git a/ld/testsuite/ld-i386/tlsgdesc1.d b/ld/testsuite/ld-i386/tlsgdesc1.d new file mode 100644 index 0000000..2a70e81 --- /dev/null +++ b/ld/testsuite/ld-i386/tlsgdesc1.d @@ -0,0 +1,4 @@ +#name: TLS GDesc->LE transition check (LEA) +#as: --32 +#ld: -melf_i386 +#error: .*: relocation R_386_TLS_GOTDESC against `foo' must be used in LEA only diff --git a/ld/testsuite/ld-i386/tlsgdesc1.s b/ld/testsuite/ld-i386/tlsgdesc1.s new file mode 100644 index 0000000..c30f752 --- /dev/null +++ b/ld/testsuite/ld-i386/tlsgdesc1.s @@ -0,0 +1,11 @@ + .text + .globl _start +_start: + movl foo@tlsdesc(%ebx), %eax + call *foo@tlscall(%eax) + .section .tdata,"awT",@progbits + .align 4 + .type foo, @object + .size foo, 4 +foo: + .long 100 diff --git a/ld/testsuite/ld-i386/tlsgdesc2.d b/ld/testsuite/ld-i386/tlsgdesc2.d new file mode 100644 index 0000000..2e6a66d --- /dev/null +++ b/ld/testsuite/ld-i386/tlsgdesc2.d @@ -0,0 +1,4 @@ +#name: TLS GDesc->LE transition check (indirect CALL) +#as: --32 +#ld: -melf_i386 +#error: .*: relocation R_386_TLS_DESC_CALL against `foo' must be used in indirect CALL only diff --git a/ld/testsuite/ld-i386/tlsgdesc2.s b/ld/testsuite/ld-i386/tlsgdesc2.s new file mode 100644 index 0000000..7d9d556 --- /dev/null +++ b/ld/testsuite/ld-i386/tlsgdesc2.s @@ -0,0 +1,11 @@ + .text + .globl _start +_start: + leal foo@tlsdesc(%ebx), %eax + jmp *foo@tlscall(%eax) + .section .tdata,"awT",@progbits + .align 4 + .type foo, @object + .size foo, 4 +foo: + .long 100 diff --git a/ld/testsuite/ld-i386/tlsie2.d b/ld/testsuite/ld-i386/tlsie2.d index ebb85fd..9f9e630 100644 --- a/ld/testsuite/ld-i386/tlsie2.d +++ b/ld/testsuite/ld-i386/tlsie2.d @@ -1,4 +1,4 @@ #name: TLS IE->LE transition check (R_386_TLS_GOTIE with %eax) #as: --32 #ld: -melf_i386 -#error: .*TLS transition from R_386_TLS_GOTIE to R_386_TLS_LE_32 against `foo'.*failed.* +#error: .*: relocation R_386_TLS_GOTIE against `foo' must be used in ADD, SUB or MOV only diff --git a/ld/testsuite/ld-i386/tlsie3.d b/ld/testsuite/ld-i386/tlsie3.d index d993f30..506f1a0 100644 --- a/ld/testsuite/ld-i386/tlsie3.d +++ b/ld/testsuite/ld-i386/tlsie3.d @@ -1,4 +1,4 @@ #name: TLS IE->LE transition check (R_386_TLS_GOTIE) #as: --32 #ld: -melf_i386 -#error: .*TLS transition from R_386_TLS_GOTIE to R_386_TLS_LE_32 against `foo'.*failed.* +#error: .*: relocation R_386_TLS_GOTIE against `foo' must be used in ADD, SUB or MOV only diff --git a/ld/testsuite/ld-i386/tlsie4.d b/ld/testsuite/ld-i386/tlsie4.d index 3ca8fdd..a516d00 100644 --- a/ld/testsuite/ld-i386/tlsie4.d +++ b/ld/testsuite/ld-i386/tlsie4.d @@ -1,4 +1,4 @@ #name: TLS IE->LE transition check (R_386_TLS_IE with %eax) #as: --32 #ld: -melf_i386 -#error: .*TLS transition from R_386_TLS_IE to R_386_TLS_LE_32 against `foo'.*failed.* +#error: .*: relocation R_386_TLS_IE against `foo' must be used in ADD or MOV only diff --git a/ld/testsuite/ld-i386/tlsie5.d b/ld/testsuite/ld-i386/tlsie5.d index 3febeb1..d344718 100644 --- a/ld/testsuite/ld-i386/tlsie5.d +++ b/ld/testsuite/ld-i386/tlsie5.d @@ -1,4 +1,4 @@ #name: TLS IE->LE transition check (R_386_TLS_IE) #as: --32 #ld: -melf_i386 -#error: .*TLS transition from R_386_TLS_IE to R_386_TLS_LE_32 against `foo'.*failed.* +#error: .*: relocation R_386_TLS_IE against `foo' must be used in ADD or MOV only diff --git a/ld/testsuite/ld-x86-64/tlsdesc3.d b/ld/testsuite/ld-x86-64/tlsdesc3.d new file mode 100644 index 0000000..bbf22eb --- /dev/null +++ b/ld/testsuite/ld-x86-64/tlsdesc3.d @@ -0,0 +1,4 @@ +#name: TLS GDesc->LE transition check (LEA) +#as: --64 +#ld: -melf_x86_64 +#error: .*: relocation R_X86_64_GOTPC32_TLSDESC against `foo' must be used in LEA only diff --git a/ld/testsuite/ld-x86-64/tlsdesc3.s b/ld/testsuite/ld-x86-64/tlsdesc3.s new file mode 100644 index 0000000..4531065 --- /dev/null +++ b/ld/testsuite/ld-x86-64/tlsdesc3.s @@ -0,0 +1,13 @@ + .text + .globl _start + .type _start,@function +_start: + movq foo@tlsdesc(%rip), %rax + call *foo@tlscall(%rax) + .globl foo + .section .tdata,"awT",@progbits + .align 8 + .type foo, @object + .size foo, 8 +foo: + .quad 100 diff --git a/ld/testsuite/ld-x86-64/tlsdesc4.d b/ld/testsuite/ld-x86-64/tlsdesc4.d new file mode 100644 index 0000000..b50115c --- /dev/null +++ b/ld/testsuite/ld-x86-64/tlsdesc4.d @@ -0,0 +1,4 @@ +#name: TLS GDesc->LE transition check (indirect CALL) +#as: --64 +#ld: -melf_x86_64 +#error: .*: relocation R_X86_64_TLSDESC_CALL against `foo' must be used in indirect CALL only diff --git a/ld/testsuite/ld-x86-64/tlsdesc4.s b/ld/testsuite/ld-x86-64/tlsdesc4.s new file mode 100644 index 0000000..b3d6c12 --- /dev/null +++ b/ld/testsuite/ld-x86-64/tlsdesc4.s @@ -0,0 +1,13 @@ + .text + .globl _start + .type _start,@function +_start: + leaq foo@tlsdesc(%rip), %rax + jmp *foo@tlscall(%rax) + .globl foo + .section .tdata,"awT",@progbits + .align 8 + .type foo, @object + .size foo, 8 +foo: + .quad 100 diff --git a/ld/testsuite/ld-x86-64/tlsie2.d b/ld/testsuite/ld-x86-64/tlsie2.d index 97dcc28..bf8a819 100644 --- a/ld/testsuite/ld-x86-64/tlsie2.d +++ b/ld/testsuite/ld-x86-64/tlsie2.d @@ -1,4 +1,4 @@ #name: TLS IE->LE transition check #as: --64 #ld: -melf_x86_64 -#error: .*TLS transition from R_X86_64_GOTTPOFF to R_X86_64_TPOFF32 against `foo'.*failed.* +#error: .*: relocation R_X86_64_GOTTPOFF against `foo' must be used in ADD or MOV only diff --git a/ld/testsuite/ld-x86-64/tlsie3.d b/ld/testsuite/ld-x86-64/tlsie3.d index 8c982a6..49d8464 100644 --- a/ld/testsuite/ld-x86-64/tlsie3.d +++ b/ld/testsuite/ld-x86-64/tlsie3.d @@ -1,4 +1,4 @@ #name: TLS IE->LE transition check (%r12) #as: --64 #ld: -melf_x86_64 -#error: .*TLS transition from R_X86_64_GOTTPOFF to R_X86_64_TPOFF32 against `foo'.*failed.* +#error: .*: relocation R_X86_64_GOTTPOFF against `foo' must be used in ADD or MOV only diff --git a/ld/testsuite/ld-x86-64/tlsie5.d b/ld/testsuite/ld-x86-64/tlsie5.d new file mode 100644 index 0000000..29de1ce --- /dev/null +++ b/ld/testsuite/ld-x86-64/tlsie5.d @@ -0,0 +1,4 @@ +#name: TLS IE->LE transition check (APX) +#as: --64 +#ld: -melf_x86_64 +#error: .*: relocation R_X86_64_CODE_6_GOTTPOFF against `foo' must be used in ADD only diff --git a/ld/testsuite/ld-x86-64/tlsie5.s b/ld/testsuite/ld-x86-64/tlsie5.s new file mode 100644 index 0000000..c39e46f --- /dev/null +++ b/ld/testsuite/ld-x86-64/tlsie5.s @@ -0,0 +1,12 @@ + .text + .globl _start +_start: + xorq %rax, foo@GOTTPOFF(%rip), %rax + movq (%rax), %rax + .globl foo + .section .tdata,"awT",@progbits + .align 4 + .type foo, @object + .size foo, 4 +foo: + .long 100 diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index ea1a91a..1cae0a3 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -537,6 +537,9 @@ run_dump_test "pr31868b" run_dump_test "pr31868b-x32" run_dump_test "pr31868c" run_dump_test "pr31868c-x32" +run_dump_test "tlsie5" +run_dump_test "tlsdesc3" +run_dump_test "tlsdesc4" if { ![skip_sframe_tests] } { run_dump_test "sframe-simple-1" -- cgit v1.1