This is the mail archive of the binutils@sourceware.cygnus.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 gas octets vs bytes support


This patch implements octets vs bytes functionality for GAS

* gas/as.h: Define OCTETS_PER_BYTE and OCTETS_PER_BYTE_POWER default
values.
* gas/frags.c (frag_new): Calculate fr_fix in octets
   (frag_now_fix) Return offset as target address offset (bytes).
   (frag_now_fix_octets) New - Return offset in octets (8-bit
quantities).
* gas/frags.h: Added prototype for frag_now_fix_octets().  Distinguish
between octets and bytes in field descriptions.
* gas/listing.c (calc_hex): Account for octets vs bytes when printing
addresses/offsets.
   (print_lines) Ditto.  Also, if LISTING_WORD_SIZE is not 1, and target
is little-endian, print the octets in a word in big-endian order so that
the display looks like a proper hexadecimal number, instead of having
the octets reversed.
* gas/read.c (do_align): When recording alignment, alignment power
should be in terms of target bytes (minimum addressible unit) instead of
octets.
   (do_org) Convert ORG target address (byte) argument into an octet
offset when generating a variable fragment.
* gas/symbols.c (resolve_symbol_value): Symbol final value converted to
a target address offset (bytes) from its octet offset.
* gas/config/obj-coff.c (coff_frob_symbol): Symbol target address offset
(bytes) is adjusted by the frag offset (octets) converted to bytes.
   (coff_frob_section) Section alignment power is in terms of bytes;
convert it to an octet alignment power when calculating size (and size
mask) in octets.  Don't modify the section size in order to "align" it
for TI COFF, since that format has a different method for storing
alignment information.



Index: gas/as.h
===================================================================
RCS file: /cvs/binutils/binutils/gas/as.h,v
retrieving revision 1.5
diff -c -3 -p -r1.5 as.h
*** as.h	1999/10/11 04:07:10	1.5
--- as.h	2000/01/26 12:52:52
*************** void eh_frame_convert_frag PARAMS ((frag
*** 643,648 ****
--- 643,658 ----
  #define BSS_SECTION_NAME	".bss"
  #endif
  
+ #ifndef OCTETS_PER_BYTE_POWER
+ #define OCTETS_PER_BYTE_POWER 0
+ #endif
+ #ifndef OCTETS_PER_BYTE
+ #define OCTETS_PER_BYTE (1<<OCTETS_PER_BYTE_POWER)
+ #endif
+ #if OCTETS_PER_BYTE != (1<<OCTETS_PER_BYTE_POWER)
+  #error "Octets per byte conflicts with its power-of-two definition!"
+ #endif
+ 
  #endif /* GAS */
  
  /* end of as.h */
Index: gas/frags.c
===================================================================
RCS file: /cvs/binutils/binutils/gas/frags.c,v
retrieving revision 1.1.1.1
diff -c -3 -p -r1.1.1.1 frags.c
*** frags.c	1999/05/03 07:28:40	1.1.1.1
--- frags.c	2000/01/26 12:52:52
*************** frag_new (old_frags_var_max_size)
*** 114,120 ****
    assert (frchain_now->frch_last == frag_now);
  
    /* Fix up old frag's fr_fix.  */
!   frag_now->fr_fix = frag_now_fix () - old_frags_var_max_size;
    /* Make sure its type is valid.  */
    assert (frag_now->fr_type != 0);
  
--- 114,120 ----
    assert (frchain_now->frch_last == frag_now);
  
    /* Fix up old frag's fr_fix.  */
!   frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size;
    /* Make sure its type is valid.  */
    assert (frag_now->fr_type != 0);
  
*************** frag_align_pattern (alignment, fill_patt
*** 336,347 ****
  }
  
  addressT
! frag_now_fix ()
  {
    if (now_seg == absolute_section)
      return abs_section_offset;
!   return (addressT) ((char*) obstack_next_free (&frchain_now->frch_obstack)
! 		     - frag_now->fr_literal);
  }
  
  void
--- 336,354 ----
  }
  
  addressT
! frag_now_fix_octets ()
  {
    if (now_seg == absolute_section)
      return abs_section_offset;
! 
!   return ((char*) obstack_next_free (&frchain_now->frch_obstack)
!           - frag_now->fr_literal);
! }
! 
! addressT
! frag_now_fix ()
! {
!   return frag_now_fix_octets() / OCTETS_PER_BYTE;
  }
  
  void
Index: gas/frags.h
===================================================================
RCS file: /cvs/binutils/binutils/gas/frags.h,v
retrieving revision 1.2
diff -c -3 -p -r1.2 frags.h
*** frags.h	1999/06/03 00:29:02	1.2
--- frags.h	2000/01/26 12:52:52
*************** struct obstack;
*** 44,57 ****
  
  struct frag
  {
!   /* Object file address. */
    addressT fr_address;
    /* Chain forward; ascending address order.  Rooted in frch_root. */
    struct frag *fr_next;
  
!   /* (Fixed) number of chars we know we have.  May be 0. */
    offsetT fr_fix;
!   /* (Variable) number of chars after above.  May be 0. */
    offsetT fr_var;
    /* For variable-length tail. */
    symbolS *fr_symbol;
--- 44,57 ----
  
  struct frag
  {
!   /* Object file address (as an octet offset). */
    addressT fr_address;
    /* Chain forward; ascending address order.  Rooted in frch_root. */
    struct frag *fr_next;
  
!   /* (Fixed) number of octets we know we have.  May be 0. */
    offsetT fr_fix;
!   /* (Variable) number of octets after above.  May be 0. */
    offsetT fr_var;
    /* For variable-length tail. */
    symbolS *fr_symbol;
*************** struct frag
*** 101,106 ****
--- 101,107 ----
     instead, use frag_now_fix ().  */
  COMMON fragS *frag_now;
  extern addressT frag_now_fix PARAMS ((void));
+ extern addressT frag_now_fix_octets PARAMS ((void));
  
  /* For foreign-segment symbol fixups. */
  COMMON fragS zero_address_frag;
Index: gas/listing.c
===================================================================
RCS file: /cvs/binutils/binutils/gas/listing.c,v
retrieving revision 1.4
diff -c -3 -p -r1.4 listing.c
*** listing.c	1999/07/11 20:19:57	1.4
--- listing.c	2000/01/26 12:52:52
*************** calc_hex (list)
*** 596,602 ****
    unsigned int address = ~ (unsigned int) 0;
    fragS *frag;
    fragS *frag_ptr;
!   unsigned int byte_in_frag;
  
    /* Find first frag which says it belongs to this line */
    frag = list->frag;
--- 596,602 ----
    unsigned int address = ~ (unsigned int) 0;
    fragS *frag;
    fragS *frag_ptr;
!   unsigned int octet_in_frag;
  
    /* Find first frag which says it belongs to this line */
    frag = list->frag;
*************** calc_hex (list)
*** 611,643 ****
    while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
      {
        /* Print as many bytes from the fixed part as is sensible */
!       byte_in_frag = 0;
!       while ((offsetT) byte_in_frag < frag_ptr->fr_fix
  	     && data_buffer_size < MAX_BYTES - 3)
  	{
  	  if (address == ~ (unsigned int) 0)
  	    {
! 	      address = frag_ptr->fr_address;
  	    }
  
  	  sprintf (data_buffer + data_buffer_size,
  		   "%02X",
! 		   (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
  	  data_buffer_size += 2;
! 	  byte_in_frag++;
  	}
        {
! 	unsigned int var_rep_max = byte_in_frag;
! 	unsigned int var_rep_idx = byte_in_frag;
  
  	/* Print as many bytes from the variable part as is sensible */
! 	while (((offsetT) byte_in_frag
! 		< frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)
  	       && data_buffer_size < MAX_BYTES - 3)
  	  {
  	    if (address == ~ (unsigned int) 0)
  	      {
! 		address = frag_ptr->fr_address;
  	      }
  	    sprintf (data_buffer + data_buffer_size,
  		     "%02X",
--- 611,643 ----
    while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
      {
        /* Print as many bytes from the fixed part as is sensible */
!       octet_in_frag = 0;
!       while ((offsetT) octet_in_frag < frag_ptr->fr_fix
  	     && data_buffer_size < MAX_BYTES - 3)
  	{
  	  if (address == ~ (unsigned int) 0)
  	    {
! 	      address = frag_ptr->fr_address / OCTETS_PER_BYTE;
  	    }
  
  	  sprintf (data_buffer + data_buffer_size,
  		   "%02X",
! 		   (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
  	  data_buffer_size += 2;
! 	  octet_in_frag++;
  	}
        {
! 	unsigned int var_rep_max = octet_in_frag;
! 	unsigned int var_rep_idx = octet_in_frag;
  
  	/* Print as many bytes from the variable part as is sensible */
! 	while (((offsetT) octet_in_frag
! 		< (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
  	       && data_buffer_size < MAX_BYTES - 3)
  	  {
  	    if (address == ~ (unsigned int) 0)
  	      {
! 		address = frag_ptr->fr_address / OCTETS_PER_BYTE;
  	      }
  	    sprintf (data_buffer + data_buffer_size,
  		     "%02X",
*************** calc_hex (list)
*** 649,655 ****
  	    data_buffer_size += 2;
  
  	    var_rep_idx++;
! 	    byte_in_frag++;
  
  	    if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
  	      var_rep_idx = var_rep_max;
--- 649,655 ----
  	    data_buffer_size += 2;
  
  	    var_rep_idx++;
! 	    octet_in_frag++;
  
  	    if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
  	      var_rep_idx = var_rep_max;
*************** print_lines (list, lineno, string, addre
*** 677,684 ****
    unsigned int idx;
    unsigned int nchars;
    unsigned int lines;
!   unsigned int byte_in_word = 0;
    char *src = data_buffer;
  
    /* Print the stuff on the first line */
    listing_page (list);
--- 677,686 ----
    unsigned int idx;
    unsigned int nchars;
    unsigned int lines;
!   unsigned int octet_in_word = 0;
    char *src = data_buffer;
+   int end = strlen(src);
+   int cur;
  
    /* Print the stuff on the first line */
    listing_page (list);
*************** print_lines (list, lineno, string, addre
*** 707,724 ****
  
    /* And the data to go along with it */
    idx = 0;
!   
!   while (*src && idx < nchars)
      {
!       fprintf (list_file, "%c%c", src[0], src[1]);
!       src += 2;
!       byte_in_word++;
        
!       if (byte_in_word == LISTING_WORD_SIZE)
  	{
  	  fprintf (list_file, " ");
  	  idx++;
! 	  byte_in_word = 0;
  	}
        
        idx += 2;
--- 709,735 ----
  
    /* And the data to go along with it */
    idx = 0;
!   cur = 0;
!   while (src[cur] && idx < nchars)
      {
!       int offset;
! #if TARGET_BYTES_BIG_ENDIAN != 0
!       offset = cur;
!       fprintf (list_file, "%c%c", src[offset], src[offset+1]);
! #else
!       offset = (cur & ~(LISTING_WORD_SIZE * 2 - 1)) 
!         + (LISTING_WORD_SIZE - octet_in_word - 1) * 2;
!       if (offset < end)
!         fprintf (list_file, "%c%c", src[offset], src[offset+1]);
! #endif
!       cur += 2;
!       octet_in_word++;
        
!       if (octet_in_word == LISTING_WORD_SIZE)
  	{
  	  fprintf (list_file, " ");
  	  idx++;
! 	  octet_in_word = 0;
  	}
        
        idx += 2;
*************** print_lines (list, lineno, string, addre
*** 740,746 ****
    
    for (lines = 0;
         lines < (unsigned int) listing_lhs_cont_lines
! 	 && *src;
         lines ++)
      {
        nchars = ((LISTING_WORD_SIZE * 2) + 1)
--- 751,757 ----
    
    for (lines = 0;
         lines < (unsigned int) listing_lhs_cont_lines
! 	 && src[cur];
         lines ++)
      {
        nchars = ((LISTING_WORD_SIZE * 2) + 1)
*************** print_lines (list, lineno, string, addre
*** 750,767 ****
        /* Print any more lines of data, but more compactly */
        fprintf (list_file, "% 4d      ", lineno);
        
!       while (*src && idx < nchars)
  	{
! 	  fprintf (list_file, "%c%c", src[0], src[1]);
! 	  src += 2;
  	  idx += 2;
! 	  byte_in_word++;
  	  
! 	  if (byte_in_word == LISTING_WORD_SIZE)
  	    {
  	      fprintf (list_file, " ");
  	      idx++;
! 	      byte_in_word = 0;
  	    }
  	}
        
--- 761,787 ----
        /* Print any more lines of data, but more compactly */
        fprintf (list_file, "% 4d      ", lineno);
        
!       while (src[cur] && idx < nchars)
  	{
!           int offset;
! #if TARGET_BYTES_BIG_ENDIAN != 0
!           offset = cur;
!           fprintf (list_file, "%c%c", src[offset], src[offset+1]);
! #else
!           offset = (cur & ~(LISTING_WORD_SIZE * 2 - 1))
!             + (LISTING_WORD_SIZE - octet_in_word - 1) * 2;
!           if (offset < end)
!             fprintf (list_file, "%c%c", src[offset], src[offset+1]);
! #endif
! 	  cur += 2;
  	  idx += 2;
! 	  octet_in_word++;
  	  
! 	  if (octet_in_word == LISTING_WORD_SIZE)
  	    {
  	      fprintf (list_file, " ");
  	      idx++;
! 	      octet_in_word = 0;
  	    }
  	}
        
Index: gas/read.c
===================================================================
RCS file: /cvs/binutils/binutils/gas/read.c,v
retrieving revision 1.9
diff -c -3 -p -r1.9 read.c
*** read.c	1999/11/03 22:14:47	1.9
--- read.c	2000/01/26 12:52:53
*************** do_align (n, fill, len, max)
*** 1194,1200 ****
   just_record_alignment:
  #endif
  
!   record_alignment (now_seg, n);
  }
  
  /* Handle the .align pseudo-op.  A positive ARG is a default alignment
--- 1194,1200 ----
   just_record_alignment:
  #endif
  
!   record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
  }
  
  /* Handle the .align pseudo-op.  A positive ARG is a default alignment
*************** do_org (segment, exp, fill)
*** 2364,2370 ****
        char *p;
  
        p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp->X_add_symbol,
! 		    exp->X_add_number, (char *) NULL);
        *p = fill;
      }
  }
--- 2364,2370 ----
        char *p;
  
        p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp->X_add_symbol,
! 		    exp->X_add_number * OCTETS_PER_BYTE, (char *) NULL);
        *p = fill;
      }
  }
Index: gas/symbols.c
===================================================================
RCS file: /cvs/binutils/binutils/gas/symbols.c,v
retrieving revision 1.10
diff -c -3 -p -r1.10 symbols.c
*** symbols.c	1999/08/03 15:29:03	1.10
--- symbols.c	2000/01/26 12:52:53
*************** resolve_symbol_value (symp, finalize)
*** 856,865 ****
        struct local_symbol *locsym = (struct local_symbol *) symp;
  
        if (local_symbol_resolved_p (locsym))
! 	return locsym->lsy_offset;
  
        final_val = (local_symbol_get_frag (locsym)->fr_address
! 		   + locsym->lsy_offset);
  
        if (finalize)
  	{
--- 856,865 ----
        struct local_symbol *locsym = (struct local_symbol *) symp;
  
        if (local_symbol_resolved_p (locsym))
! 	return locsym->lsy_offset / OCTETS_PER_BYTE;
  
        final_val = (local_symbol_get_frag (locsym)->fr_address
! 		   + locsym->lsy_offset) / OCTETS_PER_BYTE;
  
        if (finalize)
  	{
*************** resolve_symbol_value (symp, finalize)
*** 915,921 ****
  	  /* Fall through.  */
  
  	case O_constant:
! 	  final_val += symp->sy_frag->fr_address;
  	  if (final_seg == expr_section)
  	    final_seg = absolute_section;
  	  resolved = 1;
--- 915,921 ----
  	  /* Fall through.  */
  
  	case O_constant:
! 	  final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE;
  	  if (final_seg == expr_section)
  	    final_seg = absolute_section;
  	  resolved = 1;
Index: gas/config/obj-coff.c
===================================================================
RCS file: /cvs/binutils/binutils/gas/config/obj-coff.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 obj-coff.c
*** obj-coff.c	1999/09/12 03:44:41	1.19
--- obj-coff.c	2000/01/26 12:52:54
*************** coff_frob_symbol (symp, punt)
*** 1269,1275 ****
        for (; i > 0; i--)
  	{
  	  if (lptr->frag)
! 	    lptr->l.u.offset += lptr->frag->fr_address;
  	  l[i] = lptr->l;
  	  lptr = lptr->next;
  	}
--- 1269,1275 ----
        for (; i > 0; i--)
  	{
  	  if (lptr->frag)
! 	    lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
  	  l[i] = lptr->l;
  	  lptr = lptr->next;
  	}
*************** coff_frob_section (sec)
*** 1453,1477 ****
    char *p;
    fragS *fragp;
    bfd_vma size, n_entries, mask;
  
    /* The COFF back end in BFD requires that all section sizes be
!      rounded up to multiples of the corresponding section alignments.
!      Seems kinda silly to me, but that's the way it is.  */
    size = bfd_get_section_size_before_reloc (sec);
!   mask = ((bfd_vma) 1 << (bfd_vma) sec->alignment_power) - 1;
    if (size & mask)
      {
        size = (size + mask) & ~mask;
        bfd_set_section_size (stdoutput, sec, size);
      }
  
    /* If the section size is non-zero, the section symbol needs an aux
       entry associated with it, indicating the size.  We don't know
       all the values yet; coff_frob_symbol will fill them in later.  */
    if (size != 0
        || sec == text_section
        || sec == data_section
        || sec == bss_section)
      {
        symbolS *secsym = section_symbol (sec);
  
--- 1453,1484 ----
    char *p;
    fragS *fragp;
    bfd_vma size, n_entries, mask;
+   bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
  
    /* The COFF back end in BFD requires that all section sizes be
!      rounded up to multiples of the corresponding section alignments,
!      supposedly because standard COFF has no other way of encoding alignment
!      for sections.  If your COFF flavor has a different way of encoding
!      section alignment, then skip this step, as TICOFF does. */
    size = bfd_get_section_size_before_reloc (sec);
!   mask = ((bfd_vma) 1 << align_power) - 1;
! #if !defined(TICOFF)
    if (size & mask)
      {
        size = (size + mask) & ~mask;
        bfd_set_section_size (stdoutput, sec, size);
      }
+ #endif
  
    /* If the section size is non-zero, the section symbol needs an aux
       entry associated with it, indicating the size.  We don't know
       all the values yet; coff_frob_symbol will fill them in later.  */
+ #ifndef TICOFF
    if (size != 0
        || sec == text_section
        || sec == data_section
        || sec == bss_section)
+ #endif
      {
        symbolS *secsym = section_symbol (sec);
  

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