[PATCH v2] x86: Add tls check in gas

Cui, Lili lili.cui@intel.com
Mon Sep 9 08:15:57 GMT 2024


> > if (i.has_gotrel && tls_check)
> >
> > > > > +    {
> > > > > +      enum x86_tls_error_type tls_error;
> > > > > +      for (j = 0; j < i.operands; ++j)
> > > > > +       if ((tls_error = x86_check_tls_relocation (i.reloc[j])) !=
> x86_tls_error_none)
> > > > > +         x86_report_tls_error (tls_error, i.reloc[j]);
> >
> >        {
> >           tls_error = x86_check_tls_relocation (i.reloc[j]);
> >           if (tls_error == x86_tls_error_continue)
> >             continue;
> >
> >           if (tls_error != x86_tls_error_none)
> >             x86_report_tls_error (tls_error, i.reloc[j]);
> >           break;
> >         }
> >
> 
> This patch is on top of your patch.
> 

Applied this patch, thanks! Only one place that I think there is a bug. 

> > > +    case BFD_RELOC_X86_64_TLSLD:
> > > +      /* Check transition from LD access model:
> > > +
> > > +        leaq foo@tlsld(%rip), %rdi --> Only this fixed format is supported.
> > > +       */
> > > +      if (i.tm.mnem_off != MN_lea)
> > > +       return x86_tls_error_insn;
> > > +      else if (!i.base_reg)
> > > +       return x86_tls_error_no_base_reg;
> > > +      else if (i.base_reg->reg_num != RegIP)
> > > +       return x86_tls_error_RegIP;
> > > +      else if (i.types[1].bitfield.instance != RegDI)
> 
> Use
> 
>       else if (i.types[1].bitfield.class != Reg
>                || !i.op[1].regs->reg_type.bitfield.qword
>                || i.op[1].regs->reg_num != EDI_REG_NUM)
>         return x86_tls_error_dest_RegDI;
> 

If we use reg_num, the following illegal usage will also pass the test.

leaq        bar@tlsgd(%rip), %r15

> > This failed with GCC 14:
> >
> > FAIL: Check tls relocation x86-64
> > FAIL: Build size-8
> >
> > gcc  -B/export/build/gnu/tools-build/binutils-gitlab/build-x86_64-
> linux/ld/tmpdir/ld/
> > -I/export/gnu/import/git/gitlab/x86-binutils/ld/testsuite/ld-size -g
> > -O2 -fno-sanitize=all   -c -fno-lto -fPIC -c
> > /export/gnu/import/git/gitlab/x86-binutils/ld/testsuite/ld-size/size-8b.c
> > -o tmpdir/size-8b.o
> > Executing on host: sh -c {gcc
> > -B/export/build/gnu/tools-build/binutils-gitlab/build-x86_64-
> linux/ld/tmpdir/ld/
> > -I/export/gnu/import/git/gitlab/x86-binutils/ld/testsuite/ld-size -g
> > -O2 -fno-sanitize=all   -c -fno-lto -fPIC -c
> > /export/gnu/import/git/gitlab/x86-binutils/ld/testsuite/ld-size/size-8b.c
> > -o tmpdir/size-8b.o 2>&1}  /dev/null ld.tmp (timeout = 300)
> > spawn [open ...]^M
> > /tmp/cc6aqbbv.s: Assembler messages:
> > /tmp/cc6aqbbv.s:27: Error: @TLSGD operator only supports eax/rax as
> > dest register
> > /tmp/cc6aqbbv.s:27: Error: @TLSGD operator only supports eax/rax as
> > dest register
> >
> > UNSUPPORTED: Build libsize-8.so
> >

H.J, I cannot reproduce these failures with gcc14,

I checked the test case size-8b.c (FAIL: Build size-8):

https://godbolt.org/z/YE1jo54ad
set_bar:
        pushq   %rbp
        movl    %esi, %ebp
        pushq   %rbx
        movslq  %edi, %rbx
        subq    $8, %rsp
        data16  leaq        bar@tlsgd(%rip), %rdi    --> It is right, my environment does not reproduce the error case.
        .value  0x6666
        rex64
        call    __tls_get_addr@PLT
        movb    %bpl, (%rax,%rbx)
        addq    $8, %rsp
        popq    %rbx
        popq    %rbp
        ret
bar:
        .zero   10

My Binutils build option is : ../upstream/configure  --disable-nls --disable-gdb --enable-maintainer-mode --prefix=$TARGET/binary CFLAGS='-O0 -gdwarf-2 -fPIE' CXXFLAGS='-O0 -gdwarf-2 -fPIE'

Thanks,
Lili.
> --
> H.J.


More information about the Binutils mailing list