OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [ieee.c] - Diff between revs 578 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 578 Rev 1765
/* BFD back-end for ieee-695 objects.
/* BFD back-end for ieee-695 objects.
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
   2000, 2001
   2000, 2001
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
   Written by Steve Chamberlain of Cygnus Support.
   Written by Steve Chamberlain of Cygnus Support.
 
 
This file is part of BFD, the Binary File Descriptor library.
This file is part of BFD, the Binary File Descriptor library.
 
 
This program is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
#define KEEPMINUSPCININST 0
#define KEEPMINUSPCININST 0
 
 
/* IEEE 695 format is a stream of records, which we parse using a simple one-
/* IEEE 695 format is a stream of records, which we parse using a simple one-
   token (which is one byte in this lexicon) lookahead recursive decent
   token (which is one byte in this lexicon) lookahead recursive decent
   parser.  */
   parser.  */
 
 
#include "bfd.h"
#include "bfd.h"
#include "sysdep.h"
#include "sysdep.h"
#include "libbfd.h"
#include "libbfd.h"
#include "ieee.h"
#include "ieee.h"
#include "libieee.h"
#include "libieee.h"
 
 
#include <ctype.h>
#include <ctype.h>
 
 
static boolean ieee_write_byte PARAMS ((bfd *, int));
static boolean ieee_write_byte PARAMS ((bfd *, int));
static boolean ieee_write_2bytes PARAMS ((bfd *, int));
static boolean ieee_write_2bytes PARAMS ((bfd *, int));
static boolean ieee_write_int PARAMS ((bfd *, bfd_vma));
static boolean ieee_write_int PARAMS ((bfd *, bfd_vma));
static boolean ieee_write_id PARAMS ((bfd *, const char *));
static boolean ieee_write_id PARAMS ((bfd *, const char *));
static boolean ieee_write_expression
static boolean ieee_write_expression
  PARAMS ((bfd *, bfd_vma, asymbol *, boolean, unsigned int));
  PARAMS ((bfd *, bfd_vma, asymbol *, boolean, unsigned int));
static void ieee_write_int5 PARAMS ((bfd_byte *, bfd_vma));
static void ieee_write_int5 PARAMS ((bfd_byte *, bfd_vma));
static boolean ieee_write_int5_out PARAMS ((bfd *, bfd_vma));
static boolean ieee_write_int5_out PARAMS ((bfd *, bfd_vma));
static boolean ieee_write_section_part PARAMS ((bfd *));
static boolean ieee_write_section_part PARAMS ((bfd *));
static boolean do_with_relocs PARAMS ((bfd *, asection *));
static boolean do_with_relocs PARAMS ((bfd *, asection *));
static boolean do_as_repeat PARAMS ((bfd *, asection *));
static boolean do_as_repeat PARAMS ((bfd *, asection *));
static boolean do_without_relocs PARAMS ((bfd *, asection *));
static boolean do_without_relocs PARAMS ((bfd *, asection *));
static boolean ieee_write_external_part PARAMS ((bfd *));
static boolean ieee_write_external_part PARAMS ((bfd *));
static boolean ieee_write_data_part PARAMS ((bfd *));
static boolean ieee_write_data_part PARAMS ((bfd *));
static boolean ieee_write_debug_part PARAMS ((bfd *));
static boolean ieee_write_debug_part PARAMS ((bfd *));
static boolean ieee_write_me_part PARAMS ((bfd *));
static boolean ieee_write_me_part PARAMS ((bfd *));
static boolean ieee_write_processor PARAMS ((bfd *));
static boolean ieee_write_processor PARAMS ((bfd *));
 
 
static boolean ieee_slurp_debug PARAMS ((bfd *));
static boolean ieee_slurp_debug PARAMS ((bfd *));
static boolean ieee_slurp_section_data PARAMS ((bfd *));
static boolean ieee_slurp_section_data PARAMS ((bfd *));
 
 
/* Functions for writing to ieee files in the strange way that the
/* Functions for writing to ieee files in the strange way that the
   standard requires. */
   standard requires. */
 
 
static boolean
static boolean
ieee_write_byte (abfd, barg)
ieee_write_byte (abfd, barg)
     bfd *abfd;
     bfd *abfd;
     int barg;
     int barg;
{
{
  bfd_byte byte;
  bfd_byte byte;
 
 
  byte = barg;
  byte = barg;
  if (bfd_write ((PTR) &byte, 1, 1, abfd) != 1)
  if (bfd_write ((PTR) &byte, 1, 1, abfd) != 1)
    return false;
    return false;
  return true;
  return true;
}
}
 
 
static boolean
static boolean
ieee_write_2bytes (abfd, bytes)
ieee_write_2bytes (abfd, bytes)
     bfd *abfd;
     bfd *abfd;
     int bytes;
     int bytes;
{
{
  bfd_byte buffer[2];
  bfd_byte buffer[2];
 
 
  buffer[0] = bytes >> 8;
  buffer[0] = bytes >> 8;
  buffer[1] = bytes & 0xff;
  buffer[1] = bytes & 0xff;
  if (bfd_write ((PTR) buffer, 1, 2, abfd) != 2)
  if (bfd_write ((PTR) buffer, 1, 2, abfd) != 2)
    return false;
    return false;
  return true;
  return true;
}
}
 
 
static boolean
static boolean
ieee_write_int (abfd, value)
ieee_write_int (abfd, value)
     bfd *abfd;
     bfd *abfd;
     bfd_vma value;
     bfd_vma value;
{
{
  if (value <= 127)
  if (value <= 127)
    {
    {
      if (! ieee_write_byte (abfd, (bfd_byte) value))
      if (! ieee_write_byte (abfd, (bfd_byte) value))
        return false;
        return false;
    }
    }
  else
  else
    {
    {
      unsigned int length;
      unsigned int length;
 
 
      /* How many significant bytes ? */
      /* How many significant bytes ? */
      /* FIXME FOR LONGER INTS */
      /* FIXME FOR LONGER INTS */
      if (value & 0xff000000)
      if (value & 0xff000000)
        length = 4;
        length = 4;
      else if (value & 0x00ff0000)
      else if (value & 0x00ff0000)
        length = 3;
        length = 3;
      else if (value & 0x0000ff00)
      else if (value & 0x0000ff00)
        length = 2;
        length = 2;
      else
      else
        length = 1;
        length = 1;
 
 
      if (! ieee_write_byte (abfd,
      if (! ieee_write_byte (abfd,
                             (bfd_byte) ((int) ieee_number_repeat_start_enum
                             (bfd_byte) ((int) ieee_number_repeat_start_enum
                                         + length)))
                                         + length)))
        return false;
        return false;
      switch (length)
      switch (length)
        {
        {
        case 4:
        case 4:
          if (! ieee_write_byte (abfd, (bfd_byte) (value >> 24)))
          if (! ieee_write_byte (abfd, (bfd_byte) (value >> 24)))
            return false;
            return false;
          /* Fall through.  */
          /* Fall through.  */
        case 3:
        case 3:
          if (! ieee_write_byte (abfd, (bfd_byte) (value >> 16)))
          if (! ieee_write_byte (abfd, (bfd_byte) (value >> 16)))
            return false;
            return false;
          /* Fall through.  */
          /* Fall through.  */
        case 2:
        case 2:
          if (! ieee_write_byte (abfd, (bfd_byte) (value >> 8)))
          if (! ieee_write_byte (abfd, (bfd_byte) (value >> 8)))
            return false;
            return false;
          /* Fall through.  */
          /* Fall through.  */
        case 1:
        case 1:
          if (! ieee_write_byte (abfd, (bfd_byte) (value)))
          if (! ieee_write_byte (abfd, (bfd_byte) (value)))
            return false;
            return false;
        }
        }
    }
    }
 
 
  return true;
  return true;
}
}
 
 
static boolean
static boolean
ieee_write_id (abfd, id)
ieee_write_id (abfd, id)
     bfd *abfd;
     bfd *abfd;
     const char *id;
     const char *id;
{
{
  size_t length = strlen (id);
  size_t length = strlen (id);
 
 
  if (length <= 127)
  if (length <= 127)
    {
    {
      if (! ieee_write_byte (abfd, (bfd_byte) length))
      if (! ieee_write_byte (abfd, (bfd_byte) length))
        return false;
        return false;
    }
    }
  else if (length < 255)
  else if (length < 255)
    {
    {
      if (! ieee_write_byte (abfd, ieee_extension_length_1_enum)
      if (! ieee_write_byte (abfd, ieee_extension_length_1_enum)
          || ! ieee_write_byte (abfd, (bfd_byte) length))
          || ! ieee_write_byte (abfd, (bfd_byte) length))
        return false;
        return false;
    }
    }
  else if (length < 65535)
  else if (length < 65535)
    {
    {
      if (! ieee_write_byte (abfd, ieee_extension_length_2_enum)
      if (! ieee_write_byte (abfd, ieee_extension_length_2_enum)
          || ! ieee_write_2bytes (abfd, (int) length))
          || ! ieee_write_2bytes (abfd, (int) length))
        return false;
        return false;
    }
    }
  else
  else
    {
    {
      (*_bfd_error_handler)
      (*_bfd_error_handler)
        (_("%s: string too long (%d chars, max 65535)"),
        (_("%s: string too long (%d chars, max 65535)"),
         bfd_get_filename (abfd), length);
         bfd_get_filename (abfd), length);
      bfd_set_error (bfd_error_invalid_operation);
      bfd_set_error (bfd_error_invalid_operation);
      return false;
      return false;
    }
    }
 
 
  if (bfd_write ((PTR) id, 1, length, abfd) != length)
  if (bfd_write ((PTR) id, 1, length, abfd) != length)
    return false;
    return false;
  return true;
  return true;
}
}


/***************************************************************************
/***************************************************************************
Functions for reading from ieee files in the strange way that the
Functions for reading from ieee files in the strange way that the
standard requires:
standard requires:
*/
*/
 
 
#define this_byte(ieee) *((ieee)->input_p)
#define this_byte(ieee) *((ieee)->input_p)
#define next_byte(ieee) ((ieee)->input_p++)
#define next_byte(ieee) ((ieee)->input_p++)
#define this_byte_and_next(ieee) (*((ieee)->input_p++))
#define this_byte_and_next(ieee) (*((ieee)->input_p++))
 
 
static unsigned short
static unsigned short
read_2bytes (ieee)
read_2bytes (ieee)
     common_header_type *ieee;
     common_header_type *ieee;
{
{
  unsigned char c1 = this_byte_and_next (ieee);
  unsigned char c1 = this_byte_and_next (ieee);
  unsigned char c2 = this_byte_and_next (ieee);
  unsigned char c2 = this_byte_and_next (ieee);
  return (c1 << 8) | c2;
  return (c1 << 8) | c2;
}
}
 
 
static void
static void
bfd_get_string (ieee, string, length)
bfd_get_string (ieee, string, length)
     common_header_type *ieee;
     common_header_type *ieee;
     char *string;
     char *string;
     size_t length;
     size_t length;
{
{
  size_t i;
  size_t i;
  for (i = 0; i < length; i++)
  for (i = 0; i < length; i++)
    {
    {
      string[i] = this_byte_and_next (ieee);
      string[i] = this_byte_and_next (ieee);
    }
    }
}
}
 
 
static char *
static char *
read_id (ieee)
read_id (ieee)
     common_header_type *ieee;
     common_header_type *ieee;
{
{
  size_t length;
  size_t length;
  char *string;
  char *string;
  length = this_byte_and_next (ieee);
  length = this_byte_and_next (ieee);
  if (length <= 0x7f)
  if (length <= 0x7f)
    {
    {
      /* Simple string of length 0 to 127 */
      /* Simple string of length 0 to 127 */
    }
    }
  else if (length == 0xde)
  else if (length == 0xde)
    {
    {
      /* Length is next byte, allowing 0..255 */
      /* Length is next byte, allowing 0..255 */
      length = this_byte_and_next (ieee);
      length = this_byte_and_next (ieee);
    }
    }
  else if (length == 0xdf)
  else if (length == 0xdf)
    {
    {
      /* Length is next two bytes, allowing 0..65535 */
      /* Length is next two bytes, allowing 0..65535 */
      length = this_byte_and_next (ieee);
      length = this_byte_and_next (ieee);
      length = (length * 256) + this_byte_and_next (ieee);
      length = (length * 256) + this_byte_and_next (ieee);
    }
    }
  /* Buy memory and read string */
  /* Buy memory and read string */
  string = bfd_alloc (ieee->abfd, length + 1);
  string = bfd_alloc (ieee->abfd, length + 1);
  if (!string)
  if (!string)
    return NULL;
    return NULL;
  bfd_get_string (ieee, string, length);
  bfd_get_string (ieee, string, length);
  string[length] = 0;
  string[length] = 0;
  return string;
  return string;
}
}
 
 
static boolean
static boolean
ieee_write_expression (abfd, value, symbol, pcrel, index)
ieee_write_expression (abfd, value, symbol, pcrel, index)
     bfd *abfd;
     bfd *abfd;
     bfd_vma value;
     bfd_vma value;
     asymbol *symbol;
     asymbol *symbol;
     boolean pcrel;
     boolean pcrel;
     unsigned int index;
     unsigned int index;
{
{
  unsigned int term_count = 0;
  unsigned int term_count = 0;
 
 
  if (value != 0)
  if (value != 0)
    {
    {
      if (! ieee_write_int (abfd, value))
      if (! ieee_write_int (abfd, value))
        return false;
        return false;
      term_count++;
      term_count++;
    }
    }
 
 
  if (bfd_is_com_section (symbol->section)
  if (bfd_is_com_section (symbol->section)
      || bfd_is_und_section (symbol->section))
      || bfd_is_und_section (symbol->section))
    {
    {
      /* Def of a common symbol */
      /* Def of a common symbol */
      if (! ieee_write_byte (abfd, ieee_variable_X_enum)
      if (! ieee_write_byte (abfd, ieee_variable_X_enum)
          || ! ieee_write_int (abfd, symbol->value))
          || ! ieee_write_int (abfd, symbol->value))
        return false;
        return false;
      term_count++;
      term_count++;
    }
    }
  else if (! bfd_is_abs_section (symbol->section))
  else if (! bfd_is_abs_section (symbol->section))
    {
    {
      /* Ref to defined symbol - */
      /* Ref to defined symbol - */
 
 
      if (symbol->flags & BSF_GLOBAL)
      if (symbol->flags & BSF_GLOBAL)
        {
        {
          if (! ieee_write_byte (abfd, ieee_variable_I_enum)
          if (! ieee_write_byte (abfd, ieee_variable_I_enum)
              || ! ieee_write_int (abfd, symbol->value))
              || ! ieee_write_int (abfd, symbol->value))
            return false;
            return false;
          term_count++;
          term_count++;
        }
        }
      else if (symbol->flags & (BSF_LOCAL | BSF_SECTION_SYM))
      else if (symbol->flags & (BSF_LOCAL | BSF_SECTION_SYM))
        {
        {
          /* This is a reference to a defined local symbol.  We can
          /* This is a reference to a defined local symbol.  We can
             easily do a local as a section+offset.  */
             easily do a local as a section+offset.  */
          if (! ieee_write_byte (abfd, ieee_variable_R_enum)
          if (! ieee_write_byte (abfd, ieee_variable_R_enum)
              || ! ieee_write_byte (abfd,
              || ! ieee_write_byte (abfd,
                                    (bfd_byte) (symbol->section->index
                                    (bfd_byte) (symbol->section->index
                                                + IEEE_SECTION_NUMBER_BASE)))
                                                + IEEE_SECTION_NUMBER_BASE)))
            return false;
            return false;
          term_count++;
          term_count++;
          if (symbol->value != 0)
          if (symbol->value != 0)
            {
            {
              if (! ieee_write_int (abfd, symbol->value))
              if (! ieee_write_int (abfd, symbol->value))
                return false;
                return false;
              term_count++;
              term_count++;
            }
            }
        }
        }
      else
      else
        {
        {
          (*_bfd_error_handler)
          (*_bfd_error_handler)
            (_("%s: unrecognized symbol `%s' flags 0x%x"),
            (_("%s: unrecognized symbol `%s' flags 0x%x"),
             bfd_get_filename (abfd), bfd_asymbol_name (symbol),
             bfd_get_filename (abfd), bfd_asymbol_name (symbol),
             symbol->flags);
             symbol->flags);
          bfd_set_error (bfd_error_invalid_operation);
          bfd_set_error (bfd_error_invalid_operation);
          return false;
          return false;
        }
        }
    }
    }
 
 
  if (pcrel)
  if (pcrel)
    {
    {
      /* subtract the pc from here by asking for PC of this section*/
      /* subtract the pc from here by asking for PC of this section*/
      if (! ieee_write_byte (abfd, ieee_variable_P_enum)
      if (! ieee_write_byte (abfd, ieee_variable_P_enum)
          || ! ieee_write_byte (abfd,
          || ! ieee_write_byte (abfd,
                                (bfd_byte) (index + IEEE_SECTION_NUMBER_BASE))
                                (bfd_byte) (index + IEEE_SECTION_NUMBER_BASE))
          || ! ieee_write_byte (abfd, ieee_function_minus_enum))
          || ! ieee_write_byte (abfd, ieee_function_minus_enum))
        return false;
        return false;
    }
    }
 
 
  /* Handle the degenerate case of a 0 address.  */
  /* Handle the degenerate case of a 0 address.  */
  if (term_count == 0)
  if (term_count == 0)
    {
    {
      if (! ieee_write_int (abfd, 0))
      if (! ieee_write_int (abfd, 0))
        return false;
        return false;
    }
    }
 
 
  while (term_count > 1)
  while (term_count > 1)
    {
    {
      if (! ieee_write_byte (abfd, ieee_function_plus_enum))
      if (! ieee_write_byte (abfd, ieee_function_plus_enum))
        return false;
        return false;
      term_count--;
      term_count--;
    }
    }
 
 
  return true;
  return true;
}
}


/*****************************************************************************/
/*****************************************************************************/
 
 
/*
/*
writes any integer into the buffer supplied and always takes 5 bytes
writes any integer into the buffer supplied and always takes 5 bytes
*/
*/
static void
static void
ieee_write_int5 (buffer, value)
ieee_write_int5 (buffer, value)
     bfd_byte *buffer;
     bfd_byte *buffer;
     bfd_vma value;
     bfd_vma value;
{
{
  buffer[0] = (bfd_byte) ieee_number_repeat_4_enum;
  buffer[0] = (bfd_byte) ieee_number_repeat_4_enum;
  buffer[1] = (value >> 24) & 0xff;
  buffer[1] = (value >> 24) & 0xff;
  buffer[2] = (value >> 16) & 0xff;
  buffer[2] = (value >> 16) & 0xff;
  buffer[3] = (value >> 8) & 0xff;
  buffer[3] = (value >> 8) & 0xff;
  buffer[4] = (value >> 0) & 0xff;
  buffer[4] = (value >> 0) & 0xff;
}
}
 
 
static boolean
static boolean
ieee_write_int5_out (abfd, value)
ieee_write_int5_out (abfd, value)
     bfd *abfd;
     bfd *abfd;
     bfd_vma value;
     bfd_vma value;
{
{
  bfd_byte b[5];
  bfd_byte b[5];
 
 
  ieee_write_int5 (b, value);
  ieee_write_int5 (b, value);
  if (bfd_write ((PTR) b, 1, 5, abfd) != 5)
  if (bfd_write ((PTR) b, 1, 5, abfd) != 5)
    return false;
    return false;
  return true;
  return true;
}
}
 
 
static boolean
static boolean
parse_int (ieee, value_ptr)
parse_int (ieee, value_ptr)
     common_header_type *ieee;
     common_header_type *ieee;
     bfd_vma *value_ptr;
     bfd_vma *value_ptr;
{
{
  int value = this_byte (ieee);
  int value = this_byte (ieee);
  int result;
  int result;
  if (value >= 0 && value <= 127)
  if (value >= 0 && value <= 127)
    {
    {
      *value_ptr = value;
      *value_ptr = value;
      next_byte (ieee);
      next_byte (ieee);
      return true;
      return true;
    }
    }
  else if (value >= 0x80 && value <= 0x88)
  else if (value >= 0x80 && value <= 0x88)
    {
    {
      unsigned int count = value & 0xf;
      unsigned int count = value & 0xf;
      result = 0;
      result = 0;
      next_byte (ieee);
      next_byte (ieee);
      while (count)
      while (count)
        {
        {
          result = (result << 8) | this_byte_and_next (ieee);
          result = (result << 8) | this_byte_and_next (ieee);
          count--;
          count--;
        }
        }
      *value_ptr = result;
      *value_ptr = result;
      return true;
      return true;
    }
    }
  return false;
  return false;
}
}
 
 
static int
static int
parse_i (ieee, ok)
parse_i (ieee, ok)
     common_header_type *ieee;
     common_header_type *ieee;
     boolean *ok;
     boolean *ok;
{
{
  bfd_vma x;
  bfd_vma x;
  *ok = parse_int (ieee, &x);
  *ok = parse_int (ieee, &x);
  return x;
  return x;
}
}
 
 
static bfd_vma
static bfd_vma
must_parse_int (ieee)
must_parse_int (ieee)
     common_header_type *ieee;
     common_header_type *ieee;
{
{
  bfd_vma result;
  bfd_vma result;
  BFD_ASSERT (parse_int (ieee, &result) == true);
  BFD_ASSERT (parse_int (ieee, &result) == true);
  return result;
  return result;
}
}
 
 
typedef struct
typedef struct
{
{
  bfd_vma value;
  bfd_vma value;
  asection *section;
  asection *section;
  ieee_symbol_index_type symbol;
  ieee_symbol_index_type symbol;
} ieee_value_type;
} ieee_value_type;
 
 
 
 
#if KEEPMINUSPCININST
#if KEEPMINUSPCININST
 
 
#define SRC_MASK(arg) arg
#define SRC_MASK(arg) arg
#define PCREL_OFFSET false
#define PCREL_OFFSET false
 
 
#else
#else
 
 
#define SRC_MASK(arg) 0
#define SRC_MASK(arg) 0
#define PCREL_OFFSET true
#define PCREL_OFFSET true
 
 
#endif
#endif
 
 
static reloc_howto_type abs32_howto =
static reloc_howto_type abs32_howto =
  HOWTO (1,
  HOWTO (1,
         0,
         0,
         2,
         2,
         32,
         32,
         false,
         false,
         0,
         0,
         complain_overflow_bitfield,
         complain_overflow_bitfield,
         0,
         0,
         "abs32",
         "abs32",
         true,
         true,
         0xffffffff,
         0xffffffff,
         0xffffffff,
         0xffffffff,
         false);
         false);
 
 
static reloc_howto_type abs16_howto =
static reloc_howto_type abs16_howto =
  HOWTO (1,
  HOWTO (1,
         0,
         0,
         1,
         1,
         16,
         16,
         false,
         false,
         0,
         0,
         complain_overflow_bitfield,
         complain_overflow_bitfield,
         0,
         0,
         "abs16",
         "abs16",
         true,
         true,
         0x0000ffff,
         0x0000ffff,
         0x0000ffff,
         0x0000ffff,
         false);
         false);
 
 
static reloc_howto_type abs8_howto =
static reloc_howto_type abs8_howto =
  HOWTO (1,
  HOWTO (1,
         0,
         0,
         0,
         0,
         8,
         8,
         false,
         false,
         0,
         0,
         complain_overflow_bitfield,
         complain_overflow_bitfield,
         0,
         0,
         "abs8",
         "abs8",
         true,
         true,
         0x000000ff,
         0x000000ff,
         0x000000ff,
         0x000000ff,
         false);
         false);
 
 
static reloc_howto_type rel32_howto =
static reloc_howto_type rel32_howto =
  HOWTO (1,
  HOWTO (1,
         0,
         0,
         2,
         2,
         32,
         32,
         true,
         true,
         0,
         0,
         complain_overflow_signed,
         complain_overflow_signed,
         0,
         0,
         "rel32",
         "rel32",
         true,
         true,
         SRC_MASK (0xffffffff),
         SRC_MASK (0xffffffff),
         0xffffffff,
         0xffffffff,
         PCREL_OFFSET);
         PCREL_OFFSET);
 
 
static reloc_howto_type rel16_howto =
static reloc_howto_type rel16_howto =
  HOWTO (1,
  HOWTO (1,
         0,
         0,
         1,
         1,
         16,
         16,
         true,
         true,
         0,
         0,
         complain_overflow_signed,
         complain_overflow_signed,
         0,
         0,
         "rel16",
         "rel16",
         true,
         true,
         SRC_MASK (0x0000ffff),
         SRC_MASK (0x0000ffff),
         0x0000ffff,
         0x0000ffff,
         PCREL_OFFSET);
         PCREL_OFFSET);
 
 
static reloc_howto_type rel8_howto =
static reloc_howto_type rel8_howto =
  HOWTO (1,
  HOWTO (1,
         0,
         0,
         0,
         0,
         8,
         8,
         true,
         true,
         0,
         0,
         complain_overflow_signed,
         complain_overflow_signed,
         0,
         0,
         "rel8",
         "rel8",
         true,
         true,
         SRC_MASK (0x000000ff),
         SRC_MASK (0x000000ff),
         0x000000ff,
         0x000000ff,
         PCREL_OFFSET);
         PCREL_OFFSET);
 
 
static ieee_symbol_index_type NOSYMBOL = {0, 0};
static ieee_symbol_index_type NOSYMBOL = {0, 0};
 
 
static void
static void
parse_expression (ieee, value, symbol, pcrel, extra, section)
parse_expression (ieee, value, symbol, pcrel, extra, section)
     ieee_data_type *ieee;
     ieee_data_type *ieee;
     bfd_vma *value;
     bfd_vma *value;
     ieee_symbol_index_type *symbol;
     ieee_symbol_index_type *symbol;
     boolean *pcrel;
     boolean *pcrel;
     unsigned int *extra;
     unsigned int *extra;
     asection **section;
     asection **section;
 
 
{
{
#define POS sp[1]
#define POS sp[1]
#define TOS sp[0]
#define TOS sp[0]
#define NOS sp[-1]
#define NOS sp[-1]
#define INC sp++;
#define INC sp++;
#define DEC sp--;
#define DEC sp--;
 
 
  boolean loop = true;
  boolean loop = true;
  ieee_value_type stack[10];
  ieee_value_type stack[10];
 
 
  /* The stack pointer always points to the next unused location */
  /* The stack pointer always points to the next unused location */
#define PUSH(x,y,z) TOS.symbol=x;TOS.section=y;TOS.value=z;INC;
#define PUSH(x,y,z) TOS.symbol=x;TOS.section=y;TOS.value=z;INC;
#define POP(x,y,z) DEC;x=TOS.symbol;y=TOS.section;z=TOS.value;
#define POP(x,y,z) DEC;x=TOS.symbol;y=TOS.section;z=TOS.value;
  ieee_value_type *sp = stack;
  ieee_value_type *sp = stack;
 
 
  while (loop)
  while (loop)
    {
    {
      switch (this_byte (&(ieee->h)))
      switch (this_byte (&(ieee->h)))
        {
        {
        case ieee_variable_P_enum:
        case ieee_variable_P_enum:
          /* P variable, current program counter for section n */
          /* P variable, current program counter for section n */
          {
          {
            int section_n;
            int section_n;
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
            *pcrel = true;
            *pcrel = true;
            section_n = must_parse_int (&(ieee->h));
            section_n = must_parse_int (&(ieee->h));
            PUSH (NOSYMBOL, bfd_abs_section_ptr, 0);
            PUSH (NOSYMBOL, bfd_abs_section_ptr, 0);
            break;
            break;
          }
          }
        case ieee_variable_L_enum:
        case ieee_variable_L_enum:
          /* L variable  address of section N */
          /* L variable  address of section N */
          next_byte (&(ieee->h));
          next_byte (&(ieee->h));
          PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
          PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
          break;
          break;
        case ieee_variable_R_enum:
        case ieee_variable_R_enum:
          /* R variable, logical address of section module */
          /* R variable, logical address of section module */
          /* FIXME, this should be different to L */
          /* FIXME, this should be different to L */
          next_byte (&(ieee->h));
          next_byte (&(ieee->h));
          PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
          PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
          break;
          break;
        case ieee_variable_S_enum:
        case ieee_variable_S_enum:
          /* S variable, size in MAUS of section module */
          /* S variable, size in MAUS of section module */
          next_byte (&(ieee->h));
          next_byte (&(ieee->h));
          PUSH (NOSYMBOL,
          PUSH (NOSYMBOL,
                0,
                0,
                ieee->section_table[must_parse_int (&(ieee->h))]->_raw_size);
                ieee->section_table[must_parse_int (&(ieee->h))]->_raw_size);
          break;
          break;
        case ieee_variable_I_enum:
        case ieee_variable_I_enum:
          /* Push the address of variable n */
          /* Push the address of variable n */
          {
          {
            ieee_symbol_index_type sy;
            ieee_symbol_index_type sy;
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
            sy.index = (int) must_parse_int (&(ieee->h));
            sy.index = (int) must_parse_int (&(ieee->h));
            sy.letter = 'I';
            sy.letter = 'I';
 
 
            PUSH (sy, bfd_abs_section_ptr, 0);
            PUSH (sy, bfd_abs_section_ptr, 0);
          }
          }
          break;
          break;
        case ieee_variable_X_enum:
        case ieee_variable_X_enum:
          /* Push the address of external variable n */
          /* Push the address of external variable n */
          {
          {
            ieee_symbol_index_type sy;
            ieee_symbol_index_type sy;
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
            sy.index = (int) (must_parse_int (&(ieee->h)));
            sy.index = (int) (must_parse_int (&(ieee->h)));
            sy.letter = 'X';
            sy.letter = 'X';
 
 
            PUSH (sy, bfd_und_section_ptr, 0);
            PUSH (sy, bfd_und_section_ptr, 0);
          }
          }
          break;
          break;
        case ieee_function_minus_enum:
        case ieee_function_minus_enum:
          {
          {
            bfd_vma value1, value2;
            bfd_vma value1, value2;
            asection *section1, *section_dummy;
            asection *section1, *section_dummy;
            ieee_symbol_index_type sy;
            ieee_symbol_index_type sy;
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
 
 
            POP (sy, section1, value1);
            POP (sy, section1, value1);
            POP (sy, section_dummy, value2);
            POP (sy, section_dummy, value2);
            PUSH (sy, section1 ? section1 : section_dummy, value2 - value1);
            PUSH (sy, section1 ? section1 : section_dummy, value2 - value1);
          }
          }
          break;
          break;
        case ieee_function_plus_enum:
        case ieee_function_plus_enum:
          {
          {
            bfd_vma value1, value2;
            bfd_vma value1, value2;
            asection *section1;
            asection *section1;
            asection *section2;
            asection *section2;
            ieee_symbol_index_type sy1;
            ieee_symbol_index_type sy1;
            ieee_symbol_index_type sy2;
            ieee_symbol_index_type sy2;
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
 
 
            POP (sy1, section1, value1);
            POP (sy1, section1, value1);
            POP (sy2, section2, value2);
            POP (sy2, section2, value2);
            PUSH (sy1.letter ? sy1 : sy2,
            PUSH (sy1.letter ? sy1 : sy2,
                  bfd_is_abs_section (section1) ? section2 : section1,
                  bfd_is_abs_section (section1) ? section2 : section1,
                  value1 + value2);
                  value1 + value2);
          }
          }
          break;
          break;
        default:
        default:
          {
          {
            bfd_vma va;
            bfd_vma va;
            BFD_ASSERT (this_byte (&(ieee->h)) < (int) ieee_variable_A_enum
            BFD_ASSERT (this_byte (&(ieee->h)) < (int) ieee_variable_A_enum
                    || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum);
                    || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum);
            if (parse_int (&(ieee->h), &va))
            if (parse_int (&(ieee->h), &va))
              {
              {
                PUSH (NOSYMBOL, bfd_abs_section_ptr, va);
                PUSH (NOSYMBOL, bfd_abs_section_ptr, va);
              }
              }
            else
            else
              {
              {
                /*
                /*
                  Thats all that we can understand. As far as I can see
                  Thats all that we can understand. As far as I can see
                  there is a bug in the Microtec IEEE output which I'm
                  there is a bug in the Microtec IEEE output which I'm
                  using to scan, whereby the comma operator is omitted
                  using to scan, whereby the comma operator is omitted
                  sometimes in an expression, giving expressions with too
                  sometimes in an expression, giving expressions with too
                  many terms. We can tell if that's the case by ensuring
                  many terms. We can tell if that's the case by ensuring
                  that sp == stack here. If not, then we've pushed
                  that sp == stack here. If not, then we've pushed
                  something too far, so we keep adding.  */
                  something too far, so we keep adding.  */
 
 
                while (sp != stack + 1)
                while (sp != stack + 1)
                  {
                  {
                    asection *section1;
                    asection *section1;
                    ieee_symbol_index_type sy1;
                    ieee_symbol_index_type sy1;
                    POP (sy1, section1, *extra);
                    POP (sy1, section1, *extra);
                  }
                  }
                {
                {
                  asection *dummy;
                  asection *dummy;
 
 
                  POP (*symbol, dummy, *value);
                  POP (*symbol, dummy, *value);
                  if (section)
                  if (section)
                    *section = dummy;
                    *section = dummy;
                }
                }
 
 
                loop = false;
                loop = false;
              }
              }
          }
          }
        }
        }
    }
    }
}
}
 
 
 
 
#define ieee_seek(abfd, offset) \
#define ieee_seek(abfd, offset) \
  IEEE_DATA(abfd)->h.input_p = IEEE_DATA(abfd)->h.first_byte + offset
  IEEE_DATA(abfd)->h.input_p = IEEE_DATA(abfd)->h.first_byte + offset
 
 
#define ieee_pos(abfd) \
#define ieee_pos(abfd) \
  (IEEE_DATA(abfd)->h.input_p - IEEE_DATA(abfd)->h.first_byte)
  (IEEE_DATA(abfd)->h.input_p - IEEE_DATA(abfd)->h.first_byte)
 
 
static unsigned int last_index;
static unsigned int last_index;
static char last_type;          /* is the index for an X or a D */
static char last_type;          /* is the index for an X or a D */
 
 
static ieee_symbol_type *
static ieee_symbol_type *
get_symbol (abfd,
get_symbol (abfd,
            ieee,
            ieee,
            last_symbol,
            last_symbol,
            symbol_count,
            symbol_count,
            pptr,
            pptr,
            max_index,
            max_index,
            this_type
            this_type
)
)
     bfd *abfd ATTRIBUTE_UNUSED;
     bfd *abfd ATTRIBUTE_UNUSED;
     ieee_data_type *ieee;
     ieee_data_type *ieee;
     ieee_symbol_type *last_symbol;
     ieee_symbol_type *last_symbol;
     unsigned int *symbol_count;
     unsigned int *symbol_count;
     ieee_symbol_type ***pptr;
     ieee_symbol_type ***pptr;
     unsigned int *max_index;
     unsigned int *max_index;
     char this_type
     char this_type
      ;
      ;
{
{
  /* Need a new symbol */
  /* Need a new symbol */
  unsigned int new_index = must_parse_int (&(ieee->h));
  unsigned int new_index = must_parse_int (&(ieee->h));
  if (new_index != last_index || this_type != last_type)
  if (new_index != last_index || this_type != last_type)
    {
    {
      ieee_symbol_type *new_symbol = (ieee_symbol_type *) bfd_alloc (ieee->h.abfd,
      ieee_symbol_type *new_symbol = (ieee_symbol_type *) bfd_alloc (ieee->h.abfd,
                                                 sizeof (ieee_symbol_type));
                                                 sizeof (ieee_symbol_type));
      if (!new_symbol)
      if (!new_symbol)
        return NULL;
        return NULL;
 
 
      new_symbol->index = new_index;
      new_symbol->index = new_index;
      last_index = new_index;
      last_index = new_index;
      (*symbol_count)++;
      (*symbol_count)++;
      **pptr = new_symbol;
      **pptr = new_symbol;
      *pptr = &new_symbol->next;
      *pptr = &new_symbol->next;
      if (new_index > *max_index)
      if (new_index > *max_index)
        {
        {
          *max_index = new_index;
          *max_index = new_index;
        }
        }
      last_type = this_type;
      last_type = this_type;
      new_symbol->symbol.section = bfd_abs_section_ptr;
      new_symbol->symbol.section = bfd_abs_section_ptr;
      return new_symbol;
      return new_symbol;
    }
    }
  return last_symbol;
  return last_symbol;
}
}
 
 
static boolean
static boolean
ieee_slurp_external_symbols (abfd)
ieee_slurp_external_symbols (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
  file_ptr offset = ieee->w.r.external_part;
  file_ptr offset = ieee->w.r.external_part;
 
 
  ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols;
  ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols;
  ieee_symbol_type **prev_reference_ptr = &ieee->external_reference;
  ieee_symbol_type **prev_reference_ptr = &ieee->external_reference;
  ieee_symbol_type *symbol = (ieee_symbol_type *) NULL;
  ieee_symbol_type *symbol = (ieee_symbol_type *) NULL;
  unsigned int symbol_count = 0;
  unsigned int symbol_count = 0;
  boolean loop = true;
  boolean loop = true;
  last_index = 0xffffff;
  last_index = 0xffffff;
  ieee->symbol_table_full = true;
  ieee->symbol_table_full = true;
 
 
  ieee_seek (abfd, offset);
  ieee_seek (abfd, offset);
 
 
  while (loop)
  while (loop)
    {
    {
      switch (this_byte (&(ieee->h)))
      switch (this_byte (&(ieee->h)))
        {
        {
        case ieee_nn_record:
        case ieee_nn_record:
          next_byte (&(ieee->h));
          next_byte (&(ieee->h));
 
 
          symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
          symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
                               &prev_symbols_ptr,
                               &prev_symbols_ptr,
                               &ieee->external_symbol_max_index, 'I');
                               &ieee->external_symbol_max_index, 'I');
          if (symbol == NULL)
          if (symbol == NULL)
            return false;
            return false;
 
 
          symbol->symbol.the_bfd = abfd;
          symbol->symbol.the_bfd = abfd;
          symbol->symbol.name = read_id (&(ieee->h));
          symbol->symbol.name = read_id (&(ieee->h));
          symbol->symbol.udata.p = (PTR) NULL;
          symbol->symbol.udata.p = (PTR) NULL;
          symbol->symbol.flags = BSF_NO_FLAGS;
          symbol->symbol.flags = BSF_NO_FLAGS;
          break;
          break;
        case ieee_external_symbol_enum:
        case ieee_external_symbol_enum:
          next_byte (&(ieee->h));
          next_byte (&(ieee->h));
 
 
          symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
          symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
                               &prev_symbols_ptr,
                               &prev_symbols_ptr,
                               &ieee->external_symbol_max_index, 'D');
                               &ieee->external_symbol_max_index, 'D');
          if (symbol == NULL)
          if (symbol == NULL)
            return false;
            return false;
 
 
          BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index);
          BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index);
 
 
          symbol->symbol.the_bfd = abfd;
          symbol->symbol.the_bfd = abfd;
          symbol->symbol.name = read_id (&(ieee->h));
          symbol->symbol.name = read_id (&(ieee->h));
          symbol->symbol.udata.p = (PTR) NULL;
          symbol->symbol.udata.p = (PTR) NULL;
          symbol->symbol.flags = BSF_NO_FLAGS;
          symbol->symbol.flags = BSF_NO_FLAGS;
          break;
          break;
        case ieee_attribute_record_enum >> 8:
        case ieee_attribute_record_enum >> 8:
          {
          {
            unsigned int symbol_name_index;
            unsigned int symbol_name_index;
            unsigned int symbol_type_index;
            unsigned int symbol_type_index;
            unsigned int symbol_attribute_def;
            unsigned int symbol_attribute_def;
            bfd_vma value;
            bfd_vma value;
            switch (read_2bytes (ieee))
            switch (read_2bytes (ieee))
              {
              {
              case ieee_attribute_record_enum:
              case ieee_attribute_record_enum:
                symbol_name_index = must_parse_int (&(ieee->h));
                symbol_name_index = must_parse_int (&(ieee->h));
                symbol_type_index = must_parse_int (&(ieee->h));
                symbol_type_index = must_parse_int (&(ieee->h));
                symbol_attribute_def = must_parse_int (&(ieee->h));
                symbol_attribute_def = must_parse_int (&(ieee->h));
                switch (symbol_attribute_def)
                switch (symbol_attribute_def)
                  {
                  {
                  case 8:
                  case 8:
                  case 19:
                  case 19:
                    parse_int (&ieee->h, &value);
                    parse_int (&ieee->h, &value);
                    break;
                    break;
                  default:
                  default:
                    (*_bfd_error_handler)
                    (*_bfd_error_handler)
                      (_("%s: unimplemented ATI record  %u for symbol %u"),
                      (_("%s: unimplemented ATI record  %u for symbol %u"),
                       bfd_get_filename (abfd), symbol_attribute_def,
                       bfd_get_filename (abfd), symbol_attribute_def,
                       symbol_name_index);
                       symbol_name_index);
                    bfd_set_error (bfd_error_bad_value);
                    bfd_set_error (bfd_error_bad_value);
                    return false;
                    return false;
                    break;
                    break;
                  }
                  }
                break;
                break;
              case ieee_external_reference_info_record_enum:
              case ieee_external_reference_info_record_enum:
                /* Skip over ATX record. */
                /* Skip over ATX record. */
                parse_int (&(ieee->h), &value);
                parse_int (&(ieee->h), &value);
                parse_int (&(ieee->h), &value);
                parse_int (&(ieee->h), &value);
                parse_int (&(ieee->h), &value);
                parse_int (&(ieee->h), &value);
                parse_int (&(ieee->h), &value);
                parse_int (&(ieee->h), &value);
                break;
                break;
              case ieee_atn_record_enum:
              case ieee_atn_record_enum:
                /* We may get call optimization information here,
                /* We may get call optimization information here,
                   which we just ignore.  The format is
                   which we just ignore.  The format is
                   {$F1}${CE}{index}{$00}{$3F}{$3F}{#_of_ASNs} */
                   {$F1}${CE}{index}{$00}{$3F}{$3F}{#_of_ASNs} */
                parse_int (&ieee->h, &value);
                parse_int (&ieee->h, &value);
                parse_int (&ieee->h, &value);
                parse_int (&ieee->h, &value);
                parse_int (&ieee->h, &value);
                parse_int (&ieee->h, &value);
                if (value != 0x3f)
                if (value != 0x3f)
                  {
                  {
                    (*_bfd_error_handler)
                    (*_bfd_error_handler)
                      (_("%s: unexpected ATN type %d in external part"),
                      (_("%s: unexpected ATN type %d in external part"),
                         bfd_get_filename (abfd), (int) value);
                         bfd_get_filename (abfd), (int) value);
                    bfd_set_error (bfd_error_bad_value);
                    bfd_set_error (bfd_error_bad_value);
                    return false;
                    return false;
                  }
                  }
                parse_int (&ieee->h, &value);
                parse_int (&ieee->h, &value);
                parse_int (&ieee->h, &value);
                parse_int (&ieee->h, &value);
                while (value > 0)
                while (value > 0)
                  {
                  {
                    bfd_vma val1;
                    bfd_vma val1;
 
 
                    --value;
                    --value;
 
 
                    switch (read_2bytes (ieee))
                    switch (read_2bytes (ieee))
                      {
                      {
                      case ieee_asn_record_enum:
                      case ieee_asn_record_enum:
                        parse_int (&ieee->h, &val1);
                        parse_int (&ieee->h, &val1);
                        parse_int (&ieee->h, &val1);
                        parse_int (&ieee->h, &val1);
                        break;
                        break;
 
 
                      default:
                      default:
                        (*_bfd_error_handler)
                        (*_bfd_error_handler)
                          (_("%s: unexpected type after ATN"),
                          (_("%s: unexpected type after ATN"),
                             bfd_get_filename (abfd));
                             bfd_get_filename (abfd));
                        bfd_set_error (bfd_error_bad_value);
                        bfd_set_error (bfd_error_bad_value);
                        return false;
                        return false;
                      }
                      }
                  }
                  }
              }
              }
          }
          }
          break;
          break;
        case ieee_value_record_enum >> 8:
        case ieee_value_record_enum >> 8:
          {
          {
            unsigned int symbol_name_index;
            unsigned int symbol_name_index;
            ieee_symbol_index_type symbol_ignore;
            ieee_symbol_index_type symbol_ignore;
            boolean pcrel_ignore;
            boolean pcrel_ignore;
            unsigned int extra;
            unsigned int extra;
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
 
 
            symbol_name_index = must_parse_int (&(ieee->h));
            symbol_name_index = must_parse_int (&(ieee->h));
            parse_expression (ieee,
            parse_expression (ieee,
                              &symbol->symbol.value,
                              &symbol->symbol.value,
                              &symbol_ignore,
                              &symbol_ignore,
                              &pcrel_ignore,
                              &pcrel_ignore,
                              &extra,
                              &extra,
                              &symbol->symbol.section);
                              &symbol->symbol.section);
 
 
            /* Fully linked IEEE-695 files tend to give every symbol
            /* Fully linked IEEE-695 files tend to give every symbol
               an absolute value.  Try to convert that back into a
               an absolute value.  Try to convert that back into a
               section relative value.  FIXME: This won't always to
               section relative value.  FIXME: This won't always to
               the right thing.  */
               the right thing.  */
            if (bfd_is_abs_section (symbol->symbol.section)
            if (bfd_is_abs_section (symbol->symbol.section)
                && (abfd->flags & HAS_RELOC) == 0)
                && (abfd->flags & HAS_RELOC) == 0)
              {
              {
                bfd_vma val;
                bfd_vma val;
                asection *s;
                asection *s;
 
 
                val = symbol->symbol.value;
                val = symbol->symbol.value;
                for (s = abfd->sections; s != NULL; s = s->next)
                for (s = abfd->sections; s != NULL; s = s->next)
                  {
                  {
                    if (val >= s->vma && val < s->vma + s->_raw_size)
                    if (val >= s->vma && val < s->vma + s->_raw_size)
                      {
                      {
                        symbol->symbol.section = s;
                        symbol->symbol.section = s;
                        symbol->symbol.value -= s->vma;
                        symbol->symbol.value -= s->vma;
                        break;
                        break;
                      }
                      }
                  }
                  }
              }
              }
 
 
            symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
            symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
 
 
          }
          }
          break;
          break;
        case ieee_weak_external_reference_enum:
        case ieee_weak_external_reference_enum:
          {
          {
            bfd_vma size;
            bfd_vma size;
            bfd_vma value;
            bfd_vma value;
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
            /* Throw away the external reference index */
            /* Throw away the external reference index */
            (void) must_parse_int (&(ieee->h));
            (void) must_parse_int (&(ieee->h));
            /* Fetch the default size if not resolved */
            /* Fetch the default size if not resolved */
            size = must_parse_int (&(ieee->h));
            size = must_parse_int (&(ieee->h));
            /* Fetch the defautlt value if available */
            /* Fetch the defautlt value if available */
            if (parse_int (&(ieee->h), &value) == false)
            if (parse_int (&(ieee->h), &value) == false)
              {
              {
                value = 0;
                value = 0;
              }
              }
            /* This turns into a common */
            /* This turns into a common */
            symbol->symbol.section = bfd_com_section_ptr;
            symbol->symbol.section = bfd_com_section_ptr;
            symbol->symbol.value = size;
            symbol->symbol.value = size;
          }
          }
          break;
          break;
 
 
        case ieee_external_reference_enum:
        case ieee_external_reference_enum:
          next_byte (&(ieee->h));
          next_byte (&(ieee->h));
 
 
          symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
          symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
                               &prev_reference_ptr,
                               &prev_reference_ptr,
                               &ieee->external_reference_max_index, 'X');
                               &ieee->external_reference_max_index, 'X');
          if (symbol == NULL)
          if (symbol == NULL)
            return false;
            return false;
 
 
          symbol->symbol.the_bfd = abfd;
          symbol->symbol.the_bfd = abfd;
          symbol->symbol.name = read_id (&(ieee->h));
          symbol->symbol.name = read_id (&(ieee->h));
          symbol->symbol.udata.p = (PTR) NULL;
          symbol->symbol.udata.p = (PTR) NULL;
          symbol->symbol.section = bfd_und_section_ptr;
          symbol->symbol.section = bfd_und_section_ptr;
          symbol->symbol.value = (bfd_vma) 0;
          symbol->symbol.value = (bfd_vma) 0;
          symbol->symbol.flags = 0;
          symbol->symbol.flags = 0;
 
 
          BFD_ASSERT (symbol->index >= ieee->external_reference_min_index);
          BFD_ASSERT (symbol->index >= ieee->external_reference_min_index);
          break;
          break;
 
 
        default:
        default:
          loop = false;
          loop = false;
        }
        }
    }
    }
 
 
  if (ieee->external_symbol_max_index != 0)
  if (ieee->external_symbol_max_index != 0)
    {
    {
      ieee->external_symbol_count =
      ieee->external_symbol_count =
        ieee->external_symbol_max_index -
        ieee->external_symbol_max_index -
        ieee->external_symbol_min_index + 1;
        ieee->external_symbol_min_index + 1;
    }
    }
  else
  else
    {
    {
      ieee->external_symbol_count = 0;
      ieee->external_symbol_count = 0;
    }
    }
 
 
  if (ieee->external_reference_max_index != 0)
  if (ieee->external_reference_max_index != 0)
    {
    {
      ieee->external_reference_count =
      ieee->external_reference_count =
        ieee->external_reference_max_index -
        ieee->external_reference_max_index -
        ieee->external_reference_min_index + 1;
        ieee->external_reference_min_index + 1;
    }
    }
  else
  else
    {
    {
      ieee->external_reference_count = 0;
      ieee->external_reference_count = 0;
    }
    }
 
 
  abfd->symcount =
  abfd->symcount =
    ieee->external_reference_count + ieee->external_symbol_count;
    ieee->external_reference_count + ieee->external_symbol_count;
 
 
  if (symbol_count != abfd->symcount)
  if (symbol_count != abfd->symcount)
    {
    {
      /* There are gaps in the table -- */
      /* There are gaps in the table -- */
      ieee->symbol_table_full = false;
      ieee->symbol_table_full = false;
    }
    }
 
 
  *prev_symbols_ptr = (ieee_symbol_type *) NULL;
  *prev_symbols_ptr = (ieee_symbol_type *) NULL;
  *prev_reference_ptr = (ieee_symbol_type *) NULL;
  *prev_reference_ptr = (ieee_symbol_type *) NULL;
 
 
  return true;
  return true;
}
}
 
 
static boolean
static boolean
ieee_slurp_symbol_table (abfd)
ieee_slurp_symbol_table (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  if (IEEE_DATA (abfd)->read_symbols == false)
  if (IEEE_DATA (abfd)->read_symbols == false)
    {
    {
      if (! ieee_slurp_external_symbols (abfd))
      if (! ieee_slurp_external_symbols (abfd))
        return false;
        return false;
      IEEE_DATA (abfd)->read_symbols = true;
      IEEE_DATA (abfd)->read_symbols = true;
    }
    }
  return true;
  return true;
}
}
 
 
long
long
ieee_get_symtab_upper_bound (abfd)
ieee_get_symtab_upper_bound (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  if (! ieee_slurp_symbol_table (abfd))
  if (! ieee_slurp_symbol_table (abfd))
    return -1;
    return -1;
 
 
  return (abfd->symcount != 0) ?
  return (abfd->symcount != 0) ?
    (abfd->symcount + 1) * (sizeof (ieee_symbol_type *)) : 0;
    (abfd->symcount + 1) * (sizeof (ieee_symbol_type *)) : 0;
}
}
 
 
/*
/*
Move from our internal lists to the canon table, and insert in
Move from our internal lists to the canon table, and insert in
symbol index order
symbol index order
*/
*/
 
 
extern const bfd_target ieee_vec;
extern const bfd_target ieee_vec;
 
 
long
long
ieee_get_symtab (abfd, location)
ieee_get_symtab (abfd, location)
     bfd *abfd;
     bfd *abfd;
     asymbol **location;
     asymbol **location;
{
{
  ieee_symbol_type *symp;
  ieee_symbol_type *symp;
  static bfd dummy_bfd;
  static bfd dummy_bfd;
  static asymbol empty_symbol =
  static asymbol empty_symbol =
  {
  {
    &dummy_bfd,
    &dummy_bfd,
    " ieee empty",
    " ieee empty",
    (symvalue) 0,
    (symvalue) 0,
    BSF_DEBUGGING,
    BSF_DEBUGGING,
    bfd_abs_section_ptr
    bfd_abs_section_ptr
#ifdef __STDC__
#ifdef __STDC__
    /* K&R compilers can't initialise unions.  */
    /* K&R compilers can't initialise unions.  */
    , { 0 }
    , { 0 }
#endif
#endif
  };
  };
 
 
  if (abfd->symcount)
  if (abfd->symcount)
    {
    {
      ieee_data_type *ieee = IEEE_DATA (abfd);
      ieee_data_type *ieee = IEEE_DATA (abfd);
      dummy_bfd.xvec = &ieee_vec;
      dummy_bfd.xvec = &ieee_vec;
      if (! ieee_slurp_symbol_table (abfd))
      if (! ieee_slurp_symbol_table (abfd))
        return -1;
        return -1;
 
 
      if (ieee->symbol_table_full == false)
      if (ieee->symbol_table_full == false)
        {
        {
          /* Arrgh - there are gaps in the table, run through and fill them */
          /* Arrgh - there are gaps in the table, run through and fill them */
          /* up with pointers to a null place */
          /* up with pointers to a null place */
          unsigned int i;
          unsigned int i;
          for (i = 0; i < abfd->symcount; i++)
          for (i = 0; i < abfd->symcount; i++)
            {
            {
              location[i] = &empty_symbol;
              location[i] = &empty_symbol;
            }
            }
        }
        }
 
 
      ieee->external_symbol_base_offset = -ieee->external_symbol_min_index;
      ieee->external_symbol_base_offset = -ieee->external_symbol_min_index;
      for (symp = IEEE_DATA (abfd)->external_symbols;
      for (symp = IEEE_DATA (abfd)->external_symbols;
           symp != (ieee_symbol_type *) NULL;
           symp != (ieee_symbol_type *) NULL;
           symp = symp->next)
           symp = symp->next)
        {
        {
          /* Place into table at correct index locations */
          /* Place into table at correct index locations */
          location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol;
          location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol;
        }
        }
 
 
      /* The external refs are indexed in a bit */
      /* The external refs are indexed in a bit */
      ieee->external_reference_base_offset =
      ieee->external_reference_base_offset =
        -ieee->external_reference_min_index + ieee->external_symbol_count;
        -ieee->external_reference_min_index + ieee->external_symbol_count;
 
 
      for (symp = IEEE_DATA (abfd)->external_reference;
      for (symp = IEEE_DATA (abfd)->external_reference;
           symp != (ieee_symbol_type *) NULL;
           symp != (ieee_symbol_type *) NULL;
           symp = symp->next)
           symp = symp->next)
        {
        {
          location[symp->index + ieee->external_reference_base_offset] =
          location[symp->index + ieee->external_reference_base_offset] =
            &symp->symbol;
            &symp->symbol;
 
 
        }
        }
    }
    }
  if (abfd->symcount)
  if (abfd->symcount)
    {
    {
      location[abfd->symcount] = (asymbol *) NULL;
      location[abfd->symcount] = (asymbol *) NULL;
    }
    }
  return abfd->symcount;
  return abfd->symcount;
}
}
 
 
static asection *
static asection *
get_section_entry (abfd, ieee, index)
get_section_entry (abfd, ieee, index)
     bfd *abfd;
     bfd *abfd;
     ieee_data_type *ieee;
     ieee_data_type *ieee;
     unsigned int index;
     unsigned int index;
{
{
  if (index >= ieee->section_table_size)
  if (index >= ieee->section_table_size)
    {
    {
      unsigned int c, i;
      unsigned int c, i;
      asection **n;
      asection **n;
 
 
      c = ieee->section_table_size;
      c = ieee->section_table_size;
      if (c == 0)
      if (c == 0)
        c = 20;
        c = 20;
      while (c <= index)
      while (c <= index)
        c *= 2;
        c *= 2;
 
 
      n = ((asection **)
      n = ((asection **)
           bfd_realloc (ieee->section_table, c * sizeof (asection *)));
           bfd_realloc (ieee->section_table, c * sizeof (asection *)));
      if (n == NULL)
      if (n == NULL)
        return NULL;
        return NULL;
 
 
      for (i = ieee->section_table_size; i < c; i++)
      for (i = ieee->section_table_size; i < c; i++)
        n[i] = NULL;
        n[i] = NULL;
 
 
      ieee->section_table = n;
      ieee->section_table = n;
      ieee->section_table_size = c;
      ieee->section_table_size = c;
    }
    }
 
 
  if (ieee->section_table[index] == (asection *) NULL)
  if (ieee->section_table[index] == (asection *) NULL)
    {
    {
      char *tmp = bfd_alloc (abfd, 11);
      char *tmp = bfd_alloc (abfd, 11);
      asection *section;
      asection *section;
 
 
      if (!tmp)
      if (!tmp)
        return NULL;
        return NULL;
      sprintf (tmp, " fsec%4d", index);
      sprintf (tmp, " fsec%4d", index);
      section = bfd_make_section (abfd, tmp);
      section = bfd_make_section (abfd, tmp);
      ieee->section_table[index] = section;
      ieee->section_table[index] = section;
      section->flags = SEC_NO_FLAGS;
      section->flags = SEC_NO_FLAGS;
      section->target_index = index;
      section->target_index = index;
      ieee->section_table[index] = section;
      ieee->section_table[index] = section;
    }
    }
  return ieee->section_table[index];
  return ieee->section_table[index];
}
}
 
 
static void
static void
ieee_slurp_sections (abfd)
ieee_slurp_sections (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
  file_ptr offset = ieee->w.r.section_part;
  file_ptr offset = ieee->w.r.section_part;
  asection *section = (asection *) NULL;
  asection *section = (asection *) NULL;
  char *name;
  char *name;
 
 
  if (offset != 0)
  if (offset != 0)
    {
    {
      bfd_byte section_type[3];
      bfd_byte section_type[3];
      ieee_seek (abfd, offset);
      ieee_seek (abfd, offset);
      while (true)
      while (true)
        {
        {
          switch (this_byte (&(ieee->h)))
          switch (this_byte (&(ieee->h)))
            {
            {
            case ieee_section_type_enum:
            case ieee_section_type_enum:
              {
              {
                unsigned int section_index;
                unsigned int section_index;
                next_byte (&(ieee->h));
                next_byte (&(ieee->h));
                section_index = must_parse_int (&(ieee->h));
                section_index = must_parse_int (&(ieee->h));
 
 
                section = get_section_entry (abfd, ieee, section_index);
                section = get_section_entry (abfd, ieee, section_index);
 
 
                section_type[0] = this_byte_and_next (&(ieee->h));
                section_type[0] = this_byte_and_next (&(ieee->h));
 
 
                /* Set minimal section attributes. Attributes are
                /* Set minimal section attributes. Attributes are
                   extended later, based on section contents. */
                   extended later, based on section contents. */
 
 
                switch (section_type[0])
                switch (section_type[0])
                  {
                  {
                  case 0xC1:
                  case 0xC1:
                    /* Normal attributes for absolute sections  */
                    /* Normal attributes for absolute sections  */
                    section_type[1] = this_byte (&(ieee->h));
                    section_type[1] = this_byte (&(ieee->h));
                    section->flags = SEC_ALLOC;
                    section->flags = SEC_ALLOC;
                    switch (section_type[1])
                    switch (section_type[1])
                      {
                      {
                      case 0xD3:        /* AS Absolute section attributes */
                      case 0xD3:        /* AS Absolute section attributes */
                        next_byte (&(ieee->h));
                        next_byte (&(ieee->h));
                        section_type[2] = this_byte (&(ieee->h));
                        section_type[2] = this_byte (&(ieee->h));
                        switch (section_type[2])
                        switch (section_type[2])
                          {
                          {
                          case 0xD0:
                          case 0xD0:
                            /* Normal code */
                            /* Normal code */
                            next_byte (&(ieee->h));
                            next_byte (&(ieee->h));
                            section->flags |= SEC_CODE;
                            section->flags |= SEC_CODE;
                            break;
                            break;
                          case 0xC4:
                          case 0xC4:
                            /* Normal data */
                            /* Normal data */
                            next_byte (&(ieee->h));
                            next_byte (&(ieee->h));
                            section->flags |= SEC_DATA;
                            section->flags |= SEC_DATA;
                            break;
                            break;
                          case 0xD2:
                          case 0xD2:
                            next_byte (&(ieee->h));
                            next_byte (&(ieee->h));
                            /* Normal rom data */
                            /* Normal rom data */
                            section->flags |= SEC_ROM | SEC_DATA;
                            section->flags |= SEC_ROM | SEC_DATA;
                            break;
                            break;
                          default:
                          default:
                            break;
                            break;
                          }
                          }
                      }
                      }
                    break;
                    break;
                  case 0xC3:    /* Named relocatable sections (type C) */
                  case 0xC3:    /* Named relocatable sections (type C) */
                    section_type[1] = this_byte (&(ieee->h));
                    section_type[1] = this_byte (&(ieee->h));
                    section->flags = SEC_ALLOC;
                    section->flags = SEC_ALLOC;
                    switch (section_type[1])
                    switch (section_type[1])
                      {
                      {
                      case 0xD0:        /* Normal code (CP) */
                      case 0xD0:        /* Normal code (CP) */
                        next_byte (&(ieee->h));
                        next_byte (&(ieee->h));
                        section->flags |= SEC_CODE;
                        section->flags |= SEC_CODE;
                        break;
                        break;
                      case 0xC4:        /* Normal data (CD) */
                      case 0xC4:        /* Normal data (CD) */
                        next_byte (&(ieee->h));
                        next_byte (&(ieee->h));
                        section->flags |= SEC_DATA;
                        section->flags |= SEC_DATA;
                        break;
                        break;
                      case 0xD2:        /* Normal rom data (CR) */
                      case 0xD2:        /* Normal rom data (CR) */
                        next_byte (&(ieee->h));
                        next_byte (&(ieee->h));
                        section->flags |= SEC_ROM | SEC_DATA;
                        section->flags |= SEC_ROM | SEC_DATA;
                        break;
                        break;
                      default:
                      default:
                        break;
                        break;
                      }
                      }
                  }
                  }
 
 
                /* Read section name, use it if non empty. */
                /* Read section name, use it if non empty. */
                name = read_id (&ieee->h);
                name = read_id (&ieee->h);
                if (name[0])
                if (name[0])
                  section->name = name;
                  section->name = name;
 
 
                /* Skip these fields, which we don't care about */
                /* Skip these fields, which we don't care about */
                {
                {
                  bfd_vma parent, brother, context;
                  bfd_vma parent, brother, context;
                  parse_int (&(ieee->h), &parent);
                  parse_int (&(ieee->h), &parent);
                  parse_int (&(ieee->h), &brother);
                  parse_int (&(ieee->h), &brother);
                  parse_int (&(ieee->h), &context);
                  parse_int (&(ieee->h), &context);
                }
                }
              }
              }
              break;
              break;
            case ieee_section_alignment_enum:
            case ieee_section_alignment_enum:
              {
              {
                unsigned int section_index;
                unsigned int section_index;
                bfd_vma value;
                bfd_vma value;
                asection *section;
                asection *section;
                next_byte (&(ieee->h));
                next_byte (&(ieee->h));
                section_index = must_parse_int (&ieee->h);
                section_index = must_parse_int (&ieee->h);
                section = get_section_entry (abfd, ieee, section_index);
                section = get_section_entry (abfd, ieee, section_index);
                if (section_index > ieee->section_count)
                if (section_index > ieee->section_count)
                  {
                  {
                    ieee->section_count = section_index;
                    ieee->section_count = section_index;
                  }
                  }
                section->alignment_power =
                section->alignment_power =
                  bfd_log2 (must_parse_int (&ieee->h));
                  bfd_log2 (must_parse_int (&ieee->h));
                (void) parse_int (&(ieee->h), &value);
                (void) parse_int (&(ieee->h), &value);
              }
              }
              break;
              break;
            case ieee_e2_first_byte_enum:
            case ieee_e2_first_byte_enum:
              {
              {
                ieee_record_enum_type t = (ieee_record_enum_type) (read_2bytes (&(ieee->h)));
                ieee_record_enum_type t = (ieee_record_enum_type) (read_2bytes (&(ieee->h)));
 
 
                switch (t)
                switch (t)
                  {
                  {
                  case ieee_section_size_enum:
                  case ieee_section_size_enum:
                    section = ieee->section_table[must_parse_int (&(ieee->h))];
                    section = ieee->section_table[must_parse_int (&(ieee->h))];
                    section->_raw_size = must_parse_int (&(ieee->h));
                    section->_raw_size = must_parse_int (&(ieee->h));
                    break;
                    break;
                  case ieee_physical_region_size_enum:
                  case ieee_physical_region_size_enum:
                    section = ieee->section_table[must_parse_int (&(ieee->h))];
                    section = ieee->section_table[must_parse_int (&(ieee->h))];
                    section->_raw_size = must_parse_int (&(ieee->h));
                    section->_raw_size = must_parse_int (&(ieee->h));
                    break;
                    break;
                  case ieee_region_base_address_enum:
                  case ieee_region_base_address_enum:
                    section = ieee->section_table[must_parse_int (&(ieee->h))];
                    section = ieee->section_table[must_parse_int (&(ieee->h))];
                    section->vma = must_parse_int (&(ieee->h));
                    section->vma = must_parse_int (&(ieee->h));
                    section->lma = section->vma;
                    section->lma = section->vma;
                    break;
                    break;
                  case ieee_mau_size_enum:
                  case ieee_mau_size_enum:
                    must_parse_int (&(ieee->h));
                    must_parse_int (&(ieee->h));
                    must_parse_int (&(ieee->h));
                    must_parse_int (&(ieee->h));
                    break;
                    break;
                  case ieee_m_value_enum:
                  case ieee_m_value_enum:
                    must_parse_int (&(ieee->h));
                    must_parse_int (&(ieee->h));
                    must_parse_int (&(ieee->h));
                    must_parse_int (&(ieee->h));
                    break;
                    break;
                  case ieee_section_base_address_enum:
                  case ieee_section_base_address_enum:
                    section = ieee->section_table[must_parse_int (&(ieee->h))];
                    section = ieee->section_table[must_parse_int (&(ieee->h))];
                    section->vma = must_parse_int (&(ieee->h));
                    section->vma = must_parse_int (&(ieee->h));
                    section->lma = section->vma;
                    section->lma = section->vma;
                    break;
                    break;
                  case ieee_section_offset_enum:
                  case ieee_section_offset_enum:
                    (void) must_parse_int (&(ieee->h));
                    (void) must_parse_int (&(ieee->h));
                    (void) must_parse_int (&(ieee->h));
                    (void) must_parse_int (&(ieee->h));
                    break;
                    break;
                  default:
                  default:
                    return;
                    return;
                  }
                  }
              }
              }
              break;
              break;
            default:
            default:
              return;
              return;
            }
            }
        }
        }
    }
    }
}
}
 
 
/* Make a section for the debugging information, if any.  We don't try
/* Make a section for the debugging information, if any.  We don't try
   to interpret the debugging information; we just point the section
   to interpret the debugging information; we just point the section
   at the area in the file so that program which understand can dig it
   at the area in the file so that program which understand can dig it
   out.  */
   out.  */
 
 
static boolean
static boolean
ieee_slurp_debug (abfd)
ieee_slurp_debug (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
  asection *sec;
  asection *sec;
  file_ptr debug_end;
  file_ptr debug_end;
 
 
  if (ieee->w.r.debug_information_part == 0)
  if (ieee->w.r.debug_information_part == 0)
    return true;
    return true;
 
 
  sec = bfd_make_section (abfd, ".debug");
  sec = bfd_make_section (abfd, ".debug");
  if (sec == NULL)
  if (sec == NULL)
    return false;
    return false;
  sec->flags |= SEC_DEBUGGING | SEC_HAS_CONTENTS;
  sec->flags |= SEC_DEBUGGING | SEC_HAS_CONTENTS;
  sec->filepos = ieee->w.r.debug_information_part;
  sec->filepos = ieee->w.r.debug_information_part;
 
 
  debug_end = ieee->w.r.data_part;
  debug_end = ieee->w.r.data_part;
  if (debug_end == 0)
  if (debug_end == 0)
    debug_end = ieee->w.r.trailer_part;
    debug_end = ieee->w.r.trailer_part;
  if (debug_end == 0)
  if (debug_end == 0)
    debug_end = ieee->w.r.me_record;
    debug_end = ieee->w.r.me_record;
  sec->_raw_size = debug_end - ieee->w.r.debug_information_part;
  sec->_raw_size = debug_end - ieee->w.r.debug_information_part;
 
 
  return true;
  return true;
}
}


/***********************************************************************
/***********************************************************************
*  archive stuff
*  archive stuff
*/
*/
 
 
const bfd_target *
const bfd_target *
ieee_archive_p (abfd)
ieee_archive_p (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  char *library;
  char *library;
  unsigned int i;
  unsigned int i;
  unsigned char buffer[512];
  unsigned char buffer[512];
  file_ptr buffer_offset = 0;
  file_ptr buffer_offset = 0;
  ieee_ar_data_type *save = abfd->tdata.ieee_ar_data;
  ieee_ar_data_type *save = abfd->tdata.ieee_ar_data;
  ieee_ar_data_type *ieee;
  ieee_ar_data_type *ieee;
  unsigned int alc_elts;
  unsigned int alc_elts;
  ieee_ar_obstack_type *elts = NULL;
  ieee_ar_obstack_type *elts = NULL;
 
 
  abfd->tdata.ieee_ar_data =
  abfd->tdata.ieee_ar_data =
    (ieee_ar_data_type *) bfd_alloc (abfd, sizeof (ieee_ar_data_type));
    (ieee_ar_data_type *) bfd_alloc (abfd, sizeof (ieee_ar_data_type));
  if (!abfd->tdata.ieee_ar_data)
  if (!abfd->tdata.ieee_ar_data)
    goto error_return;
    goto error_return;
  ieee = IEEE_AR_DATA (abfd);
  ieee = IEEE_AR_DATA (abfd);
 
 
  /* FIXME: Check return value.  I'm not sure whether it needs to read
  /* FIXME: Check return value.  I'm not sure whether it needs to read
     the entire buffer or not.  */
     the entire buffer or not.  */
  bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
  bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
 
 
  ieee->h.first_byte = buffer;
  ieee->h.first_byte = buffer;
  ieee->h.input_p = buffer;
  ieee->h.input_p = buffer;
 
 
  ieee->h.abfd = abfd;
  ieee->h.abfd = abfd;
 
 
  if (this_byte (&(ieee->h)) != Module_Beginning)
  if (this_byte (&(ieee->h)) != Module_Beginning)
    goto got_wrong_format_error;
    goto got_wrong_format_error;
 
 
  next_byte (&(ieee->h));
  next_byte (&(ieee->h));
  library = read_id (&(ieee->h));
  library = read_id (&(ieee->h));
  if (strcmp (library, "LIBRARY") != 0)
  if (strcmp (library, "LIBRARY") != 0)
    goto got_wrong_format_error;
    goto got_wrong_format_error;
 
 
  /* Throw away the filename.  */
  /* Throw away the filename.  */
  read_id (&(ieee->h));
  read_id (&(ieee->h));
 
 
  ieee->element_count = 0;
  ieee->element_count = 0;
  ieee->element_index = 0;
  ieee->element_index = 0;
 
 
  next_byte (&(ieee->h));       /* Drop the ad part.  */
  next_byte (&(ieee->h));       /* Drop the ad part.  */
  must_parse_int (&(ieee->h));  /* And the two dummy numbers.  */
  must_parse_int (&(ieee->h));  /* And the two dummy numbers.  */
  must_parse_int (&(ieee->h));
  must_parse_int (&(ieee->h));
 
 
  alc_elts = 10;
  alc_elts = 10;
  elts = (ieee_ar_obstack_type *) bfd_malloc (alc_elts * sizeof *elts);
  elts = (ieee_ar_obstack_type *) bfd_malloc (alc_elts * sizeof *elts);
  if (elts == NULL)
  if (elts == NULL)
    goto error_return;
    goto error_return;
 
 
  /* Read the index of the BB table.  */
  /* Read the index of the BB table.  */
  while (1)
  while (1)
    {
    {
      int rec;
      int rec;
      ieee_ar_obstack_type *t;
      ieee_ar_obstack_type *t;
 
 
      rec = read_2bytes (&(ieee->h));
      rec = read_2bytes (&(ieee->h));
      if (rec != (int) ieee_assign_value_to_variable_enum)
      if (rec != (int) ieee_assign_value_to_variable_enum)
        break;
        break;
 
 
      if (ieee->element_count >= alc_elts)
      if (ieee->element_count >= alc_elts)
        {
        {
          ieee_ar_obstack_type *n;
          ieee_ar_obstack_type *n;
 
 
          alc_elts *= 2;
          alc_elts *= 2;
          n = ((ieee_ar_obstack_type *)
          n = ((ieee_ar_obstack_type *)
               bfd_realloc (elts, alc_elts * sizeof *elts));
               bfd_realloc (elts, alc_elts * sizeof *elts));
          if (n == NULL)
          if (n == NULL)
            goto error_return;
            goto error_return;
          elts = n;
          elts = n;
        }
        }
 
 
      t = &elts[ieee->element_count];
      t = &elts[ieee->element_count];
      ieee->element_count++;
      ieee->element_count++;
 
 
      must_parse_int (&(ieee->h));
      must_parse_int (&(ieee->h));
      t->file_offset = must_parse_int (&(ieee->h));
      t->file_offset = must_parse_int (&(ieee->h));
      t->abfd = (bfd *) NULL;
      t->abfd = (bfd *) NULL;
 
 
      /* Make sure that we don't go over the end of the buffer.  */
      /* Make sure that we don't go over the end of the buffer.  */
      if ((size_t) ieee_pos (abfd) > sizeof (buffer) / 2)
      if ((size_t) ieee_pos (abfd) > sizeof (buffer) / 2)
        {
        {
          /* Past half way, reseek and reprime.  */
          /* Past half way, reseek and reprime.  */
          buffer_offset += ieee_pos (abfd);
          buffer_offset += ieee_pos (abfd);
          if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0)
          if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0)
            goto error_return;
            goto error_return;
 
 
          /* FIXME: Check return value.  I'm not sure whether it needs
          /* FIXME: Check return value.  I'm not sure whether it needs
             to read the entire buffer or not.  */
             to read the entire buffer or not.  */
          bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
          bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
          ieee->h.first_byte = buffer;
          ieee->h.first_byte = buffer;
          ieee->h.input_p = buffer;
          ieee->h.input_p = buffer;
        }
        }
    }
    }
 
 
  ieee->elements = ((ieee_ar_obstack_type *)
  ieee->elements = ((ieee_ar_obstack_type *)
                    bfd_alloc (abfd,
                    bfd_alloc (abfd,
                               ieee->element_count * sizeof *ieee->elements));
                               ieee->element_count * sizeof *ieee->elements));
  if (ieee->elements == NULL)
  if (ieee->elements == NULL)
    goto error_return;
    goto error_return;
 
 
  memcpy (ieee->elements, elts,
  memcpy (ieee->elements, elts,
          ieee->element_count * sizeof *ieee->elements);
          ieee->element_count * sizeof *ieee->elements);
  free (elts);
  free (elts);
  elts = NULL;
  elts = NULL;
 
 
  /* Now scan the area again, and replace BB offsets with file offsets.  */
  /* Now scan the area again, and replace BB offsets with file offsets.  */
  for (i = 2; i < ieee->element_count; i++)
  for (i = 2; i < ieee->element_count; i++)
    {
    {
      if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0)
      if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0)
        goto error_return;
        goto error_return;
 
 
      /* FIXME: Check return value.  I'm not sure whether it needs to
      /* FIXME: Check return value.  I'm not sure whether it needs to
         read the entire buffer or not.  */
         read the entire buffer or not.  */
      bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
      bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
      ieee->h.first_byte = buffer;
      ieee->h.first_byte = buffer;
      ieee->h.input_p = buffer;
      ieee->h.input_p = buffer;
 
 
      next_byte (&(ieee->h));           /* Drop F8.  */
      next_byte (&(ieee->h));           /* Drop F8.  */
      next_byte (&(ieee->h));           /* Drop 14.  */
      next_byte (&(ieee->h));           /* Drop 14.  */
      must_parse_int (&(ieee->h));      /* Drop size of block.  */
      must_parse_int (&(ieee->h));      /* Drop size of block.  */
 
 
      if (must_parse_int (&(ieee->h)) != 0)
      if (must_parse_int (&(ieee->h)) != 0)
        /* This object has been deleted.  */
        /* This object has been deleted.  */
        ieee->elements[i].file_offset = 0;
        ieee->elements[i].file_offset = 0;
      else
      else
        ieee->elements[i].file_offset = must_parse_int (&(ieee->h));
        ieee->elements[i].file_offset = must_parse_int (&(ieee->h));
    }
    }
 
 
  /*  abfd->has_armap = ;*/
  /*  abfd->has_armap = ;*/
 
 
  return abfd->xvec;
  return abfd->xvec;
 
 
 got_wrong_format_error:
 got_wrong_format_error:
  bfd_release (abfd, ieee);
  bfd_release (abfd, ieee);
  abfd->tdata.ieee_ar_data = save;
  abfd->tdata.ieee_ar_data = save;
  bfd_set_error (bfd_error_wrong_format);
  bfd_set_error (bfd_error_wrong_format);
 
 
 error_return:
 error_return:
  if (elts != NULL)
  if (elts != NULL)
    free (elts);
    free (elts);
 
 
  return NULL;
  return NULL;
}
}
 
 
static boolean
static boolean
ieee_mkobject (abfd)
ieee_mkobject (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  abfd->tdata.ieee_data = (ieee_data_type *) bfd_zalloc (abfd, sizeof (ieee_data_type));
  abfd->tdata.ieee_data = (ieee_data_type *) bfd_zalloc (abfd, sizeof (ieee_data_type));
  return abfd->tdata.ieee_data ? true : false;
  return abfd->tdata.ieee_data ? true : false;
}
}
 
 
const bfd_target *
const bfd_target *
ieee_object_p (abfd)
ieee_object_p (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  char *processor;
  char *processor;
  unsigned int part;
  unsigned int part;
  ieee_data_type *ieee;
  ieee_data_type *ieee;
  unsigned char buffer[300];
  unsigned char buffer[300];
  ieee_data_type *save = IEEE_DATA (abfd);
  ieee_data_type *save = IEEE_DATA (abfd);
 
 
  abfd->tdata.ieee_data = 0;
  abfd->tdata.ieee_data = 0;
  ieee_mkobject (abfd);
  ieee_mkobject (abfd);
 
 
  ieee = IEEE_DATA (abfd);
  ieee = IEEE_DATA (abfd);
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    goto fail;
    goto fail;
  /* Read the first few bytes in to see if it makes sense */
  /* Read the first few bytes in to see if it makes sense */
  /* FIXME: Check return value.  I'm not sure whether it needs to read
  /* FIXME: Check return value.  I'm not sure whether it needs to read
     the entire buffer or not.  */
     the entire buffer or not.  */
  bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
  bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
 
 
  ieee->h.input_p = buffer;
  ieee->h.input_p = buffer;
  if (this_byte_and_next (&(ieee->h)) != Module_Beginning)
  if (this_byte_and_next (&(ieee->h)) != Module_Beginning)
    goto got_wrong_format;
    goto got_wrong_format;
 
 
  ieee->read_symbols = false;
  ieee->read_symbols = false;
  ieee->read_data = false;
  ieee->read_data = false;
  ieee->section_count = 0;
  ieee->section_count = 0;
  ieee->external_symbol_max_index = 0;
  ieee->external_symbol_max_index = 0;
  ieee->external_symbol_min_index = IEEE_PUBLIC_BASE;
  ieee->external_symbol_min_index = IEEE_PUBLIC_BASE;
  ieee->external_reference_min_index = IEEE_REFERENCE_BASE;
  ieee->external_reference_min_index = IEEE_REFERENCE_BASE;
  ieee->external_reference_max_index = 0;
  ieee->external_reference_max_index = 0;
  ieee->h.abfd = abfd;
  ieee->h.abfd = abfd;
  ieee->section_table = NULL;
  ieee->section_table = NULL;
  ieee->section_table_size = 0;
  ieee->section_table_size = 0;
 
 
  processor = ieee->mb.processor = read_id (&(ieee->h));
  processor = ieee->mb.processor = read_id (&(ieee->h));
  if (strcmp (processor, "LIBRARY") == 0)
  if (strcmp (processor, "LIBRARY") == 0)
    goto got_wrong_format;
    goto got_wrong_format;
  ieee->mb.module_name = read_id (&(ieee->h));
  ieee->mb.module_name = read_id (&(ieee->h));
  if (abfd->filename == (CONST char *) NULL)
  if (abfd->filename == (CONST char *) NULL)
    {
    {
      abfd->filename = ieee->mb.module_name;
      abfd->filename = ieee->mb.module_name;
    }
    }
  /* Determine the architecture and machine type of the object file.
  /* Determine the architecture and machine type of the object file.
     */
     */
  {
  {
    const bfd_arch_info_type *arch;
    const bfd_arch_info_type *arch;
    char family[10];
    char family[10];
 
 
    /* IEEE does not specify the format of the processor identificaton
    /* IEEE does not specify the format of the processor identificaton
       string, so the compiler is free to put in it whatever it wants.
       string, so the compiler is free to put in it whatever it wants.
       We try here to recognize different processors belonging to the
       We try here to recognize different processors belonging to the
       m68k family.  Code for other processors can be added here.  */
       m68k family.  Code for other processors can be added here.  */
    if ((processor[0] == '6') && (processor[1] == '8'))
    if ((processor[0] == '6') && (processor[1] == '8'))
      {
      {
        if (processor[2] == '3')            /* 683xx integrated processors */
        if (processor[2] == '3')            /* 683xx integrated processors */
          {
          {
            switch (processor[3])
            switch (processor[3])
              {
              {
              case '0':                     /* 68302, 68306, 68307 */
              case '0':                     /* 68302, 68306, 68307 */
              case '2':                     /* 68322, 68328 */
              case '2':                     /* 68322, 68328 */
              case '5':                     /* 68356 */
              case '5':                     /* 68356 */
                strcpy (family, "68000");   /* MC68000-based controllers */
                strcpy (family, "68000");   /* MC68000-based controllers */
                break;
                break;
 
 
              case '3':                     /* 68330, 68331, 68332, 68333,
              case '3':                     /* 68330, 68331, 68332, 68333,
                                               68334, 68335, 68336, 68338 */
                                               68334, 68335, 68336, 68338 */
              case '6':                     /* 68360 */
              case '6':                     /* 68360 */
              case '7':                     /* 68376 */
              case '7':                     /* 68376 */
                strcpy (family, "68332");   /* CPU32 and CPU32+ */
                strcpy (family, "68332");   /* CPU32 and CPU32+ */
                break;
                break;
 
 
              case '4':
              case '4':
                if (processor[4] == '9')    /* 68349 */
                if (processor[4] == '9')    /* 68349 */
                  strcpy (family, "68030"); /* CPU030 */
                  strcpy (family, "68030"); /* CPU030 */
                else                        /* 68340, 68341 */
                else                        /* 68340, 68341 */
                  strcpy (family, "68332"); /* CPU32 and CPU32+ */
                  strcpy (family, "68332"); /* CPU32 and CPU32+ */
                break;
                break;
 
 
              default:                      /* Does not exist yet */
              default:                      /* Does not exist yet */
                strcpy (family, "68332");   /* Guess it will be CPU32 */
                strcpy (family, "68332");   /* Guess it will be CPU32 */
              }
              }
          }
          }
        else if (toupper (processor[3]) == 'F')   /* 68F333 */
        else if (toupper (processor[3]) == 'F')   /* 68F333 */
          strcpy (family, "68332");               /* CPU32 */
          strcpy (family, "68332");               /* CPU32 */
        else if ((toupper (processor[3]) == 'C')  /* Embedded controllers */
        else if ((toupper (processor[3]) == 'C')  /* Embedded controllers */
                 && ((toupper (processor[2]) == 'E')
                 && ((toupper (processor[2]) == 'E')
                     || (toupper (processor[2]) == 'H')
                     || (toupper (processor[2]) == 'H')
                     || (toupper (processor[2]) == 'L')))
                     || (toupper (processor[2]) == 'L')))
          {
          {
            strcpy (family, "68");
            strcpy (family, "68");
            strncat (family, processor + 4, 7);
            strncat (family, processor + 4, 7);
            family[9] = '\0';
            family[9] = '\0';
          }
          }
        else                             /* "Regular" processors */
        else                             /* "Regular" processors */
          {
          {
            strncpy (family, processor, 9);
            strncpy (family, processor, 9);
            family[9] = '\0';
            family[9] = '\0';
          }
          }
      }
      }
    else if ((strncmp (processor, "cpu32", 5) == 0) /* CPU32 and CPU32+ */
    else if ((strncmp (processor, "cpu32", 5) == 0) /* CPU32 and CPU32+ */
             || (strncmp (processor, "CPU32", 5) == 0))
             || (strncmp (processor, "CPU32", 5) == 0))
      strcpy (family, "68332");
      strcpy (family, "68332");
    else
    else
      {
      {
        strncpy (family, processor, 9);
        strncpy (family, processor, 9);
        family[9] = '\0';
        family[9] = '\0';
      }
      }
 
 
    arch = bfd_scan_arch (family);
    arch = bfd_scan_arch (family);
    if (arch == 0)
    if (arch == 0)
      goto got_wrong_format;
      goto got_wrong_format;
    abfd->arch_info = arch;
    abfd->arch_info = arch;
  }
  }
 
 
  if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum)
  if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum)
    {
    {
      goto fail;
      goto fail;
    }
    }
  next_byte (&(ieee->h));
  next_byte (&(ieee->h));
 
 
  if (parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau) == false)
  if (parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau) == false)
    {
    {
      goto fail;
      goto fail;
    }
    }
  if (parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address) == false)
  if (parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address) == false)
    {
    {
      goto fail;
      goto fail;
    }
    }
 
 
  /* If there is a byte order info, take it */
  /* If there is a byte order info, take it */
  if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum ||
  if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum ||
      this_byte (&(ieee->h)) == (int) ieee_variable_M_enum)
      this_byte (&(ieee->h)) == (int) ieee_variable_M_enum)
    next_byte (&(ieee->h));
    next_byte (&(ieee->h));
 
 
  for (part = 0; part < N_W_VARIABLES; part++)
  for (part = 0; part < N_W_VARIABLES; part++)
    {
    {
      boolean ok;
      boolean ok;
      if (read_2bytes (&(ieee->h)) != (int) ieee_assign_value_to_variable_enum)
      if (read_2bytes (&(ieee->h)) != (int) ieee_assign_value_to_variable_enum)
        {
        {
          goto fail;
          goto fail;
        }
        }
      if (this_byte_and_next (&(ieee->h)) != part)
      if (this_byte_and_next (&(ieee->h)) != part)
        {
        {
          goto fail;
          goto fail;
        }
        }
 
 
      ieee->w.offset[part] = parse_i (&(ieee->h), &ok);
      ieee->w.offset[part] = parse_i (&(ieee->h), &ok);
      if (ok == false)
      if (ok == false)
        {
        {
          goto fail;
          goto fail;
        }
        }
 
 
    }
    }
 
 
  if (ieee->w.r.external_part != 0)
  if (ieee->w.r.external_part != 0)
    abfd->flags = HAS_SYMS;
    abfd->flags = HAS_SYMS;
 
 
  /* By now we know that this is a real IEEE file, we're going to read
  /* By now we know that this is a real IEEE file, we're going to read
     the whole thing into memory so that we can run up and down it
     the whole thing into memory so that we can run up and down it
     quickly.  We can work out how big the file is from the trailer
     quickly.  We can work out how big the file is from the trailer
     record */
     record */
 
 
  IEEE_DATA (abfd)->h.first_byte =
  IEEE_DATA (abfd)->h.first_byte =
    (unsigned char *) bfd_alloc (ieee->h.abfd, ieee->w.r.me_record + 1);
    (unsigned char *) bfd_alloc (ieee->h.abfd, ieee->w.r.me_record + 1);
  if (!IEEE_DATA (abfd)->h.first_byte)
  if (!IEEE_DATA (abfd)->h.first_byte)
    goto fail;
    goto fail;
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    goto fail;
    goto fail;
  /* FIXME: Check return value.  I'm not sure whether it needs to read
  /* FIXME: Check return value.  I'm not sure whether it needs to read
     the entire buffer or not.  */
     the entire buffer or not.  */
  bfd_read ((PTR) (IEEE_DATA (abfd)->h.first_byte), 1,
  bfd_read ((PTR) (IEEE_DATA (abfd)->h.first_byte), 1,
            ieee->w.r.me_record + 1, abfd);
            ieee->w.r.me_record + 1, abfd);
 
 
  ieee_slurp_sections (abfd);
  ieee_slurp_sections (abfd);
 
 
  if (! ieee_slurp_debug (abfd))
  if (! ieee_slurp_debug (abfd))
    goto fail;
    goto fail;
 
 
  /* Parse section data to activate file and section flags implied by
  /* Parse section data to activate file and section flags implied by
     section contents. */
     section contents. */
 
 
  if (! ieee_slurp_section_data (abfd))
  if (! ieee_slurp_section_data (abfd))
    goto fail;
    goto fail;
 
 
  return abfd->xvec;
  return abfd->xvec;
got_wrong_format:
got_wrong_format:
  bfd_set_error (bfd_error_wrong_format);
  bfd_set_error (bfd_error_wrong_format);
fail:
fail:
  (void) bfd_release (abfd, ieee);
  (void) bfd_release (abfd, ieee);
  abfd->tdata.ieee_data = save;
  abfd->tdata.ieee_data = save;
  return (const bfd_target *) NULL;
  return (const bfd_target *) NULL;
}
}
 
 
void
void
ieee_get_symbol_info (ignore_abfd, symbol, ret)
ieee_get_symbol_info (ignore_abfd, symbol, ret)
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
     asymbol *symbol;
     asymbol *symbol;
     symbol_info *ret;
     symbol_info *ret;
{
{
  bfd_symbol_info (symbol, ret);
  bfd_symbol_info (symbol, ret);
  if (symbol->name[0] == ' ')
  if (symbol->name[0] == ' ')
    ret->name = "* empty table entry ";
    ret->name = "* empty table entry ";
  if (!symbol->section)
  if (!symbol->section)
    ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
    ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
}
}
 
 
void
void
ieee_print_symbol (ignore_abfd, afile, symbol, how)
ieee_print_symbol (ignore_abfd, afile, symbol, how)
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
     PTR afile;
     PTR afile;
     asymbol *symbol;
     asymbol *symbol;
     bfd_print_symbol_type how;
     bfd_print_symbol_type how;
{
{
  FILE *file = (FILE *) afile;
  FILE *file = (FILE *) afile;
 
 
  switch (how)
  switch (how)
    {
    {
    case bfd_print_symbol_name:
    case bfd_print_symbol_name:
      fprintf (file, "%s", symbol->name);
      fprintf (file, "%s", symbol->name);
      break;
      break;
    case bfd_print_symbol_more:
    case bfd_print_symbol_more:
#if 0
#if 0
      fprintf (file, "%4x %2x", aout_symbol (symbol)->desc & 0xffff,
      fprintf (file, "%4x %2x", aout_symbol (symbol)->desc & 0xffff,
               aout_symbol (symbol)->other & 0xff);
               aout_symbol (symbol)->other & 0xff);
#endif
#endif
      BFD_FAIL ();
      BFD_FAIL ();
      break;
      break;
    case bfd_print_symbol_all:
    case bfd_print_symbol_all:
      {
      {
        const char *section_name =
        const char *section_name =
          (symbol->section == (asection *) NULL
          (symbol->section == (asection *) NULL
           ? "*abs"
           ? "*abs"
           : symbol->section->name);
           : symbol->section->name);
        if (symbol->name[0] == ' ')
        if (symbol->name[0] == ' ')
          {
          {
            fprintf (file, "* empty table entry ");
            fprintf (file, "* empty table entry ");
          }
          }
        else
        else
          {
          {
            bfd_print_symbol_vandf ((PTR) file, symbol);
            bfd_print_symbol_vandf ((PTR) file, symbol);
 
 
            fprintf (file, " %-5s %04x %02x %s",
            fprintf (file, " %-5s %04x %02x %s",
                     section_name,
                     section_name,
                     (unsigned) ieee_symbol (symbol)->index,
                     (unsigned) ieee_symbol (symbol)->index,
                     (unsigned) 0,
                     (unsigned) 0,
                     symbol->name);
                     symbol->name);
          }
          }
      }
      }
      break;
      break;
    }
    }
}
}
 
 
static boolean
static boolean
do_one (ieee, current_map, location_ptr, s, iterations)
do_one (ieee, current_map, location_ptr, s, iterations)
     ieee_data_type *ieee;
     ieee_data_type *ieee;
     ieee_per_section_type *current_map;
     ieee_per_section_type *current_map;
     unsigned char *location_ptr;
     unsigned char *location_ptr;
     asection *s;
     asection *s;
     int iterations;
     int iterations;
{
{
  switch (this_byte (&(ieee->h)))
  switch (this_byte (&(ieee->h)))
    {
    {
    case ieee_load_constant_bytes_enum:
    case ieee_load_constant_bytes_enum:
      {
      {
        unsigned int number_of_maus;
        unsigned int number_of_maus;
        unsigned int i;
        unsigned int i;
        next_byte (&(ieee->h));
        next_byte (&(ieee->h));
        number_of_maus = must_parse_int (&(ieee->h));
        number_of_maus = must_parse_int (&(ieee->h));
 
 
        for (i = 0; i < number_of_maus; i++)
        for (i = 0; i < number_of_maus; i++)
          {
          {
            location_ptr[current_map->pc++] = this_byte (&(ieee->h));
            location_ptr[current_map->pc++] = this_byte (&(ieee->h));
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
          }
          }
      }
      }
      break;
      break;
 
 
    case ieee_load_with_relocation_enum:
    case ieee_load_with_relocation_enum:
      {
      {
        boolean loop = true;
        boolean loop = true;
        next_byte (&(ieee->h));
        next_byte (&(ieee->h));
        while (loop)
        while (loop)
          {
          {
            switch (this_byte (&(ieee->h)))
            switch (this_byte (&(ieee->h)))
              {
              {
              case ieee_variable_R_enum:
              case ieee_variable_R_enum:
 
 
              case ieee_function_signed_open_b_enum:
              case ieee_function_signed_open_b_enum:
              case ieee_function_unsigned_open_b_enum:
              case ieee_function_unsigned_open_b_enum:
              case ieee_function_either_open_b_enum:
              case ieee_function_either_open_b_enum:
                {
                {
                  unsigned int extra = 4;
                  unsigned int extra = 4;
                  boolean pcrel = false;
                  boolean pcrel = false;
                  asection *section;
                  asection *section;
                  ieee_reloc_type *r =
                  ieee_reloc_type *r =
                  (ieee_reloc_type *) bfd_alloc (ieee->h.abfd,
                  (ieee_reloc_type *) bfd_alloc (ieee->h.abfd,
                                                 sizeof (ieee_reloc_type));
                                                 sizeof (ieee_reloc_type));
                  if (!r)
                  if (!r)
                    return false;
                    return false;
 
 
                  *(current_map->reloc_tail_ptr) = r;
                  *(current_map->reloc_tail_ptr) = r;
                  current_map->reloc_tail_ptr = &r->next;
                  current_map->reloc_tail_ptr = &r->next;
                  r->next = (ieee_reloc_type *) NULL;
                  r->next = (ieee_reloc_type *) NULL;
                  next_byte (&(ieee->h));
                  next_byte (&(ieee->h));
/*                          abort();*/
/*                          abort();*/
                  r->relent.sym_ptr_ptr = 0;
                  r->relent.sym_ptr_ptr = 0;
                  parse_expression (ieee,
                  parse_expression (ieee,
                                    &r->relent.addend,
                                    &r->relent.addend,
                                    &r->symbol,
                                    &r->symbol,
                                    &pcrel, &extra, &section);
                                    &pcrel, &extra, &section);
                  r->relent.address = current_map->pc;
                  r->relent.address = current_map->pc;
                  s->flags |= SEC_RELOC;
                  s->flags |= SEC_RELOC;
                  s->owner->flags |= HAS_RELOC;
                  s->owner->flags |= HAS_RELOC;
                  s->reloc_count++;
                  s->reloc_count++;
                  if (r->relent.sym_ptr_ptr == NULL && section != NULL)
                  if (r->relent.sym_ptr_ptr == NULL && section != NULL)
                    r->relent.sym_ptr_ptr = section->symbol_ptr_ptr;
                    r->relent.sym_ptr_ptr = section->symbol_ptr_ptr;
 
 
                  if (this_byte (&(ieee->h)) == (int) ieee_comma)
                  if (this_byte (&(ieee->h)) == (int) ieee_comma)
                    {
                    {
                      next_byte (&(ieee->h));
                      next_byte (&(ieee->h));
                      /* Fetch number of bytes to pad */
                      /* Fetch number of bytes to pad */
                      extra = must_parse_int (&(ieee->h));
                      extra = must_parse_int (&(ieee->h));
                    };
                    };
 
 
                  switch (this_byte (&(ieee->h)))
                  switch (this_byte (&(ieee->h)))
                    {
                    {
                    case ieee_function_signed_close_b_enum:
                    case ieee_function_signed_close_b_enum:
                      next_byte (&(ieee->h));
                      next_byte (&(ieee->h));
                      break;
                      break;
                    case ieee_function_unsigned_close_b_enum:
                    case ieee_function_unsigned_close_b_enum:
                      next_byte (&(ieee->h));
                      next_byte (&(ieee->h));
                      break;
                      break;
                    case ieee_function_either_close_b_enum:
                    case ieee_function_either_close_b_enum:
                      next_byte (&(ieee->h));
                      next_byte (&(ieee->h));
                      break;
                      break;
                    default:
                    default:
                      break;
                      break;
                    }
                    }
                  /* Build a relocation entry for this type */
                  /* Build a relocation entry for this type */
                  /* If pc rel then stick -ve pc into instruction
                  /* If pc rel then stick -ve pc into instruction
                     and take out of reloc ..
                     and take out of reloc ..
 
 
                     I've changed this. It's all too complicated. I
                     I've changed this. It's all too complicated. I
                     keep 0 in the instruction now.  */
                     keep 0 in the instruction now.  */
 
 
                  switch (extra)
                  switch (extra)
                    {
                    {
                    case 0:
                    case 0:
                    case 4:
                    case 4:
 
 
                      if (pcrel == true)
                      if (pcrel == true)
                        {
                        {
#if KEEPMINUSPCININST
#if KEEPMINUSPCININST
                          bfd_put_32 (ieee->h.abfd, -current_map->pc, location_ptr +
                          bfd_put_32 (ieee->h.abfd, -current_map->pc, location_ptr +
                                      current_map->pc);
                                      current_map->pc);
                          r->relent.howto = &rel32_howto;
                          r->relent.howto = &rel32_howto;
                          r->relent.addend -=
                          r->relent.addend -=
                            current_map->pc;
                            current_map->pc;
#else
#else
                          bfd_put_32 (ieee->h.abfd, 0, location_ptr +
                          bfd_put_32 (ieee->h.abfd, 0, location_ptr +
                                      current_map->pc);
                                      current_map->pc);
                          r->relent.howto = &rel32_howto;
                          r->relent.howto = &rel32_howto;
#endif
#endif
                        }
                        }
                      else
                      else
                        {
                        {
                          bfd_put_32 (ieee->h.abfd, 0, location_ptr +
                          bfd_put_32 (ieee->h.abfd, 0, location_ptr +
                                      current_map->pc);
                                      current_map->pc);
                          r->relent.howto = &abs32_howto;
                          r->relent.howto = &abs32_howto;
                        }
                        }
                      current_map->pc += 4;
                      current_map->pc += 4;
                      break;
                      break;
                    case 2:
                    case 2:
                      if (pcrel == true)
                      if (pcrel == true)
                        {
                        {
#if KEEPMINUSPCININST
#if KEEPMINUSPCININST
                          bfd_put_16 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc);
                          bfd_put_16 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc);
                          r->relent.addend -= current_map->pc;
                          r->relent.addend -= current_map->pc;
                          r->relent.howto = &rel16_howto;
                          r->relent.howto = &rel16_howto;
#else
#else
 
 
                          bfd_put_16 (ieee->h.abfd, 0, location_ptr + current_map->pc);
                          bfd_put_16 (ieee->h.abfd, 0, location_ptr + current_map->pc);
                          r->relent.howto = &rel16_howto;
                          r->relent.howto = &rel16_howto;
#endif
#endif
                        }
                        }
 
 
                      else
                      else
                        {
                        {
                          bfd_put_16 (ieee->h.abfd, 0, location_ptr + current_map->pc);
                          bfd_put_16 (ieee->h.abfd, 0, location_ptr + current_map->pc);
                          r->relent.howto = &abs16_howto;
                          r->relent.howto = &abs16_howto;
                        }
                        }
                      current_map->pc += 2;
                      current_map->pc += 2;
                      break;
                      break;
                    case 1:
                    case 1:
                      if (pcrel == true)
                      if (pcrel == true)
                        {
                        {
#if KEEPMINUSPCININST
#if KEEPMINUSPCININST
                          bfd_put_8 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc);
                          bfd_put_8 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc);
                          r->relent.addend -= current_map->pc;
                          r->relent.addend -= current_map->pc;
                          r->relent.howto = &rel8_howto;
                          r->relent.howto = &rel8_howto;
#else
#else
                          bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
                          bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
                          r->relent.howto = &rel8_howto;
                          r->relent.howto = &rel8_howto;
#endif
#endif
                        }
                        }
                      else
                      else
                        {
                        {
                          bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
                          bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
                          r->relent.howto = &abs8_howto;
                          r->relent.howto = &abs8_howto;
                        }
                        }
                      current_map->pc += 1;
                      current_map->pc += 1;
                      break;
                      break;
 
 
                    default:
                    default:
                      BFD_FAIL ();
                      BFD_FAIL ();
                      return false;
                      return false;
                    }
                    }
                }
                }
                break;
                break;
              default:
              default:
                {
                {
                  bfd_vma this_size;
                  bfd_vma this_size;
                  if (parse_int (&(ieee->h), &this_size) == true)
                  if (parse_int (&(ieee->h), &this_size) == true)
                    {
                    {
                      unsigned int i;
                      unsigned int i;
                      for (i = 0; i < this_size; i++)
                      for (i = 0; i < this_size; i++)
                        {
                        {
                          location_ptr[current_map->pc++] = this_byte (&(ieee->h));
                          location_ptr[current_map->pc++] = this_byte (&(ieee->h));
                          next_byte (&(ieee->h));
                          next_byte (&(ieee->h));
                        }
                        }
                    }
                    }
                  else
                  else
                    {
                    {
                      loop = false;
                      loop = false;
                    }
                    }
                }
                }
              }
              }
 
 
            /* Prevent more than the first load-item of an LR record
            /* Prevent more than the first load-item of an LR record
               from being repeated (MRI convention). */
               from being repeated (MRI convention). */
            if (iterations != 1)
            if (iterations != 1)
              loop = false;
              loop = false;
          }
          }
      }
      }
    }
    }
  return true;
  return true;
}
}
 
 
/* Read in all the section data and relocation stuff too */
/* Read in all the section data and relocation stuff too */
static boolean
static boolean
ieee_slurp_section_data (abfd)
ieee_slurp_section_data (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  bfd_byte *location_ptr = (bfd_byte *) NULL;
  bfd_byte *location_ptr = (bfd_byte *) NULL;
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
  unsigned int section_number;
  unsigned int section_number;
 
 
  ieee_per_section_type *current_map = (ieee_per_section_type *) NULL;
  ieee_per_section_type *current_map = (ieee_per_section_type *) NULL;
  asection *s;
  asection *s;
  /* Seek to the start of the data area */
  /* Seek to the start of the data area */
  if (ieee->read_data == true)
  if (ieee->read_data == true)
    return true;
    return true;
  ieee->read_data = true;
  ieee->read_data = true;
  ieee_seek (abfd, ieee->w.r.data_part);
  ieee_seek (abfd, ieee->w.r.data_part);
 
 
  /* Allocate enough space for all the section contents */
  /* Allocate enough space for all the section contents */
 
 
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
    {
    {
      ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd;
      ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd;
      if ((s->flags & SEC_DEBUGGING) != 0)
      if ((s->flags & SEC_DEBUGGING) != 0)
        continue;
        continue;
      per->data = (bfd_byte *) bfd_alloc (ieee->h.abfd, s->_raw_size);
      per->data = (bfd_byte *) bfd_alloc (ieee->h.abfd, s->_raw_size);
      if (!per->data)
      if (!per->data)
        return false;
        return false;
      /*SUPPRESS 68*/
      /*SUPPRESS 68*/
      per->reloc_tail_ptr =
      per->reloc_tail_ptr =
        (ieee_reloc_type **) & (s->relocation);
        (ieee_reloc_type **) & (s->relocation);
    }
    }
 
 
  while (true)
  while (true)
    {
    {
      switch (this_byte (&(ieee->h)))
      switch (this_byte (&(ieee->h)))
        {
        {
          /* IF we see anything strange then quit */
          /* IF we see anything strange then quit */
        default:
        default:
          return true;
          return true;
 
 
        case ieee_set_current_section_enum:
        case ieee_set_current_section_enum:
          next_byte (&(ieee->h));
          next_byte (&(ieee->h));
          section_number = must_parse_int (&(ieee->h));
          section_number = must_parse_int (&(ieee->h));
          s = ieee->section_table[section_number];
          s = ieee->section_table[section_number];
          s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
          s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
          current_map = (ieee_per_section_type *) s->used_by_bfd;
          current_map = (ieee_per_section_type *) s->used_by_bfd;
          location_ptr = current_map->data - s->vma;
          location_ptr = current_map->data - s->vma;
          /* The document I have says that Microtec's compilers reset */
          /* The document I have says that Microtec's compilers reset */
          /* this after a sec section, even though the standard says not */
          /* this after a sec section, even though the standard says not */
          /* to. SO .. */
          /* to. SO .. */
          current_map->pc = s->vma;
          current_map->pc = s->vma;
          break;
          break;
 
 
        case ieee_e2_first_byte_enum:
        case ieee_e2_first_byte_enum:
          next_byte (&(ieee->h));
          next_byte (&(ieee->h));
          switch (this_byte (&(ieee->h)))
          switch (this_byte (&(ieee->h)))
            {
            {
            case ieee_set_current_pc_enum & 0xff:
            case ieee_set_current_pc_enum & 0xff:
              {
              {
                bfd_vma value;
                bfd_vma value;
                ieee_symbol_index_type symbol;
                ieee_symbol_index_type symbol;
                unsigned int extra;
                unsigned int extra;
                boolean pcrel;
                boolean pcrel;
                next_byte (&(ieee->h));
                next_byte (&(ieee->h));
                must_parse_int (&(ieee->h));    /* Thow away section #*/
                must_parse_int (&(ieee->h));    /* Thow away section #*/
                parse_expression (ieee, &value,
                parse_expression (ieee, &value,
                                  &symbol,
                                  &symbol,
                                  &pcrel, &extra,
                                  &pcrel, &extra,
                                  0);
                                  0);
                current_map->pc = value;
                current_map->pc = value;
                BFD_ASSERT ((unsigned) (value - s->vma) <= s->_raw_size);
                BFD_ASSERT ((unsigned) (value - s->vma) <= s->_raw_size);
              }
              }
              break;
              break;
 
 
            case ieee_value_starting_address_enum & 0xff:
            case ieee_value_starting_address_enum & 0xff:
              next_byte (&(ieee->h));
              next_byte (&(ieee->h));
              if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum)
              if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum)
                next_byte (&(ieee->h));
                next_byte (&(ieee->h));
              abfd->start_address = must_parse_int (&(ieee->h));
              abfd->start_address = must_parse_int (&(ieee->h));
              /* We've got to the end of the data now - */
              /* We've got to the end of the data now - */
              return true;
              return true;
            default:
            default:
              BFD_FAIL ();
              BFD_FAIL ();
              return false;
              return false;
            }
            }
          break;
          break;
        case ieee_repeat_data_enum:
        case ieee_repeat_data_enum:
          {
          {
            /* Repeat the following LD or LR n times - we do this by
            /* Repeat the following LD or LR n times - we do this by
                 remembering the stream pointer before running it and
                 remembering the stream pointer before running it and
                 resetting it and running it n times. We special case
                 resetting it and running it n times. We special case
                 the repetition of a repeat_data/load_constant
                 the repetition of a repeat_data/load_constant
                 */
                 */
 
 
            unsigned int iterations;
            unsigned int iterations;
            unsigned char *start;
            unsigned char *start;
            next_byte (&(ieee->h));
            next_byte (&(ieee->h));
            iterations = must_parse_int (&(ieee->h));
            iterations = must_parse_int (&(ieee->h));
            start = ieee->h.input_p;
            start = ieee->h.input_p;
            if (start[0] == (int) ieee_load_constant_bytes_enum &&
            if (start[0] == (int) ieee_load_constant_bytes_enum &&
                start[1] == 1)
                start[1] == 1)
              {
              {
                while (iterations != 0)
                while (iterations != 0)
                  {
                  {
                    location_ptr[current_map->pc++] = start[2];
                    location_ptr[current_map->pc++] = start[2];
                    iterations--;
                    iterations--;
                  }
                  }
                next_byte (&(ieee->h));
                next_byte (&(ieee->h));
                next_byte (&(ieee->h));
                next_byte (&(ieee->h));
                next_byte (&(ieee->h));
                next_byte (&(ieee->h));
              }
              }
            else
            else
              {
              {
                while (iterations != 0)
                while (iterations != 0)
                  {
                  {
                    ieee->h.input_p = start;
                    ieee->h.input_p = start;
                    if (!do_one (ieee, current_map, location_ptr, s,
                    if (!do_one (ieee, current_map, location_ptr, s,
                                 iterations))
                                 iterations))
                      return false;
                      return false;
                    iterations--;
                    iterations--;
                  }
                  }
              }
              }
          }
          }
          break;
          break;
        case ieee_load_constant_bytes_enum:
        case ieee_load_constant_bytes_enum:
        case ieee_load_with_relocation_enum:
        case ieee_load_with_relocation_enum:
          {
          {
            if (!do_one (ieee, current_map, location_ptr, s, 1))
            if (!do_one (ieee, current_map, location_ptr, s, 1))
              return false;
              return false;
          }
          }
        }
        }
    }
    }
}
}
 
 
boolean
boolean
ieee_new_section_hook (abfd, newsect)
ieee_new_section_hook (abfd, newsect)
     bfd *abfd;
     bfd *abfd;
     asection *newsect;
     asection *newsect;
{
{
  newsect->used_by_bfd = (PTR)
  newsect->used_by_bfd = (PTR)
    bfd_alloc (abfd, sizeof (ieee_per_section_type));
    bfd_alloc (abfd, sizeof (ieee_per_section_type));
  if (!newsect->used_by_bfd)
  if (!newsect->used_by_bfd)
    return false;
    return false;
  ieee_per_section (newsect)->data = (bfd_byte *) NULL;
  ieee_per_section (newsect)->data = (bfd_byte *) NULL;
  ieee_per_section (newsect)->section = newsect;
  ieee_per_section (newsect)->section = newsect;
  return true;
  return true;
}
}
 
 
long
long
ieee_get_reloc_upper_bound (abfd, asect)
ieee_get_reloc_upper_bound (abfd, asect)
     bfd *abfd;
     bfd *abfd;
     sec_ptr asect;
     sec_ptr asect;
{
{
  if ((asect->flags & SEC_DEBUGGING) != 0)
  if ((asect->flags & SEC_DEBUGGING) != 0)
    return 0;
    return 0;
  if (! ieee_slurp_section_data (abfd))
  if (! ieee_slurp_section_data (abfd))
    return -1;
    return -1;
  return (asect->reloc_count + 1) * sizeof (arelent *);
  return (asect->reloc_count + 1) * sizeof (arelent *);
}
}
 
 
static boolean
static boolean
ieee_get_section_contents (abfd, section, location, offset, count)
ieee_get_section_contents (abfd, section, location, offset, count)
     bfd *abfd;
     bfd *abfd;
     sec_ptr section;
     sec_ptr section;
     PTR location;
     PTR location;
     file_ptr offset;
     file_ptr offset;
     bfd_size_type count;
     bfd_size_type count;
{
{
  ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;
  ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;
  if ((section->flags & SEC_DEBUGGING) != 0)
  if ((section->flags & SEC_DEBUGGING) != 0)
    return _bfd_generic_get_section_contents (abfd, section, location,
    return _bfd_generic_get_section_contents (abfd, section, location,
                                              offset, count);
                                              offset, count);
  ieee_slurp_section_data (abfd);
  ieee_slurp_section_data (abfd);
  (void) memcpy ((PTR) location, (PTR) (p->data + offset), (unsigned) count);
  (void) memcpy ((PTR) location, (PTR) (p->data + offset), (unsigned) count);
  return true;
  return true;
}
}
 
 
long
long
ieee_canonicalize_reloc (abfd, section, relptr, symbols)
ieee_canonicalize_reloc (abfd, section, relptr, symbols)
     bfd *abfd;
     bfd *abfd;
     sec_ptr section;
     sec_ptr section;
     arelent **relptr;
     arelent **relptr;
     asymbol **symbols;
     asymbol **symbols;
{
{
/*  ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;*/
/*  ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;*/
  ieee_reloc_type *src = (ieee_reloc_type *) (section->relocation);
  ieee_reloc_type *src = (ieee_reloc_type *) (section->relocation);
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
 
 
  if ((section->flags & SEC_DEBUGGING) != 0)
  if ((section->flags & SEC_DEBUGGING) != 0)
    return 0;
    return 0;
 
 
  while (src != (ieee_reloc_type *) NULL)
  while (src != (ieee_reloc_type *) NULL)
    {
    {
      /* Work out which symbol to attach it this reloc to */
      /* Work out which symbol to attach it this reloc to */
      switch (src->symbol.letter)
      switch (src->symbol.letter)
        {
        {
        case 'I':
        case 'I':
          src->relent.sym_ptr_ptr =
          src->relent.sym_ptr_ptr =
            symbols + src->symbol.index + ieee->external_symbol_base_offset;
            symbols + src->symbol.index + ieee->external_symbol_base_offset;
          break;
          break;
        case 'X':
        case 'X':
          src->relent.sym_ptr_ptr =
          src->relent.sym_ptr_ptr =
            symbols + src->symbol.index + ieee->external_reference_base_offset;
            symbols + src->symbol.index + ieee->external_reference_base_offset;
          break;
          break;
        case 0:
        case 0:
          if (src->relent.sym_ptr_ptr != NULL)
          if (src->relent.sym_ptr_ptr != NULL)
            src->relent.sym_ptr_ptr =
            src->relent.sym_ptr_ptr =
              src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr;
              src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr;
          break;
          break;
        default:
        default:
 
 
          BFD_FAIL ();
          BFD_FAIL ();
        }
        }
      *relptr++ = &src->relent;
      *relptr++ = &src->relent;
      src = src->next;
      src = src->next;
    }
    }
  *relptr = (arelent *) NULL;
  *relptr = (arelent *) NULL;
  return section->reloc_count;
  return section->reloc_count;
}
}
 
 
static int
static int
comp (ap, bp)
comp (ap, bp)
     CONST PTR ap;
     CONST PTR ap;
     CONST PTR bp;
     CONST PTR bp;
{
{
  arelent *a = *((arelent **) ap);
  arelent *a = *((arelent **) ap);
  arelent *b = *((arelent **) bp);
  arelent *b = *((arelent **) bp);
  return a->address - b->address;
  return a->address - b->address;
}
}
 
 
/* Write the section headers.  */
/* Write the section headers.  */
 
 
static boolean
static boolean
ieee_write_section_part (abfd)
ieee_write_section_part (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
  asection *s;
  asection *s;
  ieee->w.r.section_part = bfd_tell (abfd);
  ieee->w.r.section_part = bfd_tell (abfd);
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
    {
    {
      if (! bfd_is_abs_section (s)
      if (! bfd_is_abs_section (s)
          && (s->flags & SEC_DEBUGGING) == 0)
          && (s->flags & SEC_DEBUGGING) == 0)
        {
        {
          if (! ieee_write_byte (abfd, ieee_section_type_enum)
          if (! ieee_write_byte (abfd, ieee_section_type_enum)
              || ! ieee_write_byte (abfd,
              || ! ieee_write_byte (abfd,
                                    (bfd_byte) (s->index
                                    (bfd_byte) (s->index
                                                + IEEE_SECTION_NUMBER_BASE)))
                                                + IEEE_SECTION_NUMBER_BASE)))
            return false;
            return false;
 
 
          if (abfd->flags & EXEC_P)
          if (abfd->flags & EXEC_P)
            {
            {
              /* This image is executable, so output absolute sections */
              /* This image is executable, so output absolute sections */
              if (! ieee_write_byte (abfd, ieee_variable_A_enum)
              if (! ieee_write_byte (abfd, ieee_variable_A_enum)
                  || ! ieee_write_byte (abfd, ieee_variable_S_enum))
                  || ! ieee_write_byte (abfd, ieee_variable_S_enum))
                return false;
                return false;
            }
            }
          else
          else
            {
            {
              if (! ieee_write_byte (abfd, ieee_variable_C_enum))
              if (! ieee_write_byte (abfd, ieee_variable_C_enum))
                return false;
                return false;
            }
            }
 
 
          switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM))
          switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM))
            {
            {
            case SEC_CODE | SEC_LOAD:
            case SEC_CODE | SEC_LOAD:
            case SEC_CODE:
            case SEC_CODE:
              if (! ieee_write_byte (abfd, ieee_variable_P_enum))
              if (! ieee_write_byte (abfd, ieee_variable_P_enum))
                return false;
                return false;
              break;
              break;
            case SEC_DATA:
            case SEC_DATA:
            default:
            default:
              if (! ieee_write_byte (abfd, ieee_variable_D_enum))
              if (! ieee_write_byte (abfd, ieee_variable_D_enum))
                return false;
                return false;
              break;
              break;
            case SEC_ROM:
            case SEC_ROM:
            case SEC_ROM | SEC_DATA:
            case SEC_ROM | SEC_DATA:
            case SEC_ROM | SEC_LOAD:
            case SEC_ROM | SEC_LOAD:
            case SEC_ROM | SEC_DATA | SEC_LOAD:
            case SEC_ROM | SEC_DATA | SEC_LOAD:
              if (! ieee_write_byte (abfd, ieee_variable_R_enum))
              if (! ieee_write_byte (abfd, ieee_variable_R_enum))
                return false;
                return false;
            }
            }
 
 
 
 
          if (! ieee_write_id (abfd, s->name))
          if (! ieee_write_id (abfd, s->name))
            return false;
            return false;
#if 0
#if 0
          ieee_write_int (abfd, 0);      /* Parent */
          ieee_write_int (abfd, 0);      /* Parent */
          ieee_write_int (abfd, 0);      /* Brother */
          ieee_write_int (abfd, 0);      /* Brother */
          ieee_write_int (abfd, 0);      /* Context */
          ieee_write_int (abfd, 0);      /* Context */
#endif
#endif
          /* Alignment */
          /* Alignment */
          if (! ieee_write_byte (abfd, ieee_section_alignment_enum)
          if (! ieee_write_byte (abfd, ieee_section_alignment_enum)
              || ! ieee_write_byte (abfd,
              || ! ieee_write_byte (abfd,
                                    (bfd_byte) (s->index
                                    (bfd_byte) (s->index
                                                + IEEE_SECTION_NUMBER_BASE))
                                                + IEEE_SECTION_NUMBER_BASE))
              || ! ieee_write_int (abfd, 1 << s->alignment_power))
              || ! ieee_write_int (abfd, 1 << s->alignment_power))
            return false;
            return false;
 
 
          /* Size */
          /* Size */
          if (! ieee_write_2bytes (abfd, ieee_section_size_enum)
          if (! ieee_write_2bytes (abfd, ieee_section_size_enum)
              || ! ieee_write_byte (abfd,
              || ! ieee_write_byte (abfd,
                                    (bfd_byte) (s->index
                                    (bfd_byte) (s->index
                                                + IEEE_SECTION_NUMBER_BASE))
                                                + IEEE_SECTION_NUMBER_BASE))
              || ! ieee_write_int (abfd, s->_raw_size))
              || ! ieee_write_int (abfd, s->_raw_size))
            return false;
            return false;
          if (abfd->flags & EXEC_P)
          if (abfd->flags & EXEC_P)
            {
            {
              /* Relocateable sections don't have asl records */
              /* Relocateable sections don't have asl records */
              /* Vma */
              /* Vma */
              if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum)
              if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum)
                  || ! ieee_write_byte (abfd,
                  || ! ieee_write_byte (abfd,
                                        ((bfd_byte)
                                        ((bfd_byte)
                                         (s->index
                                         (s->index
                                          + IEEE_SECTION_NUMBER_BASE)))
                                          + IEEE_SECTION_NUMBER_BASE)))
                  || ! ieee_write_int (abfd, s->lma))
                  || ! ieee_write_int (abfd, s->lma))
                return false;
                return false;
            }
            }
        }
        }
    }
    }
 
 
  return true;
  return true;
}
}
 
 
 
 
static boolean
static boolean
do_with_relocs (abfd, s)
do_with_relocs (abfd, s)
     bfd *abfd;
     bfd *abfd;
     asection *s;
     asection *s;
{
{
  unsigned int number_of_maus_in_address =
  unsigned int number_of_maus_in_address =
    bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd);
    bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd);
  unsigned int relocs_to_go = s->reloc_count;
  unsigned int relocs_to_go = s->reloc_count;
  bfd_byte *stream = ieee_per_section (s)->data;
  bfd_byte *stream = ieee_per_section (s)->data;
  arelent **p = s->orelocation;
  arelent **p = s->orelocation;
  bfd_size_type current_byte_index = 0;
  bfd_size_type current_byte_index = 0;
 
 
  qsort (s->orelocation,
  qsort (s->orelocation,
         relocs_to_go,
         relocs_to_go,
         sizeof (arelent **),
         sizeof (arelent **),
         comp);
         comp);
 
 
  /* Output the section preheader */
  /* Output the section preheader */
  if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
  if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
      || ! ieee_write_byte (abfd,
      || ! ieee_write_byte (abfd,
                            (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))
                            (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))
      || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum)
      || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum)
      || ! ieee_write_byte (abfd,
      || ! ieee_write_byte (abfd,
                            (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)))
                            (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)))
    return false;
    return false;
  if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0)
  if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0)
    {
    {
      if (! ieee_write_int (abfd, s->lma))
      if (! ieee_write_int (abfd, s->lma))
        return false;
        return false;
    }
    }
  else
  else
    {
    {
      if (! ieee_write_expression (abfd, 0, s->symbol, 0, 0))
      if (! ieee_write_expression (abfd, 0, s->symbol, 0, 0))
        return false;
        return false;
    }
    }
 
 
  if (relocs_to_go == 0)
  if (relocs_to_go == 0)
    {
    {
      /* If there aren't any relocations then output the load constant
      /* If there aren't any relocations then output the load constant
         byte opcode rather than the load with relocation opcode */
         byte opcode rather than the load with relocation opcode */
 
 
      while (current_byte_index < s->_raw_size)
      while (current_byte_index < s->_raw_size)
        {
        {
          bfd_size_type run;
          bfd_size_type run;
          unsigned int MAXRUN = 127;
          unsigned int MAXRUN = 127;
          run = MAXRUN;
          run = MAXRUN;
          if (run > s->_raw_size - current_byte_index)
          if (run > s->_raw_size - current_byte_index)
            {
            {
              run = s->_raw_size - current_byte_index;
              run = s->_raw_size - current_byte_index;
            }
            }
 
 
          if (run != 0)
          if (run != 0)
            {
            {
              if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum))
              if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum))
                return false;
                return false;
              /* Output a stream of bytes */
              /* Output a stream of bytes */
              if (! ieee_write_int (abfd, run))
              if (! ieee_write_int (abfd, run))
                return false;
                return false;
              if (bfd_write ((PTR) (stream + current_byte_index),
              if (bfd_write ((PTR) (stream + current_byte_index),
                             1,
                             1,
                             run,
                             run,
                             abfd)
                             abfd)
                  != run)
                  != run)
                return false;
                return false;
              current_byte_index += run;
              current_byte_index += run;
            }
            }
        }
        }
    }
    }
  else
  else
    {
    {
      if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum))
      if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum))
        return false;
        return false;
 
 
      /* Output the data stream as the longest sequence of bytes
      /* Output the data stream as the longest sequence of bytes
         possible, allowing for the a reasonable packet size and
         possible, allowing for the a reasonable packet size and
         relocation stuffs.  */
         relocation stuffs.  */
 
 
      if ((PTR) stream == (PTR) NULL)
      if ((PTR) stream == (PTR) NULL)
        {
        {
          /* Outputting a section without data, fill it up */
          /* Outputting a section without data, fill it up */
          stream = (unsigned char *) (bfd_alloc (abfd, s->_raw_size));
          stream = (unsigned char *) (bfd_alloc (abfd, s->_raw_size));
          if (!stream)
          if (!stream)
            return false;
            return false;
          memset ((PTR) stream, 0, (size_t) s->_raw_size);
          memset ((PTR) stream, 0, (size_t) s->_raw_size);
        }
        }
      while (current_byte_index < s->_raw_size)
      while (current_byte_index < s->_raw_size)
        {
        {
          bfd_size_type run;
          bfd_size_type run;
          unsigned int MAXRUN = 127;
          unsigned int MAXRUN = 127;
          if (relocs_to_go)
          if (relocs_to_go)
            {
            {
              run = (*p)->address - current_byte_index;
              run = (*p)->address - current_byte_index;
              if (run > MAXRUN)
              if (run > MAXRUN)
                run = MAXRUN;
                run = MAXRUN;
            }
            }
          else
          else
            {
            {
              run = MAXRUN;
              run = MAXRUN;
            }
            }
          if (run > s->_raw_size - current_byte_index)
          if (run > s->_raw_size - current_byte_index)
            {
            {
              run = s->_raw_size - current_byte_index;
              run = s->_raw_size - current_byte_index;
            }
            }
 
 
          if (run != 0)
          if (run != 0)
            {
            {
              /* Output a stream of bytes */
              /* Output a stream of bytes */
              if (! ieee_write_int (abfd, run))
              if (! ieee_write_int (abfd, run))
                return false;
                return false;
              if (bfd_write ((PTR) (stream + current_byte_index),
              if (bfd_write ((PTR) (stream + current_byte_index),
                             1,
                             1,
                             run,
                             run,
                             abfd)
                             abfd)
                  != run)
                  != run)
                return false;
                return false;
              current_byte_index += run;
              current_byte_index += run;
            }
            }
          /* Output any relocations here */
          /* Output any relocations here */
          if (relocs_to_go && (*p) && (*p)->address == current_byte_index)
          if (relocs_to_go && (*p) && (*p)->address == current_byte_index)
            {
            {
              while (relocs_to_go
              while (relocs_to_go
                     && (*p) && (*p)->address == current_byte_index)
                     && (*p) && (*p)->address == current_byte_index)
                {
                {
                  arelent *r = *p;
                  arelent *r = *p;
                  bfd_signed_vma ov;
                  bfd_signed_vma ov;
 
 
#if 0
#if 0
                  if (r->howto->pc_relative)
                  if (r->howto->pc_relative)
                    {
                    {
                      r->addend += current_byte_index;
                      r->addend += current_byte_index;
                    }
                    }
#endif
#endif
 
 
                  switch (r->howto->size)
                  switch (r->howto->size)
                    {
                    {
                    case 2:
                    case 2:
 
 
                      ov = bfd_get_signed_32 (abfd,
                      ov = bfd_get_signed_32 (abfd,
                                              stream + current_byte_index);
                                              stream + current_byte_index);
                      current_byte_index += 4;
                      current_byte_index += 4;
                      break;
                      break;
                    case 1:
                    case 1:
                      ov = bfd_get_signed_16 (abfd,
                      ov = bfd_get_signed_16 (abfd,
                                              stream + current_byte_index);
                                              stream + current_byte_index);
                      current_byte_index += 2;
                      current_byte_index += 2;
                      break;
                      break;
                    case 0:
                    case 0:
                      ov = bfd_get_signed_8 (abfd,
                      ov = bfd_get_signed_8 (abfd,
                                             stream + current_byte_index);
                                             stream + current_byte_index);
                      current_byte_index++;
                      current_byte_index++;
                      break;
                      break;
                    default:
                    default:
                      ov = 0;
                      ov = 0;
                      BFD_FAIL ();
                      BFD_FAIL ();
                      return false;
                      return false;
                    }
                    }
 
 
                  ov &= r->howto->src_mask;
                  ov &= r->howto->src_mask;
 
 
                  if (r->howto->pc_relative
                  if (r->howto->pc_relative
                      && ! r->howto->pcrel_offset)
                      && ! r->howto->pcrel_offset)
                    ov += r->address;
                    ov += r->address;
 
 
                  if (! ieee_write_byte (abfd,
                  if (! ieee_write_byte (abfd,
                                         ieee_function_either_open_b_enum))
                                         ieee_function_either_open_b_enum))
                    return false;
                    return false;
 
 
/*                abort();*/
/*                abort();*/
 
 
                  if (r->sym_ptr_ptr != (asymbol **) NULL)
                  if (r->sym_ptr_ptr != (asymbol **) NULL)
                    {
                    {
                      if (! ieee_write_expression (abfd, r->addend + ov,
                      if (! ieee_write_expression (abfd, r->addend + ov,
                                                   *(r->sym_ptr_ptr),
                                                   *(r->sym_ptr_ptr),
                                                   r->howto->pc_relative,
                                                   r->howto->pc_relative,
                                                   s->index))
                                                   s->index))
                        return false;
                        return false;
                    }
                    }
                  else
                  else
                    {
                    {
                      if (! ieee_write_expression (abfd, r->addend + ov,
                      if (! ieee_write_expression (abfd, r->addend + ov,
                                                   (asymbol *) NULL,
                                                   (asymbol *) NULL,
                                                   r->howto->pc_relative,
                                                   r->howto->pc_relative,
                                                   s->index))
                                                   s->index))
                        return false;
                        return false;
                    }
                    }
 
 
                  if (number_of_maus_in_address
                  if (number_of_maus_in_address
                      != bfd_get_reloc_size (r->howto))
                      != bfd_get_reloc_size (r->howto))
                    {
                    {
                      if (! ieee_write_int (abfd,
                      if (! ieee_write_int (abfd,
                                            bfd_get_reloc_size (r->howto)))
                                            bfd_get_reloc_size (r->howto)))
                        return false;
                        return false;
                    }
                    }
                  if (! ieee_write_byte (abfd,
                  if (! ieee_write_byte (abfd,
                                         ieee_function_either_close_b_enum))
                                         ieee_function_either_close_b_enum))
                    return false;
                    return false;
 
 
                  relocs_to_go--;
                  relocs_to_go--;
                  p++;
                  p++;
                }
                }
 
 
            }
            }
        }
        }
    }
    }
 
 
  return true;
  return true;
}
}
 
 
/* If there are no relocations in the output section then we can be
/* If there are no relocations in the output section then we can be
   clever about how we write.  We block items up into a max of 127
   clever about how we write.  We block items up into a max of 127
   bytes.  */
   bytes.  */
 
 
static boolean
static boolean
do_as_repeat (abfd, s)
do_as_repeat (abfd, s)
     bfd *abfd;
     bfd *abfd;
     asection *s;
     asection *s;
{
{
  if (s->_raw_size)
  if (s->_raw_size)
    {
    {
      if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
      if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
          || ! ieee_write_byte (abfd,
          || ! ieee_write_byte (abfd,
                                (bfd_byte) (s->index
                                (bfd_byte) (s->index
                                            + IEEE_SECTION_NUMBER_BASE))
                                            + IEEE_SECTION_NUMBER_BASE))
          || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8)
          || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8)
          || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff)
          || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff)
          || ! ieee_write_byte (abfd,
          || ! ieee_write_byte (abfd,
                                (bfd_byte) (s->index
                                (bfd_byte) (s->index
                                            + IEEE_SECTION_NUMBER_BASE))
                                            + IEEE_SECTION_NUMBER_BASE))
          || ! ieee_write_int (abfd, s->lma)
          || ! ieee_write_int (abfd, s->lma)
          || ! ieee_write_byte (abfd, ieee_repeat_data_enum)
          || ! ieee_write_byte (abfd, ieee_repeat_data_enum)
          || ! ieee_write_int (abfd, s->_raw_size)
          || ! ieee_write_int (abfd, s->_raw_size)
          || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)
          || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)
          || ! ieee_write_byte (abfd, 1)
          || ! ieee_write_byte (abfd, 1)
          || ! ieee_write_byte (abfd, 0))
          || ! ieee_write_byte (abfd, 0))
        return false;
        return false;
    }
    }
 
 
  return true;
  return true;
}
}
 
 
static boolean
static boolean
do_without_relocs (abfd, s)
do_without_relocs (abfd, s)
     bfd *abfd;
     bfd *abfd;
     asection *s;
     asection *s;
{
{
  bfd_byte *stream = ieee_per_section (s)->data;
  bfd_byte *stream = ieee_per_section (s)->data;
 
 
  if (stream == 0 || ((s->flags & SEC_LOAD) == 0))
  if (stream == 0 || ((s->flags & SEC_LOAD) == 0))
    {
    {
      if (! do_as_repeat (abfd, s))
      if (! do_as_repeat (abfd, s))
        return false;
        return false;
    }
    }
  else
  else
    {
    {
      unsigned int i;
      unsigned int i;
      for (i = 0; i < s->_raw_size; i++)
      for (i = 0; i < s->_raw_size; i++)
        {
        {
          if (stream[i] != 0)
          if (stream[i] != 0)
            {
            {
              if (! do_with_relocs (abfd, s))
              if (! do_with_relocs (abfd, s))
                return false;
                return false;
              return true;
              return true;
            }
            }
        }
        }
      if (! do_as_repeat (abfd, s))
      if (! do_as_repeat (abfd, s))
        return false;
        return false;
    }
    }
 
 
  return true;
  return true;
}
}
 
 
 
 
static unsigned char *output_ptr_start;
static unsigned char *output_ptr_start;
static unsigned char *output_ptr;
static unsigned char *output_ptr;
static unsigned char *output_ptr_end;
static unsigned char *output_ptr_end;
static unsigned char *input_ptr_start;
static unsigned char *input_ptr_start;
static unsigned char *input_ptr;
static unsigned char *input_ptr;
static unsigned char *input_ptr_end;
static unsigned char *input_ptr_end;
static bfd *input_bfd;
static bfd *input_bfd;
static bfd *output_bfd;
static bfd *output_bfd;
static int output_buffer;
static int output_buffer;
 
 
static void
static void
fill ()
fill ()
{
{
  /* FIXME: Check return value.  I'm not sure whether it needs to read
  /* FIXME: Check return value.  I'm not sure whether it needs to read
     the entire buffer or not.  */
     the entire buffer or not.  */
  bfd_read ((PTR) input_ptr_start, 1, input_ptr_end - input_ptr_start, input_bfd);
  bfd_read ((PTR) input_ptr_start, 1, input_ptr_end - input_ptr_start, input_bfd);
  input_ptr = input_ptr_start;
  input_ptr = input_ptr_start;
}
}
static void
static void
flush ()
flush ()
{
{
  if (bfd_write ((PTR) (output_ptr_start), 1, output_ptr - output_ptr_start,
  if (bfd_write ((PTR) (output_ptr_start), 1, output_ptr - output_ptr_start,
                 output_bfd)
                 output_bfd)
      != (bfd_size_type) (output_ptr - output_ptr_start))
      != (bfd_size_type) (output_ptr - output_ptr_start))
    abort ();
    abort ();
  output_ptr = output_ptr_start;
  output_ptr = output_ptr_start;
  output_buffer++;
  output_buffer++;
}
}
 
 
#define THIS() ( *input_ptr )
#define THIS() ( *input_ptr )
#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); }
#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); }
#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end)  flush(); }
#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end)  flush(); }
 
 
static void
static void
write_int (value)
write_int (value)
     int value;
     int value;
{
{
  if (value >= 0 && value <= 127)
  if (value >= 0 && value <= 127)
    {
    {
      OUT (value);
      OUT (value);
    }
    }
  else
  else
    {
    {
      unsigned int length;
      unsigned int length;
      /* How many significant bytes ? */
      /* How many significant bytes ? */
      /* FIXME FOR LONGER INTS */
      /* FIXME FOR LONGER INTS */
      if (value & 0xff000000)
      if (value & 0xff000000)
        {
        {
          length = 4;
          length = 4;
        }
        }
      else if (value & 0x00ff0000)
      else if (value & 0x00ff0000)
        {
        {
          length = 3;
          length = 3;
        }
        }
      else if (value & 0x0000ff00)
      else if (value & 0x0000ff00)
        {
        {
          length = 2;
          length = 2;
        }
        }
      else
      else
        length = 1;
        length = 1;
 
 
      OUT ((int) ieee_number_repeat_start_enum + length);
      OUT ((int) ieee_number_repeat_start_enum + length);
      switch (length)
      switch (length)
        {
        {
        case 4:
        case 4:
          OUT (value >> 24);
          OUT (value >> 24);
        case 3:
        case 3:
          OUT (value >> 16);
          OUT (value >> 16);
        case 2:
        case 2:
          OUT (value >> 8);
          OUT (value >> 8);
        case 1:
        case 1:
          OUT (value);
          OUT (value);
        }
        }
 
 
    }
    }
}
}
 
 
static void
static void
copy_id ()
copy_id ()
{
{
  int length = THIS ();
  int length = THIS ();
  char ch;
  char ch;
  OUT (length);
  OUT (length);
  NEXT ();
  NEXT ();
  while (length--)
  while (length--)
    {
    {
      ch = THIS ();
      ch = THIS ();
      OUT (ch);
      OUT (ch);
      NEXT ();
      NEXT ();
    }
    }
}
}
 
 
#define VAR(x) ((x | 0x80))
#define VAR(x) ((x | 0x80))
static void
static void
copy_expression ()
copy_expression ()
{
{
  int stack[10];
  int stack[10];
  int *tos = stack;
  int *tos = stack;
  int value = 0;
  int value = 0;
  while (1)
  while (1)
    {
    {
      switch (THIS ())
      switch (THIS ())
        {
        {
        case 0x84:
        case 0x84:
          NEXT ();
          NEXT ();
          value = THIS ();
          value = THIS ();
          NEXT ();
          NEXT ();
          value = (value << 8) | THIS ();
          value = (value << 8) | THIS ();
          NEXT ();
          NEXT ();
          value = (value << 8) | THIS ();
          value = (value << 8) | THIS ();
          NEXT ();
          NEXT ();
          value = (value << 8) | THIS ();
          value = (value << 8) | THIS ();
          NEXT ();
          NEXT ();
          *tos++ = value;
          *tos++ = value;
          break;
          break;
        case 0x83:
        case 0x83:
          NEXT ();
          NEXT ();
          value = THIS ();
          value = THIS ();
          NEXT ();
          NEXT ();
          value = (value << 8) | THIS ();
          value = (value << 8) | THIS ();
          NEXT ();
          NEXT ();
          value = (value << 8) | THIS ();
          value = (value << 8) | THIS ();
          NEXT ();
          NEXT ();
          *tos++ = value;
          *tos++ = value;
          break;
          break;
        case 0x82:
        case 0x82:
          NEXT ();
          NEXT ();
          value = THIS ();
          value = THIS ();
          NEXT ();
          NEXT ();
          value = (value << 8) | THIS ();
          value = (value << 8) | THIS ();
          NEXT ();
          NEXT ();
          *tos++ = value;
          *tos++ = value;
          break;
          break;
        case 0x81:
        case 0x81:
          NEXT ();
          NEXT ();
          value = THIS ();
          value = THIS ();
          NEXT ();
          NEXT ();
          *tos++ = value;
          *tos++ = value;
          break;
          break;
        case 0x80:
        case 0x80:
          NEXT ();
          NEXT ();
          *tos++ = 0;
          *tos++ = 0;
          break;
          break;
        default:
        default:
          if (THIS () > 0x84)
          if (THIS () > 0x84)
            {
            {
              /* Not a number, just bug out with the answer */
              /* Not a number, just bug out with the answer */
              write_int (*(--tos));
              write_int (*(--tos));
              return;
              return;
            }
            }
          *tos++ = THIS ();
          *tos++ = THIS ();
          NEXT ();
          NEXT ();
          value = 0;
          value = 0;
          break;
          break;
        case 0xa5:
        case 0xa5:
          /* PLUS anything */
          /* PLUS anything */
          {
          {
            int value = *(--tos);
            int value = *(--tos);
            value += *(--tos);
            value += *(--tos);
            *tos++ = value;
            *tos++ = value;
            NEXT ();
            NEXT ();
          }
          }
          break;
          break;
        case VAR ('R'):
        case VAR ('R'):
          {
          {
            int section_number;
            int section_number;
            ieee_data_type *ieee;
            ieee_data_type *ieee;
            asection *s;
            asection *s;
            NEXT ();
            NEXT ();
            section_number = THIS ();
            section_number = THIS ();
 
 
            NEXT ();
            NEXT ();
            ieee = IEEE_DATA (input_bfd);
            ieee = IEEE_DATA (input_bfd);
            s = ieee->section_table[section_number];
            s = ieee->section_table[section_number];
            if (s->output_section)
            if (s->output_section)
              {
              {
                value = s->output_section->lma;
                value = s->output_section->lma;
              }
              }
            else
            else
              {
              {
                value = 0;
                value = 0;
              }
              }
            value += s->output_offset;
            value += s->output_offset;
            *tos++ = value;
            *tos++ = value;
            value = 0;
            value = 0;
          }
          }
          break;
          break;
        case 0x90:
        case 0x90:
          {
          {
            NEXT ();
            NEXT ();
            write_int (*(--tos));
            write_int (*(--tos));
            OUT (0x90);
            OUT (0x90);
            return;
            return;
 
 
          }
          }
        }
        }
    }
    }
 
 
}
}
 
 
/* Drop the int in the buffer, and copy a null into the gap, which we
/* Drop the int in the buffer, and copy a null into the gap, which we
   will overwrite later */
   will overwrite later */
 
 
struct output_buffer_struct
struct output_buffer_struct
{
{
  unsigned char *ptrp;
  unsigned char *ptrp;
  int buffer;
  int buffer;
};
};
 
 
static void
static void
fill_int (buf)
fill_int (buf)
     struct output_buffer_struct *buf;
     struct output_buffer_struct *buf;
{
{
  if (buf->buffer == output_buffer)
  if (buf->buffer == output_buffer)
    {
    {
      /* Still a chance to output the size */
      /* Still a chance to output the size */
      int value = output_ptr - buf->ptrp + 3;
      int value = output_ptr - buf->ptrp + 3;
      buf->ptrp[0] = value >> 24;
      buf->ptrp[0] = value >> 24;
      buf->ptrp[1] = value >> 16;
      buf->ptrp[1] = value >> 16;
      buf->ptrp[2] = value >> 8;
      buf->ptrp[2] = value >> 8;
      buf->ptrp[3] = value >> 0;
      buf->ptrp[3] = value >> 0;
    }
    }
}
}
 
 
static void
static void
drop_int (buf)
drop_int (buf)
     struct output_buffer_struct *buf;
     struct output_buffer_struct *buf;
{
{
  int type = THIS ();
  int type = THIS ();
  int ch;
  int ch;
  if (type <= 0x84)
  if (type <= 0x84)
    {
    {
      NEXT ();
      NEXT ();
      switch (type)
      switch (type)
        {
        {
        case 0x84:
        case 0x84:
          ch = THIS ();
          ch = THIS ();
          NEXT ();
          NEXT ();
        case 0x83:
        case 0x83:
          ch = THIS ();
          ch = THIS ();
          NEXT ();
          NEXT ();
        case 0x82:
        case 0x82:
          ch = THIS ();
          ch = THIS ();
          NEXT ();
          NEXT ();
        case 0x81:
        case 0x81:
          ch = THIS ();
          ch = THIS ();
          NEXT ();
          NEXT ();
        case 0x80:
        case 0x80:
          break;
          break;
        }
        }
    }
    }
  OUT (0x84);
  OUT (0x84);
  buf->ptrp = output_ptr;
  buf->ptrp = output_ptr;
  buf->buffer = output_buffer;
  buf->buffer = output_buffer;
  OUT (0);
  OUT (0);
  OUT (0);
  OUT (0);
  OUT (0);
  OUT (0);
  OUT (0);
  OUT (0);
}
}
 
 
static void
static void
copy_int ()
copy_int ()
{
{
  int type = THIS ();
  int type = THIS ();
  int ch;
  int ch;
  if (type <= 0x84)
  if (type <= 0x84)
    {
    {
      OUT (type);
      OUT (type);
      NEXT ();
      NEXT ();
      switch (type)
      switch (type)
        {
        {
        case 0x84:
        case 0x84:
          ch = THIS ();
          ch = THIS ();
          NEXT ();
          NEXT ();
          OUT (ch);
          OUT (ch);
        case 0x83:
        case 0x83:
          ch = THIS ();
          ch = THIS ();
          NEXT ();
          NEXT ();
          OUT (ch);
          OUT (ch);
        case 0x82:
        case 0x82:
          ch = THIS ();
          ch = THIS ();
          NEXT ();
          NEXT ();
          OUT (ch);
          OUT (ch);
        case 0x81:
        case 0x81:
          ch = THIS ();
          ch = THIS ();
          NEXT ();
          NEXT ();
          OUT (ch);
          OUT (ch);
        case 0x80:
        case 0x80:
          break;
          break;
        }
        }
    }
    }
}
}
 
 
#define ID copy_id()
#define ID copy_id()
#define INT copy_int()
#define INT copy_int()
#define EXP copy_expression()
#define EXP copy_expression()
static void copy_till_end ();
static void copy_till_end ();
#define INTn(q) copy_int()
#define INTn(q) copy_int()
#define EXPn(q) copy_expression()
#define EXPn(q) copy_expression()
 
 
static void
static void
f1_record ()
f1_record ()
{
{
  int ch;
  int ch;
  /* ATN record */
  /* ATN record */
  NEXT ();
  NEXT ();
  ch = THIS ();
  ch = THIS ();
  switch (ch)
  switch (ch)
    {
    {
    default:
    default:
      OUT (0xf1);
      OUT (0xf1);
      OUT (ch);
      OUT (ch);
      break;
      break;
    case 0xc9:
    case 0xc9:
      NEXT ();
      NEXT ();
      OUT (0xf1);
      OUT (0xf1);
      OUT (0xc9);
      OUT (0xc9);
      INT;
      INT;
      INT;
      INT;
      ch = THIS ();
      ch = THIS ();
      switch (ch)
      switch (ch)
        {
        {
        case 0x16:
        case 0x16:
          NEXT ();
          NEXT ();
          break;
          break;
        case 0x01:
        case 0x01:
          NEXT ();
          NEXT ();
          break;
          break;
        case 0x00:
        case 0x00:
          NEXT ();
          NEXT ();
          INT;
          INT;
          break;
          break;
        case 0x03:
        case 0x03:
          NEXT ();
          NEXT ();
          INT;
          INT;
          break;
          break;
        case 0x13:
        case 0x13:
          EXPn (instruction address);
          EXPn (instruction address);
          break;
          break;
        default:
        default:
          break;
          break;
        }
        }
      break;
      break;
    case 0xd8:
    case 0xd8:
      /* EXternal ref */
      /* EXternal ref */
      NEXT ();
      NEXT ();
      OUT (0xf1);
      OUT (0xf1);
      OUT (0xd8);
      OUT (0xd8);
      EXP;
      EXP;
      EXP;
      EXP;
      EXP;
      EXP;
      EXP;
      EXP;
      break;
      break;
    case 0xce:
    case 0xce:
      NEXT ();
      NEXT ();
      OUT (0xf1);
      OUT (0xf1);
      OUT (0xce);
      OUT (0xce);
      INT;
      INT;
      INT;
      INT;
      ch = THIS ();
      ch = THIS ();
      INT;
      INT;
      switch (ch)
      switch (ch)
        {
        {
        case 0x01:
        case 0x01:
          INT;
          INT;
          INT;
          INT;
          break;
          break;
        case 0x02:
        case 0x02:
          INT;
          INT;
          break;
          break;
        case 0x04:
        case 0x04:
          EXPn (external function);
          EXPn (external function);
          break;
          break;
        case 0x05:
        case 0x05:
          break;
          break;
        case 0x07:
        case 0x07:
          INTn (line number);
          INTn (line number);
          INT;
          INT;
        case 0x08:
        case 0x08:
          break;
          break;
        case 0x0a:
        case 0x0a:
          INTn (locked register);
          INTn (locked register);
          INT;
          INT;
          break;
          break;
        case 0x3f:
        case 0x3f:
          copy_till_end ();
          copy_till_end ();
          break;
          break;
        case 0x3e:
        case 0x3e:
          copy_till_end ();
          copy_till_end ();
          break;
          break;
        case 0x40:
        case 0x40:
          copy_till_end ();
          copy_till_end ();
          break;
          break;
        case 0x41:
        case 0x41:
          ID;
          ID;
          break;
          break;
        }
        }
    }
    }
 
 
}
}
 
 
static void
static void
f0_record ()
f0_record ()
{
{
  /* Attribute record */
  /* Attribute record */
  NEXT ();
  NEXT ();
  OUT (0xf0);
  OUT (0xf0);
  INTn (Symbol name);
  INTn (Symbol name);
  ID;
  ID;
}
}
 
 
static void
static void
copy_till_end ()
copy_till_end ()
{
{
  int ch = THIS ();
  int ch = THIS ();
  while (1)
  while (1)
    {
    {
      while (ch <= 0x80)
      while (ch <= 0x80)
        {
        {
          OUT (ch);
          OUT (ch);
          NEXT ();
          NEXT ();
          ch = THIS ();
          ch = THIS ();
        }
        }
      switch (ch)
      switch (ch)
        {
        {
        case 0x84:
        case 0x84:
          OUT (THIS ());
          OUT (THIS ());
          NEXT ();
          NEXT ();
        case 0x83:
        case 0x83:
          OUT (THIS ());
          OUT (THIS ());
          NEXT ();
          NEXT ();
        case 0x82:
        case 0x82:
          OUT (THIS ());
          OUT (THIS ());
          NEXT ();
          NEXT ();
        case 0x81:
        case 0x81:
          OUT (THIS ());
          OUT (THIS ());
          NEXT ();
          NEXT ();
          OUT (THIS ());
          OUT (THIS ());
          NEXT ();
          NEXT ();
 
 
          ch = THIS ();
          ch = THIS ();
          break;
          break;
        default:
        default:
          return;
          return;
        }
        }
    }
    }
 
 
}
}
 
 
static void
static void
f2_record ()
f2_record ()
{
{
  NEXT ();
  NEXT ();
  OUT (0xf2);
  OUT (0xf2);
  INT;
  INT;
  NEXT ();
  NEXT ();
  OUT (0xce);
  OUT (0xce);
  INT;
  INT;
  copy_till_end ();
  copy_till_end ();
}
}
 
 
 
 
static void block ();
static void block ();
static void
static void
f8_record ()
f8_record ()
{
{
  int ch;
  int ch;
  NEXT ();
  NEXT ();
  ch = THIS ();
  ch = THIS ();
  switch (ch)
  switch (ch)
    {
    {
    case 0x01:
    case 0x01:
    case 0x02:
    case 0x02:
    case 0x03:
    case 0x03:
      /* Unique typedefs for module */
      /* Unique typedefs for module */
      /* GLobal typedefs  */
      /* GLobal typedefs  */
      /* High level module scope beginning */
      /* High level module scope beginning */
      {
      {
        struct output_buffer_struct ob;
        struct output_buffer_struct ob;
        NEXT ();
        NEXT ();
        OUT (0xf8);
        OUT (0xf8);
        OUT (ch);
        OUT (ch);
        drop_int (&ob);
        drop_int (&ob);
        ID;
        ID;
 
 
        block ();
        block ();
 
 
        NEXT ();
        NEXT ();
        fill_int (&ob);
        fill_int (&ob);
        OUT (0xf9);
        OUT (0xf9);
      }
      }
      break;
      break;
    case 0x04:
    case 0x04:
      /* Global function */
      /* Global function */
      {
      {
        struct output_buffer_struct ob;
        struct output_buffer_struct ob;
        NEXT ();
        NEXT ();
        OUT (0xf8);
        OUT (0xf8);
        OUT (0x04);
        OUT (0x04);
        drop_int (&ob);
        drop_int (&ob);
        ID;
        ID;
        INTn (stack size);
        INTn (stack size);
        INTn (ret val);
        INTn (ret val);
        EXPn (offset);
        EXPn (offset);
 
 
        block ();
        block ();
 
 
        NEXT ();
        NEXT ();
        OUT (0xf9);
        OUT (0xf9);
        EXPn (size of block);
        EXPn (size of block);
        fill_int (&ob);
        fill_int (&ob);
      }
      }
      break;
      break;
 
 
    case 0x05:
    case 0x05:
      /* File name for source line numbers */
      /* File name for source line numbers */
      {
      {
        struct output_buffer_struct ob;
        struct output_buffer_struct ob;
        NEXT ();
        NEXT ();
        OUT (0xf8);
        OUT (0xf8);
        OUT (0x05);
        OUT (0x05);
        drop_int (&ob);
        drop_int (&ob);
        ID;
        ID;
        INTn (year);
        INTn (year);
        INTn (month);
        INTn (month);
        INTn (day);
        INTn (day);
        INTn (hour);
        INTn (hour);
        INTn (monute);
        INTn (monute);
        INTn (second);
        INTn (second);
        block ();
        block ();
        NEXT ();
        NEXT ();
        OUT (0xf9);
        OUT (0xf9);
        fill_int (&ob);
        fill_int (&ob);
      }
      }
      break;
      break;
 
 
    case 0x06:
    case 0x06:
      /* Local function */
      /* Local function */
      {
      {
        struct output_buffer_struct ob;
        struct output_buffer_struct ob;
        NEXT ();
        NEXT ();
        OUT (0xf8);
        OUT (0xf8);
        OUT (0x06);
        OUT (0x06);
        drop_int (&ob);
        drop_int (&ob);
        ID;
        ID;
        INTn (stack size);
        INTn (stack size);
        INTn (type return);
        INTn (type return);
        EXPn (offset);
        EXPn (offset);
        block ();
        block ();
        NEXT ();
        NEXT ();
        OUT (0xf9);
        OUT (0xf9);
        EXPn (size);
        EXPn (size);
        fill_int (&ob);
        fill_int (&ob);
      }
      }
      break;
      break;
 
 
    case 0x0a:
    case 0x0a:
      /* Assembler module scope beginning -*/
      /* Assembler module scope beginning -*/
      {
      {
        struct output_buffer_struct ob;
        struct output_buffer_struct ob;
 
 
        NEXT ();
        NEXT ();
        OUT (0xf8);
        OUT (0xf8);
        OUT (0x0a);
        OUT (0x0a);
        drop_int (&ob);
        drop_int (&ob);
        ID;
        ID;
        ID;
        ID;
        INT;
        INT;
        ID;
        ID;
        INT;
        INT;
        INT;
        INT;
        INT;
        INT;
        INT;
        INT;
        INT;
        INT;
        INT;
        INT;
 
 
        block ();
        block ();
 
 
        NEXT ();
        NEXT ();
        OUT (0xf9);
        OUT (0xf9);
        fill_int (&ob);
        fill_int (&ob);
      }
      }
      break;
      break;
    case 0x0b:
    case 0x0b:
      {
      {
        struct output_buffer_struct ob;
        struct output_buffer_struct ob;
        NEXT ();
        NEXT ();
        OUT (0xf8);
        OUT (0xf8);
        OUT (0x0b);
        OUT (0x0b);
        drop_int (&ob);
        drop_int (&ob);
        ID;
        ID;
        INT;
        INT;
        INTn (section index);
        INTn (section index);
        EXPn (offset);
        EXPn (offset);
        INTn (stuff);
        INTn (stuff);
 
 
        block ();
        block ();
 
 
        OUT (0xf9);
        OUT (0xf9);
        NEXT ();
        NEXT ();
        EXPn (Size in Maus);
        EXPn (Size in Maus);
        fill_int (&ob);
        fill_int (&ob);
      }
      }
      break;
      break;
    }
    }
}
}
 
 
static void
static void
e2_record ()
e2_record ()
{
{
  OUT (0xe2);
  OUT (0xe2);
  NEXT ();
  NEXT ();
  OUT (0xce);
  OUT (0xce);
  NEXT ();
  NEXT ();
  INT;
  INT;
  EXP;
  EXP;
}
}
 
 
static void
static void
block ()
block ()
{
{
  int ch;
  int ch;
  while (1)
  while (1)
    {
    {
      ch = THIS ();
      ch = THIS ();
      switch (ch)
      switch (ch)
        {
        {
        case 0xe1:
        case 0xe1:
        case 0xe5:
        case 0xe5:
          return;
          return;
        case 0xf9:
        case 0xf9:
          return;
          return;
        case 0xf0:
        case 0xf0:
          f0_record ();
          f0_record ();
          break;
          break;
        case 0xf1:
        case 0xf1:
          f1_record ();
          f1_record ();
          break;
          break;
        case 0xf2:
        case 0xf2:
          f2_record ();
          f2_record ();
          break;
          break;
        case 0xf8:
        case 0xf8:
          f8_record ();
          f8_record ();
          break;
          break;
        case 0xe2:
        case 0xe2:
          e2_record ();
          e2_record ();
          break;
          break;
 
 
        }
        }
    }
    }
}
}
 
 
 
 
 
 
/* relocate_debug,
/* relocate_debug,
   moves all the debug information from the source bfd to the output
   moves all the debug information from the source bfd to the output
   bfd, and relocates any expressions it finds
   bfd, and relocates any expressions it finds
*/
*/
 
 
static void
static void
relocate_debug (output, input)
relocate_debug (output, input)
     bfd *output ATTRIBUTE_UNUSED;
     bfd *output ATTRIBUTE_UNUSED;
     bfd *input;
     bfd *input;
{
{
#define IBS 400
#define IBS 400
#define OBS 400
#define OBS 400
  unsigned char input_buffer[IBS];
  unsigned char input_buffer[IBS];
 
 
  input_ptr_start = input_ptr = input_buffer;
  input_ptr_start = input_ptr = input_buffer;
  input_ptr_end = input_buffer + IBS;
  input_ptr_end = input_buffer + IBS;
  input_bfd = input;
  input_bfd = input;
  /* FIXME: Check return value.  I'm not sure whether it needs to read
  /* FIXME: Check return value.  I'm not sure whether it needs to read
     the entire buffer or not.  */
     the entire buffer or not.  */
  bfd_read ((PTR) input_ptr_start, 1, IBS, input);
  bfd_read ((PTR) input_ptr_start, 1, IBS, input);
  block ();
  block ();
}
}
 
 
/* Gather together all the debug information from each input BFD into
/* Gather together all the debug information from each input BFD into
   one place, relocating it and emitting it as we go.  */
   one place, relocating it and emitting it as we go.  */
 
 
static boolean
static boolean
ieee_write_debug_part (abfd)
ieee_write_debug_part (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
  bfd_chain_type *chain = ieee->chain_root;
  bfd_chain_type *chain = ieee->chain_root;
  unsigned char output_buffer[OBS];
  unsigned char output_buffer[OBS];
  boolean some_debug = false;
  boolean some_debug = false;
  file_ptr here = bfd_tell (abfd);
  file_ptr here = bfd_tell (abfd);
 
 
  output_ptr_start = output_ptr = output_buffer;
  output_ptr_start = output_ptr = output_buffer;
  output_ptr_end = output_buffer + OBS;
  output_ptr_end = output_buffer + OBS;
  output_ptr = output_buffer;
  output_ptr = output_buffer;
  output_bfd = abfd;
  output_bfd = abfd;
 
 
  if (chain == (bfd_chain_type *) NULL)
  if (chain == (bfd_chain_type *) NULL)
    {
    {
      asection *s;
      asection *s;
 
 
      for (s = abfd->sections; s != NULL; s = s->next)
      for (s = abfd->sections; s != NULL; s = s->next)
        if ((s->flags & SEC_DEBUGGING) != 0)
        if ((s->flags & SEC_DEBUGGING) != 0)
          break;
          break;
      if (s == NULL)
      if (s == NULL)
        {
        {
          ieee->w.r.debug_information_part = 0;
          ieee->w.r.debug_information_part = 0;
          return true;
          return true;
        }
        }
 
 
      ieee->w.r.debug_information_part = here;
      ieee->w.r.debug_information_part = here;
      if (bfd_write (s->contents, 1, s->_raw_size, abfd) != s->_raw_size)
      if (bfd_write (s->contents, 1, s->_raw_size, abfd) != s->_raw_size)
        return false;
        return false;
    }
    }
  else
  else
    {
    {
      while (chain != (bfd_chain_type *) NULL)
      while (chain != (bfd_chain_type *) NULL)
        {
        {
          bfd *entry = chain->this;
          bfd *entry = chain->this;
          ieee_data_type *entry_ieee = IEEE_DATA (entry);
          ieee_data_type *entry_ieee = IEEE_DATA (entry);
          if (entry_ieee->w.r.debug_information_part)
          if (entry_ieee->w.r.debug_information_part)
            {
            {
              if (bfd_seek (entry, entry_ieee->w.r.debug_information_part,
              if (bfd_seek (entry, entry_ieee->w.r.debug_information_part,
                            SEEK_SET)
                            SEEK_SET)
                  != 0)
                  != 0)
                return false;
                return false;
              relocate_debug (abfd, entry);
              relocate_debug (abfd, entry);
            }
            }
 
 
          chain = chain->next;
          chain = chain->next;
        }
        }
      if (some_debug)
      if (some_debug)
        {
        {
          ieee->w.r.debug_information_part = here;
          ieee->w.r.debug_information_part = here;
        }
        }
      else
      else
        {
        {
          ieee->w.r.debug_information_part = 0;
          ieee->w.r.debug_information_part = 0;
        }
        }
 
 
      flush ();
      flush ();
    }
    }
 
 
  return true;
  return true;
}
}
 
 
/* Write the data in an ieee way.  */
/* Write the data in an ieee way.  */
 
 
static boolean
static boolean
ieee_write_data_part (abfd)
ieee_write_data_part (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  asection *s;
  asection *s;
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee->w.r.data_part = bfd_tell (abfd);
  ieee->w.r.data_part = bfd_tell (abfd);
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
    {
    {
      /* Skip sections that have no loadable contents (.bss,
      /* Skip sections that have no loadable contents (.bss,
         debugging, etc.)  */
         debugging, etc.)  */
      if ((s->flags & SEC_LOAD) == 0)
      if ((s->flags & SEC_LOAD) == 0)
        continue;
        continue;
 
 
      /* Sort the reloc records so we can insert them in the correct
      /* Sort the reloc records so we can insert them in the correct
         places */
         places */
      if (s->reloc_count != 0)
      if (s->reloc_count != 0)
        {
        {
          if (! do_with_relocs (abfd, s))
          if (! do_with_relocs (abfd, s))
            return false;
            return false;
        }
        }
      else
      else
        {
        {
          if (! do_without_relocs (abfd, s))
          if (! do_without_relocs (abfd, s))
            return false;
            return false;
        }
        }
    }
    }
 
 
  return true;
  return true;
}
}
 
 
 
 
static boolean
static boolean
init_for_output (abfd)
init_for_output (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  asection *s;
  asection *s;
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
    {
    {
      if ((s->flags & SEC_DEBUGGING) != 0)
      if ((s->flags & SEC_DEBUGGING) != 0)
        continue;
        continue;
      if (s->_raw_size != 0)
      if (s->_raw_size != 0)
        {
        {
          ieee_per_section (s)->data = (bfd_byte *) (bfd_alloc (abfd, s->_raw_size));
          ieee_per_section (s)->data = (bfd_byte *) (bfd_alloc (abfd, s->_raw_size));
          if (!ieee_per_section (s)->data)
          if (!ieee_per_section (s)->data)
            return false;
            return false;
        }
        }
    }
    }
  return true;
  return true;
}
}


/** exec and core file sections */
/** exec and core file sections */
 
 
/* set section contents is complicated with IEEE since the format is
/* set section contents is complicated with IEEE since the format is
* not a byte image, but a record stream.
* not a byte image, but a record stream.
*/
*/
boolean
boolean
ieee_set_section_contents (abfd, section, location, offset, count)
ieee_set_section_contents (abfd, section, location, offset, count)
     bfd *abfd;
     bfd *abfd;
     sec_ptr section;
     sec_ptr section;
     PTR location;
     PTR location;
     file_ptr offset;
     file_ptr offset;
     bfd_size_type count;
     bfd_size_type count;
{
{
  if ((section->flags & SEC_DEBUGGING) != 0)
  if ((section->flags & SEC_DEBUGGING) != 0)
    {
    {
      if (section->contents == NULL)
      if (section->contents == NULL)
        {
        {
          section->contents = ((unsigned char *)
          section->contents = ((unsigned char *)
                               bfd_alloc (abfd, section->_raw_size));
                               bfd_alloc (abfd, section->_raw_size));
          if (section->contents == NULL)
          if (section->contents == NULL)
            return false;
            return false;
        }
        }
      /* bfd_set_section_contents has already checked that everything
      /* bfd_set_section_contents has already checked that everything
         is within range.  */
         is within range.  */
      memcpy (section->contents + offset, location, count);
      memcpy (section->contents + offset, location, count);
      return true;
      return true;
    }
    }
 
 
  if (ieee_per_section (section)->data == (bfd_byte *) NULL)
  if (ieee_per_section (section)->data == (bfd_byte *) NULL)
    {
    {
      if (!init_for_output (abfd))
      if (!init_for_output (abfd))
        return false;
        return false;
    }
    }
  memcpy ((PTR) (ieee_per_section (section)->data + offset),
  memcpy ((PTR) (ieee_per_section (section)->data + offset),
          (PTR) location,
          (PTR) location,
          (unsigned int) count);
          (unsigned int) count);
  return true;
  return true;
}
}
 
 
/* Write the external symbols of a file.  IEEE considers two sorts of
/* Write the external symbols of a file.  IEEE considers two sorts of
   external symbols, public, and referenced.  It uses to internal
   external symbols, public, and referenced.  It uses to internal
   forms to index them as well.  When we write them out we turn their
   forms to index them as well.  When we write them out we turn their
   symbol values into indexes from the right base.  */
   symbol values into indexes from the right base.  */
 
 
static boolean
static boolean
ieee_write_external_part (abfd)
ieee_write_external_part (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  asymbol **q;
  asymbol **q;
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
 
 
  unsigned int reference_index = IEEE_REFERENCE_BASE;
  unsigned int reference_index = IEEE_REFERENCE_BASE;
  unsigned int public_index = IEEE_PUBLIC_BASE + 2;
  unsigned int public_index = IEEE_PUBLIC_BASE + 2;
  file_ptr here = bfd_tell (abfd);
  file_ptr here = bfd_tell (abfd);
  boolean hadone = false;
  boolean hadone = false;
  if (abfd->outsymbols != (asymbol **) NULL)
  if (abfd->outsymbols != (asymbol **) NULL)
    {
    {
 
 
      for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++)
      for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++)
        {
        {
          asymbol *p = *q;
          asymbol *p = *q;
          if (bfd_is_und_section (p->section))
          if (bfd_is_und_section (p->section))
            {
            {
              /* This must be a symbol reference .. */
              /* This must be a symbol reference .. */
              if (! ieee_write_byte (abfd, ieee_external_reference_enum)
              if (! ieee_write_byte (abfd, ieee_external_reference_enum)
                  || ! ieee_write_int (abfd, reference_index)
                  || ! ieee_write_int (abfd, reference_index)
                  || ! ieee_write_id (abfd, p->name))
                  || ! ieee_write_id (abfd, p->name))
                return false;
                return false;
              p->value = reference_index;
              p->value = reference_index;
              reference_index++;
              reference_index++;
              hadone = true;
              hadone = true;
            }
            }
          else if (bfd_is_com_section (p->section))
          else if (bfd_is_com_section (p->section))
            {
            {
              /* This is a weak reference */
              /* This is a weak reference */
              if (! ieee_write_byte (abfd, ieee_external_reference_enum)
              if (! ieee_write_byte (abfd, ieee_external_reference_enum)
                  || ! ieee_write_int (abfd, reference_index)
                  || ! ieee_write_int (abfd, reference_index)
                  || ! ieee_write_id (abfd, p->name)
                  || ! ieee_write_id (abfd, p->name)
                  || ! ieee_write_byte (abfd,
                  || ! ieee_write_byte (abfd,
                                        ieee_weak_external_reference_enum)
                                        ieee_weak_external_reference_enum)
                  || ! ieee_write_int (abfd, reference_index)
                  || ! ieee_write_int (abfd, reference_index)
                  || ! ieee_write_int (abfd, p->value))
                  || ! ieee_write_int (abfd, p->value))
                return false;
                return false;
              p->value = reference_index;
              p->value = reference_index;
              reference_index++;
              reference_index++;
              hadone = true;
              hadone = true;
            }
            }
          else if (p->flags & BSF_GLOBAL)
          else if (p->flags & BSF_GLOBAL)
            {
            {
              /* This must be a symbol definition */
              /* This must be a symbol definition */
 
 
              if (! ieee_write_byte (abfd, ieee_external_symbol_enum)
              if (! ieee_write_byte (abfd, ieee_external_symbol_enum)
                  || ! ieee_write_int (abfd, public_index)
                  || ! ieee_write_int (abfd, public_index)
                  || ! ieee_write_id (abfd, p->name)
                  || ! ieee_write_id (abfd, p->name)
                  || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum)
                  || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum)
                  || ! ieee_write_int (abfd, public_index)
                  || ! ieee_write_int (abfd, public_index)
                  || ! ieee_write_byte (abfd, 15) /* instruction address */
                  || ! ieee_write_byte (abfd, 15) /* instruction address */
                  || ! ieee_write_byte (abfd, 19) /* static symbol */
                  || ! ieee_write_byte (abfd, 19) /* static symbol */
                  || ! ieee_write_byte (abfd, 1)) /* one of them */
                  || ! ieee_write_byte (abfd, 1)) /* one of them */
                return false;
                return false;
 
 
              /* Write out the value */
              /* Write out the value */
              if (! ieee_write_2bytes (abfd, ieee_value_record_enum)
              if (! ieee_write_2bytes (abfd, ieee_value_record_enum)
                  || ! ieee_write_int (abfd, public_index))
                  || ! ieee_write_int (abfd, public_index))
                return false;
                return false;
              if (! bfd_is_abs_section (p->section))
              if (! bfd_is_abs_section (p->section))
                {
                {
                  if (abfd->flags & EXEC_P)
                  if (abfd->flags & EXEC_P)
                    {
                    {
                      /* If fully linked, then output all symbols
                      /* If fully linked, then output all symbols
                         relocated */
                         relocated */
                      if (! (ieee_write_int
                      if (! (ieee_write_int
                             (abfd,
                             (abfd,
                              (p->value
                              (p->value
                               + p->section->output_offset
                               + p->section->output_offset
                               + p->section->output_section->vma))))
                               + p->section->output_section->vma))))
                        return false;
                        return false;
                    }
                    }
                  else
                  else
                    {
                    {
                      if (! (ieee_write_expression
                      if (! (ieee_write_expression
                             (abfd,
                             (abfd,
                              p->value + p->section->output_offset,
                              p->value + p->section->output_offset,
                              p->section->output_section->symbol,
                              p->section->output_section->symbol,
                              false, 0)))
                              false, 0)))
                        return false;
                        return false;
                    }
                    }
                }
                }
              else
              else
                {
                {
                  if (! ieee_write_expression (abfd,
                  if (! ieee_write_expression (abfd,
                                               p->value,
                                               p->value,
                                               bfd_abs_section_ptr->symbol,
                                               bfd_abs_section_ptr->symbol,
                                               false, 0))
                                               false, 0))
                    return false;
                    return false;
                }
                }
              p->value = public_index;
              p->value = public_index;
              public_index++;
              public_index++;
              hadone = true;
              hadone = true;
            }
            }
          else
          else
            {
            {
              /* This can happen - when there are gaps in the symbols read */
              /* This can happen - when there are gaps in the symbols read */
              /* from an input ieee file */
              /* from an input ieee file */
            }
            }
        }
        }
    }
    }
  if (hadone)
  if (hadone)
    ieee->w.r.external_part = here;
    ieee->w.r.external_part = here;
 
 
  return true;
  return true;
}
}
 
 
 
 
static CONST unsigned char exten[] =
static CONST unsigned char exten[] =
{
{
  0xf0, 0x20, 0x00,
  0xf0, 0x20, 0x00,
  0xf1, 0xce, 0x20, 0x00, 37, 3, 3,     /* Set version 3 rev 3          */
  0xf1, 0xce, 0x20, 0x00, 37, 3, 3,     /* Set version 3 rev 3          */
  0xf1, 0xce, 0x20, 0x00, 39, 2,/* keep symbol in  original case */
  0xf1, 0xce, 0x20, 0x00, 39, 2,/* keep symbol in  original case */
  0xf1, 0xce, 0x20, 0x00, 38    /* set object type relocateable to x */
  0xf1, 0xce, 0x20, 0x00, 38    /* set object type relocateable to x */
};
};
 
 
static CONST unsigned char envi[] =
static CONST unsigned char envi[] =
{
{
  0xf0, 0x21, 0x00,
  0xf0, 0x21, 0x00,
 
 
/*    0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11,
/*    0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11,
    0x19, 0x2c,
    0x19, 0x2c,
*/
*/
  0xf1, 0xce, 0x21, 00, 52, 0x00,       /* exec ok */
  0xf1, 0xce, 0x21, 00, 52, 0x00,       /* exec ok */
 
 
  0xf1, 0xce, 0x21, 0, 53, 0x03,/* host unix */
  0xf1, 0xce, 0x21, 0, 53, 0x03,/* host unix */
/*    0xf1, 0xce, 0x21, 0, 54, 2,1,1    tool & version # */
/*    0xf1, 0xce, 0x21, 0, 54, 2,1,1    tool & version # */
};
};
 
 
static boolean
static boolean
ieee_write_me_part (abfd)
ieee_write_me_part (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee->w.r.trailer_part = bfd_tell (abfd);
  ieee->w.r.trailer_part = bfd_tell (abfd);
  if (abfd->start_address)
  if (abfd->start_address)
    {
    {
      if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum)
      if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum)
          || ! ieee_write_byte (abfd, ieee_function_either_open_b_enum)
          || ! ieee_write_byte (abfd, ieee_function_either_open_b_enum)
          || ! ieee_write_int (abfd, abfd->start_address)
          || ! ieee_write_int (abfd, abfd->start_address)
          || ! ieee_write_byte (abfd, ieee_function_either_close_b_enum))
          || ! ieee_write_byte (abfd, ieee_function_either_close_b_enum))
        return false;
        return false;
    }
    }
  ieee->w.r.me_record = bfd_tell (abfd);
  ieee->w.r.me_record = bfd_tell (abfd);
  if (! ieee_write_byte (abfd, ieee_module_end_enum))
  if (! ieee_write_byte (abfd, ieee_module_end_enum))
    return false;
    return false;
  return true;
  return true;
}
}
 
 
/* Write out the IEEE processor ID.  */
/* Write out the IEEE processor ID.  */
 
 
static boolean
static boolean
ieee_write_processor (abfd)
ieee_write_processor (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  const bfd_arch_info_type *arch;
  const bfd_arch_info_type *arch;
 
 
  arch = bfd_get_arch_info (abfd);
  arch = bfd_get_arch_info (abfd);
  switch (arch->arch)
  switch (arch->arch)
    {
    {
    default:
    default:
      if (! ieee_write_id (abfd, bfd_printable_name (abfd)))
      if (! ieee_write_id (abfd, bfd_printable_name (abfd)))
        return false;
        return false;
      break;
      break;
 
 
    case bfd_arch_a29k:
    case bfd_arch_a29k:
      if (! ieee_write_id (abfd, "29000"))
      if (! ieee_write_id (abfd, "29000"))
        return false;
        return false;
      break;
      break;
 
 
    case bfd_arch_h8300:
    case bfd_arch_h8300:
      if (! ieee_write_id (abfd, "H8/300"))
      if (! ieee_write_id (abfd, "H8/300"))
        return false;
        return false;
      break;
      break;
 
 
    case bfd_arch_h8500:
    case bfd_arch_h8500:
      if (! ieee_write_id (abfd, "H8/500"))
      if (! ieee_write_id (abfd, "H8/500"))
        return false;
        return false;
      break;
      break;
 
 
    case bfd_arch_i960:
    case bfd_arch_i960:
      switch (arch->mach)
      switch (arch->mach)
        {
        {
        default:
        default:
        case bfd_mach_i960_core:
        case bfd_mach_i960_core:
        case bfd_mach_i960_ka_sa:
        case bfd_mach_i960_ka_sa:
          if (! ieee_write_id (abfd, "80960KA"))
          if (! ieee_write_id (abfd, "80960KA"))
            return false;
            return false;
          break;
          break;
 
 
        case bfd_mach_i960_kb_sb:
        case bfd_mach_i960_kb_sb:
          if (! ieee_write_id (abfd, "80960KB"))
          if (! ieee_write_id (abfd, "80960KB"))
            return false;
            return false;
          break;
          break;
 
 
        case bfd_mach_i960_ca:
        case bfd_mach_i960_ca:
          if (! ieee_write_id (abfd, "80960CA"))
          if (! ieee_write_id (abfd, "80960CA"))
            return false;
            return false;
          break;
          break;
 
 
        case bfd_mach_i960_mc:
        case bfd_mach_i960_mc:
        case bfd_mach_i960_xa:
        case bfd_mach_i960_xa:
          if (! ieee_write_id (abfd, "80960MC"))
          if (! ieee_write_id (abfd, "80960MC"))
            return false;
            return false;
          break;
          break;
        }
        }
      break;
      break;
 
 
    case bfd_arch_m68k:
    case bfd_arch_m68k:
      {
      {
        const char *id;
        const char *id;
 
 
        switch (arch->mach)
        switch (arch->mach)
          {
          {
          default:              id = "68020"; break;
          default:              id = "68020"; break;
          case bfd_mach_m68000: id = "68000"; break;
          case bfd_mach_m68000: id = "68000"; break;
          case bfd_mach_m68008: id = "68008"; break;
          case bfd_mach_m68008: id = "68008"; break;
          case bfd_mach_m68010: id = "68010"; break;
          case bfd_mach_m68010: id = "68010"; break;
          case bfd_mach_m68020: id = "68020"; break;
          case bfd_mach_m68020: id = "68020"; break;
          case bfd_mach_m68030: id = "68030"; break;
          case bfd_mach_m68030: id = "68030"; break;
          case bfd_mach_m68040: id = "68040"; break;
          case bfd_mach_m68040: id = "68040"; break;
          case bfd_mach_m68060: id = "68060"; break;
          case bfd_mach_m68060: id = "68060"; break;
          case bfd_mach_cpu32:  id = "cpu32"; break;
          case bfd_mach_cpu32:  id = "cpu32"; break;
          case bfd_mach_mcf5200:id = "5200";  break;
          case bfd_mach_mcf5200:id = "5200";  break;
          case bfd_mach_mcf5206e:id = "5206e"; break;
          case bfd_mach_mcf5206e:id = "5206e"; break;
          case bfd_mach_mcf5307:id = "5307";  break;
          case bfd_mach_mcf5307:id = "5307";  break;
          case bfd_mach_mcf5407:id = "5407";  break;
          case bfd_mach_mcf5407:id = "5407";  break;
          }
          }
 
 
        if (! ieee_write_id (abfd, id))
        if (! ieee_write_id (abfd, id))
          return false;
          return false;
      }
      }
      break;
      break;
    }
    }
 
 
  return true;
  return true;
}
}
 
 
boolean
boolean
ieee_write_object_contents (abfd)
ieee_write_object_contents (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  ieee_data_type *ieee = IEEE_DATA (abfd);
  ieee_data_type *ieee = IEEE_DATA (abfd);
  unsigned int i;
  unsigned int i;
  file_ptr old;
  file_ptr old;
 
 
  /* Fast forward over the header area */
  /* Fast forward over the header area */
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    return false;
    return false;
 
 
  if (! ieee_write_byte (abfd, ieee_module_beginning_enum)
  if (! ieee_write_byte (abfd, ieee_module_beginning_enum)
      || ! ieee_write_processor (abfd)
      || ! ieee_write_processor (abfd)
      || ! ieee_write_id (abfd, abfd->filename))
      || ! ieee_write_id (abfd, abfd->filename))
    return false;
    return false;
 
 
  /* Fast forward over the variable bits */
  /* Fast forward over the variable bits */
  if (! ieee_write_byte (abfd, ieee_address_descriptor_enum))
  if (! ieee_write_byte (abfd, ieee_address_descriptor_enum))
    return false;
    return false;
 
 
  /* Bits per MAU */
  /* Bits per MAU */
  if (! ieee_write_byte (abfd, (bfd_byte) (bfd_arch_bits_per_byte (abfd))))
  if (! ieee_write_byte (abfd, (bfd_byte) (bfd_arch_bits_per_byte (abfd))))
    return false;
    return false;
  /* MAU's per address */
  /* MAU's per address */
  if (! ieee_write_byte (abfd,
  if (! ieee_write_byte (abfd,
                         (bfd_byte) (bfd_arch_bits_per_address (abfd)
                         (bfd_byte) (bfd_arch_bits_per_address (abfd)
                                     / bfd_arch_bits_per_byte (abfd))))
                                     / bfd_arch_bits_per_byte (abfd))))
    return false;
    return false;
 
 
  old = bfd_tell (abfd);
  old = bfd_tell (abfd);
  if (bfd_seek (abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR) != 0)
  if (bfd_seek (abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR) != 0)
    return false;
    return false;
 
 
  ieee->w.r.extension_record = bfd_tell (abfd);
  ieee->w.r.extension_record = bfd_tell (abfd);
  if (bfd_write ((char *) exten, 1, sizeof (exten), abfd) != sizeof (exten))
  if (bfd_write ((char *) exten, 1, sizeof (exten), abfd) != sizeof (exten))
    return false;
    return false;
  if (abfd->flags & EXEC_P)
  if (abfd->flags & EXEC_P)
    {
    {
      if (! ieee_write_byte (abfd, 0x1)) /* Absolute */
      if (! ieee_write_byte (abfd, 0x1)) /* Absolute */
        return false;
        return false;
    }
    }
  else
  else
    {
    {
      if (! ieee_write_byte (abfd, 0x2)) /* Relocateable */
      if (! ieee_write_byte (abfd, 0x2)) /* Relocateable */
        return false;
        return false;
    }
    }
 
 
  ieee->w.r.environmental_record = bfd_tell (abfd);
  ieee->w.r.environmental_record = bfd_tell (abfd);
  if (bfd_write ((char *) envi, 1, sizeof (envi), abfd) != sizeof (envi))
  if (bfd_write ((char *) envi, 1, sizeof (envi), abfd) != sizeof (envi))
    return false;
    return false;
 
 
  /* The HP emulator database requires a timestamp in the file.  */
  /* The HP emulator database requires a timestamp in the file.  */
  {
  {
    time_t now;
    time_t now;
    const struct tm *t;
    const struct tm *t;
 
 
    time (&now);
    time (&now);
    t = (struct tm *) localtime (&now);
    t = (struct tm *) localtime (&now);
    if (! ieee_write_2bytes (abfd, (int) ieee_atn_record_enum)
    if (! ieee_write_2bytes (abfd, (int) ieee_atn_record_enum)
        || ! ieee_write_byte (abfd, 0x21)
        || ! ieee_write_byte (abfd, 0x21)
        || ! ieee_write_byte (abfd, 0)
        || ! ieee_write_byte (abfd, 0)
        || ! ieee_write_byte (abfd, 50)
        || ! ieee_write_byte (abfd, 50)
        || ! ieee_write_int (abfd, t->tm_year + 1900)
        || ! ieee_write_int (abfd, t->tm_year + 1900)
        || ! ieee_write_int (abfd, t->tm_mon + 1)
        || ! ieee_write_int (abfd, t->tm_mon + 1)
        || ! ieee_write_int (abfd, t->tm_mday)
        || ! ieee_write_int (abfd, t->tm_mday)
        || ! ieee_write_int (abfd, t->tm_hour)
        || ! ieee_write_int (abfd, t->tm_hour)
        || ! ieee_write_int (abfd, t->tm_min)
        || ! ieee_write_int (abfd, t->tm_min)
        || ! ieee_write_int (abfd, t->tm_sec))
        || ! ieee_write_int (abfd, t->tm_sec))
      return false;
      return false;
  }
  }
 
 
  output_bfd = abfd;
  output_bfd = abfd;
 
 
  flush ();
  flush ();
 
 
  if (! ieee_write_section_part (abfd))
  if (! ieee_write_section_part (abfd))
    return false;
    return false;
  /* First write the symbols.  This changes their values into table
  /* First write the symbols.  This changes their values into table
    indeces so we cant use it after this point.  */
    indeces so we cant use it after this point.  */
  if (! ieee_write_external_part (abfd))
  if (! ieee_write_external_part (abfd))
    return false;
    return false;
 
 
  /*  ieee_write_byte(abfd, ieee_record_seperator_enum);*/
  /*  ieee_write_byte(abfd, ieee_record_seperator_enum);*/
 
 
  /*  ieee_write_byte(abfd, ieee_record_seperator_enum);*/
  /*  ieee_write_byte(abfd, ieee_record_seperator_enum);*/
 
 
 
 
  /* Write any debugs we have been told about.  */
  /* Write any debugs we have been told about.  */
  if (! ieee_write_debug_part (abfd))
  if (! ieee_write_debug_part (abfd))
    return false;
    return false;
 
 
  /* Can only write the data once the symbols have been written, since
  /* Can only write the data once the symbols have been written, since
     the data contains relocation information which points to the
     the data contains relocation information which points to the
     symbols.  */
     symbols.  */
  if (! ieee_write_data_part (abfd))
  if (! ieee_write_data_part (abfd))
    return false;
    return false;
 
 
  /* At the end we put the end!  */
  /* At the end we put the end!  */
  if (! ieee_write_me_part (abfd))
  if (! ieee_write_me_part (abfd))
    return false;
    return false;
 
 
  /* Generate the header */
  /* Generate the header */
  if (bfd_seek (abfd, old, SEEK_SET) != 0)
  if (bfd_seek (abfd, old, SEEK_SET) != 0)
    return false;
    return false;
 
 
  for (i = 0; i < N_W_VARIABLES; i++)
  for (i = 0; i < N_W_VARIABLES; i++)
    {
    {
      if (! ieee_write_2bytes (abfd, ieee_assign_value_to_variable_enum)
      if (! ieee_write_2bytes (abfd, ieee_assign_value_to_variable_enum)
          || ! ieee_write_byte (abfd, (bfd_byte) i)
          || ! ieee_write_byte (abfd, (bfd_byte) i)
          || ! ieee_write_int5_out (abfd, ieee->w.offset[i]))
          || ! ieee_write_int5_out (abfd, ieee->w.offset[i]))
        return false;
        return false;
    }
    }
 
 
  return true;
  return true;
}
}


/* Native-level interface to symbols. */
/* Native-level interface to symbols. */
 
 
/* We read the symbols into a buffer, which is discarded when this
/* We read the symbols into a buffer, which is discarded when this
   function exits.  We read the strings into a buffer large enough to
   function exits.  We read the strings into a buffer large enough to
   hold them all plus all the cached symbol entries. */
   hold them all plus all the cached symbol entries. */
 
 
asymbol *
asymbol *
ieee_make_empty_symbol (abfd)
ieee_make_empty_symbol (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
  ieee_symbol_type *new =
  ieee_symbol_type *new =
    (ieee_symbol_type *) bfd_zalloc (abfd, sizeof (ieee_symbol_type));
    (ieee_symbol_type *) bfd_zalloc (abfd, sizeof (ieee_symbol_type));
  if (!new)
  if (!new)
    return NULL;
    return NULL;
  new->symbol.the_bfd = abfd;
  new->symbol.the_bfd = abfd;
  return &new->symbol;
  return &new->symbol;
}
}
 
 
static bfd *
static bfd *
ieee_openr_next_archived_file (arch, prev)
ieee_openr_next_archived_file (arch, prev)
     bfd *arch;
     bfd *arch;
     bfd *prev;
     bfd *prev;
{
{
  ieee_ar_data_type *ar = IEEE_AR_DATA (arch);
  ieee_ar_data_type *ar = IEEE_AR_DATA (arch);
  /* take the next one from the arch state, or reset */
  /* take the next one from the arch state, or reset */
  if (prev == (bfd *) NULL)
  if (prev == (bfd *) NULL)
    {
    {
      /* Reset the index - the first two entries are bogus*/
      /* Reset the index - the first two entries are bogus*/
      ar->element_index = 2;
      ar->element_index = 2;
    }
    }
  while (true)
  while (true)
    {
    {
      ieee_ar_obstack_type *p = ar->elements + ar->element_index;
      ieee_ar_obstack_type *p = ar->elements + ar->element_index;
      ar->element_index++;
      ar->element_index++;
      if (ar->element_index <= ar->element_count)
      if (ar->element_index <= ar->element_count)
        {
        {
          if (p->file_offset != (file_ptr) 0)
          if (p->file_offset != (file_ptr) 0)
            {
            {
              if (p->abfd == (bfd *) NULL)
              if (p->abfd == (bfd *) NULL)
                {
                {
                  p->abfd = _bfd_create_empty_archive_element_shell (arch);
                  p->abfd = _bfd_create_empty_archive_element_shell (arch);
                  p->abfd->origin = p->file_offset;
                  p->abfd->origin = p->file_offset;
                }
                }
              return p->abfd;
              return p->abfd;
            }
            }
        }
        }
      else
      else
        {
        {
          bfd_set_error (bfd_error_no_more_archived_files);
          bfd_set_error (bfd_error_no_more_archived_files);
          return (bfd *) NULL;
          return (bfd *) NULL;
        }
        }
 
 
    }
    }
}
}
 
 
static boolean
static boolean
ieee_find_nearest_line (abfd,
ieee_find_nearest_line (abfd,
                        section,
                        section,
                        symbols,
                        symbols,
                        offset,
                        offset,
                        filename_ptr,
                        filename_ptr,
                        functionname_ptr,
                        functionname_ptr,
                        line_ptr)
                        line_ptr)
     bfd *abfd ATTRIBUTE_UNUSED;
     bfd *abfd ATTRIBUTE_UNUSED;
     asection *section ATTRIBUTE_UNUSED;
     asection *section ATTRIBUTE_UNUSED;
     asymbol **symbols ATTRIBUTE_UNUSED;
     asymbol **symbols ATTRIBUTE_UNUSED;
     bfd_vma offset ATTRIBUTE_UNUSED;
     bfd_vma offset ATTRIBUTE_UNUSED;
     const char **filename_ptr ATTRIBUTE_UNUSED;
     const char **filename_ptr ATTRIBUTE_UNUSED;
     const char **functionname_ptr ATTRIBUTE_UNUSED;
     const char **functionname_ptr ATTRIBUTE_UNUSED;
     unsigned int *line_ptr ATTRIBUTE_UNUSED;
     unsigned int *line_ptr ATTRIBUTE_UNUSED;
{
{
  return false;
  return false;
}
}
 
 
static int
static int
ieee_generic_stat_arch_elt (abfd, buf)
ieee_generic_stat_arch_elt (abfd, buf)
     bfd *abfd;
     bfd *abfd;
     struct stat *buf;
     struct stat *buf;
{
{
  ieee_ar_data_type *ar = (ieee_ar_data_type *) NULL;
  ieee_ar_data_type *ar = (ieee_ar_data_type *) NULL;
  ieee_data_type *ieee;
  ieee_data_type *ieee;
 
 
  if (abfd->my_archive != NULL)
  if (abfd->my_archive != NULL)
    ar = abfd->my_archive->tdata.ieee_ar_data;
    ar = abfd->my_archive->tdata.ieee_ar_data;
  if (ar == (ieee_ar_data_type *) NULL)
  if (ar == (ieee_ar_data_type *) NULL)
    {
    {
      bfd_set_error (bfd_error_invalid_operation);
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
      return -1;
    }
    }
 
 
  if (IEEE_DATA (abfd) == NULL)
  if (IEEE_DATA (abfd) == NULL)
    {
    {
      if (ieee_object_p (abfd) == NULL)
      if (ieee_object_p (abfd) == NULL)
        {
        {
          bfd_set_error (bfd_error_wrong_format);
          bfd_set_error (bfd_error_wrong_format);
          return -1;
          return -1;
        }
        }
    }
    }
 
 
  ieee = IEEE_DATA (abfd);
  ieee = IEEE_DATA (abfd);
 
 
  buf->st_size = ieee->w.r.me_record + 1;
  buf->st_size = ieee->w.r.me_record + 1;
  buf->st_mode = 0644;
  buf->st_mode = 0644;
  return 0;
  return 0;
}
}
 
 
static int
static int
ieee_sizeof_headers (abfd, x)
ieee_sizeof_headers (abfd, x)
     bfd *abfd ATTRIBUTE_UNUSED;
     bfd *abfd ATTRIBUTE_UNUSED;
     boolean x ATTRIBUTE_UNUSED;
     boolean x ATTRIBUTE_UNUSED;
{
{
  return 0;
  return 0;
}
}
 
 
 
 
/* The debug info routines are never used.  */
/* The debug info routines are never used.  */
#if 0
#if 0
 
 
static void
static void
ieee_bfd_debug_info_start (abfd)
ieee_bfd_debug_info_start (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
 
 
}
}
 
 
static void
static void
ieee_bfd_debug_info_end (abfd)
ieee_bfd_debug_info_end (abfd)
     bfd *abfd;
     bfd *abfd;
{
{
 
 
}
}
 
 
 
 
/* Add this section to the list of sections we have debug info for, to
/* Add this section to the list of sections we have debug info for, to
   be ready to output it at close time
   be ready to output it at close time
   */
   */
static void
static void
ieee_bfd_debug_info_accumulate (abfd, section)
ieee_bfd_debug_info_accumulate (abfd, section)
     bfd *abfd;
     bfd *abfd;
     asection *section;
     asection *section;
{
{
  ieee_data_type *ieee = IEEE_DATA (section->owner);
  ieee_data_type *ieee = IEEE_DATA (section->owner);
  ieee_data_type *output_ieee = IEEE_DATA (abfd);
  ieee_data_type *output_ieee = IEEE_DATA (abfd);
  /* can only accumulate data from other ieee bfds */
  /* can only accumulate data from other ieee bfds */
  if (section->owner->xvec != abfd->xvec)
  if (section->owner->xvec != abfd->xvec)
    return;
    return;
  /* Only bother once per bfd */
  /* Only bother once per bfd */
  if (ieee->done_debug == true)
  if (ieee->done_debug == true)
    return;
    return;
  ieee->done_debug = true;
  ieee->done_debug = true;
 
 
  /* Don't bother if there is no debug info */
  /* Don't bother if there is no debug info */
  if (ieee->w.r.debug_information_part == 0)
  if (ieee->w.r.debug_information_part == 0)
    return;
    return;
 
 
 
 
  /* Add to chain */
  /* Add to chain */
  {
  {
    bfd_chain_type *n = (bfd_chain_type *) bfd_alloc (abfd, sizeof (bfd_chain_type));
    bfd_chain_type *n = (bfd_chain_type *) bfd_alloc (abfd, sizeof (bfd_chain_type));
    if (!n)
    if (!n)
      abort ();         /* FIXME */
      abort ();         /* FIXME */
    n->this = section->owner;
    n->this = section->owner;
    n->next = (bfd_chain_type *) NULL;
    n->next = (bfd_chain_type *) NULL;
 
 
    if (output_ieee->chain_head)
    if (output_ieee->chain_head)
      {
      {
        output_ieee->chain_head->next = n;
        output_ieee->chain_head->next = n;
      }
      }
    else
    else
      {
      {
        output_ieee->chain_root = n;
        output_ieee->chain_root = n;
 
 
      }
      }
    output_ieee->chain_head = n;
    output_ieee->chain_head = n;
  }
  }
}
}
 
 
#endif
#endif
 
 
#define ieee_close_and_cleanup _bfd_generic_close_and_cleanup
#define ieee_close_and_cleanup _bfd_generic_close_and_cleanup
#define ieee_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
#define ieee_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
 
 
#define ieee_slurp_armap bfd_true
#define ieee_slurp_armap bfd_true
#define ieee_slurp_extended_name_table bfd_true
#define ieee_slurp_extended_name_table bfd_true
#define ieee_construct_extended_name_table \
#define ieee_construct_extended_name_table \
  ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
  ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
   bfd_true)
   bfd_true)
#define ieee_truncate_arname bfd_dont_truncate_arname
#define ieee_truncate_arname bfd_dont_truncate_arname
#define ieee_write_armap \
#define ieee_write_armap \
  ((boolean (*) \
  ((boolean (*) \
    PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
    PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
   bfd_true)
   bfd_true)
#define ieee_read_ar_hdr bfd_nullvoidptr
#define ieee_read_ar_hdr bfd_nullvoidptr
#define ieee_update_armap_timestamp bfd_true
#define ieee_update_armap_timestamp bfd_true
#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index
#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index
 
 
#define ieee_bfd_is_local_label_name bfd_generic_is_local_label_name
#define ieee_bfd_is_local_label_name bfd_generic_is_local_label_name
#define ieee_get_lineno _bfd_nosymbols_get_lineno
#define ieee_get_lineno _bfd_nosymbols_get_lineno
#define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
#define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
#define ieee_read_minisymbols _bfd_generic_read_minisymbols
#define ieee_read_minisymbols _bfd_generic_read_minisymbols
#define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
#define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
 
 
#define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
#define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
 
 
#define ieee_set_arch_mach _bfd_generic_set_arch_mach
#define ieee_set_arch_mach _bfd_generic_set_arch_mach
 
 
#define ieee_get_section_contents_in_window \
#define ieee_get_section_contents_in_window \
  _bfd_generic_get_section_contents_in_window
  _bfd_generic_get_section_contents_in_window
#define ieee_bfd_get_relocated_section_contents \
#define ieee_bfd_get_relocated_section_contents \
  bfd_generic_get_relocated_section_contents
  bfd_generic_get_relocated_section_contents
#define ieee_bfd_relax_section bfd_generic_relax_section
#define ieee_bfd_relax_section bfd_generic_relax_section
#define ieee_bfd_gc_sections bfd_generic_gc_sections
#define ieee_bfd_gc_sections bfd_generic_gc_sections
#define ieee_bfd_merge_sections bfd_generic_merge_sections
#define ieee_bfd_merge_sections bfd_generic_merge_sections
#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols
#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols
#define ieee_bfd_final_link _bfd_generic_final_link
#define ieee_bfd_final_link _bfd_generic_final_link
#define ieee_bfd_link_split_section  _bfd_generic_link_split_section
#define ieee_bfd_link_split_section  _bfd_generic_link_split_section
 
 
/*SUPPRESS 460 */
/*SUPPRESS 460 */
const bfd_target ieee_vec =
const bfd_target ieee_vec =
{
{
  "ieee",                       /* name */
  "ieee",                       /* name */
  bfd_target_ieee_flavour,
  bfd_target_ieee_flavour,
  BFD_ENDIAN_UNKNOWN,           /* target byte order */
  BFD_ENDIAN_UNKNOWN,           /* target byte order */
  BFD_ENDIAN_UNKNOWN,           /* target headers byte order */
  BFD_ENDIAN_UNKNOWN,           /* target headers byte order */
  (HAS_RELOC | EXEC_P |         /* object flags */
  (HAS_RELOC | EXEC_P |         /* object flags */
   HAS_LINENO | HAS_DEBUG |
   HAS_LINENO | HAS_DEBUG |
   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
   | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
   | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  '_',                          /* leading underscore */
  '_',                          /* leading underscore */
  ' ',                          /* ar_pad_char */
  ' ',                          /* ar_pad_char */
  16,                           /* ar_max_namelen */
  16,                           /* ar_max_namelen */
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
 
 
  {_bfd_dummy_target,
  {_bfd_dummy_target,
   ieee_object_p,               /* bfd_check_format */
   ieee_object_p,               /* bfd_check_format */
   ieee_archive_p,
   ieee_archive_p,
   _bfd_dummy_target,
   _bfd_dummy_target,
  },
  },
  {
  {
    bfd_false,
    bfd_false,
    ieee_mkobject,
    ieee_mkobject,
    _bfd_generic_mkarchive,
    _bfd_generic_mkarchive,
    bfd_false
    bfd_false
  },
  },
  {
  {
    bfd_false,
    bfd_false,
    ieee_write_object_contents,
    ieee_write_object_contents,
    _bfd_write_archive_contents,
    _bfd_write_archive_contents,
    bfd_false,
    bfd_false,
  },
  },
 
 
  BFD_JUMP_TABLE_GENERIC (ieee),
  BFD_JUMP_TABLE_GENERIC (ieee),
  BFD_JUMP_TABLE_COPY (_bfd_generic),
  BFD_JUMP_TABLE_COPY (_bfd_generic),
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
  BFD_JUMP_TABLE_ARCHIVE (ieee),
  BFD_JUMP_TABLE_ARCHIVE (ieee),
  BFD_JUMP_TABLE_SYMBOLS (ieee),
  BFD_JUMP_TABLE_SYMBOLS (ieee),
  BFD_JUMP_TABLE_RELOCS (ieee),
  BFD_JUMP_TABLE_RELOCS (ieee),
  BFD_JUMP_TABLE_WRITE (ieee),
  BFD_JUMP_TABLE_WRITE (ieee),
  BFD_JUMP_TABLE_LINK (ieee),
  BFD_JUMP_TABLE_LINK (ieee),
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
 
 
  NULL,
  NULL,
 
 
  (PTR) 0
  (PTR) 0
};
};
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.