[PATCH] i386: Don't add 0x66 prefix to IRET for .code16gcc
H.J. Lu
hjl.tools@gmail.com
Mon Apr 29 15:09:00 GMT 2019
On Mon, Apr 29, 2019 at 12:01 AM Jan Beulich <JBeulich@suse.com> wrote:
>
> >>> On 26.04.19 at 19:22, <hjl.tools@gmail.com> wrote:
> > The .code16gcc directive supports 16bit mode with 32-bit address. Since
> > IRET (opcode 0xcf) in 16bit mode returns from an interrupt in 16bit mode,
> > we shouldn't add 0x66 prefix for IRET.
> >
> > PR gas/24485
> > * config/tc-i386.c (process_suffix): Don't add DATA_PREFIX_OPCODE
> > to IRET for .code16gcc.
>
> This, at the very least, needs to be accompanied by a warning:
This patch fixes:
[hjl@gnu-cfl-1 tmp]$ cat foo.c
extern void bar (void);
__attribute__((interrupt))
void
foo (void *frame)
{
bar ();
}
[hjl@gnu-cfl-1 tmp]$ gcc -O2 -mgeneral-regs-only -m16 -S foo.c
[hjl@gnu-cfl-1 tmp]$ cat foo.s
.file "foo.c"
.code16gcc
.text
.p2align 4,,15
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %ecx
pushl %edx
pushl %eax
andl $-16, %esp
.cfi_offset 1, -12
.cfi_offset 2, -16
.cfi_offset 0, -20
cld
call bar
leal -12(%ebp), %esp
popl %eax
.cfi_restore 0
popl %edx
.cfi_restore 2
popl %ecx
.cfi_restore 1
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
iret
.cfi_endproc
.LFE0:
.size foo, .-foo
.ident "GCC: (GNU) 8.3.1 20190311 (Red Hat 8.3.1-3)"
.section .note.GNU-stack,"",@progbits
[hjl@gnu-cfl-1 tmp]$
> As the bug report validly says, the changed behavior is what is
> wanted only "almost always". The report even mentions the
> (supposedly uncommon) case: Code manually building a frame
> and IRETing to it will now be silently(!) broken.
The .code16gcc directive is to support "gcc -m16". Any other purposes
are not supported.
> In fact I think the better solution would be to reject ambiguous
> code by demanding a suffix in all cases in .code16gcc mode.
This may break existing codes.
--
H.J.
More information about the Binutils
mailing list