This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

.code16gcc, i386, and loop/jcc/jmp data-size overrides


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

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.  */



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]