Skip to content
Commit f8c50ae2 authored by Indu Bhagat's avatar Indu Bhagat
Browse files

gas: x86: ginsn: handle sub-QWORD ALU with imm and MOV ops correctly

PR gas/31326
SCFI must handle non QWORD ALU with imm and MOV ops correctly

As per the x86 ISA manual:
  - 32-bit operands generate a 32-bit result, zero-extended to a 64-bit
    result in the destination general-purpose register.
  - 8-bit and 16-bit operands generate an 8-bit or 16-bit result. The
    upper 56 bits or 48 bits (respectively) of the destination
    general-purpose register are not modified by the operation.

Unlike previously thought, sub-QWORD ALU/imm and MOV ops do have
implications on SCFI.  SCFI/ginsn machinery does not track operation size
in the ginsn representation.  But given that these sub-QWORD ops update
only a portion of a 64-bit destination register, for SCFI purposes, this
needs to be deemed as an untraceable update (when the destination is
REG_SP / REG_FP). Although in most cases, sub-QWORD ops are not expected
for stack management, but the SCFI machinery must behave correctly, when
such ops are indeed present.

As mentioned earlier, ginsn representation does not carry operation size
information.  To resolve the issue raised in PR gas/31326, an option is
to force the generation of GINSN_TYPE_OTHER for all cases when there is
a 8/16/32 bit op.  But this may dilute the utility of ginsn for other
use-cases, when they pop up in future.

The current approach is less disruptive than above in that it generates
GINSN_TYPE_OTHER for all cases only when:
  - there is a 8/16/32 bit op, and
  - the 64-bit op is otherwise traceable.

In other words this means:
 - For add/sub ops where dest is reg and src is reg/mem: these always
   make dest reg untraceable; So, the current handling is unchanged.  We
   simply skip detecting 8/16/32-bit ops.
 - An x86 pop instruction is translated to a load ginsn followed by a stack
   increment add op.  A load op always makes dest reg untraceable.
   Hence, if the pop instruction is sub-QWORD, we continue to (skip
   detecting 8/16/32-bit op, and) generate the load instruction as usual.
   This means that if input asm does have save and restore of unequal sized
   registers, gas/SCFI will not detect nor warn.
 - For ALU imm or MOV reg,reg, however, a GINSN_TYPE_OTHER is generated
   when a 8/16/32-bit op is seen.

gas/
	PR gas/31326
	* config/tc-i386.c (x86_ginsn_addsub_reg_mem): Add a code
	comment.
	(x86_ginsn_addsub_mem_reg): Likewise.
	(x86_ginsn_alu_imm): Detect sub-QWORD opsize and exit early.
	(x86_ginsn_move): Likewise.
	(x86_ginsn_new): Add comment for 8-bit add/sub opcodes (in
        opcode_space SPACE_BASE) about skipped handling.

gas/testsuite/:
	PR gas/31326
	* gas/scfi/x86_64/ginsn-add-1.l: Update.
	* gas/scfi/x86_64/ginsn-add-1.s: Add some sub-QWORD add ops.
	* gas/scfi/x86_64/ginsn-dw2-regnum-1.l: Update.
	* gas/scfi/x86_64/ginsn-dw2-regnum-1.s: Use mov ops instead of
	add to invoke and test the ginsn_dw2_regnum code path.
parent b5f29db5
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment