This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[patch] fix for offset operands in i386 intel syntax
- To: binutils at sourceware dot cygnus dot com
- Subject: [patch] fix for offset operands in i386 intel syntax
- From: Diego Novillo <dnovillo at redhat dot com>
- Date: Fri, 15 Dec 2000 13:40:58 -0500
- Organization: Red Hat Canada
This problem occurs when emitting C++ thunks. References to the
GOT are not parsed correctly:
add %ebx, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_+[.-.L23]
GAS thinks that the above is a memory reference. The patch
below fixes this problem.
How do I configure GAS for all the different binary flavours
(a.out, elf, etc). The patch also adds a new test to intel.s but
I'm not sure if I need to pad with nops for a.out.
2000-12-15 Diego Novillo <dnovillo@redhat.com>
* config/tc-i386.c (intel_e09_1): Only flag as a memory operand if
it's not an offset expression.
(intel_e10_1): Ditto. Also, if the operand is an offset expression,
keep the braces '[' and ']' in the output string.
(intel_e11): Ditto. Also remove comparison intel_parser.op_modifier
!= FLAT. There is no such op_modifier.
2000-12-15 Diego Novillo <dnovillo@redhat.com>
* testsuite/gas/i386/intel.[sd]: Add tests for offset expressions
involving _GLOBAL_OFFSET_TABLE_.
Index: config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.70
diff -d -c -p -r1.70 tc-i386.c
*** tc-i386.c 2000/12/11 14:01:46 1.70
--- tc-i386.c 2000/12/15 18:32:25
*************** intel_e09_1 ()
*** 4588,4594 ****
/* e09 : e10 e09' */
else if (cur_token.code == ':')
{
! intel_parser.is_mem = 1;
return (intel_match_token (':') && intel_e10 () && intel_e09_1 ());
}
--- 4588,4597 ----
/* e09 : e10 e09' */
else if (cur_token.code == ':')
{
! /* Mark as a memory operand only if it's not already known to be an
! offset expression. */
! if (intel_parser.op_modifier != OFFSET_FLAT)
! intel_parser.is_mem = 1;
return (intel_match_token (':') && intel_e10 () && intel_e09_1 ());
}
*************** intel_e10_1 ()
*** 4615,4627 ****
if (cur_token.code == '[')
{
intel_match_token ('[');
- intel_parser.is_mem = 1;
/* Add a '+' to the displacement string if necessary. */
! if (*intel_parser.disp != '\0')
strcat (intel_parser.disp, "+");
! return (intel_expr () && intel_match_token (']') && intel_e10_1 ());
}
/* e10' Empty */
--- 4618,4647 ----
if (cur_token.code == '[')
{
intel_match_token ('[');
+ /* Mark as a memory operand only if it's not already known to be an
+ offset expression. If it's an offset expression, we need to keep
+ the brace in. */
+ if (intel_parser.op_modifier != OFFSET_FLAT)
+ intel_parser.is_mem = 1;
+ else
+ strcat (intel_parser.disp, "[");
+
/* Add a '+' to the displacement string if necessary. */
! if (*intel_parser.disp != '\0'
! && *(intel_parser.disp + strlen (intel_parser.disp) - 1) != '+')
strcat (intel_parser.disp, "+");
! if (intel_expr () && intel_match_token (']'))
! {
! /* Preserve brackets when the operand is an offset expression. */
! if (intel_parser.op_modifier == OFFSET_FLAT)
! strcat (intel_parser.disp, "]");
!
! return intel_e10_1 ();
! }
! else
! return 0;
}
/* e10' Empty */
*************** intel_e11 ()
*** 4663,4669 ****
else if (cur_token.code == '[')
{
intel_match_token ('[');
! intel_parser.is_mem = 1;
/* Operands for jump/call inside brackets denote absolute addresses. */
if (current_templates->start->opcode_modifier & Jump
--- 4683,4696 ----
else if (cur_token.code == '[')
{
intel_match_token ('[');
!
! /* Mark as a memory operand only if it's not already known to be an
! offset expression. If it's an offset expression, we need to keep
! the brace in. */
! if (intel_parser.op_modifier != OFFSET_FLAT)
! intel_parser.is_mem = 1;
! else
! strcat (intel_parser.disp, "[");
/* Operands for jump/call inside brackets denote absolute addresses. */
if (current_templates->start->opcode_modifier & Jump
*************** intel_e11 ()
*** 4673,4682 ****
i.types[this_operand] |= JumpAbsolute;
/* Add a '+' to the displacement string if necessary. */
! if (*intel_parser.disp != '\0')
strcat (intel_parser.disp, "+");
! return (intel_expr () && intel_match_token (']'));
}
/* e11 BYTE
--- 4700,4719 ----
i.types[this_operand] |= JumpAbsolute;
/* Add a '+' to the displacement string if necessary. */
! if (*intel_parser.disp != '\0'
! && *(intel_parser.disp + strlen (intel_parser.disp) - 1) != '+')
strcat (intel_parser.disp, "+");
! if (intel_expr () && intel_match_token (']'))
! {
! /* Preserve brackets when the operand is an offset expression. */
! if (intel_parser.op_modifier == OFFSET_FLAT)
! strcat (intel_parser.disp, "]");
!
! return 1;
! }
! else
! return 0;
}
/* e11 BYTE
*************** intel_e11 ()
*** 4701,4708 ****
{
strcat (intel_parser.disp, cur_token.str);
intel_match_token (cur_token.code);
- intel_parser.is_mem = 1;
return 1;
}
--- 4738,4749 ----
{
strcat (intel_parser.disp, cur_token.str);
intel_match_token (cur_token.code);
+ /* Mark as a memory operand only if it's not already known to be an
+ offset expression. */
+ if (intel_parser.op_modifier != OFFSET_FLAT)
+ intel_parser.is_mem = 1;
+
return 1;
}
*************** intel_e11 ()
*** 4832,4839 ****
/* The identifier represents a memory reference only if it's not
preceded by an offset modifier. */
! if (intel_parser.op_modifier != OFFSET_FLAT
! && intel_parser.op_modifier != FLAT)
intel_parser.is_mem = 1;
return 1;
--- 4873,4879 ----
/* The identifier represents a memory reference only if it's not
preceded by an offset modifier. */
! if (intel_parser.op_modifier != OFFSET_FLAT)
intel_parser.is_mem = 1;
return 1;
Index: testsuite/gas/i386/intel.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/i386/intel.d,v
retrieving revision 1.7
diff -d -c -p -r1.7 intel.d
*** intel.d 2000/12/11 21:49:36 1.7
--- intel.d 2000/12/15 18:32:25
*************** Disassembly of section .text:
*** 623,625 ****
--- 623,627 ----
a78: e9 55 ff ff ff [ ]*jmp 9d2 <bar>
a7d: 8b 83 (00 00|d0 09) 00 00 [ ]*mov (0x0|0x9d0)\(%ebx\),%eax
a83: 90 [ ]*nop[ ]*
+ a84: 5b [ ]*pop %ebx
+ a85: 81 c3 03 00 00 00 [ ]*add \$0x3,%ebx
Index: testsuite/gas/i386/intel.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/i386/intel.s,v
retrieving revision 1.7
diff -d -c -p -r1.7 intel.s
*** intel.s 2000/12/11 21:49:36 1.7
--- intel.s 2000/12/15 18:32:26
*************** rot5:
*** 618,620 ****
--- 618,623 ----
jmp bar
mov eax, DWORD PTR gs_foo@GOT[ebx]
nop
+ .L23:
+ pop %ebx
+ add %ebx, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_+[.-.L23]