[PATCH V5] x86: Add tls check in gas

Cui, Lili lili.cui@intel.com
Fri Oct 11 09:28:09 GMT 2024


> On 19.09.2024 08:38, Cui, Lili wrote:
> > +    case BFD_RELOC_386_TLS_GOTIE:
> > +      /* Check GOTIE access model:
> > +
> > +	 subl foo@gotntpoff(%reg1), %reg2
> > +	 movl foo@gotntpoff(%reg1), %reg2
> > +	 addl foo@gotntpoff(%reg1), %reg2
> > +
> > +	 Memory operand: SIB is not supported.
> > +       */
> > +    case BFD_RELOC_386_TLS_IE_32:
> > +      /* Check IE_32 access model:
> > +
> > +	 subl foo@gottpoff(%reg1), %reg2
> > +	 movl foo@gottpoff(%reg1), %reg2
> > +	 addl foo@gottpoff(%reg1), %reg2
> > +
> > +	 Memory operand: SIB is not supported.
> > +       */
> > +      if (i.tm.mnem_off != MN_sub
> > +	  && i.tm.mnem_off != MN_add
> > +	  && i.tm.mnem_off != MN_mov)
> > +	return x86_tls_error_insn;
> > +      if (i.op[1].regs->reg_type.bitfield.class != Reg
> > +	  || i.op[0].regs->reg_type.bitfield.class
> > +	  || i.imm_operands)
> 
> You may not de-reference i.op[0].regs for the intended forms at all. If anything,
> i.op[0].disps may be de-referenced there.
> 
> You may also not de-reference i.op[1].regs until you've checked that operand 1
> actually is a register. There are insn forms after all where operand 1 is a memory
> one.
> 
> Which member of the union is valid to de-reference can only be told by
> inspecting i.types[] and/or i.tm.operand_types[] (when insns are more
> constrained than mov/add/sub are, going from just
> i.{reg,imm,mem,disp}_operands may also be possible, just to mention it).
> 
> I expect you want to check for operand counts first: No immediate one, a single
> disp one, and a single register one. Then check that it's the destination that's the
> register one. There may then not be any need to access any i.op[<n>].reg
> anymore.
> 

Jan, do you mean to modify it like this?

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 25ecaa66104..358d76e7bd2 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -6545,9 +6545,10 @@ x86_check_tls_relocation (enum bfd_reloc_code_real r_type)
          && i.tm.mnem_off != MN_add
          && i.tm.mnem_off != MN_mov)
        return x86_tls_error_insn;
-      if (i.op[1].regs->reg_type.bitfield.class != Reg
-         || i.op[0].regs->reg_type.bitfield.class
-         || i.imm_operands)
+      if (i.imm_operands
+         || i.disp_operands != 1
+         || i.reg_operands != 1
+         || i.types[1].bitfield.class != Reg)
        return x86_tls_error_opcode;
       if (!i.base_reg)
        return x86_tls_error_no_base_reg;
@@ -6567,9 +6568,10 @@ x86_check_tls_relocation (enum bfd_reloc_code_real r_type)
        */
       if (i.tm.mnem_off != MN_add && i.tm.mnem_off != MN_mov)
        return x86_tls_error_insn;
-      if (i.op[1].regs->reg_type.bitfield.class != Reg
-         || i.op[0].regs->reg_type.bitfield.class
-         || i.imm_operands)
+      if (i.imm_operands
+         || i.disp_operands != 1
+         || i.reg_operands != 1
+         || i.types[1].bitfield.class != Reg)
        return x86_tls_error_opcode;
       if (i.base_reg || i.index_reg)
        return x86_tls_error_require_no_base_index_reg;
@@ -6587,10 +6589,9 @@ x86_check_tls_relocation (enum bfd_reloc_code_real r_type)
        */
       if (i.tm.mnem_off != MN_add && i.tm.mnem_off != MN_mov)
        return x86_tls_error_insn;
-      if (i.op[i.operands - 1].regs->reg_type.bitfield.class != Reg
-         || (i.op[0].regs->reg_type.bitfield.class
-             && i.tm.opcode_modifier.vexvvvv != VexVVVV_DST)
-         || i.imm_operands)
+      if (i.imm_operands
+         || i.disp_operands != 1
+         || i.types[i.operands - 1].bitfield.class != Reg)
        return x86_tls_error_opcode;
       if (!i.base_reg)
        return x86_tls_error_no_base_reg;

Thanks,
Lili.


More information about the Binutils mailing list