This is the mail archive of the binutils@sources.redhat.com 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]

[patch] fix for offset operands in i386 intel syntax


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]

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