public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* .code16gcc, i386, and loop/jcc/jmp data-size overrides
@ 2006-04-08 16:01 No Name
  2006-04-10  6:49 ` Alan Modra
  0 siblings, 1 reply; 4+ messages in thread
From: No Name @ 2006-04-08 16:01 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1477 bytes --]

Would it be ok for gas to generate extra size prefixes when compiling with 
code16gcc?

Like that the produced object with 16bit code could run with an EIP > 
0xffff.
It would seem that the spirit of code16gcc is to be 32bit allover anyway.

The attached patch is probably incomplete, "jcxz" should be tweaked also. 
And maybe the "loop/jcxz" handling is trickier due to suffixes manipulating 
addr-sizes instead of the data-sizes.

* code
.L19:
	movl	-8(%ebp), %eax
	addl	8(%ebp), %eax
	cmpb	$0, (%eax)
	jne	.L21
!!>>	jmp	.L20 <<!!
.L21:

* original gnu assembler
After reloc to 0x40000, executing the jmp cause eip to be truncated to 16bit 
(data size).

	67 66 8b 45 f8       	addr32 mov 0xfffffff8(%ebp),%eax
	67 66 03 45 08       	addr32 add 0x8(%ebp),%eax
	67 80 38 00          	addr32 cmpb $0x0,(%eax)
	75 03                	jne    40250 <printf+0x2f>
!!>>	e9 68 01             	jmp    3b8 <SEL_GDT_USER3+0x328> <<!!
	67 66 8b 45 f8       	addr32 mov 0xfffffff8(%ebp),%eax
	67 66 03 45 08       	addr32 add 0x8(%ebp),%eax

* with the attached binutils 1.16 patch

	67 66 8b 45 f8       	addr32 mov 0xfffffff8(%ebp),%eax
	67 66 03 45 08       	addr32 add 0x8(%ebp),%eax
	67 80 38 00          	addr32 cmpb $0x0,(%eax)
	66                   	data32
	75 06                	jne    40262 <printf+0x33>
!!>>	66 e9 8a 01 00 00    	jmpl   403ec <printf+0x1bd> <<!!
	67 66 8b 45 f8       	addr32 mov 0xfffffff8(%ebp),%eax
	67 66 03 45 08       	addr32 add 0x8(%ebp),%eax

--
jpa


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: binutils-2.16.gasPatch.forCode16gccFix.200604071624.patch --]
[-- Type: text/x-diff; name="binutils-2.16.gasPatch.forCode16gccFix.200604071624.patch", Size: 8276 bytes --]

diff -ur binutils-2.16/gas/config/tc-i386.c binutils-2.16-code16gccFix/gas/config/tc-i386.c
--- binutils-2.16/gas/config/tc-i386.c	2005-04-13 10:58:42.000000000 -0700
+++ binutils-2.16-code16gccFix/gas/config/tc-i386.c	2006-04-07 16:19:58.000000000 -0700
@@ -2446,10 +2446,15 @@
 	  unsigned int prefix = DATA_PREFIX_OPCODE;
 
 	  if (i.tm.opcode_modifier & JumpByte) /* jcxz, loop */
-	    prefix = ADDR_PREFIX_OPCODE;
+          {
+            if (!add_prefix (prefix))
+              return 0;
+            prefix = ADDR_PREFIX_OPCODE;
+          }
 
 	  if (!add_prefix (prefix))
 	    return 0;
+
 	}
 
       /* Set mode64 for an operand.  */
@@ -3179,6 +3184,13 @@
 	  FRAG_APPEND_1_CHAR (ADDR_PREFIX_OPCODE);
 	  i.prefixes -= 1;
 	}
+      if (flag_code == CODE_16BIT)
+        if (i.prefix[DATA_PREFIX] != 0)
+	  {
+	    FRAG_APPEND_1_CHAR (DATA_PREFIX_OPCODE);
+	    i.prefixes -= 1;
+	  }
+
       /* Pentium4 branch hints.  */
       if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */
 	  || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */)
diff -ur binutils-2.16/include/opcode/i386.h binutils-2.16-code16gccFix/include/opcode/i386.h
--- binutils-2.16/include/opcode/i386.h	2005-04-13 10:59:03.000000000 -0700
+++ binutils-2.16-code16gccFix/include/opcode/i386.h	2006-04-07 16:10:34.000000000 -0700
@@ -393,15 +393,15 @@
 {"lcall",  1,	0xff, 3, 0,	 wl_Suf|Modrm|DefaultSize,	{WordMem|JumpAbsolute, 0, 0} },
 
 #define JUMP_PC_RELATIVE 0xeb
-{"jmp",	   1,	0xeb, X, 0,	 NoSuf|Jump,		{ Disp,0, 0} },
-{"jmp",	   1,	0xff, 4, CpuNo64, wl_Suf|Modrm,		{ WordReg|WordMem|JumpAbsolute, 0, 0} },
-{"jmp",	   1,	0xff, 4, Cpu64,	 wq_Suf|Modrm|NoRex64,	{ Reg16|Reg64|ShortMem|LLongMem|JumpAbsolute, 0, 0} },
+{"jmp",	   1,	0xeb, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp,0, 0} },
+{"jmp",	   1,	0xff, 4, CpuNo64, wl_Suf|Modrm|DefaultSize,		{ WordReg|WordMem|JumpAbsolute, 0, 0} },
+{"jmp",	   1,	0xff, 4, Cpu64,	 wq_Suf|Modrm|NoRex64|DefaultSize,	{ Reg16|Reg64|ShortMem|LLongMem|JumpAbsolute, 0, 0} },
 /* Intel Syntax.  */
-{"jmp",    2,	0xea, X, CpuNo64,wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
+{"jmp",    2,	0xea, X, CpuNo64,wl_Suf|JumpInterSegment|DefaultSize, { Imm16, Imm16|Imm32, 0} },
 /* Intel Syntax.  */
-{"jmp",    1,	0xff, 5, 0,	 x_Suf|Modrm,		{ WordMem|JumpAbsolute, 0, 0} },
-{"ljmp",   2,	0xea, X, CpuNo64, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
-{"ljmp",   1,	0xff, 5, 0,	 wl_Suf|Modrm,		{ WordMem|JumpAbsolute, 0, 0} },
+{"jmp",    1,	0xff, 5, 0,	 x_Suf|Modrm|DefaultSize,		{ WordMem|JumpAbsolute, 0, 0} },
+{"ljmp",   2,	0xea, X, CpuNo64, wl_Suf|JumpInterSegment|DefaultSize, { Imm16, Imm16|Imm32, 0} },
+{"ljmp",   1,	0xff, 5, 0,	 wl_Suf|Modrm|DefaultSize,		{ WordMem|JumpAbsolute, 0, 0} },
 
 {"ret",	   0,	0xc3, X, CpuNo64,wl_Suf|DefaultSize,	{ 0, 0, 0} },
 {"ret",	   1,	0xc2, X, CpuNo64,wl_Suf|DefaultSize,	{ Imm16, 0, 0} },
@@ -415,36 +415,36 @@
 {"leave",  0,	0xc9, X, Cpu64,  wq_Suf|DefaultSize|NoRex64,	{ 0, 0, 0} },
 
 /* Conditional jumps.  */
-{"jo",	   1,	0x70, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jno",	   1,	0x71, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jb",	   1,	0x72, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jc",	   1,	0x72, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jnae",   1,	0x72, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jnb",	   1,	0x73, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jnc",	   1,	0x73, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jae",	   1,	0x73, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"je",	   1,	0x74, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jz",	   1,	0x74, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jne",	   1,	0x75, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jnz",	   1,	0x75, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jbe",	   1,	0x76, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jna",	   1,	0x76, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jnbe",   1,	0x77, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"ja",	   1,	0x77, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"js",	   1,	0x78, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jns",	   1,	0x79, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jp",	   1,	0x7a, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jpe",	   1,	0x7a, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jnp",	   1,	0x7b, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jpo",	   1,	0x7b, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jl",	   1,	0x7c, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jnge",   1,	0x7c, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jnl",	   1,	0x7d, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jge",	   1,	0x7d, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jle",	   1,	0x7e, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jng",	   1,	0x7e, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jnle",   1,	0x7f, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
-{"jg",	   1,	0x7f, X, 0,	 NoSuf|Jump,		{ Disp, 0, 0} },
+{"jo",	   1,	0x70, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jno",	   1,	0x71, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jb",	   1,	0x72, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jc",	   1,	0x72, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jnae",   1,	0x72, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jnb",	   1,	0x73, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jnc",	   1,	0x73, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jae",	   1,	0x73, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"je",	   1,	0x74, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jz",	   1,	0x74, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jne",	   1,	0x75, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jnz",	   1,	0x75, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jbe",	   1,	0x76, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jna",	   1,	0x76, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jnbe",   1,	0x77, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"ja",	   1,	0x77, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"js",	   1,	0x78, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jns",	   1,	0x79, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jp",	   1,	0x7a, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jpe",	   1,	0x7a, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jnp",	   1,	0x7b, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jpo",	   1,	0x7b, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jl",	   1,	0x7c, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jnge",   1,	0x7c, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jnl",	   1,	0x7d, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jge",	   1,	0x7d, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jle",	   1,	0x7e, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jng",	   1,	0x7e, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jnle",   1,	0x7f, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
+{"jg",	   1,	0x7f, X, 0,	 NoSuf|Jump|DefaultSize,		{ Disp, 0, 0} },
 
 /* jcxz vs. jecxz is chosen on the basis of the address size prefix.  */
 {"jcxz",  1,	0xe3, X, CpuNo64,NoSuf|JumpByte|Size16, { Disp, 0, 0} },
@@ -456,16 +456,16 @@
    %cx rather than %ecx for the loop count, so the `w' form of these
    instructions emit an address size prefix rather than a data size
    prefix.  */
-{"loop",   1,	0xe2, X, CpuNo64,wl_Suf|JumpByte,{ Disp, 0, 0} },
+{"loop",   1,	0xe2, X, CpuNo64,wl_Suf|JumpByte|DefaultSize,{ Disp, 0, 0} },
 {"loop",   1,	0xe2, X, Cpu64,	 lq_Suf|JumpByte|NoRex64,{ Disp, 0, 0} },
-{"loopz",  1,	0xe1, X, CpuNo64,wl_Suf|JumpByte,{ Disp, 0, 0} },
+{"loopz",  1,	0xe1, X, CpuNo64,wl_Suf|JumpByte|DefaultSize,{ Disp, 0, 0} },
 {"loopz",  1,	0xe1, X, Cpu64,	 lq_Suf|JumpByte|NoRex64,{ Disp, 0, 0} },
-{"loope",  1,	0xe1, X, CpuNo64,wl_Suf|JumpByte,{ Disp, 0, 0} },
+{"loope",  1,	0xe1, X, CpuNo64,wl_Suf|JumpByte|DefaultSize,{ Disp, 0, 0} },
 {"loope",  1,	0xe1, X, Cpu64,	 lq_Suf|JumpByte|NoRex64,{ Disp, 0, 0} },
-{"loopnz", 1,	0xe0, X, CpuNo64,wl_Suf|JumpByte,{ Disp, 0, 0} },
+{"loopnz", 1,	0xe0, X, CpuNo64,wl_Suf|JumpByte|DefaultSize,{ Disp, 0, 0} },
 {"loopnz", 1,	0xe0, X, Cpu64,	 lq_Suf|JumpByte|NoRex64,{ Disp, 0, 0} },
-{"loopne", 1,	0xe0, X, CpuNo64,wl_Suf|JumpByte,{ Disp, 0, 0} },
+{"loopne", 1,	0xe0, X, CpuNo64,wl_Suf|JumpByte|DefaultSize,{ Disp, 0, 0} },
 {"loopne", 1,	0xe0, X, Cpu64,	 lq_Suf|JumpByte|NoRex64,{ Disp, 0, 0} },
 
 /* Set byte on flag instructions.  */



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: .code16gcc, i386, and loop/jcc/jmp data-size overrides
  2006-04-08 16:01 .code16gcc, i386, and loop/jcc/jmp data-size overrides No Name
@ 2006-04-10  6:49 ` Alan Modra
  0 siblings, 0 replies; 4+ messages in thread
From: Alan Modra @ 2006-04-10  6:49 UTC (permalink / raw)
  To: No Name; +Cc: binutils

On Fri, Apr 07, 2006 at 04:39:17PM -0700, No Name wrote:
> Would it be ok for gas to generate extra size prefixes when compiling with 
> code16gcc?

One of the beauties of free software is that you are free to make such
changes for yourself.  I don't think this is a generally useful change
though:  .code16gcc is a hack to make use of gcc code in real mode where
you usually only have 64k of code space.  I know it's possible to set up
16-bit segments with a larger limit, but this isn't normal.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: .code16gcc, i386, and loop/jcc/jmp data-size overrides
@ 2006-04-10 19:25 No Name
  0 siblings, 0 replies; 4+ messages in thread
From: No Name @ 2006-04-10 19:25 UTC (permalink / raw)
  To: binutils

From: Etienne Lorrain <etienne_lorrain@yahoo.fr>
>  Any interrupt or exception in 16 bits mode will only save the lower 16 
>bits of the
>program counter IP, so any code with EIP > 0xffff cannot be interrupted.
I'm running in PM16 with 32bitSS so the ful 32bit eip is saved.
But as Alan said, 16bit mode with big segments is not normal.
So I'll just keep that patch local.
Thanks for the feedback.
--
jpa


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: .code16gcc, i386, and loop/jcc/jmp data-size overrides
@ 2006-04-10 10:41 Etienne Lorrain
  0 siblings, 0 replies; 4+ messages in thread
From: Etienne Lorrain @ 2006-04-10 10:41 UTC (permalink / raw)
  To: binutils, no_mayl

> Would it be ok for gas to generate extra size prefixes when compiling with code16gcc?
> 
> Like that the produced object with 16bit code could run with an EIP > 0xffff.
> It would seem that the spirit of code16gcc is to be 32bit allover anyway.

 Any interrupt or exception in 16 bits mode will only save the lower 16 bits of the
program counter IP, so any code with EIP > 0xffff cannot be interrupted.

 Etienne.


	
	
		
___________________________________________________________________________ 
Découvez le nouveau Yahoo! Messenger : appelez vers des téléphones en France et à partir de 0,012 €/minute ! 
Téléchargez sur http://fr.messenger.yahoo.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-04-10 18:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-08 16:01 .code16gcc, i386, and loop/jcc/jmp data-size overrides No Name
2006-04-10  6:49 ` Alan Modra
2006-04-10 10:41 Etienne Lorrain
2006-04-10 19:25 No Name

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).