[PATCH] gas: x86: ginsn: handle sub-QWORD ALU with imm and MOV ops correctly
Jan Beulich
jbeulich@suse.com
Mon Feb 5 10:02:51 GMT 2024
On 02.02.2024 08:25, Indu Bhagat wrote:
> 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.
While I'm not fully convinced this moves us in the right direction, it
still looks okay to me, so feel free to put in. Going forward I may then
be proven wrong, once the whole thing ends up more complete and not
experimental anymore.
Jan
More information about the Binutils
mailing list