ieee.c revision 104834
133965Sjdp/* BFD back-end for ieee-695 objects.
278828Sobrien   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
391041Sobrien   2000, 2001, 2002
433965Sjdp   Free Software Foundation, Inc.
533965Sjdp
633965Sjdp   Written by Steve Chamberlain of Cygnus Support.
733965Sjdp
891041Sobrien   This file is part of BFD, the Binary File Descriptor library.
933965Sjdp
1091041Sobrien   This program is free software; you can redistribute it and/or modify
1191041Sobrien   it under the terms of the GNU General Public License as published by
1291041Sobrien   the Free Software Foundation; either version 2 of the License, or
1391041Sobrien   (at your option) any later version.
1433965Sjdp
1591041Sobrien   This program is distributed in the hope that it will be useful,
1691041Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1791041Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1891041Sobrien   GNU General Public License for more details.
1933965Sjdp
2091041Sobrien   You should have received a copy of the GNU General Public License
2191041Sobrien   along with this program; if not, write to the Free Software
2291041Sobrien   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2333965Sjdp
2433965Sjdp#define KEEPMINUSPCININST 0
2533965Sjdp
2633965Sjdp/* IEEE 695 format is a stream of records, which we parse using a simple one-
2733965Sjdp   token (which is one byte in this lexicon) lookahead recursive decent
2833965Sjdp   parser.  */
2933965Sjdp
3033965Sjdp#include "bfd.h"
3133965Sjdp#include "sysdep.h"
3233965Sjdp#include "libbfd.h"
3333965Sjdp#include "ieee.h"
3433965Sjdp#include "libieee.h"
3589857Sobrien#include "safe-ctype.h"
3633965Sjdp
3789857Sobrienstruct output_buffer_struct
3889857Sobrien{
3989857Sobrien  unsigned char *ptrp;
4089857Sobrien  int buffer;
4189857Sobrien};
4260484Sobrien
4333965Sjdpstatic boolean ieee_write_byte PARAMS ((bfd *, int));
4433965Sjdpstatic boolean ieee_write_2bytes PARAMS ((bfd *, int));
4533965Sjdpstatic boolean ieee_write_int PARAMS ((bfd *, bfd_vma));
4633965Sjdpstatic boolean ieee_write_id PARAMS ((bfd *, const char *));
4789857Sobrienstatic unsigned short read_2bytes PARAMS ((common_header_type *));
4889857Sobrienstatic void bfd_get_string PARAMS ((common_header_type *, char *, size_t));
4989857Sobrienstatic char *read_id PARAMS ((common_header_type *));
5033965Sjdpstatic boolean ieee_write_expression
5133965Sjdp  PARAMS ((bfd *, bfd_vma, asymbol *, boolean, unsigned int));
5233965Sjdpstatic void ieee_write_int5 PARAMS ((bfd_byte *, bfd_vma));
5333965Sjdpstatic boolean ieee_write_int5_out PARAMS ((bfd *, bfd_vma));
5489857Sobrienstatic boolean parse_int PARAMS ((common_header_type *, bfd_vma *));
5589857Sobrienstatic int parse_i PARAMS ((common_header_type *, boolean *));
5689857Sobrienstatic bfd_vma must_parse_int PARAMS ((common_header_type *));
5789857Sobrienstatic void parse_expression
5889857Sobrien  PARAMS ((ieee_data_type *, bfd_vma *, ieee_symbol_index_type *,
5989857Sobrien	   boolean *, unsigned int *, asection **));
6089857Sobrienstatic file_ptr ieee_part_after PARAMS ((ieee_data_type *, file_ptr));
6189857Sobrienstatic ieee_symbol_type *get_symbol
6289857Sobrien  PARAMS ((bfd *, ieee_data_type *, ieee_symbol_type *, unsigned int *,
6389857Sobrien	   ieee_symbol_type ***, unsigned int *, int));
6489857Sobrienstatic boolean ieee_slurp_external_symbols PARAMS ((bfd *));
6589857Sobrienstatic boolean ieee_slurp_symbol_table PARAMS ((bfd *));
6689857Sobrienstatic long ieee_get_symtab_upper_bound PARAMS ((bfd *));
6789857Sobrienstatic long ieee_get_symtab PARAMS ((bfd *, asymbol **));
6889857Sobrienstatic asection *get_section_entry
6989857Sobrien  PARAMS ((bfd *, ieee_data_type *i, unsigned int));
7089857Sobrienstatic void ieee_slurp_sections PARAMS ((bfd *));
7189857Sobrienstatic boolean ieee_slurp_debug PARAMS ((bfd *));
7289857Sobrienconst bfd_target *ieee_archive_p PARAMS ((bfd *));
7389857Sobrienconst bfd_target *ieee_object_p PARAMS ((bfd *));
7489857Sobrienstatic void ieee_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
7589857Sobrienstatic void ieee_print_symbol
7689857Sobrien  PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
7789857Sobrienstatic boolean do_one
7889857Sobrien  PARAMS ((ieee_data_type *, ieee_per_section_type *, unsigned char *,
7989857Sobrien	   asection *, int));
8089857Sobrienstatic boolean ieee_slurp_section_data PARAMS ((bfd *));
8189857Sobrienstatic boolean ieee_new_section_hook PARAMS ((bfd *, asection *));
8289857Sobrienstatic long ieee_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
8389857Sobrienstatic boolean ieee_get_section_contents
8489857Sobrien  PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
8589857Sobrienstatic long ieee_canonicalize_reloc
8689857Sobrien  PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
8789857Sobrienstatic int comp PARAMS ((const PTR, const PTR));
8833965Sjdpstatic boolean ieee_write_section_part PARAMS ((bfd *));
8933965Sjdpstatic boolean do_with_relocs PARAMS ((bfd *, asection *));
9033965Sjdpstatic boolean do_as_repeat PARAMS ((bfd *, asection *));
9133965Sjdpstatic boolean do_without_relocs PARAMS ((bfd *, asection *));
9289857Sobrienstatic boolean ieee_mkobject PARAMS ((bfd *));
9389857Sobrienstatic void fill PARAMS ((void));
9489857Sobrienstatic void flush PARAMS ((void));
9589857Sobrienstatic void write_int PARAMS ((int));
9689857Sobrienstatic void copy_id PARAMS ((void));
9789857Sobrienstatic void copy_expression PARAMS ((void));
9889857Sobrienstatic void fill_int PARAMS ((struct output_buffer_struct *));
9989857Sobrienstatic void drop_int PARAMS ((struct output_buffer_struct *));
10089857Sobrienstatic void copy_int PARAMS ((void));
10189857Sobrienstatic void f1_record PARAMS ((void));
10289857Sobrienstatic void f0_record PARAMS ((void));
10389857Sobrienstatic void copy_till_end PARAMS ((void));
10489857Sobrienstatic void f2_record PARAMS ((void));
10589857Sobrienstatic void f8_record PARAMS ((void));
10689857Sobrienstatic void e2_record PARAMS ((void));
10789857Sobrienstatic void block PARAMS ((void));
10889857Sobrienstatic void relocate_debug PARAMS ((bfd *, bfd *));
10989857Sobrienstatic boolean ieee_write_debug_part PARAMS ((bfd *));
11089857Sobrienstatic boolean ieee_write_data_part PARAMS ((bfd *));
11189857Sobrienstatic boolean init_for_output PARAMS ((bfd *));
11289857Sobrienstatic boolean ieee_set_section_contents
11389857Sobrien  PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
11433965Sjdpstatic boolean ieee_write_external_part PARAMS ((bfd *));
11533965Sjdpstatic boolean ieee_write_me_part PARAMS ((bfd *));
11633965Sjdpstatic boolean ieee_write_processor PARAMS ((bfd *));
11789857Sobrienstatic boolean ieee_write_object_contents PARAMS ((bfd *));
11889857Sobrienstatic asymbol *ieee_make_empty_symbol PARAMS ((bfd *));
11989857Sobrienstatic bfd *ieee_openr_next_archived_file PARAMS ((bfd *, bfd *));
12089857Sobrienstatic boolean ieee_find_nearest_line
12189857Sobrien  PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **,
12289857Sobrien	   const char **, unsigned int *));
12389857Sobrienstatic int ieee_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
12489857Sobrienstatic int ieee_sizeof_headers PARAMS ((bfd *, boolean));
12533965Sjdp
12633965Sjdp/* Functions for writing to ieee files in the strange way that the
12733965Sjdp   standard requires. */
12833965Sjdp
12933965Sjdpstatic boolean
13033965Sjdpieee_write_byte (abfd, barg)
13133965Sjdp     bfd *abfd;
13233965Sjdp     int barg;
13333965Sjdp{
13433965Sjdp  bfd_byte byte;
13533965Sjdp
13633965Sjdp  byte = barg;
13789857Sobrien  if (bfd_bwrite ((PTR) &byte, (bfd_size_type) 1, abfd) != 1)
13833965Sjdp    return false;
13933965Sjdp  return true;
14033965Sjdp}
14133965Sjdp
14233965Sjdpstatic boolean
14333965Sjdpieee_write_2bytes (abfd, bytes)
14433965Sjdp     bfd *abfd;
14533965Sjdp     int bytes;
14633965Sjdp{
14733965Sjdp  bfd_byte buffer[2];
14833965Sjdp
14933965Sjdp  buffer[0] = bytes >> 8;
15033965Sjdp  buffer[1] = bytes & 0xff;
15189857Sobrien  if (bfd_bwrite ((PTR) buffer, (bfd_size_type) 2, abfd) != 2)
15233965Sjdp    return false;
15333965Sjdp  return true;
15433965Sjdp}
15533965Sjdp
15633965Sjdpstatic boolean
15733965Sjdpieee_write_int (abfd, value)
15833965Sjdp     bfd *abfd;
15933965Sjdp     bfd_vma value;
16033965Sjdp{
16133965Sjdp  if (value <= 127)
16233965Sjdp    {
16333965Sjdp      if (! ieee_write_byte (abfd, (bfd_byte) value))
16433965Sjdp	return false;
16533965Sjdp    }
16633965Sjdp  else
16733965Sjdp    {
16833965Sjdp      unsigned int length;
16933965Sjdp
17033965Sjdp      /* How many significant bytes ? */
17133965Sjdp      /* FIXME FOR LONGER INTS */
17233965Sjdp      if (value & 0xff000000)
17333965Sjdp	length = 4;
17433965Sjdp      else if (value & 0x00ff0000)
17533965Sjdp	length = 3;
17633965Sjdp      else if (value & 0x0000ff00)
17733965Sjdp	length = 2;
17833965Sjdp      else
17933965Sjdp	length = 1;
18033965Sjdp
18133965Sjdp      if (! ieee_write_byte (abfd,
18233965Sjdp			     (bfd_byte) ((int) ieee_number_repeat_start_enum
18333965Sjdp					 + length)))
18433965Sjdp	return false;
18533965Sjdp      switch (length)
18633965Sjdp	{
18733965Sjdp	case 4:
18833965Sjdp	  if (! ieee_write_byte (abfd, (bfd_byte) (value >> 24)))
18933965Sjdp	    return false;
19033965Sjdp	  /* Fall through.  */
19133965Sjdp	case 3:
19233965Sjdp	  if (! ieee_write_byte (abfd, (bfd_byte) (value >> 16)))
19333965Sjdp	    return false;
19433965Sjdp	  /* Fall through.  */
19533965Sjdp	case 2:
19633965Sjdp	  if (! ieee_write_byte (abfd, (bfd_byte) (value >> 8)))
19733965Sjdp	    return false;
19833965Sjdp	  /* Fall through.  */
19933965Sjdp	case 1:
20033965Sjdp	  if (! ieee_write_byte (abfd, (bfd_byte) (value)))
20133965Sjdp	    return false;
20233965Sjdp	}
20333965Sjdp    }
20433965Sjdp
20533965Sjdp  return true;
20633965Sjdp}
20733965Sjdp
20833965Sjdpstatic boolean
20933965Sjdpieee_write_id (abfd, id)
21033965Sjdp     bfd *abfd;
21133965Sjdp     const char *id;
21233965Sjdp{
21333965Sjdp  size_t length = strlen (id);
21433965Sjdp
21533965Sjdp  if (length <= 127)
21633965Sjdp    {
21733965Sjdp      if (! ieee_write_byte (abfd, (bfd_byte) length))
21833965Sjdp	return false;
21933965Sjdp    }
22033965Sjdp  else if (length < 255)
22133965Sjdp    {
22233965Sjdp      if (! ieee_write_byte (abfd, ieee_extension_length_1_enum)
22333965Sjdp	  || ! ieee_write_byte (abfd, (bfd_byte) length))
22433965Sjdp	return false;
22533965Sjdp    }
22633965Sjdp  else if (length < 65535)
22733965Sjdp    {
22833965Sjdp      if (! ieee_write_byte (abfd, ieee_extension_length_2_enum)
22933965Sjdp	  || ! ieee_write_2bytes (abfd, (int) length))
23033965Sjdp	return false;
23133965Sjdp    }
23233965Sjdp  else
23333965Sjdp    {
23433965Sjdp      (*_bfd_error_handler)
23560484Sobrien	(_("%s: string too long (%d chars, max 65535)"),
23633965Sjdp	 bfd_get_filename (abfd), length);
23733965Sjdp      bfd_set_error (bfd_error_invalid_operation);
23833965Sjdp      return false;
23933965Sjdp    }
24033965Sjdp
24189857Sobrien  if (bfd_bwrite ((PTR) id, (bfd_size_type) length, abfd) != length)
24233965Sjdp    return false;
24333965Sjdp  return true;
24433965Sjdp}
24533965Sjdp
24633965Sjdp/***************************************************************************
24733965SjdpFunctions for reading from ieee files in the strange way that the
24833965Sjdpstandard requires:
24933965Sjdp*/
25033965Sjdp
25133965Sjdp#define this_byte(ieee) *((ieee)->input_p)
25233965Sjdp#define next_byte(ieee) ((ieee)->input_p++)
25333965Sjdp#define this_byte_and_next(ieee) (*((ieee)->input_p++))
25433965Sjdp
25533965Sjdpstatic unsigned short
25633965Sjdpread_2bytes (ieee)
25733965Sjdp     common_header_type *ieee;
25833965Sjdp{
25933965Sjdp  unsigned char c1 = this_byte_and_next (ieee);
26033965Sjdp  unsigned char c2 = this_byte_and_next (ieee);
26133965Sjdp  return (c1 << 8) | c2;
26233965Sjdp}
26333965Sjdp
26433965Sjdpstatic void
26533965Sjdpbfd_get_string (ieee, string, length)
26633965Sjdp     common_header_type *ieee;
26733965Sjdp     char *string;
26833965Sjdp     size_t length;
26933965Sjdp{
27033965Sjdp  size_t i;
27133965Sjdp  for (i = 0; i < length; i++)
27233965Sjdp    {
27333965Sjdp      string[i] = this_byte_and_next (ieee);
27433965Sjdp    }
27533965Sjdp}
27633965Sjdp
27733965Sjdpstatic char *
27833965Sjdpread_id (ieee)
27933965Sjdp     common_header_type *ieee;
28033965Sjdp{
28133965Sjdp  size_t length;
28233965Sjdp  char *string;
28333965Sjdp  length = this_byte_and_next (ieee);
28433965Sjdp  if (length <= 0x7f)
28533965Sjdp    {
28633965Sjdp      /* Simple string of length 0 to 127 */
28733965Sjdp    }
28833965Sjdp  else if (length == 0xde)
28933965Sjdp    {
29033965Sjdp      /* Length is next byte, allowing 0..255 */
29133965Sjdp      length = this_byte_and_next (ieee);
29233965Sjdp    }
29333965Sjdp  else if (length == 0xdf)
29433965Sjdp    {
29533965Sjdp      /* Length is next two bytes, allowing 0..65535 */
29633965Sjdp      length = this_byte_and_next (ieee);
29733965Sjdp      length = (length * 256) + this_byte_and_next (ieee);
29833965Sjdp    }
29933965Sjdp  /* Buy memory and read string */
30089857Sobrien  string = bfd_alloc (ieee->abfd, (bfd_size_type) length + 1);
30133965Sjdp  if (!string)
30233965Sjdp    return NULL;
30333965Sjdp  bfd_get_string (ieee, string, length);
30433965Sjdp  string[length] = 0;
30533965Sjdp  return string;
30633965Sjdp}
30733965Sjdp
30833965Sjdpstatic boolean
30933965Sjdpieee_write_expression (abfd, value, symbol, pcrel, index)
31033965Sjdp     bfd *abfd;
31133965Sjdp     bfd_vma value;
31233965Sjdp     asymbol *symbol;
31333965Sjdp     boolean pcrel;
31433965Sjdp     unsigned int index;
31533965Sjdp{
31633965Sjdp  unsigned int term_count = 0;
31733965Sjdp
31833965Sjdp  if (value != 0)
31933965Sjdp    {
32033965Sjdp      if (! ieee_write_int (abfd, value))
32133965Sjdp	return false;
32233965Sjdp      term_count++;
32333965Sjdp    }
32433965Sjdp
32533965Sjdp  if (bfd_is_com_section (symbol->section)
32633965Sjdp      || bfd_is_und_section (symbol->section))
32733965Sjdp    {
32833965Sjdp      /* Def of a common symbol */
32933965Sjdp      if (! ieee_write_byte (abfd, ieee_variable_X_enum)
33033965Sjdp	  || ! ieee_write_int (abfd, symbol->value))
33133965Sjdp	return false;
33233965Sjdp      term_count++;
33333965Sjdp    }
33433965Sjdp  else if (! bfd_is_abs_section (symbol->section))
33533965Sjdp    {
33633965Sjdp      /* Ref to defined symbol - */
33733965Sjdp
33833965Sjdp      if (symbol->flags & BSF_GLOBAL)
33933965Sjdp	{
34033965Sjdp	  if (! ieee_write_byte (abfd, ieee_variable_I_enum)
34133965Sjdp	      || ! ieee_write_int (abfd, symbol->value))
34233965Sjdp	    return false;
34333965Sjdp	  term_count++;
34433965Sjdp	}
34533965Sjdp      else if (symbol->flags & (BSF_LOCAL | BSF_SECTION_SYM))
34633965Sjdp	{
34733965Sjdp	  /* This is a reference to a defined local symbol.  We can
34833965Sjdp	     easily do a local as a section+offset.  */
34933965Sjdp	  if (! ieee_write_byte (abfd, ieee_variable_R_enum)
35033965Sjdp	      || ! ieee_write_byte (abfd,
35133965Sjdp				    (bfd_byte) (symbol->section->index
35233965Sjdp						+ IEEE_SECTION_NUMBER_BASE)))
35333965Sjdp	    return false;
35433965Sjdp	  term_count++;
35533965Sjdp	  if (symbol->value != 0)
35633965Sjdp	    {
35733965Sjdp	      if (! ieee_write_int (abfd, symbol->value))
35833965Sjdp		return false;
35933965Sjdp	      term_count++;
36033965Sjdp	    }
36133965Sjdp	}
36233965Sjdp      else
36333965Sjdp	{
36433965Sjdp	  (*_bfd_error_handler)
36560484Sobrien	    (_("%s: unrecognized symbol `%s' flags 0x%x"),
36633965Sjdp	     bfd_get_filename (abfd), bfd_asymbol_name (symbol),
36733965Sjdp	     symbol->flags);
36833965Sjdp	  bfd_set_error (bfd_error_invalid_operation);
36933965Sjdp	  return false;
37033965Sjdp	}
37133965Sjdp    }
37233965Sjdp
37333965Sjdp  if (pcrel)
37433965Sjdp    {
37533965Sjdp      /* subtract the pc from here by asking for PC of this section*/
37633965Sjdp      if (! ieee_write_byte (abfd, ieee_variable_P_enum)
37733965Sjdp	  || ! ieee_write_byte (abfd,
37833965Sjdp				(bfd_byte) (index + IEEE_SECTION_NUMBER_BASE))
37933965Sjdp	  || ! ieee_write_byte (abfd, ieee_function_minus_enum))
38033965Sjdp	return false;
38133965Sjdp    }
38233965Sjdp
38333965Sjdp  /* Handle the degenerate case of a 0 address.  */
38433965Sjdp  if (term_count == 0)
38533965Sjdp    {
38689857Sobrien      if (! ieee_write_int (abfd, (bfd_vma) 0))
38733965Sjdp	return false;
38833965Sjdp    }
38933965Sjdp
39033965Sjdp  while (term_count > 1)
39133965Sjdp    {
39233965Sjdp      if (! ieee_write_byte (abfd, ieee_function_plus_enum))
39333965Sjdp	return false;
39433965Sjdp      term_count--;
39533965Sjdp    }
39633965Sjdp
39733965Sjdp  return true;
39833965Sjdp}
39933965Sjdp
40033965Sjdp/*****************************************************************************/
40133965Sjdp
40233965Sjdp/*
40333965Sjdpwrites any integer into the buffer supplied and always takes 5 bytes
40433965Sjdp*/
40533965Sjdpstatic void
40633965Sjdpieee_write_int5 (buffer, value)
40733965Sjdp     bfd_byte *buffer;
40833965Sjdp     bfd_vma value;
40933965Sjdp{
41033965Sjdp  buffer[0] = (bfd_byte) ieee_number_repeat_4_enum;
41133965Sjdp  buffer[1] = (value >> 24) & 0xff;
41233965Sjdp  buffer[2] = (value >> 16) & 0xff;
41333965Sjdp  buffer[3] = (value >> 8) & 0xff;
41433965Sjdp  buffer[4] = (value >> 0) & 0xff;
41533965Sjdp}
41633965Sjdp
41733965Sjdpstatic boolean
41833965Sjdpieee_write_int5_out (abfd, value)
41933965Sjdp     bfd *abfd;
42033965Sjdp     bfd_vma value;
42133965Sjdp{
42233965Sjdp  bfd_byte b[5];
42333965Sjdp
42433965Sjdp  ieee_write_int5 (b, value);
42589857Sobrien  if (bfd_bwrite ((PTR) b, (bfd_size_type) 5, abfd) != 5)
42633965Sjdp    return false;
42733965Sjdp  return true;
42833965Sjdp}
42933965Sjdp
43033965Sjdpstatic boolean
43133965Sjdpparse_int (ieee, value_ptr)
43233965Sjdp     common_header_type *ieee;
43333965Sjdp     bfd_vma *value_ptr;
43433965Sjdp{
43533965Sjdp  int value = this_byte (ieee);
43633965Sjdp  int result;
43733965Sjdp  if (value >= 0 && value <= 127)
43833965Sjdp    {
43933965Sjdp      *value_ptr = value;
44033965Sjdp      next_byte (ieee);
44133965Sjdp      return true;
44233965Sjdp    }
44333965Sjdp  else if (value >= 0x80 && value <= 0x88)
44433965Sjdp    {
44533965Sjdp      unsigned int count = value & 0xf;
44633965Sjdp      result = 0;
44733965Sjdp      next_byte (ieee);
44833965Sjdp      while (count)
44933965Sjdp	{
45033965Sjdp	  result = (result << 8) | this_byte_and_next (ieee);
45133965Sjdp	  count--;
45233965Sjdp	}
45333965Sjdp      *value_ptr = result;
45433965Sjdp      return true;
45533965Sjdp    }
45633965Sjdp  return false;
45733965Sjdp}
45833965Sjdp
45933965Sjdpstatic int
46033965Sjdpparse_i (ieee, ok)
46133965Sjdp     common_header_type *ieee;
46233965Sjdp     boolean *ok;
46333965Sjdp{
46433965Sjdp  bfd_vma x;
46533965Sjdp  *ok = parse_int (ieee, &x);
46633965Sjdp  return x;
46733965Sjdp}
46833965Sjdp
46933965Sjdpstatic bfd_vma
47033965Sjdpmust_parse_int (ieee)
47133965Sjdp     common_header_type *ieee;
47233965Sjdp{
47333965Sjdp  bfd_vma result;
474104834Sobrien  BFD_ASSERT (parse_int (ieee, &result));
47533965Sjdp  return result;
47633965Sjdp}
47733965Sjdp
47833965Sjdptypedef struct
47933965Sjdp{
48033965Sjdp  bfd_vma value;
48133965Sjdp  asection *section;
48233965Sjdp  ieee_symbol_index_type symbol;
48333965Sjdp} ieee_value_type;
48433965Sjdp
48533965Sjdp
48633965Sjdp#if KEEPMINUSPCININST
48733965Sjdp
48833965Sjdp#define SRC_MASK(arg) arg
48933965Sjdp#define PCREL_OFFSET false
49033965Sjdp
49133965Sjdp#else
49233965Sjdp
49333965Sjdp#define SRC_MASK(arg) 0
49433965Sjdp#define PCREL_OFFSET true
49533965Sjdp
49633965Sjdp#endif
49733965Sjdp
49833965Sjdpstatic reloc_howto_type abs32_howto =
49933965Sjdp  HOWTO (1,
50033965Sjdp	 0,
50133965Sjdp	 2,
50233965Sjdp	 32,
50333965Sjdp	 false,
50433965Sjdp	 0,
50533965Sjdp	 complain_overflow_bitfield,
50633965Sjdp	 0,
50733965Sjdp	 "abs32",
50833965Sjdp	 true,
50933965Sjdp	 0xffffffff,
51033965Sjdp	 0xffffffff,
51133965Sjdp	 false);
51233965Sjdp
51333965Sjdpstatic reloc_howto_type abs16_howto =
51433965Sjdp  HOWTO (1,
51533965Sjdp	 0,
51633965Sjdp	 1,
51733965Sjdp	 16,
51833965Sjdp	 false,
51933965Sjdp	 0,
52033965Sjdp	 complain_overflow_bitfield,
52133965Sjdp	 0,
52233965Sjdp	 "abs16",
52333965Sjdp	 true,
52433965Sjdp	 0x0000ffff,
52533965Sjdp	 0x0000ffff,
52633965Sjdp	 false);
52733965Sjdp
52833965Sjdpstatic reloc_howto_type abs8_howto =
52933965Sjdp  HOWTO (1,
53033965Sjdp	 0,
53133965Sjdp	 0,
53233965Sjdp	 8,
53333965Sjdp	 false,
53433965Sjdp	 0,
53533965Sjdp	 complain_overflow_bitfield,
53633965Sjdp	 0,
53733965Sjdp	 "abs8",
53833965Sjdp	 true,
53933965Sjdp	 0x000000ff,
54033965Sjdp	 0x000000ff,
54133965Sjdp	 false);
54233965Sjdp
54333965Sjdpstatic reloc_howto_type rel32_howto =
54433965Sjdp  HOWTO (1,
54533965Sjdp	 0,
54633965Sjdp	 2,
54733965Sjdp	 32,
54833965Sjdp	 true,
54933965Sjdp	 0,
55033965Sjdp	 complain_overflow_signed,
55133965Sjdp	 0,
55233965Sjdp	 "rel32",
55333965Sjdp	 true,
55433965Sjdp	 SRC_MASK (0xffffffff),
55533965Sjdp	 0xffffffff,
55633965Sjdp	 PCREL_OFFSET);
55733965Sjdp
55833965Sjdpstatic reloc_howto_type rel16_howto =
55933965Sjdp  HOWTO (1,
56033965Sjdp	 0,
56133965Sjdp	 1,
56233965Sjdp	 16,
56333965Sjdp	 true,
56433965Sjdp	 0,
56533965Sjdp	 complain_overflow_signed,
56633965Sjdp	 0,
56733965Sjdp	 "rel16",
56833965Sjdp	 true,
56933965Sjdp	 SRC_MASK (0x0000ffff),
57033965Sjdp	 0x0000ffff,
57133965Sjdp	 PCREL_OFFSET);
57233965Sjdp
57333965Sjdpstatic reloc_howto_type rel8_howto =
57433965Sjdp  HOWTO (1,
57533965Sjdp	 0,
57633965Sjdp	 0,
57733965Sjdp	 8,
57833965Sjdp	 true,
57933965Sjdp	 0,
58033965Sjdp	 complain_overflow_signed,
58133965Sjdp	 0,
58233965Sjdp	 "rel8",
58333965Sjdp	 true,
58433965Sjdp	 SRC_MASK (0x000000ff),
58533965Sjdp	 0x000000ff,
58633965Sjdp	 PCREL_OFFSET);
58733965Sjdp
58833965Sjdpstatic ieee_symbol_index_type NOSYMBOL = {0, 0};
58933965Sjdp
59033965Sjdpstatic void
59133965Sjdpparse_expression (ieee, value, symbol, pcrel, extra, section)
59233965Sjdp     ieee_data_type *ieee;
59333965Sjdp     bfd_vma *value;
59433965Sjdp     ieee_symbol_index_type *symbol;
59533965Sjdp     boolean *pcrel;
59633965Sjdp     unsigned int *extra;
59733965Sjdp     asection **section;
59833965Sjdp
59933965Sjdp{
60033965Sjdp#define POS sp[1]
60133965Sjdp#define TOS sp[0]
60233965Sjdp#define NOS sp[-1]
60333965Sjdp#define INC sp++;
60433965Sjdp#define DEC sp--;
60533965Sjdp
60633965Sjdp  boolean loop = true;
60733965Sjdp  ieee_value_type stack[10];
60833965Sjdp
60933965Sjdp  /* The stack pointer always points to the next unused location */
61033965Sjdp#define PUSH(x,y,z) TOS.symbol=x;TOS.section=y;TOS.value=z;INC;
61133965Sjdp#define POP(x,y,z) DEC;x=TOS.symbol;y=TOS.section;z=TOS.value;
61233965Sjdp  ieee_value_type *sp = stack;
61389857Sobrien  asection *dummy;
61433965Sjdp
61589857Sobrien  while (loop && ieee->h.input_p < ieee->h.last_byte)
61633965Sjdp    {
61733965Sjdp      switch (this_byte (&(ieee->h)))
61833965Sjdp	{
61933965Sjdp	case ieee_variable_P_enum:
62033965Sjdp	  /* P variable, current program counter for section n */
62133965Sjdp	  {
62233965Sjdp	    int section_n;
62333965Sjdp	    next_byte (&(ieee->h));
62433965Sjdp	    *pcrel = true;
62533965Sjdp	    section_n = must_parse_int (&(ieee->h));
62633965Sjdp	    PUSH (NOSYMBOL, bfd_abs_section_ptr, 0);
62733965Sjdp	    break;
62833965Sjdp	  }
62933965Sjdp	case ieee_variable_L_enum:
63033965Sjdp	  /* L variable  address of section N */
63133965Sjdp	  next_byte (&(ieee->h));
63233965Sjdp	  PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
63333965Sjdp	  break;
63433965Sjdp	case ieee_variable_R_enum:
63533965Sjdp	  /* R variable, logical address of section module */
63633965Sjdp	  /* FIXME, this should be different to L */
63733965Sjdp	  next_byte (&(ieee->h));
63833965Sjdp	  PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
63933965Sjdp	  break;
64033965Sjdp	case ieee_variable_S_enum:
64133965Sjdp	  /* S variable, size in MAUS of section module */
64233965Sjdp	  next_byte (&(ieee->h));
64333965Sjdp	  PUSH (NOSYMBOL,
64433965Sjdp		0,
64533965Sjdp		ieee->section_table[must_parse_int (&(ieee->h))]->_raw_size);
64633965Sjdp	  break;
64733965Sjdp	case ieee_variable_I_enum:
64833965Sjdp	  /* Push the address of variable n */
64933965Sjdp	  {
65033965Sjdp	    ieee_symbol_index_type sy;
65133965Sjdp	    next_byte (&(ieee->h));
65233965Sjdp	    sy.index = (int) must_parse_int (&(ieee->h));
65333965Sjdp	    sy.letter = 'I';
65433965Sjdp
65533965Sjdp	    PUSH (sy, bfd_abs_section_ptr, 0);
65633965Sjdp	  }
65733965Sjdp	  break;
65833965Sjdp	case ieee_variable_X_enum:
65933965Sjdp	  /* Push the address of external variable n */
66033965Sjdp	  {
66133965Sjdp	    ieee_symbol_index_type sy;
66233965Sjdp	    next_byte (&(ieee->h));
66333965Sjdp	    sy.index = (int) (must_parse_int (&(ieee->h)));
66433965Sjdp	    sy.letter = 'X';
66533965Sjdp
66633965Sjdp	    PUSH (sy, bfd_und_section_ptr, 0);
66733965Sjdp	  }
66833965Sjdp	  break;
66933965Sjdp	case ieee_function_minus_enum:
67033965Sjdp	  {
67133965Sjdp	    bfd_vma value1, value2;
67233965Sjdp	    asection *section1, *section_dummy;
67333965Sjdp	    ieee_symbol_index_type sy;
67433965Sjdp	    next_byte (&(ieee->h));
67533965Sjdp
67633965Sjdp	    POP (sy, section1, value1);
67733965Sjdp	    POP (sy, section_dummy, value2);
67833965Sjdp	    PUSH (sy, section1 ? section1 : section_dummy, value2 - value1);
67933965Sjdp	  }
68033965Sjdp	  break;
68133965Sjdp	case ieee_function_plus_enum:
68233965Sjdp	  {
68333965Sjdp	    bfd_vma value1, value2;
68433965Sjdp	    asection *section1;
68533965Sjdp	    asection *section2;
68633965Sjdp	    ieee_symbol_index_type sy1;
68733965Sjdp	    ieee_symbol_index_type sy2;
68833965Sjdp	    next_byte (&(ieee->h));
68933965Sjdp
69033965Sjdp	    POP (sy1, section1, value1);
69133965Sjdp	    POP (sy2, section2, value2);
69233965Sjdp	    PUSH (sy1.letter ? sy1 : sy2,
69333965Sjdp		  bfd_is_abs_section (section1) ? section2 : section1,
69433965Sjdp		  value1 + value2);
69533965Sjdp	  }
69633965Sjdp	  break;
69733965Sjdp	default:
69833965Sjdp	  {
69933965Sjdp	    bfd_vma va;
70033965Sjdp	    BFD_ASSERT (this_byte (&(ieee->h)) < (int) ieee_variable_A_enum
70133965Sjdp		    || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum);
70233965Sjdp	    if (parse_int (&(ieee->h), &va))
70333965Sjdp	      {
70433965Sjdp		PUSH (NOSYMBOL, bfd_abs_section_ptr, va);
70533965Sjdp	      }
70633965Sjdp	    else
70733965Sjdp	      {
70889857Sobrien		/* Thats all that we can understand.  */
70933965Sjdp		loop = false;
71033965Sjdp	      }
71133965Sjdp	  }
71233965Sjdp	}
71333965Sjdp    }
71489857Sobrien
71589857Sobrien  /* As far as I can see there is a bug in the Microtec IEEE output
71689857Sobrien     which I'm using to scan, whereby the comma operator is omitted
71789857Sobrien     sometimes in an expression, giving expressions with too many
71889857Sobrien     terms.  We can tell if that's the case by ensuring that
71989857Sobrien     sp == stack here.  If not, then we've pushed something too far,
72089857Sobrien     so we keep adding.  */
72189857Sobrien
72289857Sobrien  while (sp != stack + 1)
72389857Sobrien    {
72489857Sobrien      asection *section1;
72589857Sobrien      ieee_symbol_index_type sy1;
72689857Sobrien      POP (sy1, section1, *extra);
72789857Sobrien    }
72889857Sobrien
72989857Sobrien  POP (*symbol, dummy, *value);
73089857Sobrien  if (section)
73189857Sobrien    *section = dummy;
73233965Sjdp}
73333965Sjdp
73433965Sjdp
73589857Sobrien#define ieee_seek(ieee, offset) \
73689857Sobrien  do								\
73789857Sobrien    {								\
73889857Sobrien      ieee->h.input_p = ieee->h.first_byte + offset;		\
73989857Sobrien      ieee->h.last_byte = (ieee->h.first_byte			\
74089857Sobrien			   + ieee_part_after (ieee, offset));	\
74189857Sobrien    }								\
74289857Sobrien  while (0)
74333965Sjdp
74489857Sobrien#define ieee_pos(ieee) \
74589857Sobrien  (ieee->h.input_p - ieee->h.first_byte)
74633965Sjdp
74789857Sobrien/* Find the first part of the ieee file after HERE.  */
74889857Sobrien
74989857Sobrienstatic file_ptr
75089857Sobrienieee_part_after (ieee, here)
75189857Sobrien     ieee_data_type *ieee;
75289857Sobrien     file_ptr here;
75389857Sobrien{
75489857Sobrien  int part;
75589857Sobrien  file_ptr after = ieee->w.r.me_record;
75689857Sobrien
75789857Sobrien  /* File parts can come in any order, except that module end is
75889857Sobrien     guaranteed to be last (and the header first).  */
75989857Sobrien  for (part = 0; part < N_W_VARIABLES; part++)
76089857Sobrien    if (ieee->w.offset[part] > here && after > ieee->w.offset[part])
76189857Sobrien      after = ieee->w.offset[part];
76289857Sobrien
76389857Sobrien  return after;
76489857Sobrien}
76589857Sobrien
76633965Sjdpstatic unsigned int last_index;
76733965Sjdpstatic char last_type;		/* is the index for an X or a D */
76833965Sjdp
76933965Sjdpstatic ieee_symbol_type *
77089857Sobrienget_symbol (abfd, ieee, last_symbol, symbol_count, pptr, max_index, this_type)
77160484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
77233965Sjdp     ieee_data_type *ieee;
77333965Sjdp     ieee_symbol_type *last_symbol;
77433965Sjdp     unsigned int *symbol_count;
77533965Sjdp     ieee_symbol_type ***pptr;
77633965Sjdp     unsigned int *max_index;
77789857Sobrien     int this_type;
77833965Sjdp{
77933965Sjdp  /* Need a new symbol */
78033965Sjdp  unsigned int new_index = must_parse_int (&(ieee->h));
78133965Sjdp  if (new_index != last_index || this_type != last_type)
78233965Sjdp    {
78389857Sobrien      ieee_symbol_type *new_symbol;
78489857Sobrien      bfd_size_type amt = sizeof (ieee_symbol_type);
78589857Sobrien
78689857Sobrien      new_symbol = (ieee_symbol_type *) bfd_alloc (ieee->h.abfd, amt);
78733965Sjdp      if (!new_symbol)
78833965Sjdp	return NULL;
78933965Sjdp
79033965Sjdp      new_symbol->index = new_index;
79133965Sjdp      last_index = new_index;
79233965Sjdp      (*symbol_count)++;
79333965Sjdp      **pptr = new_symbol;
79433965Sjdp      *pptr = &new_symbol->next;
79533965Sjdp      if (new_index > *max_index)
79633965Sjdp	{
79733965Sjdp	  *max_index = new_index;
79833965Sjdp	}
79933965Sjdp      last_type = this_type;
80033965Sjdp      new_symbol->symbol.section = bfd_abs_section_ptr;
80133965Sjdp      return new_symbol;
80233965Sjdp    }
80333965Sjdp  return last_symbol;
80433965Sjdp}
80533965Sjdp
80633965Sjdpstatic boolean
80733965Sjdpieee_slurp_external_symbols (abfd)
80833965Sjdp     bfd *abfd;
80933965Sjdp{
81033965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
81133965Sjdp  file_ptr offset = ieee->w.r.external_part;
81233965Sjdp
81333965Sjdp  ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols;
81433965Sjdp  ieee_symbol_type **prev_reference_ptr = &ieee->external_reference;
81533965Sjdp  ieee_symbol_type *symbol = (ieee_symbol_type *) NULL;
81633965Sjdp  unsigned int symbol_count = 0;
81733965Sjdp  boolean loop = true;
81833965Sjdp  last_index = 0xffffff;
81933965Sjdp  ieee->symbol_table_full = true;
82033965Sjdp
82189857Sobrien  ieee_seek (ieee, offset);
82233965Sjdp
82333965Sjdp  while (loop)
82433965Sjdp    {
82533965Sjdp      switch (this_byte (&(ieee->h)))
82633965Sjdp	{
82733965Sjdp	case ieee_nn_record:
82833965Sjdp	  next_byte (&(ieee->h));
82933965Sjdp
83033965Sjdp	  symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
83133965Sjdp			       &prev_symbols_ptr,
83233965Sjdp			       &ieee->external_symbol_max_index, 'I');
83333965Sjdp	  if (symbol == NULL)
83433965Sjdp	    return false;
83533965Sjdp
83633965Sjdp	  symbol->symbol.the_bfd = abfd;
83733965Sjdp	  symbol->symbol.name = read_id (&(ieee->h));
83833965Sjdp	  symbol->symbol.udata.p = (PTR) NULL;
83933965Sjdp	  symbol->symbol.flags = BSF_NO_FLAGS;
84033965Sjdp	  break;
84133965Sjdp	case ieee_external_symbol_enum:
84233965Sjdp	  next_byte (&(ieee->h));
84333965Sjdp
84433965Sjdp	  symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
84533965Sjdp			       &prev_symbols_ptr,
84633965Sjdp			       &ieee->external_symbol_max_index, 'D');
84733965Sjdp	  if (symbol == NULL)
84833965Sjdp	    return false;
84933965Sjdp
85033965Sjdp	  BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index);
85133965Sjdp
85233965Sjdp	  symbol->symbol.the_bfd = abfd;
85333965Sjdp	  symbol->symbol.name = read_id (&(ieee->h));
85433965Sjdp	  symbol->symbol.udata.p = (PTR) NULL;
85533965Sjdp	  symbol->symbol.flags = BSF_NO_FLAGS;
85633965Sjdp	  break;
85733965Sjdp	case ieee_attribute_record_enum >> 8:
85833965Sjdp	  {
85933965Sjdp	    unsigned int symbol_name_index;
86033965Sjdp	    unsigned int symbol_type_index;
86133965Sjdp	    unsigned int symbol_attribute_def;
86233965Sjdp	    bfd_vma value;
86389857Sobrien	    switch (read_2bytes (&ieee->h))
86433965Sjdp	      {
86533965Sjdp	      case ieee_attribute_record_enum:
86633965Sjdp		symbol_name_index = must_parse_int (&(ieee->h));
86733965Sjdp		symbol_type_index = must_parse_int (&(ieee->h));
86833965Sjdp		symbol_attribute_def = must_parse_int (&(ieee->h));
86933965Sjdp		switch (symbol_attribute_def)
87033965Sjdp		  {
87133965Sjdp		  case 8:
87233965Sjdp		  case 19:
87333965Sjdp		    parse_int (&ieee->h, &value);
87433965Sjdp		    break;
87533965Sjdp		  default:
87633965Sjdp		    (*_bfd_error_handler)
87791041Sobrien		      (_("%s: unimplemented ATI record %u for symbol %u"),
87889857Sobrien		       bfd_archive_filename (abfd), symbol_attribute_def,
87933965Sjdp		       symbol_name_index);
88033965Sjdp		    bfd_set_error (bfd_error_bad_value);
88133965Sjdp		    return false;
88233965Sjdp		    break;
88333965Sjdp		  }
88433965Sjdp		break;
88533965Sjdp	      case ieee_external_reference_info_record_enum:
88633965Sjdp		/* Skip over ATX record. */
88733965Sjdp		parse_int (&(ieee->h), &value);
88833965Sjdp		parse_int (&(ieee->h), &value);
88933965Sjdp		parse_int (&(ieee->h), &value);
89033965Sjdp		parse_int (&(ieee->h), &value);
89133965Sjdp		break;
89260484Sobrien	      case ieee_atn_record_enum:
89360484Sobrien		/* We may get call optimization information here,
89460484Sobrien		   which we just ignore.  The format is
89560484Sobrien		   {$F1}${CE}{index}{$00}{$3F}{$3F}{#_of_ASNs} */
89660484Sobrien		parse_int (&ieee->h, &value);
89760484Sobrien		parse_int (&ieee->h, &value);
89860484Sobrien		parse_int (&ieee->h, &value);
89960484Sobrien		if (value != 0x3f)
90060484Sobrien		  {
90160484Sobrien		    (*_bfd_error_handler)
90260484Sobrien		      (_("%s: unexpected ATN type %d in external part"),
90389857Sobrien			 bfd_archive_filename (abfd), (int) value);
90460484Sobrien		    bfd_set_error (bfd_error_bad_value);
90560484Sobrien		    return false;
90660484Sobrien		  }
90760484Sobrien		parse_int (&ieee->h, &value);
90860484Sobrien		parse_int (&ieee->h, &value);
90960484Sobrien		while (value > 0)
91060484Sobrien		  {
91160484Sobrien		    bfd_vma val1;
91260484Sobrien
91360484Sobrien		    --value;
91460484Sobrien
91589857Sobrien		    switch (read_2bytes (&ieee->h))
91660484Sobrien		      {
91760484Sobrien		      case ieee_asn_record_enum:
91860484Sobrien			parse_int (&ieee->h, &val1);
91960484Sobrien			parse_int (&ieee->h, &val1);
92060484Sobrien			break;
92160484Sobrien
92260484Sobrien		      default:
92360484Sobrien			(*_bfd_error_handler)
92460484Sobrien			  (_("%s: unexpected type after ATN"),
92589857Sobrien			     bfd_archive_filename (abfd));
92660484Sobrien			bfd_set_error (bfd_error_bad_value);
92760484Sobrien			return false;
92860484Sobrien		      }
92960484Sobrien		  }
93033965Sjdp	      }
93133965Sjdp	  }
93233965Sjdp	  break;
93333965Sjdp	case ieee_value_record_enum >> 8:
93433965Sjdp	  {
93533965Sjdp	    unsigned int symbol_name_index;
93633965Sjdp	    ieee_symbol_index_type symbol_ignore;
93733965Sjdp	    boolean pcrel_ignore;
93833965Sjdp	    unsigned int extra;
93933965Sjdp	    next_byte (&(ieee->h));
94033965Sjdp	    next_byte (&(ieee->h));
94133965Sjdp
94233965Sjdp	    symbol_name_index = must_parse_int (&(ieee->h));
94333965Sjdp	    parse_expression (ieee,
94433965Sjdp			      &symbol->symbol.value,
94533965Sjdp			      &symbol_ignore,
94633965Sjdp			      &pcrel_ignore,
94733965Sjdp			      &extra,
94833965Sjdp			      &symbol->symbol.section);
94933965Sjdp
95060484Sobrien	    /* Fully linked IEEE-695 files tend to give every symbol
95160484Sobrien               an absolute value.  Try to convert that back into a
95260484Sobrien               section relative value.  FIXME: This won't always to
95360484Sobrien               the right thing.  */
95460484Sobrien	    if (bfd_is_abs_section (symbol->symbol.section)
95560484Sobrien		&& (abfd->flags & HAS_RELOC) == 0)
95660484Sobrien	      {
95760484Sobrien		bfd_vma val;
95860484Sobrien		asection *s;
95960484Sobrien
96060484Sobrien		val = symbol->symbol.value;
96160484Sobrien		for (s = abfd->sections; s != NULL; s = s->next)
96260484Sobrien		  {
96360484Sobrien		    if (val >= s->vma && val < s->vma + s->_raw_size)
96460484Sobrien		      {
96560484Sobrien			symbol->symbol.section = s;
96660484Sobrien			symbol->symbol.value -= s->vma;
96760484Sobrien			break;
96860484Sobrien		      }
96960484Sobrien		  }
97060484Sobrien	      }
97160484Sobrien
97233965Sjdp	    symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
97333965Sjdp
97433965Sjdp	  }
97533965Sjdp	  break;
97633965Sjdp	case ieee_weak_external_reference_enum:
97733965Sjdp	  {
97833965Sjdp	    bfd_vma size;
97933965Sjdp	    bfd_vma value;
98033965Sjdp	    next_byte (&(ieee->h));
98133965Sjdp	    /* Throw away the external reference index */
98233965Sjdp	    (void) must_parse_int (&(ieee->h));
98333965Sjdp	    /* Fetch the default size if not resolved */
98433965Sjdp	    size = must_parse_int (&(ieee->h));
98533965Sjdp	    /* Fetch the defautlt value if available */
986104834Sobrien	    if (! parse_int (&(ieee->h), &value))
98733965Sjdp	      {
98833965Sjdp		value = 0;
98933965Sjdp	      }
99033965Sjdp	    /* This turns into a common */
99133965Sjdp	    symbol->symbol.section = bfd_com_section_ptr;
99233965Sjdp	    symbol->symbol.value = size;
99333965Sjdp	  }
99433965Sjdp	  break;
99533965Sjdp
99633965Sjdp	case ieee_external_reference_enum:
99733965Sjdp	  next_byte (&(ieee->h));
99833965Sjdp
99933965Sjdp	  symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
100033965Sjdp			       &prev_reference_ptr,
100133965Sjdp			       &ieee->external_reference_max_index, 'X');
100233965Sjdp	  if (symbol == NULL)
100333965Sjdp	    return false;
100433965Sjdp
100533965Sjdp	  symbol->symbol.the_bfd = abfd;
100633965Sjdp	  symbol->symbol.name = read_id (&(ieee->h));
100733965Sjdp	  symbol->symbol.udata.p = (PTR) NULL;
100833965Sjdp	  symbol->symbol.section = bfd_und_section_ptr;
100933965Sjdp	  symbol->symbol.value = (bfd_vma) 0;
101033965Sjdp	  symbol->symbol.flags = 0;
101133965Sjdp
101233965Sjdp	  BFD_ASSERT (symbol->index >= ieee->external_reference_min_index);
101333965Sjdp	  break;
101433965Sjdp
101533965Sjdp	default:
101633965Sjdp	  loop = false;
101733965Sjdp	}
101833965Sjdp    }
101933965Sjdp
102033965Sjdp  if (ieee->external_symbol_max_index != 0)
102133965Sjdp    {
102233965Sjdp      ieee->external_symbol_count =
102333965Sjdp	ieee->external_symbol_max_index -
102433965Sjdp	ieee->external_symbol_min_index + 1;
102533965Sjdp    }
102633965Sjdp  else
102733965Sjdp    {
102833965Sjdp      ieee->external_symbol_count = 0;
102933965Sjdp    }
103033965Sjdp
103133965Sjdp  if (ieee->external_reference_max_index != 0)
103233965Sjdp    {
103333965Sjdp      ieee->external_reference_count =
103433965Sjdp	ieee->external_reference_max_index -
103533965Sjdp	ieee->external_reference_min_index + 1;
103633965Sjdp    }
103733965Sjdp  else
103833965Sjdp    {
103933965Sjdp      ieee->external_reference_count = 0;
104033965Sjdp    }
104133965Sjdp
104233965Sjdp  abfd->symcount =
104333965Sjdp    ieee->external_reference_count + ieee->external_symbol_count;
104433965Sjdp
104533965Sjdp  if (symbol_count != abfd->symcount)
104633965Sjdp    {
104733965Sjdp      /* There are gaps in the table -- */
104833965Sjdp      ieee->symbol_table_full = false;
104933965Sjdp    }
105033965Sjdp
105133965Sjdp  *prev_symbols_ptr = (ieee_symbol_type *) NULL;
105233965Sjdp  *prev_reference_ptr = (ieee_symbol_type *) NULL;
105333965Sjdp
105433965Sjdp  return true;
105533965Sjdp}
105633965Sjdp
105733965Sjdpstatic boolean
105833965Sjdpieee_slurp_symbol_table (abfd)
105933965Sjdp     bfd *abfd;
106033965Sjdp{
1061104834Sobrien  if (! IEEE_DATA (abfd)->read_symbols)
106233965Sjdp    {
106333965Sjdp      if (! ieee_slurp_external_symbols (abfd))
106433965Sjdp	return false;
106533965Sjdp      IEEE_DATA (abfd)->read_symbols = true;
106633965Sjdp    }
106733965Sjdp  return true;
106833965Sjdp}
106933965Sjdp
107089857Sobrienstatic long
107133965Sjdpieee_get_symtab_upper_bound (abfd)
107233965Sjdp     bfd *abfd;
107333965Sjdp{
107433965Sjdp  if (! ieee_slurp_symbol_table (abfd))
107533965Sjdp    return -1;
107633965Sjdp
107733965Sjdp  return (abfd->symcount != 0) ?
107833965Sjdp    (abfd->symcount + 1) * (sizeof (ieee_symbol_type *)) : 0;
107933965Sjdp}
108033965Sjdp
108133965Sjdp/*
108233965SjdpMove from our internal lists to the canon table, and insert in
108333965Sjdpsymbol index order
108433965Sjdp*/
108533965Sjdp
108633965Sjdpextern const bfd_target ieee_vec;
108733965Sjdp
108889857Sobrienstatic long
108933965Sjdpieee_get_symtab (abfd, location)
109033965Sjdp     bfd *abfd;
109133965Sjdp     asymbol **location;
109233965Sjdp{
109333965Sjdp  ieee_symbol_type *symp;
109433965Sjdp  static bfd dummy_bfd;
109533965Sjdp  static asymbol empty_symbol =
109660484Sobrien  {
109760484Sobrien    &dummy_bfd,
109860484Sobrien    " ieee empty",
109960484Sobrien    (symvalue) 0,
110060484Sobrien    BSF_DEBUGGING,
110160484Sobrien    bfd_abs_section_ptr
110260484Sobrien#ifdef __STDC__
110360484Sobrien    /* K&R compilers can't initialise unions.  */
110460484Sobrien    , { 0 }
110560484Sobrien#endif
110660484Sobrien  };
110733965Sjdp
110833965Sjdp  if (abfd->symcount)
110933965Sjdp    {
111033965Sjdp      ieee_data_type *ieee = IEEE_DATA (abfd);
111133965Sjdp      dummy_bfd.xvec = &ieee_vec;
111233965Sjdp      if (! ieee_slurp_symbol_table (abfd))
111333965Sjdp	return -1;
111433965Sjdp
1115104834Sobrien      if (! ieee->symbol_table_full)
111633965Sjdp	{
111733965Sjdp	  /* Arrgh - there are gaps in the table, run through and fill them */
111833965Sjdp	  /* up with pointers to a null place */
111933965Sjdp	  unsigned int i;
112033965Sjdp	  for (i = 0; i < abfd->symcount; i++)
112133965Sjdp	    {
112233965Sjdp	      location[i] = &empty_symbol;
112333965Sjdp	    }
112433965Sjdp	}
112533965Sjdp
112633965Sjdp      ieee->external_symbol_base_offset = -ieee->external_symbol_min_index;
112733965Sjdp      for (symp = IEEE_DATA (abfd)->external_symbols;
112833965Sjdp	   symp != (ieee_symbol_type *) NULL;
112933965Sjdp	   symp = symp->next)
113033965Sjdp	{
113133965Sjdp	  /* Place into table at correct index locations */
113233965Sjdp	  location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol;
113333965Sjdp	}
113433965Sjdp
113533965Sjdp      /* The external refs are indexed in a bit */
113633965Sjdp      ieee->external_reference_base_offset =
113733965Sjdp	-ieee->external_reference_min_index + ieee->external_symbol_count;
113833965Sjdp
113933965Sjdp      for (symp = IEEE_DATA (abfd)->external_reference;
114033965Sjdp	   symp != (ieee_symbol_type *) NULL;
114133965Sjdp	   symp = symp->next)
114233965Sjdp	{
114333965Sjdp	  location[symp->index + ieee->external_reference_base_offset] =
114433965Sjdp	    &symp->symbol;
114533965Sjdp
114633965Sjdp	}
114733965Sjdp    }
114833965Sjdp  if (abfd->symcount)
114933965Sjdp    {
115033965Sjdp      location[abfd->symcount] = (asymbol *) NULL;
115133965Sjdp    }
115233965Sjdp  return abfd->symcount;
115333965Sjdp}
115433965Sjdp
115533965Sjdpstatic asection *
115633965Sjdpget_section_entry (abfd, ieee, index)
115733965Sjdp     bfd *abfd;
115833965Sjdp     ieee_data_type *ieee;
115933965Sjdp     unsigned int index;
116033965Sjdp{
116133965Sjdp  if (index >= ieee->section_table_size)
116233965Sjdp    {
116333965Sjdp      unsigned int c, i;
116433965Sjdp      asection **n;
116589857Sobrien      bfd_size_type amt;
116633965Sjdp
116733965Sjdp      c = ieee->section_table_size;
116833965Sjdp      if (c == 0)
116933965Sjdp	c = 20;
117033965Sjdp      while (c <= index)
117133965Sjdp	c *= 2;
117233965Sjdp
117389857Sobrien      amt = c;
117489857Sobrien      amt *= sizeof (asection *);
117589857Sobrien      n = (asection **) bfd_realloc (ieee->section_table, amt);
117633965Sjdp      if (n == NULL)
117733965Sjdp	return NULL;
117833965Sjdp
117933965Sjdp      for (i = ieee->section_table_size; i < c; i++)
118033965Sjdp	n[i] = NULL;
118133965Sjdp
118233965Sjdp      ieee->section_table = n;
118333965Sjdp      ieee->section_table_size = c;
118433965Sjdp    }
118533965Sjdp
118633965Sjdp  if (ieee->section_table[index] == (asection *) NULL)
118733965Sjdp    {
118889857Sobrien      char *tmp = bfd_alloc (abfd, (bfd_size_type) 11);
118933965Sjdp      asection *section;
119033965Sjdp
119133965Sjdp      if (!tmp)
119233965Sjdp	return NULL;
119333965Sjdp      sprintf (tmp, " fsec%4d", index);
119433965Sjdp      section = bfd_make_section (abfd, tmp);
119533965Sjdp      ieee->section_table[index] = section;
119633965Sjdp      section->flags = SEC_NO_FLAGS;
119733965Sjdp      section->target_index = index;
119833965Sjdp      ieee->section_table[index] = section;
119933965Sjdp    }
120033965Sjdp  return ieee->section_table[index];
120133965Sjdp}
120233965Sjdp
120333965Sjdpstatic void
120433965Sjdpieee_slurp_sections (abfd)
120533965Sjdp     bfd *abfd;
120633965Sjdp{
120733965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
120833965Sjdp  file_ptr offset = ieee->w.r.section_part;
120933965Sjdp  char *name;
121033965Sjdp
121133965Sjdp  if (offset != 0)
121233965Sjdp    {
121333965Sjdp      bfd_byte section_type[3];
121489857Sobrien      ieee_seek (ieee, offset);
121533965Sjdp      while (true)
121633965Sjdp	{
121733965Sjdp	  switch (this_byte (&(ieee->h)))
121833965Sjdp	    {
121933965Sjdp	    case ieee_section_type_enum:
122033965Sjdp	      {
122189857Sobrien		asection *section;
122233965Sjdp		unsigned int section_index;
122333965Sjdp		next_byte (&(ieee->h));
122433965Sjdp		section_index = must_parse_int (&(ieee->h));
122533965Sjdp
122633965Sjdp		section = get_section_entry (abfd, ieee, section_index);
122733965Sjdp
122833965Sjdp		section_type[0] = this_byte_and_next (&(ieee->h));
122933965Sjdp
123033965Sjdp		/* Set minimal section attributes. Attributes are
123133965Sjdp		   extended later, based on section contents. */
123233965Sjdp
123333965Sjdp		switch (section_type[0])
123433965Sjdp		  {
123533965Sjdp		  case 0xC1:
123633965Sjdp		    /* Normal attributes for absolute sections	*/
123733965Sjdp		    section_type[1] = this_byte (&(ieee->h));
123833965Sjdp		    section->flags = SEC_ALLOC;
123933965Sjdp		    switch (section_type[1])
124033965Sjdp		      {
124133965Sjdp		      case 0xD3:	/* AS Absolute section attributes */
124233965Sjdp			next_byte (&(ieee->h));
124333965Sjdp			section_type[2] = this_byte (&(ieee->h));
124433965Sjdp			switch (section_type[2])
124533965Sjdp			  {
124633965Sjdp			  case 0xD0:
124733965Sjdp			    /* Normal code */
124833965Sjdp			    next_byte (&(ieee->h));
124933965Sjdp			    section->flags |= SEC_CODE;
125033965Sjdp			    break;
125133965Sjdp			  case 0xC4:
125233965Sjdp			    /* Normal data */
125333965Sjdp			    next_byte (&(ieee->h));
125433965Sjdp			    section->flags |= SEC_DATA;
125533965Sjdp			    break;
125633965Sjdp			  case 0xD2:
125733965Sjdp			    next_byte (&(ieee->h));
125833965Sjdp			    /* Normal rom data */
125933965Sjdp			    section->flags |= SEC_ROM | SEC_DATA;
126033965Sjdp			    break;
126133965Sjdp			  default:
126233965Sjdp			    break;
126333965Sjdp			  }
126433965Sjdp		      }
126533965Sjdp		    break;
126633965Sjdp		  case 0xC3:	/* Named relocatable sections (type C) */
126733965Sjdp		    section_type[1] = this_byte (&(ieee->h));
126833965Sjdp		    section->flags = SEC_ALLOC;
126933965Sjdp		    switch (section_type[1])
127033965Sjdp		      {
127133965Sjdp		      case 0xD0:	/* Normal code (CP) */
127233965Sjdp			next_byte (&(ieee->h));
127333965Sjdp			section->flags |= SEC_CODE;
127433965Sjdp			break;
127533965Sjdp		      case 0xC4:	/* Normal data (CD) */
127633965Sjdp			next_byte (&(ieee->h));
127733965Sjdp			section->flags |= SEC_DATA;
127833965Sjdp			break;
127933965Sjdp		      case 0xD2:	/* Normal rom data (CR) */
128033965Sjdp			next_byte (&(ieee->h));
128133965Sjdp			section->flags |= SEC_ROM | SEC_DATA;
128233965Sjdp			break;
128333965Sjdp		      default:
128433965Sjdp			break;
128533965Sjdp		      }
128633965Sjdp		  }
128733965Sjdp
128833965Sjdp		/* Read section name, use it if non empty. */
128933965Sjdp		name = read_id (&ieee->h);
129033965Sjdp		if (name[0])
129133965Sjdp		  section->name = name;
129233965Sjdp
129333965Sjdp		/* Skip these fields, which we don't care about */
129433965Sjdp		{
129533965Sjdp		  bfd_vma parent, brother, context;
129633965Sjdp		  parse_int (&(ieee->h), &parent);
129733965Sjdp		  parse_int (&(ieee->h), &brother);
129833965Sjdp		  parse_int (&(ieee->h), &context);
129933965Sjdp		}
130033965Sjdp	      }
130133965Sjdp	      break;
130233965Sjdp	    case ieee_section_alignment_enum:
130333965Sjdp	      {
130433965Sjdp		unsigned int section_index;
130533965Sjdp		bfd_vma value;
130633965Sjdp		asection *section;
130733965Sjdp		next_byte (&(ieee->h));
130833965Sjdp		section_index = must_parse_int (&ieee->h);
130933965Sjdp		section = get_section_entry (abfd, ieee, section_index);
131033965Sjdp		if (section_index > ieee->section_count)
131133965Sjdp		  {
131233965Sjdp		    ieee->section_count = section_index;
131333965Sjdp		  }
131433965Sjdp		section->alignment_power =
131533965Sjdp		  bfd_log2 (must_parse_int (&ieee->h));
131633965Sjdp		(void) parse_int (&(ieee->h), &value);
131733965Sjdp	      }
131833965Sjdp	      break;
131933965Sjdp	    case ieee_e2_first_byte_enum:
132033965Sjdp	      {
132189857Sobrien		asection *section;
132289857Sobrien		ieee_record_enum_type t;
132333965Sjdp
132489857Sobrien		t = (ieee_record_enum_type) (read_2bytes (&(ieee->h)));
132533965Sjdp		switch (t)
132633965Sjdp		  {
132733965Sjdp		  case ieee_section_size_enum:
132833965Sjdp		    section = ieee->section_table[must_parse_int (&(ieee->h))];
132933965Sjdp		    section->_raw_size = must_parse_int (&(ieee->h));
133033965Sjdp		    break;
133133965Sjdp		  case ieee_physical_region_size_enum:
133233965Sjdp		    section = ieee->section_table[must_parse_int (&(ieee->h))];
133333965Sjdp		    section->_raw_size = must_parse_int (&(ieee->h));
133433965Sjdp		    break;
133533965Sjdp		  case ieee_region_base_address_enum:
133633965Sjdp		    section = ieee->section_table[must_parse_int (&(ieee->h))];
133733965Sjdp		    section->vma = must_parse_int (&(ieee->h));
133833965Sjdp		    section->lma = section->vma;
133933965Sjdp		    break;
134033965Sjdp		  case ieee_mau_size_enum:
134133965Sjdp		    must_parse_int (&(ieee->h));
134233965Sjdp		    must_parse_int (&(ieee->h));
134333965Sjdp		    break;
134433965Sjdp		  case ieee_m_value_enum:
134533965Sjdp		    must_parse_int (&(ieee->h));
134633965Sjdp		    must_parse_int (&(ieee->h));
134733965Sjdp		    break;
134833965Sjdp		  case ieee_section_base_address_enum:
134933965Sjdp		    section = ieee->section_table[must_parse_int (&(ieee->h))];
135033965Sjdp		    section->vma = must_parse_int (&(ieee->h));
135133965Sjdp		    section->lma = section->vma;
135233965Sjdp		    break;
135333965Sjdp		  case ieee_section_offset_enum:
135433965Sjdp		    (void) must_parse_int (&(ieee->h));
135533965Sjdp		    (void) must_parse_int (&(ieee->h));
135633965Sjdp		    break;
135733965Sjdp		  default:
135833965Sjdp		    return;
135933965Sjdp		  }
136033965Sjdp	      }
136133965Sjdp	      break;
136233965Sjdp	    default:
136333965Sjdp	      return;
136433965Sjdp	    }
136533965Sjdp	}
136633965Sjdp    }
136733965Sjdp}
136833965Sjdp
136933965Sjdp/* Make a section for the debugging information, if any.  We don't try
137033965Sjdp   to interpret the debugging information; we just point the section
137133965Sjdp   at the area in the file so that program which understand can dig it
137233965Sjdp   out.  */
137333965Sjdp
137433965Sjdpstatic boolean
137533965Sjdpieee_slurp_debug (abfd)
137633965Sjdp     bfd *abfd;
137733965Sjdp{
137833965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
137933965Sjdp  asection *sec;
138060484Sobrien  file_ptr debug_end;
138133965Sjdp
138233965Sjdp  if (ieee->w.r.debug_information_part == 0)
138333965Sjdp    return true;
138433965Sjdp
138533965Sjdp  sec = bfd_make_section (abfd, ".debug");
138633965Sjdp  if (sec == NULL)
138733965Sjdp    return false;
138833965Sjdp  sec->flags |= SEC_DEBUGGING | SEC_HAS_CONTENTS;
138933965Sjdp  sec->filepos = ieee->w.r.debug_information_part;
139033965Sjdp
139189857Sobrien  debug_end = ieee_part_after (ieee, ieee->w.r.debug_information_part);
139260484Sobrien  sec->_raw_size = debug_end - ieee->w.r.debug_information_part;
139360484Sobrien
139433965Sjdp  return true;
139533965Sjdp}
139633965Sjdp
139733965Sjdp/***********************************************************************
139833965Sjdp*  archive stuff
139933965Sjdp*/
140033965Sjdp
140133965Sjdpconst bfd_target *
140233965Sjdpieee_archive_p (abfd)
140333965Sjdp     bfd *abfd;
140433965Sjdp{
140533965Sjdp  char *library;
140633965Sjdp  unsigned int i;
140733965Sjdp  unsigned char buffer[512];
140833965Sjdp  file_ptr buffer_offset = 0;
140933965Sjdp  ieee_ar_data_type *save = abfd->tdata.ieee_ar_data;
141033965Sjdp  ieee_ar_data_type *ieee;
141189857Sobrien  bfd_size_type alc_elts;
141233965Sjdp  ieee_ar_obstack_type *elts = NULL;
141389857Sobrien  bfd_size_type amt = sizeof (ieee_ar_data_type);
141433965Sjdp
141589857Sobrien  abfd->tdata.ieee_ar_data = (ieee_ar_data_type *) bfd_alloc (abfd, amt);
141633965Sjdp  if (!abfd->tdata.ieee_ar_data)
1417104834Sobrien    goto error_ret_restore;
141833965Sjdp  ieee = IEEE_AR_DATA (abfd);
141933965Sjdp
142089857Sobrien  /* Ignore the return value here.  It doesn't matter if we don't read
142189857Sobrien     the entire buffer.  We might have a very small ieee file.  */
142289857Sobrien  bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd);
142333965Sjdp
142433965Sjdp  ieee->h.first_byte = buffer;
142533965Sjdp  ieee->h.input_p = buffer;
142633965Sjdp
142733965Sjdp  ieee->h.abfd = abfd;
142833965Sjdp
142933965Sjdp  if (this_byte (&(ieee->h)) != Module_Beginning)
143077298Sobrien    goto got_wrong_format_error;
143133965Sjdp
143233965Sjdp  next_byte (&(ieee->h));
143333965Sjdp  library = read_id (&(ieee->h));
143433965Sjdp  if (strcmp (library, "LIBRARY") != 0)
143577298Sobrien    goto got_wrong_format_error;
143677298Sobrien
143777298Sobrien  /* Throw away the filename.  */
143833965Sjdp  read_id (&(ieee->h));
143933965Sjdp
144033965Sjdp  ieee->element_count = 0;
144133965Sjdp  ieee->element_index = 0;
144233965Sjdp
144377298Sobrien  next_byte (&(ieee->h));	/* Drop the ad part.  */
144477298Sobrien  must_parse_int (&(ieee->h));	/* And the two dummy numbers.  */
144533965Sjdp  must_parse_int (&(ieee->h));
144633965Sjdp
144733965Sjdp  alc_elts = 10;
144833965Sjdp  elts = (ieee_ar_obstack_type *) bfd_malloc (alc_elts * sizeof *elts);
144933965Sjdp  if (elts == NULL)
145033965Sjdp    goto error_return;
145133965Sjdp
145277298Sobrien  /* Read the index of the BB table.  */
145333965Sjdp  while (1)
145433965Sjdp    {
145533965Sjdp      int rec;
145633965Sjdp      ieee_ar_obstack_type *t;
145733965Sjdp
145833965Sjdp      rec = read_2bytes (&(ieee->h));
145933965Sjdp      if (rec != (int) ieee_assign_value_to_variable_enum)
146033965Sjdp	break;
146133965Sjdp
146233965Sjdp      if (ieee->element_count >= alc_elts)
146333965Sjdp	{
146433965Sjdp	  ieee_ar_obstack_type *n;
146533965Sjdp
146633965Sjdp	  alc_elts *= 2;
146733965Sjdp	  n = ((ieee_ar_obstack_type *)
146833965Sjdp	       bfd_realloc (elts, alc_elts * sizeof *elts));
146933965Sjdp	  if (n == NULL)
147033965Sjdp	    goto error_return;
147133965Sjdp	  elts = n;
147233965Sjdp	}
147333965Sjdp
147433965Sjdp      t = &elts[ieee->element_count];
147533965Sjdp      ieee->element_count++;
147633965Sjdp
147733965Sjdp      must_parse_int (&(ieee->h));
147833965Sjdp      t->file_offset = must_parse_int (&(ieee->h));
147933965Sjdp      t->abfd = (bfd *) NULL;
148033965Sjdp
148177298Sobrien      /* Make sure that we don't go over the end of the buffer.  */
148289857Sobrien      if ((size_t) ieee_pos (IEEE_DATA (abfd)) > sizeof (buffer) / 2)
148333965Sjdp	{
148477298Sobrien	  /* Past half way, reseek and reprime.  */
148589857Sobrien	  buffer_offset += ieee_pos (IEEE_DATA (abfd));
148633965Sjdp	  if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0)
148733965Sjdp	    goto error_return;
148877298Sobrien
148989857Sobrien	  /* Again ignore return value of bfd_bread.  */
149089857Sobrien	  bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd);
149133965Sjdp	  ieee->h.first_byte = buffer;
149233965Sjdp	  ieee->h.input_p = buffer;
149333965Sjdp	}
149433965Sjdp    }
149533965Sjdp
149689857Sobrien  amt = ieee->element_count;
149789857Sobrien  amt *= sizeof *ieee->elements;
149889857Sobrien  ieee->elements = (ieee_ar_obstack_type *) bfd_alloc (abfd, amt);
149933965Sjdp  if (ieee->elements == NULL)
150033965Sjdp    goto error_return;
150177298Sobrien
150289857Sobrien  memcpy (ieee->elements, elts, (size_t) amt);
150333965Sjdp  free (elts);
150433965Sjdp  elts = NULL;
150533965Sjdp
150677298Sobrien  /* Now scan the area again, and replace BB offsets with file offsets.  */
150733965Sjdp  for (i = 2; i < ieee->element_count; i++)
150833965Sjdp    {
150933965Sjdp      if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0)
151033965Sjdp	goto error_return;
151177298Sobrien
151289857Sobrien      /* Again ignore return value of bfd_bread.  */
151389857Sobrien      bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd);
151433965Sjdp      ieee->h.first_byte = buffer;
151533965Sjdp      ieee->h.input_p = buffer;
151633965Sjdp
151777298Sobrien      next_byte (&(ieee->h));		/* Drop F8.  */
151877298Sobrien      next_byte (&(ieee->h));		/* Drop 14.  */
151977298Sobrien      must_parse_int (&(ieee->h));	/* Drop size of block.  */
152089857Sobrien
152133965Sjdp      if (must_parse_int (&(ieee->h)) != 0)
152277298Sobrien	/* This object has been deleted.  */
152377298Sobrien	ieee->elements[i].file_offset = 0;
152433965Sjdp      else
152577298Sobrien	ieee->elements[i].file_offset = must_parse_int (&(ieee->h));
152633965Sjdp    }
152733965Sjdp
152833965Sjdp  /*  abfd->has_armap = ;*/
152933965Sjdp
153033965Sjdp  return abfd->xvec;
153133965Sjdp
153260484Sobrien got_wrong_format_error:
153360484Sobrien  bfd_set_error (bfd_error_wrong_format);
153433965Sjdp error_return:
153533965Sjdp  if (elts != NULL)
153633965Sjdp    free (elts);
1537104834Sobrien  bfd_release (abfd, ieee);
1538104834Sobrien error_ret_restore:
1539104834Sobrien  abfd->tdata.ieee_ar_data = save;
154077298Sobrien
154133965Sjdp  return NULL;
154233965Sjdp}
154333965Sjdp
154433965Sjdpconst bfd_target *
154533965Sjdpieee_object_p (abfd)
154633965Sjdp     bfd *abfd;
154733965Sjdp{
154833965Sjdp  char *processor;
154933965Sjdp  unsigned int part;
155033965Sjdp  ieee_data_type *ieee;
155133965Sjdp  unsigned char buffer[300];
155233965Sjdp  ieee_data_type *save = IEEE_DATA (abfd);
155389857Sobrien  bfd_size_type amt;
155433965Sjdp
155533965Sjdp  abfd->tdata.ieee_data = 0;
155633965Sjdp  ieee_mkobject (abfd);
155733965Sjdp
155833965Sjdp  ieee = IEEE_DATA (abfd);
155933965Sjdp  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
156033965Sjdp    goto fail;
156189857Sobrien  /* Read the first few bytes in to see if it makes sense.  Ignore
156289857Sobrien     bfd_bread return value;  The file might be very small.  */
156389857Sobrien  bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd);
156433965Sjdp
156533965Sjdp  ieee->h.input_p = buffer;
156633965Sjdp  if (this_byte_and_next (&(ieee->h)) != Module_Beginning)
156733965Sjdp    goto got_wrong_format;
156833965Sjdp
156933965Sjdp  ieee->read_symbols = false;
157033965Sjdp  ieee->read_data = false;
157133965Sjdp  ieee->section_count = 0;
157233965Sjdp  ieee->external_symbol_max_index = 0;
157333965Sjdp  ieee->external_symbol_min_index = IEEE_PUBLIC_BASE;
157433965Sjdp  ieee->external_reference_min_index = IEEE_REFERENCE_BASE;
157533965Sjdp  ieee->external_reference_max_index = 0;
157633965Sjdp  ieee->h.abfd = abfd;
157733965Sjdp  ieee->section_table = NULL;
157833965Sjdp  ieee->section_table_size = 0;
157933965Sjdp
158033965Sjdp  processor = ieee->mb.processor = read_id (&(ieee->h));
158133965Sjdp  if (strcmp (processor, "LIBRARY") == 0)
158233965Sjdp    goto got_wrong_format;
158333965Sjdp  ieee->mb.module_name = read_id (&(ieee->h));
158489857Sobrien  if (abfd->filename == (const char *) NULL)
158533965Sjdp    {
158633965Sjdp      abfd->filename = ieee->mb.module_name;
158733965Sjdp    }
158833965Sjdp  /* Determine the architecture and machine type of the object file.
158933965Sjdp     */
159033965Sjdp  {
159160484Sobrien    const bfd_arch_info_type *arch;
159260484Sobrien    char family[10];
159360484Sobrien
159460484Sobrien    /* IEEE does not specify the format of the processor identificaton
159560484Sobrien       string, so the compiler is free to put in it whatever it wants.
159660484Sobrien       We try here to recognize different processors belonging to the
159760484Sobrien       m68k family.  Code for other processors can be added here.  */
159860484Sobrien    if ((processor[0] == '6') && (processor[1] == '8'))
159960484Sobrien      {
160060484Sobrien	if (processor[2] == '3')	    /* 683xx integrated processors */
160160484Sobrien	  {
160260484Sobrien	    switch (processor[3])
160360484Sobrien	      {
160460484Sobrien	      case '0':			    /* 68302, 68306, 68307 */
160560484Sobrien	      case '2':			    /* 68322, 68328 */
160660484Sobrien	      case '5':			    /* 68356 */
160760484Sobrien		strcpy (family, "68000");   /* MC68000-based controllers */
160860484Sobrien		break;
160960484Sobrien
161060484Sobrien	      case '3':			    /* 68330, 68331, 68332, 68333,
161160484Sobrien					       68334, 68335, 68336, 68338 */
161260484Sobrien	      case '6':			    /* 68360 */
161360484Sobrien	      case '7':			    /* 68376 */
161460484Sobrien		strcpy (family, "68332");   /* CPU32 and CPU32+ */
161560484Sobrien		break;
161660484Sobrien
161760484Sobrien	      case '4':
161860484Sobrien		if (processor[4] == '9')    /* 68349 */
161960484Sobrien		  strcpy (family, "68030"); /* CPU030 */
162060484Sobrien		else		            /* 68340, 68341 */
162160484Sobrien		  strcpy (family, "68332"); /* CPU32 and CPU32+ */
162260484Sobrien		break;
162360484Sobrien
162460484Sobrien	      default:			    /* Does not exist yet */
162560484Sobrien		strcpy (family, "68332");   /* Guess it will be CPU32 */
162660484Sobrien	      }
162760484Sobrien	  }
162889857Sobrien	else if (TOUPPER (processor[3]) == 'F')  /* 68F333 */
162989857Sobrien	  strcpy (family, "68332");	           /* CPU32 */
163089857Sobrien	else if ((TOUPPER (processor[3]) == 'C') /* Embedded controllers */
163189857Sobrien		 && ((TOUPPER (processor[2]) == 'E')
163289857Sobrien		     || (TOUPPER (processor[2]) == 'H')
163389857Sobrien		     || (TOUPPER (processor[2]) == 'L')))
163460484Sobrien	  {
163560484Sobrien	    strcpy (family, "68");
163660484Sobrien	    strncat (family, processor + 4, 7);
163760484Sobrien	    family[9] = '\0';
163860484Sobrien	  }
163960484Sobrien	else				 /* "Regular" processors */
164060484Sobrien	  {
164160484Sobrien	    strncpy (family, processor, 9);
164260484Sobrien	    family[9] = '\0';
164360484Sobrien	  }
164460484Sobrien      }
164560484Sobrien    else if ((strncmp (processor, "cpu32", 5) == 0) /* CPU32 and CPU32+ */
164660484Sobrien	     || (strncmp (processor, "CPU32", 5) == 0))
164760484Sobrien      strcpy (family, "68332");
164860484Sobrien    else
164960484Sobrien      {
165060484Sobrien	strncpy (family, processor, 9);
165160484Sobrien	family[9] = '\0';
165260484Sobrien      }
165360484Sobrien
165460484Sobrien    arch = bfd_scan_arch (family);
165533965Sjdp    if (arch == 0)
165633965Sjdp      goto got_wrong_format;
165733965Sjdp    abfd->arch_info = arch;
165833965Sjdp  }
165933965Sjdp
166033965Sjdp  if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum)
166133965Sjdp    {
166233965Sjdp      goto fail;
166333965Sjdp    }
166433965Sjdp  next_byte (&(ieee->h));
166533965Sjdp
1666104834Sobrien  if (! parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau))
166733965Sjdp    {
166833965Sjdp      goto fail;
166933965Sjdp    }
1670104834Sobrien  if (! parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address))
167133965Sjdp    {
167233965Sjdp      goto fail;
167333965Sjdp    }
167433965Sjdp
167533965Sjdp  /* If there is a byte order info, take it */
167633965Sjdp  if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum ||
167733965Sjdp      this_byte (&(ieee->h)) == (int) ieee_variable_M_enum)
167833965Sjdp    next_byte (&(ieee->h));
167933965Sjdp
168033965Sjdp  for (part = 0; part < N_W_VARIABLES; part++)
168133965Sjdp    {
168233965Sjdp      boolean ok;
168333965Sjdp      if (read_2bytes (&(ieee->h)) != (int) ieee_assign_value_to_variable_enum)
168433965Sjdp	{
168533965Sjdp	  goto fail;
168633965Sjdp	}
168733965Sjdp      if (this_byte_and_next (&(ieee->h)) != part)
168833965Sjdp	{
168933965Sjdp	  goto fail;
169033965Sjdp	}
169133965Sjdp
169233965Sjdp      ieee->w.offset[part] = parse_i (&(ieee->h), &ok);
1693104834Sobrien      if (! ok)
169433965Sjdp	{
169533965Sjdp	  goto fail;
169633965Sjdp	}
169733965Sjdp
169833965Sjdp    }
169933965Sjdp
170033965Sjdp  if (ieee->w.r.external_part != 0)
170133965Sjdp    abfd->flags = HAS_SYMS;
170233965Sjdp
170333965Sjdp  /* By now we know that this is a real IEEE file, we're going to read
170433965Sjdp     the whole thing into memory so that we can run up and down it
170533965Sjdp     quickly.  We can work out how big the file is from the trailer
170633965Sjdp     record */
170733965Sjdp
170889857Sobrien  amt = ieee->w.r.me_record + 1;
170933965Sjdp  IEEE_DATA (abfd)->h.first_byte =
171089857Sobrien    (unsigned char *) bfd_alloc (ieee->h.abfd, amt);
171133965Sjdp  if (!IEEE_DATA (abfd)->h.first_byte)
171233965Sjdp    goto fail;
171333965Sjdp  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
171433965Sjdp    goto fail;
171533965Sjdp  /* FIXME: Check return value.  I'm not sure whether it needs to read
171633965Sjdp     the entire buffer or not.  */
171789857Sobrien  bfd_bread ((PTR) (IEEE_DATA (abfd)->h.first_byte),
171889857Sobrien	    (bfd_size_type) ieee->w.r.me_record + 1, abfd);
171933965Sjdp
172033965Sjdp  ieee_slurp_sections (abfd);
172133965Sjdp
172233965Sjdp  if (! ieee_slurp_debug (abfd))
172333965Sjdp    goto fail;
172433965Sjdp
172533965Sjdp  /* Parse section data to activate file and section flags implied by
172633965Sjdp     section contents. */
172733965Sjdp
172833965Sjdp  if (! ieee_slurp_section_data (abfd))
172933965Sjdp    goto fail;
173089857Sobrien
173133965Sjdp  return abfd->xvec;
173233965Sjdpgot_wrong_format:
173333965Sjdp  bfd_set_error (bfd_error_wrong_format);
173433965Sjdpfail:
1735104834Sobrien  bfd_release (abfd, ieee);
173633965Sjdp  abfd->tdata.ieee_data = save;
173733965Sjdp  return (const bfd_target *) NULL;
173833965Sjdp}
173933965Sjdp
174089857Sobrienstatic void
174133965Sjdpieee_get_symbol_info (ignore_abfd, symbol, ret)
174260484Sobrien     bfd *ignore_abfd ATTRIBUTE_UNUSED;
174333965Sjdp     asymbol *symbol;
174433965Sjdp     symbol_info *ret;
174533965Sjdp{
174633965Sjdp  bfd_symbol_info (symbol, ret);
174733965Sjdp  if (symbol->name[0] == ' ')
174833965Sjdp    ret->name = "* empty table entry ";
174933965Sjdp  if (!symbol->section)
175033965Sjdp    ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
175133965Sjdp}
175233965Sjdp
175389857Sobrienstatic void
175489857Sobrienieee_print_symbol (abfd, afile, symbol, how)
175589857Sobrien     bfd *abfd;
175633965Sjdp     PTR afile;
175733965Sjdp     asymbol *symbol;
175833965Sjdp     bfd_print_symbol_type how;
175933965Sjdp{
176033965Sjdp  FILE *file = (FILE *) afile;
176133965Sjdp
176233965Sjdp  switch (how)
176333965Sjdp    {
176433965Sjdp    case bfd_print_symbol_name:
176533965Sjdp      fprintf (file, "%s", symbol->name);
176633965Sjdp      break;
176733965Sjdp    case bfd_print_symbol_more:
176833965Sjdp#if 0
176933965Sjdp      fprintf (file, "%4x %2x", aout_symbol (symbol)->desc & 0xffff,
177033965Sjdp	       aout_symbol (symbol)->other & 0xff);
177133965Sjdp#endif
177233965Sjdp      BFD_FAIL ();
177333965Sjdp      break;
177433965Sjdp    case bfd_print_symbol_all:
177533965Sjdp      {
177633965Sjdp	const char *section_name =
177733965Sjdp	  (symbol->section == (asection *) NULL
177833965Sjdp	   ? "*abs"
177933965Sjdp	   : symbol->section->name);
178033965Sjdp	if (symbol->name[0] == ' ')
178133965Sjdp	  {
178233965Sjdp	    fprintf (file, "* empty table entry ");
178333965Sjdp	  }
178433965Sjdp	else
178533965Sjdp	  {
178689857Sobrien	    bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
178733965Sjdp
178833965Sjdp	    fprintf (file, " %-5s %04x %02x %s",
178933965Sjdp		     section_name,
179033965Sjdp		     (unsigned) ieee_symbol (symbol)->index,
179133965Sjdp		     (unsigned) 0,
179233965Sjdp		     symbol->name);
179333965Sjdp	  }
179433965Sjdp      }
179533965Sjdp      break;
179633965Sjdp    }
179733965Sjdp}
179833965Sjdp
179933965Sjdpstatic boolean
180033965Sjdpdo_one (ieee, current_map, location_ptr, s, iterations)
180133965Sjdp     ieee_data_type *ieee;
180233965Sjdp     ieee_per_section_type *current_map;
180333965Sjdp     unsigned char *location_ptr;
180433965Sjdp     asection *s;
180533965Sjdp     int iterations;
180633965Sjdp{
180733965Sjdp  switch (this_byte (&(ieee->h)))
180833965Sjdp    {
180933965Sjdp    case ieee_load_constant_bytes_enum:
181033965Sjdp      {
181133965Sjdp	unsigned int number_of_maus;
181233965Sjdp	unsigned int i;
181333965Sjdp	next_byte (&(ieee->h));
181433965Sjdp	number_of_maus = must_parse_int (&(ieee->h));
181533965Sjdp
181633965Sjdp	for (i = 0; i < number_of_maus; i++)
181733965Sjdp	  {
181833965Sjdp	    location_ptr[current_map->pc++] = this_byte (&(ieee->h));
181933965Sjdp	    next_byte (&(ieee->h));
182033965Sjdp	  }
182133965Sjdp      }
182233965Sjdp      break;
182333965Sjdp
182433965Sjdp    case ieee_load_with_relocation_enum:
182533965Sjdp      {
182633965Sjdp	boolean loop = true;
182733965Sjdp	next_byte (&(ieee->h));
182833965Sjdp	while (loop)
182933965Sjdp	  {
183033965Sjdp	    switch (this_byte (&(ieee->h)))
183133965Sjdp	      {
183233965Sjdp	      case ieee_variable_R_enum:
183333965Sjdp
183433965Sjdp	      case ieee_function_signed_open_b_enum:
183533965Sjdp	      case ieee_function_unsigned_open_b_enum:
183633965Sjdp	      case ieee_function_either_open_b_enum:
183733965Sjdp		{
183833965Sjdp		  unsigned int extra = 4;
183933965Sjdp		  boolean pcrel = false;
184033965Sjdp		  asection *section;
184189857Sobrien		  ieee_reloc_type *r;
184289857Sobrien		  bfd_size_type amt = sizeof (ieee_reloc_type);
184389857Sobrien
184489857Sobrien		  r = (ieee_reloc_type *) bfd_alloc (ieee->h.abfd, amt);
184533965Sjdp		  if (!r)
184633965Sjdp		    return false;
184733965Sjdp
184833965Sjdp		  *(current_map->reloc_tail_ptr) = r;
184933965Sjdp		  current_map->reloc_tail_ptr = &r->next;
185033965Sjdp		  r->next = (ieee_reloc_type *) NULL;
185133965Sjdp		  next_byte (&(ieee->h));
185233965Sjdp/*			    abort();*/
185333965Sjdp		  r->relent.sym_ptr_ptr = 0;
185433965Sjdp		  parse_expression (ieee,
185533965Sjdp				    &r->relent.addend,
185633965Sjdp				    &r->symbol,
185733965Sjdp				    &pcrel, &extra, &section);
185833965Sjdp		  r->relent.address = current_map->pc;
185933965Sjdp		  s->flags |= SEC_RELOC;
186033965Sjdp		  s->owner->flags |= HAS_RELOC;
186133965Sjdp		  s->reloc_count++;
186238889Sjdp		  if (r->relent.sym_ptr_ptr == NULL && section != NULL)
186338889Sjdp		    r->relent.sym_ptr_ptr = section->symbol_ptr_ptr;
186433965Sjdp
186533965Sjdp		  if (this_byte (&(ieee->h)) == (int) ieee_comma)
186633965Sjdp		    {
186733965Sjdp		      next_byte (&(ieee->h));
186833965Sjdp		      /* Fetch number of bytes to pad */
186933965Sjdp		      extra = must_parse_int (&(ieee->h));
187033965Sjdp		    };
187133965Sjdp
187233965Sjdp		  switch (this_byte (&(ieee->h)))
187333965Sjdp		    {
187433965Sjdp		    case ieee_function_signed_close_b_enum:
187533965Sjdp		      next_byte (&(ieee->h));
187633965Sjdp		      break;
187733965Sjdp		    case ieee_function_unsigned_close_b_enum:
187833965Sjdp		      next_byte (&(ieee->h));
187933965Sjdp		      break;
188033965Sjdp		    case ieee_function_either_close_b_enum:
188133965Sjdp		      next_byte (&(ieee->h));
188233965Sjdp		      break;
188333965Sjdp		    default:
188433965Sjdp		      break;
188533965Sjdp		    }
188633965Sjdp		  /* Build a relocation entry for this type */
188733965Sjdp		  /* If pc rel then stick -ve pc into instruction
188833965Sjdp		     and take out of reloc ..
188933965Sjdp
189033965Sjdp		     I've changed this. It's all too complicated. I
189133965Sjdp		     keep 0 in the instruction now.  */
189233965Sjdp
189333965Sjdp		  switch (extra)
189433965Sjdp		    {
189533965Sjdp		    case 0:
189633965Sjdp		    case 4:
189733965Sjdp
1898104834Sobrien		      if (pcrel)
189933965Sjdp			{
190033965Sjdp#if KEEPMINUSPCININST
190189857Sobrien			  bfd_put_32 (ieee->h.abfd, -current_map->pc,
190289857Sobrien				      location_ptr + current_map->pc);
190333965Sjdp			  r->relent.howto = &rel32_howto;
190489857Sobrien			  r->relent.addend -= current_map->pc;
190533965Sjdp#else
190689857Sobrien			  bfd_put_32 (ieee->h.abfd, (bfd_vma) 0, location_ptr +
190733965Sjdp				      current_map->pc);
190833965Sjdp			  r->relent.howto = &rel32_howto;
190933965Sjdp#endif
191033965Sjdp			}
191133965Sjdp		      else
191233965Sjdp			{
191389857Sobrien			  bfd_put_32 (ieee->h.abfd, (bfd_vma) 0,
191489857Sobrien				      location_ptr + current_map->pc);
191533965Sjdp			  r->relent.howto = &abs32_howto;
191633965Sjdp			}
191733965Sjdp		      current_map->pc += 4;
191833965Sjdp		      break;
191933965Sjdp		    case 2:
1920104834Sobrien		      if (pcrel)
192133965Sjdp			{
192233965Sjdp#if KEEPMINUSPCININST
192389857Sobrien			  bfd_put_16 (ieee->h.abfd, (bfd_vma) -current_map->pc,
192489857Sobrien				      location_ptr + current_map->pc);
192533965Sjdp			  r->relent.addend -= current_map->pc;
192633965Sjdp			  r->relent.howto = &rel16_howto;
192733965Sjdp#else
192833965Sjdp
192989857Sobrien			  bfd_put_16 (ieee->h.abfd, (bfd_vma) 0,
193089857Sobrien				      location_ptr + current_map->pc);
193133965Sjdp			  r->relent.howto = &rel16_howto;
193233965Sjdp#endif
193333965Sjdp			}
193433965Sjdp
193533965Sjdp		      else
193633965Sjdp			{
193789857Sobrien			  bfd_put_16 (ieee->h.abfd, (bfd_vma) 0,
193889857Sobrien				      location_ptr + current_map->pc);
193933965Sjdp			  r->relent.howto = &abs16_howto;
194033965Sjdp			}
194133965Sjdp		      current_map->pc += 2;
194233965Sjdp		      break;
194333965Sjdp		    case 1:
1944104834Sobrien		      if (pcrel)
194533965Sjdp			{
194633965Sjdp#if KEEPMINUSPCININST
194733965Sjdp			  bfd_put_8 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc);
194833965Sjdp			  r->relent.addend -= current_map->pc;
194933965Sjdp			  r->relent.howto = &rel8_howto;
195033965Sjdp#else
195133965Sjdp			  bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
195233965Sjdp			  r->relent.howto = &rel8_howto;
195333965Sjdp#endif
195433965Sjdp			}
195533965Sjdp		      else
195633965Sjdp			{
195733965Sjdp			  bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
195833965Sjdp			  r->relent.howto = &abs8_howto;
195933965Sjdp			}
196033965Sjdp		      current_map->pc += 1;
196133965Sjdp		      break;
196233965Sjdp
196333965Sjdp		    default:
196433965Sjdp		      BFD_FAIL ();
196533965Sjdp		      return false;
196633965Sjdp		    }
196733965Sjdp		}
196833965Sjdp		break;
196933965Sjdp	      default:
197033965Sjdp		{
197133965Sjdp		  bfd_vma this_size;
1972104834Sobrien		  if (parse_int (&(ieee->h), &this_size))
197333965Sjdp		    {
197433965Sjdp		      unsigned int i;
197533965Sjdp		      for (i = 0; i < this_size; i++)
197633965Sjdp			{
197733965Sjdp			  location_ptr[current_map->pc++] = this_byte (&(ieee->h));
197833965Sjdp			  next_byte (&(ieee->h));
197933965Sjdp			}
198033965Sjdp		    }
198133965Sjdp		  else
198233965Sjdp		    {
198333965Sjdp		      loop = false;
198433965Sjdp		    }
198533965Sjdp		}
198633965Sjdp	      }
198733965Sjdp
198833965Sjdp	    /* Prevent more than the first load-item of an LR record
198933965Sjdp	       from being repeated (MRI convention). */
199033965Sjdp	    if (iterations != 1)
199133965Sjdp	      loop = false;
199233965Sjdp	  }
199333965Sjdp      }
199433965Sjdp    }
199533965Sjdp  return true;
199633965Sjdp}
199733965Sjdp
199833965Sjdp/* Read in all the section data and relocation stuff too */
199933965Sjdpstatic boolean
200033965Sjdpieee_slurp_section_data (abfd)
200133965Sjdp     bfd *abfd;
200233965Sjdp{
200333965Sjdp  bfd_byte *location_ptr = (bfd_byte *) NULL;
200433965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
200533965Sjdp  unsigned int section_number;
200633965Sjdp
200733965Sjdp  ieee_per_section_type *current_map = (ieee_per_section_type *) NULL;
200833965Sjdp  asection *s;
200933965Sjdp  /* Seek to the start of the data area */
2010104834Sobrien  if (ieee->read_data)
201133965Sjdp    return true;
201233965Sjdp  ieee->read_data = true;
201389857Sobrien  ieee_seek (ieee, ieee->w.r.data_part);
201433965Sjdp
201533965Sjdp  /* Allocate enough space for all the section contents */
201633965Sjdp
201733965Sjdp  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
201833965Sjdp    {
201933965Sjdp      ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd;
202033965Sjdp      if ((s->flags & SEC_DEBUGGING) != 0)
202133965Sjdp	continue;
202233965Sjdp      per->data = (bfd_byte *) bfd_alloc (ieee->h.abfd, s->_raw_size);
202333965Sjdp      if (!per->data)
202433965Sjdp	return false;
202533965Sjdp      /*SUPPRESS 68*/
202633965Sjdp      per->reloc_tail_ptr =
202733965Sjdp	(ieee_reloc_type **) & (s->relocation);
202833965Sjdp    }
202933965Sjdp
203033965Sjdp  while (true)
203133965Sjdp    {
203233965Sjdp      switch (this_byte (&(ieee->h)))
203333965Sjdp	{
203433965Sjdp	  /* IF we see anything strange then quit */
203533965Sjdp	default:
203633965Sjdp	  return true;
203733965Sjdp
203833965Sjdp	case ieee_set_current_section_enum:
203933965Sjdp	  next_byte (&(ieee->h));
204033965Sjdp	  section_number = must_parse_int (&(ieee->h));
204133965Sjdp	  s = ieee->section_table[section_number];
204233965Sjdp	  s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
204333965Sjdp	  current_map = (ieee_per_section_type *) s->used_by_bfd;
204433965Sjdp	  location_ptr = current_map->data - s->vma;
204533965Sjdp	  /* The document I have says that Microtec's compilers reset */
204633965Sjdp	  /* this after a sec section, even though the standard says not */
204733965Sjdp	  /* to. SO .. */
204833965Sjdp	  current_map->pc = s->vma;
204933965Sjdp	  break;
205033965Sjdp
205133965Sjdp	case ieee_e2_first_byte_enum:
205233965Sjdp	  next_byte (&(ieee->h));
205333965Sjdp	  switch (this_byte (&(ieee->h)))
205433965Sjdp	    {
205533965Sjdp	    case ieee_set_current_pc_enum & 0xff:
205633965Sjdp	      {
205733965Sjdp		bfd_vma value;
205833965Sjdp		ieee_symbol_index_type symbol;
205933965Sjdp		unsigned int extra;
206033965Sjdp		boolean pcrel;
206133965Sjdp		next_byte (&(ieee->h));
206289857Sobrien		must_parse_int (&(ieee->h));	/* Throw away section #*/
206333965Sjdp		parse_expression (ieee, &value,
206433965Sjdp				  &symbol,
206533965Sjdp				  &pcrel, &extra,
206633965Sjdp				  0);
206733965Sjdp		current_map->pc = value;
206833965Sjdp		BFD_ASSERT ((unsigned) (value - s->vma) <= s->_raw_size);
206933965Sjdp	      }
207033965Sjdp	      break;
207133965Sjdp
207233965Sjdp	    case ieee_value_starting_address_enum & 0xff:
207333965Sjdp	      next_byte (&(ieee->h));
207433965Sjdp	      if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum)
207533965Sjdp		next_byte (&(ieee->h));
207633965Sjdp	      abfd->start_address = must_parse_int (&(ieee->h));
207733965Sjdp	      /* We've got to the end of the data now - */
207833965Sjdp	      return true;
207933965Sjdp	    default:
208033965Sjdp	      BFD_FAIL ();
208133965Sjdp	      return false;
208233965Sjdp	    }
208333965Sjdp	  break;
208433965Sjdp	case ieee_repeat_data_enum:
208533965Sjdp	  {
208633965Sjdp	    /* Repeat the following LD or LR n times - we do this by
208733965Sjdp		 remembering the stream pointer before running it and
208833965Sjdp		 resetting it and running it n times. We special case
208933965Sjdp		 the repetition of a repeat_data/load_constant
209033965Sjdp		 */
209133965Sjdp
209233965Sjdp	    unsigned int iterations;
209333965Sjdp	    unsigned char *start;
209433965Sjdp	    next_byte (&(ieee->h));
209533965Sjdp	    iterations = must_parse_int (&(ieee->h));
209633965Sjdp	    start = ieee->h.input_p;
209733965Sjdp	    if (start[0] == (int) ieee_load_constant_bytes_enum &&
209833965Sjdp		start[1] == 1)
209933965Sjdp	      {
210033965Sjdp		while (iterations != 0)
210133965Sjdp		  {
210233965Sjdp		    location_ptr[current_map->pc++] = start[2];
210333965Sjdp		    iterations--;
210433965Sjdp		  }
210533965Sjdp		next_byte (&(ieee->h));
210633965Sjdp		next_byte (&(ieee->h));
210733965Sjdp		next_byte (&(ieee->h));
210833965Sjdp	      }
210933965Sjdp	    else
211033965Sjdp	      {
211133965Sjdp		while (iterations != 0)
211233965Sjdp		  {
211333965Sjdp		    ieee->h.input_p = start;
211433965Sjdp		    if (!do_one (ieee, current_map, location_ptr, s,
211589857Sobrien				 (int) iterations))
211633965Sjdp		      return false;
211733965Sjdp		    iterations--;
211833965Sjdp		  }
211933965Sjdp	      }
212033965Sjdp	  }
212133965Sjdp	  break;
212233965Sjdp	case ieee_load_constant_bytes_enum:
212333965Sjdp	case ieee_load_with_relocation_enum:
212433965Sjdp	  {
212533965Sjdp	    if (!do_one (ieee, current_map, location_ptr, s, 1))
212633965Sjdp	      return false;
212733965Sjdp	  }
212833965Sjdp	}
212933965Sjdp    }
213033965Sjdp}
213133965Sjdp
213289857Sobrienstatic boolean
213333965Sjdpieee_new_section_hook (abfd, newsect)
213433965Sjdp     bfd *abfd;
213533965Sjdp     asection *newsect;
213633965Sjdp{
213733965Sjdp  newsect->used_by_bfd = (PTR)
213889857Sobrien    bfd_alloc (abfd, (bfd_size_type) sizeof (ieee_per_section_type));
213933965Sjdp  if (!newsect->used_by_bfd)
214033965Sjdp    return false;
214133965Sjdp  ieee_per_section (newsect)->data = (bfd_byte *) NULL;
214233965Sjdp  ieee_per_section (newsect)->section = newsect;
214333965Sjdp  return true;
214433965Sjdp}
214533965Sjdp
214689857Sobrienstatic long
214733965Sjdpieee_get_reloc_upper_bound (abfd, asect)
214833965Sjdp     bfd *abfd;
214933965Sjdp     sec_ptr asect;
215033965Sjdp{
215133965Sjdp  if ((asect->flags & SEC_DEBUGGING) != 0)
215233965Sjdp    return 0;
215333965Sjdp  if (! ieee_slurp_section_data (abfd))
215433965Sjdp    return -1;
215533965Sjdp  return (asect->reloc_count + 1) * sizeof (arelent *);
215633965Sjdp}
215733965Sjdp
215833965Sjdpstatic boolean
215933965Sjdpieee_get_section_contents (abfd, section, location, offset, count)
216033965Sjdp     bfd *abfd;
216133965Sjdp     sec_ptr section;
216233965Sjdp     PTR location;
216333965Sjdp     file_ptr offset;
216433965Sjdp     bfd_size_type count;
216533965Sjdp{
216633965Sjdp  ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;
216733965Sjdp  if ((section->flags & SEC_DEBUGGING) != 0)
216833965Sjdp    return _bfd_generic_get_section_contents (abfd, section, location,
216933965Sjdp					      offset, count);
217033965Sjdp  ieee_slurp_section_data (abfd);
217133965Sjdp  (void) memcpy ((PTR) location, (PTR) (p->data + offset), (unsigned) count);
217233965Sjdp  return true;
217333965Sjdp}
217433965Sjdp
217589857Sobrienstatic long
217633965Sjdpieee_canonicalize_reloc (abfd, section, relptr, symbols)
217733965Sjdp     bfd *abfd;
217833965Sjdp     sec_ptr section;
217933965Sjdp     arelent **relptr;
218033965Sjdp     asymbol **symbols;
218133965Sjdp{
218233965Sjdp/*  ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;*/
218333965Sjdp  ieee_reloc_type *src = (ieee_reloc_type *) (section->relocation);
218433965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
218533965Sjdp
218633965Sjdp  if ((section->flags & SEC_DEBUGGING) != 0)
218733965Sjdp    return 0;
218833965Sjdp
218933965Sjdp  while (src != (ieee_reloc_type *) NULL)
219033965Sjdp    {
219133965Sjdp      /* Work out which symbol to attach it this reloc to */
219233965Sjdp      switch (src->symbol.letter)
219333965Sjdp	{
219433965Sjdp	case 'I':
219533965Sjdp	  src->relent.sym_ptr_ptr =
219633965Sjdp	    symbols + src->symbol.index + ieee->external_symbol_base_offset;
219733965Sjdp	  break;
219833965Sjdp	case 'X':
219933965Sjdp	  src->relent.sym_ptr_ptr =
220033965Sjdp	    symbols + src->symbol.index + ieee->external_reference_base_offset;
220133965Sjdp	  break;
220233965Sjdp	case 0:
220338889Sjdp	  if (src->relent.sym_ptr_ptr != NULL)
220438889Sjdp	    src->relent.sym_ptr_ptr =
220538889Sjdp	      src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr;
220633965Sjdp	  break;
220733965Sjdp	default:
220833965Sjdp
220933965Sjdp	  BFD_FAIL ();
221033965Sjdp	}
221133965Sjdp      *relptr++ = &src->relent;
221233965Sjdp      src = src->next;
221333965Sjdp    }
221433965Sjdp  *relptr = (arelent *) NULL;
221533965Sjdp  return section->reloc_count;
221633965Sjdp}
221733965Sjdp
221833965Sjdpstatic int
221933965Sjdpcomp (ap, bp)
222089857Sobrien     const PTR ap;
222189857Sobrien     const PTR bp;
222233965Sjdp{
222333965Sjdp  arelent *a = *((arelent **) ap);
222433965Sjdp  arelent *b = *((arelent **) bp);
222533965Sjdp  return a->address - b->address;
222633965Sjdp}
222733965Sjdp
222833965Sjdp/* Write the section headers.  */
222933965Sjdp
223033965Sjdpstatic boolean
223133965Sjdpieee_write_section_part (abfd)
223233965Sjdp     bfd *abfd;
223333965Sjdp{
223433965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
223533965Sjdp  asection *s;
223633965Sjdp  ieee->w.r.section_part = bfd_tell (abfd);
223733965Sjdp  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
223833965Sjdp    {
223933965Sjdp      if (! bfd_is_abs_section (s)
224033965Sjdp	  && (s->flags & SEC_DEBUGGING) == 0)
224133965Sjdp	{
224233965Sjdp	  if (! ieee_write_byte (abfd, ieee_section_type_enum)
224333965Sjdp	      || ! ieee_write_byte (abfd,
224433965Sjdp				    (bfd_byte) (s->index
224533965Sjdp						+ IEEE_SECTION_NUMBER_BASE)))
224633965Sjdp	    return false;
224733965Sjdp
224833965Sjdp	  if (abfd->flags & EXEC_P)
224933965Sjdp	    {
225033965Sjdp	      /* This image is executable, so output absolute sections */
225133965Sjdp	      if (! ieee_write_byte (abfd, ieee_variable_A_enum)
225233965Sjdp		  || ! ieee_write_byte (abfd, ieee_variable_S_enum))
225333965Sjdp		return false;
225433965Sjdp	    }
225533965Sjdp	  else
225633965Sjdp	    {
225733965Sjdp	      if (! ieee_write_byte (abfd, ieee_variable_C_enum))
225833965Sjdp		return false;
225933965Sjdp	    }
226033965Sjdp
226133965Sjdp	  switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM))
226233965Sjdp	    {
226333965Sjdp	    case SEC_CODE | SEC_LOAD:
226433965Sjdp	    case SEC_CODE:
226533965Sjdp	      if (! ieee_write_byte (abfd, ieee_variable_P_enum))
226633965Sjdp		return false;
226733965Sjdp	      break;
226833965Sjdp	    case SEC_DATA:
226933965Sjdp	    default:
227033965Sjdp	      if (! ieee_write_byte (abfd, ieee_variable_D_enum))
227133965Sjdp		return false;
227233965Sjdp	      break;
227333965Sjdp	    case SEC_ROM:
227433965Sjdp	    case SEC_ROM | SEC_DATA:
227533965Sjdp	    case SEC_ROM | SEC_LOAD:
227633965Sjdp	    case SEC_ROM | SEC_DATA | SEC_LOAD:
227733965Sjdp	      if (! ieee_write_byte (abfd, ieee_variable_R_enum))
227833965Sjdp		return false;
227933965Sjdp	    }
228033965Sjdp
228133965Sjdp
228233965Sjdp	  if (! ieee_write_id (abfd, s->name))
228333965Sjdp	    return false;
228433965Sjdp#if 0
228533965Sjdp	  ieee_write_int (abfd, 0);	/* Parent */
228633965Sjdp	  ieee_write_int (abfd, 0);	/* Brother */
228733965Sjdp	  ieee_write_int (abfd, 0);	/* Context */
228833965Sjdp#endif
228933965Sjdp	  /* Alignment */
229033965Sjdp	  if (! ieee_write_byte (abfd, ieee_section_alignment_enum)
229133965Sjdp	      || ! ieee_write_byte (abfd,
229233965Sjdp				    (bfd_byte) (s->index
229333965Sjdp						+ IEEE_SECTION_NUMBER_BASE))
229489857Sobrien	      || ! ieee_write_int (abfd, (bfd_vma) 1 << s->alignment_power))
229533965Sjdp	    return false;
229633965Sjdp
229733965Sjdp	  /* Size */
229833965Sjdp	  if (! ieee_write_2bytes (abfd, ieee_section_size_enum)
229933965Sjdp	      || ! ieee_write_byte (abfd,
230033965Sjdp				    (bfd_byte) (s->index
230133965Sjdp						+ IEEE_SECTION_NUMBER_BASE))
230233965Sjdp	      || ! ieee_write_int (abfd, s->_raw_size))
230333965Sjdp	    return false;
230433965Sjdp	  if (abfd->flags & EXEC_P)
230533965Sjdp	    {
230633965Sjdp	      /* Relocateable sections don't have asl records */
230733965Sjdp	      /* Vma */
230833965Sjdp	      if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum)
230933965Sjdp		  || ! ieee_write_byte (abfd,
231033965Sjdp					((bfd_byte)
231133965Sjdp					 (s->index
231233965Sjdp					  + IEEE_SECTION_NUMBER_BASE)))
231333965Sjdp		  || ! ieee_write_int (abfd, s->lma))
231433965Sjdp		return false;
231533965Sjdp	    }
231633965Sjdp	}
231733965Sjdp    }
231833965Sjdp
231933965Sjdp  return true;
232033965Sjdp}
232133965Sjdp
232233965Sjdp
232333965Sjdpstatic boolean
232433965Sjdpdo_with_relocs (abfd, s)
232533965Sjdp     bfd *abfd;
232633965Sjdp     asection *s;
232733965Sjdp{
232833965Sjdp  unsigned int number_of_maus_in_address =
232933965Sjdp    bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd);
233033965Sjdp  unsigned int relocs_to_go = s->reloc_count;
233133965Sjdp  bfd_byte *stream = ieee_per_section (s)->data;
233233965Sjdp  arelent **p = s->orelocation;
233333965Sjdp  bfd_size_type current_byte_index = 0;
233433965Sjdp
233533965Sjdp  qsort (s->orelocation,
233633965Sjdp	 relocs_to_go,
233733965Sjdp	 sizeof (arelent **),
233833965Sjdp	 comp);
233933965Sjdp
234033965Sjdp  /* Output the section preheader */
234133965Sjdp  if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
234233965Sjdp      || ! ieee_write_byte (abfd,
234333965Sjdp			    (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))
234433965Sjdp      || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum)
234533965Sjdp      || ! ieee_write_byte (abfd,
234633965Sjdp			    (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)))
234733965Sjdp    return false;
234889857Sobrien
234933965Sjdp  if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0)
235033965Sjdp    {
235133965Sjdp      if (! ieee_write_int (abfd, s->lma))
235233965Sjdp	return false;
235333965Sjdp    }
235433965Sjdp  else
235533965Sjdp    {
235689857Sobrien      if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0))
235733965Sjdp	return false;
235833965Sjdp    }
235933965Sjdp
236033965Sjdp  if (relocs_to_go == 0)
236133965Sjdp    {
236233965Sjdp      /* If there aren't any relocations then output the load constant
236333965Sjdp	 byte opcode rather than the load with relocation opcode */
236433965Sjdp
236533965Sjdp      while (current_byte_index < s->_raw_size)
236633965Sjdp	{
236733965Sjdp	  bfd_size_type run;
236833965Sjdp	  unsigned int MAXRUN = 127;
236933965Sjdp	  run = MAXRUN;
237033965Sjdp	  if (run > s->_raw_size - current_byte_index)
237133965Sjdp	    {
237233965Sjdp	      run = s->_raw_size - current_byte_index;
237333965Sjdp	    }
237433965Sjdp
237533965Sjdp	  if (run != 0)
237633965Sjdp	    {
237733965Sjdp	      if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum))
237833965Sjdp		return false;
237933965Sjdp	      /* Output a stream of bytes */
238033965Sjdp	      if (! ieee_write_int (abfd, run))
238133965Sjdp		return false;
238289857Sobrien	      if (bfd_bwrite ((PTR) (stream + current_byte_index), run, abfd)
238333965Sjdp		  != run)
238433965Sjdp		return false;
238533965Sjdp	      current_byte_index += run;
238633965Sjdp	    }
238733965Sjdp	}
238833965Sjdp    }
238933965Sjdp  else
239033965Sjdp    {
239133965Sjdp      if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum))
239233965Sjdp	return false;
239333965Sjdp
239433965Sjdp      /* Output the data stream as the longest sequence of bytes
239533965Sjdp	 possible, allowing for the a reasonable packet size and
239633965Sjdp	 relocation stuffs.  */
239733965Sjdp
239833965Sjdp      if ((PTR) stream == (PTR) NULL)
239933965Sjdp	{
240033965Sjdp	  /* Outputting a section without data, fill it up */
2401104834Sobrien	  stream = (unsigned char *) bfd_zalloc (abfd, s->_raw_size);
240233965Sjdp	  if (!stream)
240333965Sjdp	    return false;
240433965Sjdp	}
240533965Sjdp      while (current_byte_index < s->_raw_size)
240633965Sjdp	{
240733965Sjdp	  bfd_size_type run;
240833965Sjdp	  unsigned int MAXRUN = 127;
240933965Sjdp	  if (relocs_to_go)
241033965Sjdp	    {
241133965Sjdp	      run = (*p)->address - current_byte_index;
241233965Sjdp	      if (run > MAXRUN)
241333965Sjdp		run = MAXRUN;
241433965Sjdp	    }
241533965Sjdp	  else
241633965Sjdp	    {
241733965Sjdp	      run = MAXRUN;
241833965Sjdp	    }
241933965Sjdp	  if (run > s->_raw_size - current_byte_index)
242033965Sjdp	    {
242133965Sjdp	      run = s->_raw_size - current_byte_index;
242233965Sjdp	    }
242333965Sjdp
242433965Sjdp	  if (run != 0)
242533965Sjdp	    {
242633965Sjdp	      /* Output a stream of bytes */
242733965Sjdp	      if (! ieee_write_int (abfd, run))
242833965Sjdp		return false;
242989857Sobrien	      if (bfd_bwrite ((PTR) (stream + current_byte_index), run, abfd)
243033965Sjdp		  != run)
243133965Sjdp		return false;
243233965Sjdp	      current_byte_index += run;
243333965Sjdp	    }
243433965Sjdp	  /* Output any relocations here */
243533965Sjdp	  if (relocs_to_go && (*p) && (*p)->address == current_byte_index)
243633965Sjdp	    {
243733965Sjdp	      while (relocs_to_go
243833965Sjdp		     && (*p) && (*p)->address == current_byte_index)
243933965Sjdp		{
244033965Sjdp		  arelent *r = *p;
244133965Sjdp		  bfd_signed_vma ov;
244233965Sjdp
244333965Sjdp#if 0
244433965Sjdp		  if (r->howto->pc_relative)
244533965Sjdp		    {
244633965Sjdp		      r->addend += current_byte_index;
244733965Sjdp		    }
244833965Sjdp#endif
244933965Sjdp
245033965Sjdp		  switch (r->howto->size)
245133965Sjdp		    {
245233965Sjdp		    case 2:
245333965Sjdp
245433965Sjdp		      ov = bfd_get_signed_32 (abfd,
245533965Sjdp					      stream + current_byte_index);
245633965Sjdp		      current_byte_index += 4;
245733965Sjdp		      break;
245833965Sjdp		    case 1:
245933965Sjdp		      ov = bfd_get_signed_16 (abfd,
246033965Sjdp					      stream + current_byte_index);
246133965Sjdp		      current_byte_index += 2;
246233965Sjdp		      break;
246333965Sjdp		    case 0:
246433965Sjdp		      ov = bfd_get_signed_8 (abfd,
246533965Sjdp					     stream + current_byte_index);
246633965Sjdp		      current_byte_index++;
246733965Sjdp		      break;
246833965Sjdp		    default:
246933965Sjdp		      ov = 0;
247033965Sjdp		      BFD_FAIL ();
247133965Sjdp		      return false;
247233965Sjdp		    }
247333965Sjdp
247433965Sjdp		  ov &= r->howto->src_mask;
247533965Sjdp
247633965Sjdp		  if (r->howto->pc_relative
247733965Sjdp		      && ! r->howto->pcrel_offset)
247833965Sjdp		    ov += r->address;
247933965Sjdp
248033965Sjdp		  if (! ieee_write_byte (abfd,
248133965Sjdp					 ieee_function_either_open_b_enum))
248233965Sjdp		    return false;
248333965Sjdp
248433965Sjdp/*		  abort();*/
248533965Sjdp
248633965Sjdp		  if (r->sym_ptr_ptr != (asymbol **) NULL)
248733965Sjdp		    {
248833965Sjdp		      if (! ieee_write_expression (abfd, r->addend + ov,
248933965Sjdp						   *(r->sym_ptr_ptr),
249033965Sjdp						   r->howto->pc_relative,
249189857Sobrien						   (unsigned) s->index))
249233965Sjdp			return false;
249333965Sjdp		    }
249433965Sjdp		  else
249533965Sjdp		    {
249633965Sjdp		      if (! ieee_write_expression (abfd, r->addend + ov,
249733965Sjdp						   (asymbol *) NULL,
249833965Sjdp						   r->howto->pc_relative,
249989857Sobrien						   (unsigned) s->index))
250033965Sjdp			return false;
250133965Sjdp		    }
250233965Sjdp
250333965Sjdp		  if (number_of_maus_in_address
250433965Sjdp		      != bfd_get_reloc_size (r->howto))
250533965Sjdp		    {
250689857Sobrien		      bfd_vma rsize = bfd_get_reloc_size (r->howto);
250789857Sobrien		      if (! ieee_write_int (abfd, rsize))
250833965Sjdp			return false;
250933965Sjdp		    }
251033965Sjdp		  if (! ieee_write_byte (abfd,
251133965Sjdp					 ieee_function_either_close_b_enum))
251233965Sjdp		    return false;
251333965Sjdp
251433965Sjdp		  relocs_to_go--;
251533965Sjdp		  p++;
251633965Sjdp		}
251733965Sjdp
251833965Sjdp	    }
251933965Sjdp	}
252033965Sjdp    }
252133965Sjdp
252233965Sjdp  return true;
252333965Sjdp}
252433965Sjdp
252533965Sjdp/* If there are no relocations in the output section then we can be
252633965Sjdp   clever about how we write.  We block items up into a max of 127
252733965Sjdp   bytes.  */
252833965Sjdp
252933965Sjdpstatic boolean
253033965Sjdpdo_as_repeat (abfd, s)
253133965Sjdp     bfd *abfd;
253233965Sjdp     asection *s;
253333965Sjdp{
253433965Sjdp  if (s->_raw_size)
253533965Sjdp    {
253633965Sjdp      if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
253733965Sjdp	  || ! ieee_write_byte (abfd,
253833965Sjdp				(bfd_byte) (s->index
253933965Sjdp					    + IEEE_SECTION_NUMBER_BASE))
254033965Sjdp	  || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8)
254133965Sjdp	  || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff)
254233965Sjdp	  || ! ieee_write_byte (abfd,
254333965Sjdp				(bfd_byte) (s->index
254489857Sobrien					    + IEEE_SECTION_NUMBER_BASE)))
254589857Sobrien	return false;
254689857Sobrien
254789857Sobrien      if ((abfd->flags & EXEC_P) != 0)
254889857Sobrien	{
254989857Sobrien	  if (! ieee_write_int (abfd, s->lma))
255089857Sobrien	    return false;
255189857Sobrien	}
255289857Sobrien      else
255389857Sobrien	{
255489857Sobrien	  if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0))
255589857Sobrien	    return false;
255689857Sobrien	}
255789857Sobrien
255889857Sobrien      if (! ieee_write_byte (abfd, ieee_repeat_data_enum)
255933965Sjdp	  || ! ieee_write_int (abfd, s->_raw_size)
256033965Sjdp	  || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)
256133965Sjdp	  || ! ieee_write_byte (abfd, 1)
256233965Sjdp	  || ! ieee_write_byte (abfd, 0))
256333965Sjdp	return false;
256433965Sjdp    }
256533965Sjdp
256633965Sjdp  return true;
256733965Sjdp}
256833965Sjdp
256933965Sjdpstatic boolean
257033965Sjdpdo_without_relocs (abfd, s)
257133965Sjdp     bfd *abfd;
257233965Sjdp     asection *s;
257333965Sjdp{
257433965Sjdp  bfd_byte *stream = ieee_per_section (s)->data;
257533965Sjdp
257633965Sjdp  if (stream == 0 || ((s->flags & SEC_LOAD) == 0))
257733965Sjdp    {
257833965Sjdp      if (! do_as_repeat (abfd, s))
257933965Sjdp	return false;
258033965Sjdp    }
258133965Sjdp  else
258233965Sjdp    {
258333965Sjdp      unsigned int i;
258433965Sjdp      for (i = 0; i < s->_raw_size; i++)
258533965Sjdp	{
258633965Sjdp	  if (stream[i] != 0)
258733965Sjdp	    {
258833965Sjdp	      if (! do_with_relocs (abfd, s))
258933965Sjdp		return false;
259033965Sjdp	      return true;
259133965Sjdp	    }
259233965Sjdp	}
259333965Sjdp      if (! do_as_repeat (abfd, s))
259433965Sjdp	return false;
259533965Sjdp    }
259633965Sjdp
259733965Sjdp  return true;
259833965Sjdp}
259933965Sjdp
260033965Sjdp
260133965Sjdpstatic unsigned char *output_ptr_start;
260233965Sjdpstatic unsigned char *output_ptr;
260333965Sjdpstatic unsigned char *output_ptr_end;
260433965Sjdpstatic unsigned char *input_ptr_start;
260533965Sjdpstatic unsigned char *input_ptr;
260633965Sjdpstatic unsigned char *input_ptr_end;
260733965Sjdpstatic bfd *input_bfd;
260833965Sjdpstatic bfd *output_bfd;
260933965Sjdpstatic int output_buffer;
261033965Sjdp
261189857Sobrienstatic boolean
261289857Sobrienieee_mkobject (abfd)
261389857Sobrien     bfd *abfd;
261489857Sobrien{
261589857Sobrien  bfd_size_type amt;
261689857Sobrien
261789857Sobrien  output_ptr_start = NULL;
261889857Sobrien  output_ptr = NULL;
261989857Sobrien  output_ptr_end = NULL;
262089857Sobrien  input_ptr_start = NULL;
262189857Sobrien  input_ptr = NULL;
262289857Sobrien  input_ptr_end = NULL;
262389857Sobrien  input_bfd = NULL;
262489857Sobrien  output_bfd = NULL;
262589857Sobrien  output_buffer = 0;
262689857Sobrien  amt = sizeof (ieee_data_type);
262789857Sobrien  abfd->tdata.ieee_data = (ieee_data_type *) bfd_zalloc (abfd, amt);
2628104834Sobrien  return abfd->tdata.ieee_data != NULL;
262989857Sobrien}
263089857Sobrien
263133965Sjdpstatic void
263233965Sjdpfill ()
263333965Sjdp{
263489857Sobrien  bfd_size_type amt = input_ptr_end - input_ptr_start;
263533965Sjdp  /* FIXME: Check return value.  I'm not sure whether it needs to read
263633965Sjdp     the entire buffer or not.  */
263789857Sobrien  bfd_bread ((PTR) input_ptr_start, amt, input_bfd);
263833965Sjdp  input_ptr = input_ptr_start;
263933965Sjdp}
264089857Sobrien
264133965Sjdpstatic void
264233965Sjdpflush ()
264333965Sjdp{
264489857Sobrien  bfd_size_type amt = output_ptr - output_ptr_start;
264589857Sobrien  if (bfd_bwrite ((PTR) (output_ptr_start), amt, output_bfd) != amt)
264633965Sjdp    abort ();
264733965Sjdp  output_ptr = output_ptr_start;
264833965Sjdp  output_buffer++;
264933965Sjdp}
265033965Sjdp
265133965Sjdp#define THIS() ( *input_ptr )
265233965Sjdp#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); }
265333965Sjdp#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end)  flush(); }
265433965Sjdp
265533965Sjdpstatic void
265633965Sjdpwrite_int (value)
265733965Sjdp     int value;
265833965Sjdp{
265933965Sjdp  if (value >= 0 && value <= 127)
266033965Sjdp    {
266133965Sjdp      OUT (value);
266233965Sjdp    }
266333965Sjdp  else
266433965Sjdp    {
266533965Sjdp      unsigned int length;
266633965Sjdp      /* How many significant bytes ? */
266733965Sjdp      /* FIXME FOR LONGER INTS */
266833965Sjdp      if (value & 0xff000000)
266933965Sjdp	{
267033965Sjdp	  length = 4;
267133965Sjdp	}
267233965Sjdp      else if (value & 0x00ff0000)
267333965Sjdp	{
267433965Sjdp	  length = 3;
267533965Sjdp	}
267633965Sjdp      else if (value & 0x0000ff00)
267733965Sjdp	{
267833965Sjdp	  length = 2;
267933965Sjdp	}
268033965Sjdp      else
268133965Sjdp	length = 1;
268233965Sjdp
268333965Sjdp      OUT ((int) ieee_number_repeat_start_enum + length);
268433965Sjdp      switch (length)
268533965Sjdp	{
268633965Sjdp	case 4:
268733965Sjdp	  OUT (value >> 24);
268833965Sjdp	case 3:
268933965Sjdp	  OUT (value >> 16);
269033965Sjdp	case 2:
269133965Sjdp	  OUT (value >> 8);
269233965Sjdp	case 1:
269333965Sjdp	  OUT (value);
269433965Sjdp	}
269533965Sjdp
269633965Sjdp    }
269733965Sjdp}
269833965Sjdp
269933965Sjdpstatic void
270033965Sjdpcopy_id ()
270133965Sjdp{
270233965Sjdp  int length = THIS ();
270333965Sjdp  char ch;
270433965Sjdp  OUT (length);
270533965Sjdp  NEXT ();
270633965Sjdp  while (length--)
270733965Sjdp    {
270833965Sjdp      ch = THIS ();
270933965Sjdp      OUT (ch);
271033965Sjdp      NEXT ();
271133965Sjdp    }
271233965Sjdp}
271333965Sjdp
271433965Sjdp#define VAR(x) ((x | 0x80))
271533965Sjdpstatic void
271633965Sjdpcopy_expression ()
271733965Sjdp{
271833965Sjdp  int stack[10];
271933965Sjdp  int *tos = stack;
272089857Sobrien  int value;
272133965Sjdp  while (1)
272233965Sjdp    {
272333965Sjdp      switch (THIS ())
272433965Sjdp	{
272533965Sjdp	case 0x84:
272633965Sjdp	  NEXT ();
272733965Sjdp	  value = THIS ();
272833965Sjdp	  NEXT ();
272933965Sjdp	  value = (value << 8) | THIS ();
273033965Sjdp	  NEXT ();
273133965Sjdp	  value = (value << 8) | THIS ();
273233965Sjdp	  NEXT ();
273333965Sjdp	  value = (value << 8) | THIS ();
273433965Sjdp	  NEXT ();
273533965Sjdp	  *tos++ = value;
273633965Sjdp	  break;
273733965Sjdp	case 0x83:
273833965Sjdp	  NEXT ();
273933965Sjdp	  value = THIS ();
274033965Sjdp	  NEXT ();
274133965Sjdp	  value = (value << 8) | THIS ();
274233965Sjdp	  NEXT ();
274333965Sjdp	  value = (value << 8) | THIS ();
274433965Sjdp	  NEXT ();
274533965Sjdp	  *tos++ = value;
274633965Sjdp	  break;
274733965Sjdp	case 0x82:
274833965Sjdp	  NEXT ();
274933965Sjdp	  value = THIS ();
275033965Sjdp	  NEXT ();
275133965Sjdp	  value = (value << 8) | THIS ();
275233965Sjdp	  NEXT ();
275333965Sjdp	  *tos++ = value;
275433965Sjdp	  break;
275533965Sjdp	case 0x81:
275633965Sjdp	  NEXT ();
275733965Sjdp	  value = THIS ();
275833965Sjdp	  NEXT ();
275933965Sjdp	  *tos++ = value;
276033965Sjdp	  break;
276133965Sjdp	case 0x80:
276233965Sjdp	  NEXT ();
276333965Sjdp	  *tos++ = 0;
276433965Sjdp	  break;
276533965Sjdp	default:
276633965Sjdp	  if (THIS () > 0x84)
276733965Sjdp	    {
276833965Sjdp	      /* Not a number, just bug out with the answer */
276933965Sjdp	      write_int (*(--tos));
277033965Sjdp	      return;
277133965Sjdp	    }
277233965Sjdp	  *tos++ = THIS ();
277333965Sjdp	  NEXT ();
277433965Sjdp	  break;
277533965Sjdp	case 0xa5:
277633965Sjdp	  /* PLUS anything */
277789857Sobrien	  value = *(--tos);
277889857Sobrien	  value += *(--tos);
277989857Sobrien	  *tos++ = value;
278089857Sobrien	  NEXT ();
278133965Sjdp	  break;
278233965Sjdp	case VAR ('R'):
278333965Sjdp	  {
278433965Sjdp	    int section_number;
278533965Sjdp	    ieee_data_type *ieee;
278633965Sjdp	    asection *s;
278733965Sjdp	    NEXT ();
278833965Sjdp	    section_number = THIS ();
278933965Sjdp
279033965Sjdp	    NEXT ();
279133965Sjdp	    ieee = IEEE_DATA (input_bfd);
279233965Sjdp	    s = ieee->section_table[section_number];
279389857Sobrien	    value = 0;
279433965Sjdp	    if (s->output_section)
279589857Sobrien	      value = s->output_section->lma;
279633965Sjdp	    value += s->output_offset;
279733965Sjdp	    *tos++ = value;
279833965Sjdp	  }
279933965Sjdp	  break;
280033965Sjdp	case 0x90:
280133965Sjdp	  {
280233965Sjdp	    NEXT ();
280333965Sjdp	    write_int (*(--tos));
280433965Sjdp	    OUT (0x90);
280533965Sjdp	    return;
280633965Sjdp	  }
280733965Sjdp	}
280833965Sjdp    }
280933965Sjdp}
281033965Sjdp
281133965Sjdp/* Drop the int in the buffer, and copy a null into the gap, which we
281233965Sjdp   will overwrite later */
281333965Sjdp
281433965Sjdpstatic void
281533965Sjdpfill_int (buf)
281633965Sjdp     struct output_buffer_struct *buf;
281733965Sjdp{
281833965Sjdp  if (buf->buffer == output_buffer)
281933965Sjdp    {
282033965Sjdp      /* Still a chance to output the size */
282133965Sjdp      int value = output_ptr - buf->ptrp + 3;
282233965Sjdp      buf->ptrp[0] = value >> 24;
282333965Sjdp      buf->ptrp[1] = value >> 16;
282433965Sjdp      buf->ptrp[2] = value >> 8;
282533965Sjdp      buf->ptrp[3] = value >> 0;
282633965Sjdp    }
282733965Sjdp}
282833965Sjdp
282933965Sjdpstatic void
283033965Sjdpdrop_int (buf)
283133965Sjdp     struct output_buffer_struct *buf;
283233965Sjdp{
283333965Sjdp  int type = THIS ();
283433965Sjdp  int ch;
283533965Sjdp  if (type <= 0x84)
283633965Sjdp    {
283733965Sjdp      NEXT ();
283833965Sjdp      switch (type)
283933965Sjdp	{
284033965Sjdp	case 0x84:
284133965Sjdp	  ch = THIS ();
284233965Sjdp	  NEXT ();
284333965Sjdp	case 0x83:
284433965Sjdp	  ch = THIS ();
284533965Sjdp	  NEXT ();
284633965Sjdp	case 0x82:
284733965Sjdp	  ch = THIS ();
284833965Sjdp	  NEXT ();
284933965Sjdp	case 0x81:
285033965Sjdp	  ch = THIS ();
285133965Sjdp	  NEXT ();
285233965Sjdp	case 0x80:
285333965Sjdp	  break;
285433965Sjdp	}
285533965Sjdp    }
285633965Sjdp  OUT (0x84);
285733965Sjdp  buf->ptrp = output_ptr;
285833965Sjdp  buf->buffer = output_buffer;
285933965Sjdp  OUT (0);
286033965Sjdp  OUT (0);
286133965Sjdp  OUT (0);
286233965Sjdp  OUT (0);
286333965Sjdp}
286433965Sjdp
286533965Sjdpstatic void
286633965Sjdpcopy_int ()
286733965Sjdp{
286833965Sjdp  int type = THIS ();
286933965Sjdp  int ch;
287033965Sjdp  if (type <= 0x84)
287133965Sjdp    {
287233965Sjdp      OUT (type);
287333965Sjdp      NEXT ();
287433965Sjdp      switch (type)
287533965Sjdp	{
287633965Sjdp	case 0x84:
287733965Sjdp	  ch = THIS ();
287833965Sjdp	  NEXT ();
287933965Sjdp	  OUT (ch);
288033965Sjdp	case 0x83:
288133965Sjdp	  ch = THIS ();
288233965Sjdp	  NEXT ();
288333965Sjdp	  OUT (ch);
288433965Sjdp	case 0x82:
288533965Sjdp	  ch = THIS ();
288633965Sjdp	  NEXT ();
288733965Sjdp	  OUT (ch);
288833965Sjdp	case 0x81:
288933965Sjdp	  ch = THIS ();
289033965Sjdp	  NEXT ();
289133965Sjdp	  OUT (ch);
289233965Sjdp	case 0x80:
289333965Sjdp	  break;
289433965Sjdp	}
289533965Sjdp    }
289633965Sjdp}
289733965Sjdp
289833965Sjdp#define ID copy_id()
289933965Sjdp#define INT copy_int()
290033965Sjdp#define EXP copy_expression()
290133965Sjdp#define INTn(q) copy_int()
290233965Sjdp#define EXPn(q) copy_expression()
290333965Sjdp
290433965Sjdpstatic void
290533965Sjdpf1_record ()
290633965Sjdp{
290733965Sjdp  int ch;
290833965Sjdp  /* ATN record */
290933965Sjdp  NEXT ();
291033965Sjdp  ch = THIS ();
291133965Sjdp  switch (ch)
291233965Sjdp    {
291333965Sjdp    default:
291433965Sjdp      OUT (0xf1);
291533965Sjdp      OUT (ch);
291633965Sjdp      break;
291733965Sjdp    case 0xc9:
291833965Sjdp      NEXT ();
291933965Sjdp      OUT (0xf1);
292033965Sjdp      OUT (0xc9);
292133965Sjdp      INT;
292233965Sjdp      INT;
292333965Sjdp      ch = THIS ();
292433965Sjdp      switch (ch)
292533965Sjdp	{
292633965Sjdp	case 0x16:
292733965Sjdp	  NEXT ();
292833965Sjdp	  break;
292933965Sjdp	case 0x01:
293033965Sjdp	  NEXT ();
293133965Sjdp	  break;
293233965Sjdp	case 0x00:
293333965Sjdp	  NEXT ();
293433965Sjdp	  INT;
293533965Sjdp	  break;
293633965Sjdp	case 0x03:
293733965Sjdp	  NEXT ();
293833965Sjdp	  INT;
293933965Sjdp	  break;
294033965Sjdp	case 0x13:
294133965Sjdp	  EXPn (instruction address);
294233965Sjdp	  break;
294333965Sjdp	default:
294433965Sjdp	  break;
294533965Sjdp	}
294633965Sjdp      break;
294733965Sjdp    case 0xd8:
294833965Sjdp      /* EXternal ref */
294933965Sjdp      NEXT ();
295033965Sjdp      OUT (0xf1);
295133965Sjdp      OUT (0xd8);
295233965Sjdp      EXP;
295333965Sjdp      EXP;
295433965Sjdp      EXP;
295533965Sjdp      EXP;
295633965Sjdp      break;
295733965Sjdp    case 0xce:
295833965Sjdp      NEXT ();
295933965Sjdp      OUT (0xf1);
296033965Sjdp      OUT (0xce);
296133965Sjdp      INT;
296233965Sjdp      INT;
296333965Sjdp      ch = THIS ();
296433965Sjdp      INT;
296533965Sjdp      switch (ch)
296633965Sjdp	{
296733965Sjdp	case 0x01:
296833965Sjdp	  INT;
296933965Sjdp	  INT;
297033965Sjdp	  break;
297133965Sjdp	case 0x02:
297233965Sjdp	  INT;
297333965Sjdp	  break;
297433965Sjdp	case 0x04:
297533965Sjdp	  EXPn (external function);
297633965Sjdp	  break;
297733965Sjdp	case 0x05:
297833965Sjdp	  break;
297933965Sjdp	case 0x07:
298033965Sjdp	  INTn (line number);
298133965Sjdp	  INT;
298233965Sjdp	case 0x08:
298333965Sjdp	  break;
298433965Sjdp	case 0x0a:
298533965Sjdp	  INTn (locked register);
298633965Sjdp	  INT;
298733965Sjdp	  break;
298833965Sjdp	case 0x3f:
298933965Sjdp	  copy_till_end ();
299033965Sjdp	  break;
299133965Sjdp	case 0x3e:
299233965Sjdp	  copy_till_end ();
299333965Sjdp	  break;
299433965Sjdp	case 0x40:
299533965Sjdp	  copy_till_end ();
299633965Sjdp	  break;
299733965Sjdp	case 0x41:
299833965Sjdp	  ID;
299933965Sjdp	  break;
300033965Sjdp	}
300133965Sjdp    }
300233965Sjdp
300333965Sjdp}
300433965Sjdp
300533965Sjdpstatic void
300633965Sjdpf0_record ()
300733965Sjdp{
300833965Sjdp  /* Attribute record */
300933965Sjdp  NEXT ();
301033965Sjdp  OUT (0xf0);
301133965Sjdp  INTn (Symbol name);
301233965Sjdp  ID;
301333965Sjdp}
301433965Sjdp
301533965Sjdpstatic void
301633965Sjdpcopy_till_end ()
301733965Sjdp{
301833965Sjdp  int ch = THIS ();
301933965Sjdp  while (1)
302033965Sjdp    {
302133965Sjdp      while (ch <= 0x80)
302233965Sjdp	{
302333965Sjdp	  OUT (ch);
302433965Sjdp	  NEXT ();
302533965Sjdp	  ch = THIS ();
302633965Sjdp	}
302733965Sjdp      switch (ch)
302833965Sjdp	{
302933965Sjdp	case 0x84:
303033965Sjdp	  OUT (THIS ());
303133965Sjdp	  NEXT ();
303233965Sjdp	case 0x83:
303333965Sjdp	  OUT (THIS ());
303433965Sjdp	  NEXT ();
303533965Sjdp	case 0x82:
303633965Sjdp	  OUT (THIS ());
303733965Sjdp	  NEXT ();
303833965Sjdp	case 0x81:
303933965Sjdp	  OUT (THIS ());
304033965Sjdp	  NEXT ();
304133965Sjdp	  OUT (THIS ());
304233965Sjdp	  NEXT ();
304333965Sjdp
304433965Sjdp	  ch = THIS ();
304533965Sjdp	  break;
304633965Sjdp	default:
304733965Sjdp	  return;
304833965Sjdp	}
304933965Sjdp    }
305033965Sjdp
305133965Sjdp}
305233965Sjdp
305333965Sjdpstatic void
305433965Sjdpf2_record ()
305533965Sjdp{
305633965Sjdp  NEXT ();
305733965Sjdp  OUT (0xf2);
305833965Sjdp  INT;
305933965Sjdp  NEXT ();
306033965Sjdp  OUT (0xce);
306133965Sjdp  INT;
306233965Sjdp  copy_till_end ();
306333965Sjdp}
306433965Sjdp
306533965Sjdp
306633965Sjdpstatic void
306733965Sjdpf8_record ()
306833965Sjdp{
306933965Sjdp  int ch;
307033965Sjdp  NEXT ();
307133965Sjdp  ch = THIS ();
307233965Sjdp  switch (ch)
307333965Sjdp    {
307433965Sjdp    case 0x01:
307533965Sjdp    case 0x02:
307633965Sjdp    case 0x03:
307733965Sjdp      /* Unique typedefs for module */
307833965Sjdp      /* GLobal typedefs  */
307933965Sjdp      /* High level module scope beginning */
308033965Sjdp      {
308133965Sjdp	struct output_buffer_struct ob;
308233965Sjdp	NEXT ();
308333965Sjdp	OUT (0xf8);
308433965Sjdp	OUT (ch);
308533965Sjdp	drop_int (&ob);
308633965Sjdp	ID;
308733965Sjdp
308833965Sjdp	block ();
308933965Sjdp
309033965Sjdp	NEXT ();
309133965Sjdp	fill_int (&ob);
309233965Sjdp	OUT (0xf9);
309333965Sjdp      }
309433965Sjdp      break;
309533965Sjdp    case 0x04:
309633965Sjdp      /* Global function */
309733965Sjdp      {
309833965Sjdp	struct output_buffer_struct ob;
309933965Sjdp	NEXT ();
310033965Sjdp	OUT (0xf8);
310133965Sjdp	OUT (0x04);
310233965Sjdp	drop_int (&ob);
310333965Sjdp	ID;
310433965Sjdp	INTn (stack size);
310533965Sjdp	INTn (ret val);
310633965Sjdp	EXPn (offset);
310733965Sjdp
310833965Sjdp	block ();
310933965Sjdp
311033965Sjdp	NEXT ();
311133965Sjdp	OUT (0xf9);
311233965Sjdp	EXPn (size of block);
311333965Sjdp	fill_int (&ob);
311433965Sjdp      }
311533965Sjdp      break;
311633965Sjdp
311733965Sjdp    case 0x05:
311833965Sjdp      /* File name for source line numbers */
311933965Sjdp      {
312033965Sjdp	struct output_buffer_struct ob;
312133965Sjdp	NEXT ();
312233965Sjdp	OUT (0xf8);
312333965Sjdp	OUT (0x05);
312433965Sjdp	drop_int (&ob);
312533965Sjdp	ID;
312633965Sjdp	INTn (year);
312733965Sjdp	INTn (month);
312833965Sjdp	INTn (day);
312933965Sjdp	INTn (hour);
313033965Sjdp	INTn (monute);
313133965Sjdp	INTn (second);
313233965Sjdp	block ();
313333965Sjdp	NEXT ();
313433965Sjdp	OUT (0xf9);
313533965Sjdp	fill_int (&ob);
313633965Sjdp      }
313733965Sjdp      break;
313833965Sjdp
313933965Sjdp    case 0x06:
314033965Sjdp      /* Local function */
314133965Sjdp      {
314233965Sjdp	struct output_buffer_struct ob;
314333965Sjdp	NEXT ();
314433965Sjdp	OUT (0xf8);
314533965Sjdp	OUT (0x06);
314633965Sjdp	drop_int (&ob);
314733965Sjdp	ID;
314833965Sjdp	INTn (stack size);
314933965Sjdp	INTn (type return);
315033965Sjdp	EXPn (offset);
315133965Sjdp	block ();
315233965Sjdp	NEXT ();
315333965Sjdp	OUT (0xf9);
315433965Sjdp	EXPn (size);
315533965Sjdp	fill_int (&ob);
315633965Sjdp      }
315733965Sjdp      break;
315833965Sjdp
315933965Sjdp    case 0x0a:
316033965Sjdp      /* Assembler module scope beginning -*/
316133965Sjdp      {
316233965Sjdp	struct output_buffer_struct ob;
316333965Sjdp
316433965Sjdp	NEXT ();
316533965Sjdp	OUT (0xf8);
316633965Sjdp	OUT (0x0a);
316733965Sjdp	drop_int (&ob);
316833965Sjdp	ID;
316933965Sjdp	ID;
317033965Sjdp	INT;
317133965Sjdp	ID;
317233965Sjdp	INT;
317333965Sjdp	INT;
317433965Sjdp	INT;
317533965Sjdp	INT;
317633965Sjdp	INT;
317733965Sjdp	INT;
317833965Sjdp
317933965Sjdp	block ();
318033965Sjdp
318133965Sjdp	NEXT ();
318233965Sjdp	OUT (0xf9);
318333965Sjdp	fill_int (&ob);
318433965Sjdp      }
318533965Sjdp      break;
318633965Sjdp    case 0x0b:
318733965Sjdp      {
318833965Sjdp	struct output_buffer_struct ob;
318933965Sjdp	NEXT ();
319033965Sjdp	OUT (0xf8);
319133965Sjdp	OUT (0x0b);
319233965Sjdp	drop_int (&ob);
319333965Sjdp	ID;
319433965Sjdp	INT;
319533965Sjdp	INTn (section index);
319633965Sjdp	EXPn (offset);
319733965Sjdp	INTn (stuff);
319833965Sjdp
319933965Sjdp	block ();
320033965Sjdp
320133965Sjdp	OUT (0xf9);
320233965Sjdp	NEXT ();
320333965Sjdp	EXPn (Size in Maus);
320433965Sjdp	fill_int (&ob);
320533965Sjdp      }
320633965Sjdp      break;
320733965Sjdp    }
320833965Sjdp}
320933965Sjdp
321033965Sjdpstatic void
321133965Sjdpe2_record ()
321233965Sjdp{
321333965Sjdp  OUT (0xe2);
321433965Sjdp  NEXT ();
321533965Sjdp  OUT (0xce);
321633965Sjdp  NEXT ();
321733965Sjdp  INT;
321833965Sjdp  EXP;
321933965Sjdp}
322033965Sjdp
322133965Sjdpstatic void
322233965Sjdpblock ()
322333965Sjdp{
322433965Sjdp  int ch;
322533965Sjdp  while (1)
322633965Sjdp    {
322733965Sjdp      ch = THIS ();
322833965Sjdp      switch (ch)
322933965Sjdp	{
323033965Sjdp	case 0xe1:
323133965Sjdp	case 0xe5:
323233965Sjdp	  return;
323333965Sjdp	case 0xf9:
323433965Sjdp	  return;
323533965Sjdp	case 0xf0:
323633965Sjdp	  f0_record ();
323733965Sjdp	  break;
323833965Sjdp	case 0xf1:
323933965Sjdp	  f1_record ();
324033965Sjdp	  break;
324133965Sjdp	case 0xf2:
324233965Sjdp	  f2_record ();
324333965Sjdp	  break;
324433965Sjdp	case 0xf8:
324533965Sjdp	  f8_record ();
324633965Sjdp	  break;
324733965Sjdp	case 0xe2:
324833965Sjdp	  e2_record ();
324933965Sjdp	  break;
325033965Sjdp
325133965Sjdp	}
325233965Sjdp    }
325333965Sjdp}
325433965Sjdp
325533965Sjdp
325633965Sjdp
325733965Sjdp/* relocate_debug,
325833965Sjdp   moves all the debug information from the source bfd to the output
325933965Sjdp   bfd, and relocates any expressions it finds
326033965Sjdp*/
326133965Sjdp
326233965Sjdpstatic void
326333965Sjdprelocate_debug (output, input)
326460484Sobrien     bfd *output ATTRIBUTE_UNUSED;
326533965Sjdp     bfd *input;
326633965Sjdp{
326733965Sjdp#define IBS 400
326833965Sjdp#define OBS 400
326933965Sjdp  unsigned char input_buffer[IBS];
327033965Sjdp
327133965Sjdp  input_ptr_start = input_ptr = input_buffer;
327233965Sjdp  input_ptr_end = input_buffer + IBS;
327333965Sjdp  input_bfd = input;
327433965Sjdp  /* FIXME: Check return value.  I'm not sure whether it needs to read
327533965Sjdp     the entire buffer or not.  */
327689857Sobrien  bfd_bread ((PTR) input_ptr_start, (bfd_size_type) IBS, input);
327733965Sjdp  block ();
327833965Sjdp}
327933965Sjdp
328077298Sobrien/* Gather together all the debug information from each input BFD into
328177298Sobrien   one place, relocating it and emitting it as we go.  */
328233965Sjdp
328333965Sjdpstatic boolean
328433965Sjdpieee_write_debug_part (abfd)
328533965Sjdp     bfd *abfd;
328633965Sjdp{
328733965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
328833965Sjdp  bfd_chain_type *chain = ieee->chain_root;
328989857Sobrien  unsigned char obuff[OBS];
329033965Sjdp  boolean some_debug = false;
329133965Sjdp  file_ptr here = bfd_tell (abfd);
329233965Sjdp
329389857Sobrien  output_ptr_start = output_ptr = obuff;
329489857Sobrien  output_ptr_end = obuff + OBS;
329589857Sobrien  output_ptr = obuff;
329633965Sjdp  output_bfd = abfd;
329733965Sjdp
329833965Sjdp  if (chain == (bfd_chain_type *) NULL)
329933965Sjdp    {
330033965Sjdp      asection *s;
330133965Sjdp
330233965Sjdp      for (s = abfd->sections; s != NULL; s = s->next)
330333965Sjdp	if ((s->flags & SEC_DEBUGGING) != 0)
330433965Sjdp	  break;
330533965Sjdp      if (s == NULL)
330633965Sjdp	{
330733965Sjdp	  ieee->w.r.debug_information_part = 0;
330833965Sjdp	  return true;
330933965Sjdp	}
331033965Sjdp
331133965Sjdp      ieee->w.r.debug_information_part = here;
331289857Sobrien      if (bfd_bwrite (s->contents, s->_raw_size, abfd) != s->_raw_size)
331333965Sjdp	return false;
331433965Sjdp    }
331533965Sjdp  else
331633965Sjdp    {
331733965Sjdp      while (chain != (bfd_chain_type *) NULL)
331833965Sjdp	{
331933965Sjdp	  bfd *entry = chain->this;
332033965Sjdp	  ieee_data_type *entry_ieee = IEEE_DATA (entry);
332133965Sjdp	  if (entry_ieee->w.r.debug_information_part)
332233965Sjdp	    {
332333965Sjdp	      if (bfd_seek (entry, entry_ieee->w.r.debug_information_part,
332489857Sobrien			    SEEK_SET) != 0)
332533965Sjdp		return false;
332633965Sjdp	      relocate_debug (abfd, entry);
332733965Sjdp	    }
332833965Sjdp
332933965Sjdp	  chain = chain->next;
333033965Sjdp	}
333133965Sjdp      if (some_debug)
333233965Sjdp	{
333333965Sjdp	  ieee->w.r.debug_information_part = here;
333433965Sjdp	}
333533965Sjdp      else
333633965Sjdp	{
333733965Sjdp	  ieee->w.r.debug_information_part = 0;
333833965Sjdp	}
333933965Sjdp
334033965Sjdp      flush ();
334133965Sjdp    }
334233965Sjdp
334333965Sjdp  return true;
334433965Sjdp}
334533965Sjdp
334633965Sjdp/* Write the data in an ieee way.  */
334733965Sjdp
334833965Sjdpstatic boolean
334933965Sjdpieee_write_data_part (abfd)
335033965Sjdp     bfd *abfd;
335133965Sjdp{
335233965Sjdp  asection *s;
335333965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
335433965Sjdp  ieee->w.r.data_part = bfd_tell (abfd);
335533965Sjdp  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
335633965Sjdp    {
335733965Sjdp      /* Skip sections that have no loadable contents (.bss,
335833965Sjdp         debugging, etc.)  */
335933965Sjdp      if ((s->flags & SEC_LOAD) == 0)
336033965Sjdp	continue;
336133965Sjdp
336233965Sjdp      /* Sort the reloc records so we can insert them in the correct
336333965Sjdp	 places */
336433965Sjdp      if (s->reloc_count != 0)
336533965Sjdp	{
336633965Sjdp	  if (! do_with_relocs (abfd, s))
336733965Sjdp	    return false;
336833965Sjdp	}
336933965Sjdp      else
337033965Sjdp	{
337133965Sjdp	  if (! do_without_relocs (abfd, s))
337233965Sjdp	    return false;
337333965Sjdp	}
337433965Sjdp    }
337533965Sjdp
337633965Sjdp  return true;
337733965Sjdp}
337833965Sjdp
337933965Sjdp
338033965Sjdpstatic boolean
338133965Sjdpinit_for_output (abfd)
338233965Sjdp     bfd *abfd;
338333965Sjdp{
338433965Sjdp  asection *s;
338533965Sjdp  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
338633965Sjdp    {
338733965Sjdp      if ((s->flags & SEC_DEBUGGING) != 0)
338833965Sjdp	continue;
338933965Sjdp      if (s->_raw_size != 0)
339033965Sjdp	{
339189857Sobrien	  bfd_size_type size = s->_raw_size;
339289857Sobrien	  ieee_per_section (s)->data = (bfd_byte *) (bfd_alloc (abfd, size));
339333965Sjdp	  if (!ieee_per_section (s)->data)
339433965Sjdp	    return false;
339533965Sjdp	}
339633965Sjdp    }
339733965Sjdp  return true;
339833965Sjdp}
339933965Sjdp
340033965Sjdp/** exec and core file sections */
340133965Sjdp
340233965Sjdp/* set section contents is complicated with IEEE since the format is
340333965Sjdp* not a byte image, but a record stream.
340433965Sjdp*/
340589857Sobrienstatic boolean
340633965Sjdpieee_set_section_contents (abfd, section, location, offset, count)
340733965Sjdp     bfd *abfd;
340833965Sjdp     sec_ptr section;
340933965Sjdp     PTR location;
341033965Sjdp     file_ptr offset;
341133965Sjdp     bfd_size_type count;
341233965Sjdp{
341333965Sjdp  if ((section->flags & SEC_DEBUGGING) != 0)
341433965Sjdp    {
341533965Sjdp      if (section->contents == NULL)
341633965Sjdp	{
341789857Sobrien	  bfd_size_type size = section->_raw_size;
341889857Sobrien	  section->contents = (unsigned char *) bfd_alloc (abfd, size);
341933965Sjdp	  if (section->contents == NULL)
342033965Sjdp	    return false;
342133965Sjdp	}
342233965Sjdp      /* bfd_set_section_contents has already checked that everything
342333965Sjdp         is within range.  */
342489857Sobrien      memcpy (section->contents + offset, location, (size_t) count);
342533965Sjdp      return true;
342633965Sjdp    }
342733965Sjdp
342833965Sjdp  if (ieee_per_section (section)->data == (bfd_byte *) NULL)
342933965Sjdp    {
343033965Sjdp      if (!init_for_output (abfd))
343133965Sjdp	return false;
343233965Sjdp    }
343333965Sjdp  memcpy ((PTR) (ieee_per_section (section)->data + offset),
343433965Sjdp	  (PTR) location,
343533965Sjdp	  (unsigned int) count);
343633965Sjdp  return true;
343733965Sjdp}
343833965Sjdp
343933965Sjdp/* Write the external symbols of a file.  IEEE considers two sorts of
344033965Sjdp   external symbols, public, and referenced.  It uses to internal
344133965Sjdp   forms to index them as well.  When we write them out we turn their
344233965Sjdp   symbol values into indexes from the right base.  */
344333965Sjdp
344433965Sjdpstatic boolean
344533965Sjdpieee_write_external_part (abfd)
344633965Sjdp     bfd *abfd;
344733965Sjdp{
344833965Sjdp  asymbol **q;
344933965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
345033965Sjdp
345133965Sjdp  unsigned int reference_index = IEEE_REFERENCE_BASE;
345233965Sjdp  unsigned int public_index = IEEE_PUBLIC_BASE + 2;
345333965Sjdp  file_ptr here = bfd_tell (abfd);
345433965Sjdp  boolean hadone = false;
345533965Sjdp  if (abfd->outsymbols != (asymbol **) NULL)
345633965Sjdp    {
345733965Sjdp
345833965Sjdp      for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++)
345933965Sjdp	{
346033965Sjdp	  asymbol *p = *q;
346133965Sjdp	  if (bfd_is_und_section (p->section))
346233965Sjdp	    {
346333965Sjdp	      /* This must be a symbol reference .. */
346433965Sjdp	      if (! ieee_write_byte (abfd, ieee_external_reference_enum)
346589857Sobrien		  || ! ieee_write_int (abfd, (bfd_vma) reference_index)
346633965Sjdp		  || ! ieee_write_id (abfd, p->name))
346733965Sjdp		return false;
346833965Sjdp	      p->value = reference_index;
346933965Sjdp	      reference_index++;
347033965Sjdp	      hadone = true;
347133965Sjdp	    }
347233965Sjdp	  else if (bfd_is_com_section (p->section))
347333965Sjdp	    {
347433965Sjdp	      /* This is a weak reference */
347533965Sjdp	      if (! ieee_write_byte (abfd, ieee_external_reference_enum)
347689857Sobrien		  || ! ieee_write_int (abfd, (bfd_vma) reference_index)
347733965Sjdp		  || ! ieee_write_id (abfd, p->name)
347833965Sjdp		  || ! ieee_write_byte (abfd,
347933965Sjdp					ieee_weak_external_reference_enum)
348089857Sobrien		  || ! ieee_write_int (abfd, (bfd_vma) reference_index)
348133965Sjdp		  || ! ieee_write_int (abfd, p->value))
348233965Sjdp		return false;
348333965Sjdp	      p->value = reference_index;
348433965Sjdp	      reference_index++;
348533965Sjdp	      hadone = true;
348633965Sjdp	    }
348733965Sjdp	  else if (p->flags & BSF_GLOBAL)
348833965Sjdp	    {
348933965Sjdp	      /* This must be a symbol definition */
349033965Sjdp
349133965Sjdp	      if (! ieee_write_byte (abfd, ieee_external_symbol_enum)
349289857Sobrien		  || ! ieee_write_int (abfd, (bfd_vma) public_index)
349333965Sjdp		  || ! ieee_write_id (abfd, p->name)
349433965Sjdp		  || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum)
349589857Sobrien		  || ! ieee_write_int (abfd, (bfd_vma) public_index)
349633965Sjdp		  || ! ieee_write_byte (abfd, 15) /* instruction address */
349733965Sjdp		  || ! ieee_write_byte (abfd, 19) /* static symbol */
349833965Sjdp		  || ! ieee_write_byte (abfd, 1)) /* one of them */
349933965Sjdp		return false;
350033965Sjdp
350133965Sjdp	      /* Write out the value */
350233965Sjdp	      if (! ieee_write_2bytes (abfd, ieee_value_record_enum)
350389857Sobrien		  || ! ieee_write_int (abfd, (bfd_vma) public_index))
350433965Sjdp		return false;
350533965Sjdp	      if (! bfd_is_abs_section (p->section))
350633965Sjdp		{
350733965Sjdp		  if (abfd->flags & EXEC_P)
350833965Sjdp		    {
350933965Sjdp		      /* If fully linked, then output all symbols
351033965Sjdp			 relocated */
351133965Sjdp		      if (! (ieee_write_int
351233965Sjdp			     (abfd,
351333965Sjdp			      (p->value
351433965Sjdp			       + p->section->output_offset
351533965Sjdp			       + p->section->output_section->vma))))
351633965Sjdp			return false;
351733965Sjdp		    }
351833965Sjdp		  else
351933965Sjdp		    {
352033965Sjdp		      if (! (ieee_write_expression
352133965Sjdp			     (abfd,
352233965Sjdp			      p->value + p->section->output_offset,
352333965Sjdp			      p->section->output_section->symbol,
352433965Sjdp			      false, 0)))
352533965Sjdp			return false;
352633965Sjdp		    }
352733965Sjdp		}
352833965Sjdp	      else
352933965Sjdp		{
353033965Sjdp		  if (! ieee_write_expression (abfd,
353133965Sjdp					       p->value,
353233965Sjdp					       bfd_abs_section_ptr->symbol,
353333965Sjdp					       false, 0))
353433965Sjdp		    return false;
353533965Sjdp		}
353633965Sjdp	      p->value = public_index;
353733965Sjdp	      public_index++;
353833965Sjdp	      hadone = true;
353933965Sjdp	    }
354033965Sjdp	  else
354133965Sjdp	    {
354233965Sjdp	      /* This can happen - when there are gaps in the symbols read */
354333965Sjdp	      /* from an input ieee file */
354433965Sjdp	    }
354533965Sjdp	}
354633965Sjdp    }
354733965Sjdp  if (hadone)
354833965Sjdp    ieee->w.r.external_part = here;
354933965Sjdp
355033965Sjdp  return true;
355133965Sjdp}
355233965Sjdp
355333965Sjdp
355489857Sobrienstatic const unsigned char exten[] =
355533965Sjdp{
355633965Sjdp  0xf0, 0x20, 0x00,
355733965Sjdp  0xf1, 0xce, 0x20, 0x00, 37, 3, 3,	/* Set version 3 rev 3   	*/
355833965Sjdp  0xf1, 0xce, 0x20, 0x00, 39, 2,/* keep symbol in  original case */
355933965Sjdp  0xf1, 0xce, 0x20, 0x00, 38	/* set object type relocateable to x */
356033965Sjdp};
356133965Sjdp
356289857Sobrienstatic const unsigned char envi[] =
356333965Sjdp{
356433965Sjdp  0xf0, 0x21, 0x00,
356533965Sjdp
356633965Sjdp/*    0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11,
356733965Sjdp    0x19, 0x2c,
356833965Sjdp*/
356933965Sjdp  0xf1, 0xce, 0x21, 00, 52, 0x00,	/* exec ok */
357033965Sjdp
357133965Sjdp  0xf1, 0xce, 0x21, 0, 53, 0x03,/* host unix */
357233965Sjdp/*    0xf1, 0xce, 0x21, 0, 54, 2,1,1	tool & version # */
357333965Sjdp};
357433965Sjdp
357533965Sjdpstatic boolean
357633965Sjdpieee_write_me_part (abfd)
357733965Sjdp     bfd *abfd;
357833965Sjdp{
357933965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
358033965Sjdp  ieee->w.r.trailer_part = bfd_tell (abfd);
358133965Sjdp  if (abfd->start_address)
358233965Sjdp    {
358333965Sjdp      if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum)
358433965Sjdp	  || ! ieee_write_byte (abfd, ieee_function_either_open_b_enum)
358533965Sjdp	  || ! ieee_write_int (abfd, abfd->start_address)
358633965Sjdp	  || ! ieee_write_byte (abfd, ieee_function_either_close_b_enum))
358733965Sjdp	return false;
358833965Sjdp    }
358933965Sjdp  ieee->w.r.me_record = bfd_tell (abfd);
359033965Sjdp  if (! ieee_write_byte (abfd, ieee_module_end_enum))
359133965Sjdp    return false;
359233965Sjdp  return true;
359333965Sjdp}
359433965Sjdp
359533965Sjdp/* Write out the IEEE processor ID.  */
359633965Sjdp
359733965Sjdpstatic boolean
359833965Sjdpieee_write_processor (abfd)
359933965Sjdp     bfd *abfd;
360033965Sjdp{
360133965Sjdp  const bfd_arch_info_type *arch;
360233965Sjdp
360333965Sjdp  arch = bfd_get_arch_info (abfd);
360433965Sjdp  switch (arch->arch)
360533965Sjdp    {
360633965Sjdp    default:
360733965Sjdp      if (! ieee_write_id (abfd, bfd_printable_name (abfd)))
360833965Sjdp	return false;
360933965Sjdp      break;
361033965Sjdp
361133965Sjdp    case bfd_arch_a29k:
361233965Sjdp      if (! ieee_write_id (abfd, "29000"))
361333965Sjdp	return false;
361433965Sjdp      break;
361533965Sjdp
361633965Sjdp    case bfd_arch_h8300:
361733965Sjdp      if (! ieee_write_id (abfd, "H8/300"))
361833965Sjdp	return false;
361933965Sjdp      break;
362033965Sjdp
362133965Sjdp    case bfd_arch_h8500:
362233965Sjdp      if (! ieee_write_id (abfd, "H8/500"))
362333965Sjdp	return false;
362433965Sjdp      break;
362533965Sjdp
362633965Sjdp    case bfd_arch_i960:
362733965Sjdp      switch (arch->mach)
362833965Sjdp	{
362933965Sjdp	default:
363033965Sjdp	case bfd_mach_i960_core:
363133965Sjdp	case bfd_mach_i960_ka_sa:
363233965Sjdp	  if (! ieee_write_id (abfd, "80960KA"))
363333965Sjdp	    return false;
363433965Sjdp	  break;
363533965Sjdp
363633965Sjdp	case bfd_mach_i960_kb_sb:
363733965Sjdp	  if (! ieee_write_id (abfd, "80960KB"))
363833965Sjdp	    return false;
363933965Sjdp	  break;
364033965Sjdp
364133965Sjdp	case bfd_mach_i960_ca:
364233965Sjdp	  if (! ieee_write_id (abfd, "80960CA"))
364333965Sjdp	    return false;
364433965Sjdp	  break;
364533965Sjdp
364633965Sjdp	case bfd_mach_i960_mc:
364733965Sjdp	case bfd_mach_i960_xa:
364833965Sjdp	  if (! ieee_write_id (abfd, "80960MC"))
364933965Sjdp	    return false;
365033965Sjdp	  break;
365133965Sjdp	}
365233965Sjdp      break;
365333965Sjdp
365433965Sjdp    case bfd_arch_m68k:
365533965Sjdp      {
365660484Sobrien	const char *id;
365733965Sjdp
365860484Sobrien	switch (arch->mach)
365960484Sobrien	  {
366060484Sobrien	  default:		id = "68020"; break;
366160484Sobrien	  case bfd_mach_m68000: id = "68000"; break;
366260484Sobrien	  case bfd_mach_m68008: id = "68008"; break;
366360484Sobrien	  case bfd_mach_m68010: id = "68010"; break;
366460484Sobrien	  case bfd_mach_m68020: id = "68020"; break;
366560484Sobrien	  case bfd_mach_m68030: id = "68030"; break;
366660484Sobrien	  case bfd_mach_m68040: id = "68040"; break;
366760484Sobrien	  case bfd_mach_m68060: id = "68060"; break;
366860484Sobrien	  case bfd_mach_cpu32:  id = "cpu32"; break;
366978828Sobrien	  case bfd_mach_mcf5200:id = "5200";  break;
367078828Sobrien	  case bfd_mach_mcf5206e:id = "5206e"; break;
367178828Sobrien	  case bfd_mach_mcf5307:id = "5307";  break;
367278828Sobrien	  case bfd_mach_mcf5407:id = "5407";  break;
367360484Sobrien	  }
367460484Sobrien
367560484Sobrien	if (! ieee_write_id (abfd, id))
367633965Sjdp	  return false;
367733965Sjdp      }
367833965Sjdp      break;
367933965Sjdp    }
368033965Sjdp
368133965Sjdp  return true;
368233965Sjdp}
368333965Sjdp
368489857Sobrienstatic boolean
368533965Sjdpieee_write_object_contents (abfd)
368633965Sjdp     bfd *abfd;
368733965Sjdp{
368833965Sjdp  ieee_data_type *ieee = IEEE_DATA (abfd);
368933965Sjdp  unsigned int i;
369033965Sjdp  file_ptr old;
369133965Sjdp
369233965Sjdp  /* Fast forward over the header area */
369333965Sjdp  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
369433965Sjdp    return false;
369533965Sjdp
369633965Sjdp  if (! ieee_write_byte (abfd, ieee_module_beginning_enum)
369733965Sjdp      || ! ieee_write_processor (abfd)
369833965Sjdp      || ! ieee_write_id (abfd, abfd->filename))
369933965Sjdp    return false;
370033965Sjdp
370133965Sjdp  /* Fast forward over the variable bits */
370233965Sjdp  if (! ieee_write_byte (abfd, ieee_address_descriptor_enum))
370333965Sjdp    return false;
370433965Sjdp
370533965Sjdp  /* Bits per MAU */
370633965Sjdp  if (! ieee_write_byte (abfd, (bfd_byte) (bfd_arch_bits_per_byte (abfd))))
370733965Sjdp    return false;
370833965Sjdp  /* MAU's per address */
370933965Sjdp  if (! ieee_write_byte (abfd,
371033965Sjdp			 (bfd_byte) (bfd_arch_bits_per_address (abfd)
371133965Sjdp				     / bfd_arch_bits_per_byte (abfd))))
371233965Sjdp    return false;
371333965Sjdp
371433965Sjdp  old = bfd_tell (abfd);
371533965Sjdp  if (bfd_seek (abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR) != 0)
371633965Sjdp    return false;
371733965Sjdp
371833965Sjdp  ieee->w.r.extension_record = bfd_tell (abfd);
371989857Sobrien  if (bfd_bwrite ((char *) exten, (bfd_size_type) sizeof (exten), abfd)
372089857Sobrien      != sizeof (exten))
372133965Sjdp    return false;
372233965Sjdp  if (abfd->flags & EXEC_P)
372333965Sjdp    {
372433965Sjdp      if (! ieee_write_byte (abfd, 0x1)) /* Absolute */
372533965Sjdp	return false;
372633965Sjdp    }
372733965Sjdp  else
372833965Sjdp    {
372933965Sjdp      if (! ieee_write_byte (abfd, 0x2)) /* Relocateable */
373033965Sjdp	return false;
373133965Sjdp    }
373233965Sjdp
373333965Sjdp  ieee->w.r.environmental_record = bfd_tell (abfd);
373489857Sobrien  if (bfd_bwrite ((char *) envi, (bfd_size_type) sizeof (envi), abfd)
373589857Sobrien      != sizeof (envi))
373633965Sjdp    return false;
373733965Sjdp
373833965Sjdp  /* The HP emulator database requires a timestamp in the file.  */
373933965Sjdp  {
374033965Sjdp    time_t now;
374133965Sjdp    const struct tm *t;
374233965Sjdp
374333965Sjdp    time (&now);
374433965Sjdp    t = (struct tm *) localtime (&now);
374533965Sjdp    if (! ieee_write_2bytes (abfd, (int) ieee_atn_record_enum)
374633965Sjdp	|| ! ieee_write_byte (abfd, 0x21)
374733965Sjdp	|| ! ieee_write_byte (abfd, 0)
374833965Sjdp	|| ! ieee_write_byte (abfd, 50)
374989857Sobrien	|| ! ieee_write_int (abfd, (bfd_vma) (t->tm_year + 1900))
375089857Sobrien	|| ! ieee_write_int (abfd, (bfd_vma) (t->tm_mon + 1))
375189857Sobrien	|| ! ieee_write_int (abfd, (bfd_vma) t->tm_mday)
375289857Sobrien	|| ! ieee_write_int (abfd, (bfd_vma) t->tm_hour)
375389857Sobrien	|| ! ieee_write_int (abfd, (bfd_vma) t->tm_min)
375489857Sobrien	|| ! ieee_write_int (abfd, (bfd_vma) t->tm_sec))
375533965Sjdp      return false;
375633965Sjdp  }
375733965Sjdp
375833965Sjdp  output_bfd = abfd;
375933965Sjdp
376033965Sjdp  flush ();
376133965Sjdp
376233965Sjdp  if (! ieee_write_section_part (abfd))
376333965Sjdp    return false;
376433965Sjdp  /* First write the symbols.  This changes their values into table
376533965Sjdp    indeces so we cant use it after this point.  */
376633965Sjdp  if (! ieee_write_external_part (abfd))
376733965Sjdp    return false;
376833965Sjdp
376933965Sjdp  /*  ieee_write_byte(abfd, ieee_record_seperator_enum);*/
377033965Sjdp
377133965Sjdp  /*  ieee_write_byte(abfd, ieee_record_seperator_enum);*/
377233965Sjdp
377333965Sjdp
377433965Sjdp  /* Write any debugs we have been told about.  */
377533965Sjdp  if (! ieee_write_debug_part (abfd))
377633965Sjdp    return false;
377733965Sjdp
377833965Sjdp  /* Can only write the data once the symbols have been written, since
377933965Sjdp     the data contains relocation information which points to the
378033965Sjdp     symbols.  */
378133965Sjdp  if (! ieee_write_data_part (abfd))
378233965Sjdp    return false;
378333965Sjdp
378433965Sjdp  /* At the end we put the end!  */
378533965Sjdp  if (! ieee_write_me_part (abfd))
378633965Sjdp    return false;
378733965Sjdp
378833965Sjdp  /* Generate the header */
378933965Sjdp  if (bfd_seek (abfd, old, SEEK_SET) != 0)
379033965Sjdp    return false;
379133965Sjdp
379233965Sjdp  for (i = 0; i < N_W_VARIABLES; i++)
379333965Sjdp    {
379433965Sjdp      if (! ieee_write_2bytes (abfd, ieee_assign_value_to_variable_enum)
379533965Sjdp	  || ! ieee_write_byte (abfd, (bfd_byte) i)
379689857Sobrien	  || ! ieee_write_int5_out (abfd, (bfd_vma) ieee->w.offset[i]))
379733965Sjdp	return false;
379833965Sjdp    }
379933965Sjdp
380033965Sjdp  return true;
380133965Sjdp}
380233965Sjdp
380333965Sjdp/* Native-level interface to symbols. */
380433965Sjdp
380533965Sjdp/* We read the symbols into a buffer, which is discarded when this
380633965Sjdp   function exits.  We read the strings into a buffer large enough to
380733965Sjdp   hold them all plus all the cached symbol entries. */
380833965Sjdp
380989857Sobrienstatic asymbol *
381033965Sjdpieee_make_empty_symbol (abfd)
381133965Sjdp     bfd *abfd;
381233965Sjdp{
381389857Sobrien  bfd_size_type amt = sizeof (ieee_symbol_type);
381489857Sobrien  ieee_symbol_type *new = (ieee_symbol_type *) bfd_zalloc (abfd, amt);
381533965Sjdp  if (!new)
381633965Sjdp    return NULL;
381733965Sjdp  new->symbol.the_bfd = abfd;
381833965Sjdp  return &new->symbol;
381933965Sjdp}
382033965Sjdp
382133965Sjdpstatic bfd *
382233965Sjdpieee_openr_next_archived_file (arch, prev)
382333965Sjdp     bfd *arch;
382433965Sjdp     bfd *prev;
382533965Sjdp{
382633965Sjdp  ieee_ar_data_type *ar = IEEE_AR_DATA (arch);
382733965Sjdp  /* take the next one from the arch state, or reset */
382833965Sjdp  if (prev == (bfd *) NULL)
382933965Sjdp    {
383033965Sjdp      /* Reset the index - the first two entries are bogus*/
383133965Sjdp      ar->element_index = 2;
383233965Sjdp    }
383333965Sjdp  while (true)
383433965Sjdp    {
383533965Sjdp      ieee_ar_obstack_type *p = ar->elements + ar->element_index;
383633965Sjdp      ar->element_index++;
383733965Sjdp      if (ar->element_index <= ar->element_count)
383833965Sjdp	{
383933965Sjdp	  if (p->file_offset != (file_ptr) 0)
384033965Sjdp	    {
384133965Sjdp	      if (p->abfd == (bfd *) NULL)
384233965Sjdp		{
384333965Sjdp		  p->abfd = _bfd_create_empty_archive_element_shell (arch);
384433965Sjdp		  p->abfd->origin = p->file_offset;
384533965Sjdp		}
384633965Sjdp	      return p->abfd;
384733965Sjdp	    }
384833965Sjdp	}
384933965Sjdp      else
385033965Sjdp	{
385133965Sjdp	  bfd_set_error (bfd_error_no_more_archived_files);
385233965Sjdp	  return (bfd *) NULL;
385333965Sjdp	}
385433965Sjdp
385533965Sjdp    }
385633965Sjdp}
385733965Sjdp
385833965Sjdpstatic boolean
385989857Sobrienieee_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
386089857Sobrien			functionname_ptr, line_ptr)
386160484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
386260484Sobrien     asection *section ATTRIBUTE_UNUSED;
386360484Sobrien     asymbol **symbols ATTRIBUTE_UNUSED;
386460484Sobrien     bfd_vma offset ATTRIBUTE_UNUSED;
386560484Sobrien     const char **filename_ptr ATTRIBUTE_UNUSED;
386660484Sobrien     const char **functionname_ptr ATTRIBUTE_UNUSED;
386760484Sobrien     unsigned int *line_ptr ATTRIBUTE_UNUSED;
386833965Sjdp{
386933965Sjdp  return false;
387033965Sjdp}
387133965Sjdp
387233965Sjdpstatic int
387333965Sjdpieee_generic_stat_arch_elt (abfd, buf)
387433965Sjdp     bfd *abfd;
387533965Sjdp     struct stat *buf;
387633965Sjdp{
387738889Sjdp  ieee_ar_data_type *ar = (ieee_ar_data_type *) NULL;
387833965Sjdp  ieee_data_type *ieee;
387933965Sjdp
388038889Sjdp  if (abfd->my_archive != NULL)
388138889Sjdp    ar = abfd->my_archive->tdata.ieee_ar_data;
388233965Sjdp  if (ar == (ieee_ar_data_type *) NULL)
388333965Sjdp    {
388433965Sjdp      bfd_set_error (bfd_error_invalid_operation);
388533965Sjdp      return -1;
388633965Sjdp    }
388733965Sjdp
388833965Sjdp  if (IEEE_DATA (abfd) == NULL)
388933965Sjdp    {
389033965Sjdp      if (ieee_object_p (abfd) == NULL)
389133965Sjdp	{
389233965Sjdp	  bfd_set_error (bfd_error_wrong_format);
389333965Sjdp	  return -1;
389433965Sjdp	}
389533965Sjdp    }
389633965Sjdp
389733965Sjdp  ieee = IEEE_DATA (abfd);
389833965Sjdp
389933965Sjdp  buf->st_size = ieee->w.r.me_record + 1;
390033965Sjdp  buf->st_mode = 0644;
390133965Sjdp  return 0;
390233965Sjdp}
390333965Sjdp
390433965Sjdpstatic int
390533965Sjdpieee_sizeof_headers (abfd, x)
390660484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
390760484Sobrien     boolean x ATTRIBUTE_UNUSED;
390833965Sjdp{
390933965Sjdp  return 0;
391033965Sjdp}
391133965Sjdp
391233965Sjdp
391333965Sjdp/* The debug info routines are never used.  */
391433965Sjdp#if 0
391533965Sjdp
391633965Sjdpstatic void
391733965Sjdpieee_bfd_debug_info_start (abfd)
391833965Sjdp     bfd *abfd;
391933965Sjdp{
392033965Sjdp
392133965Sjdp}
392233965Sjdp
392333965Sjdpstatic void
392433965Sjdpieee_bfd_debug_info_end (abfd)
392533965Sjdp     bfd *abfd;
392633965Sjdp{
392733965Sjdp
392833965Sjdp}
392933965Sjdp
393033965Sjdp
393133965Sjdp/* Add this section to the list of sections we have debug info for, to
393233965Sjdp   be ready to output it at close time
393333965Sjdp   */
393433965Sjdpstatic void
393533965Sjdpieee_bfd_debug_info_accumulate (abfd, section)
393633965Sjdp     bfd *abfd;
393733965Sjdp     asection *section;
393833965Sjdp{
393933965Sjdp  ieee_data_type *ieee = IEEE_DATA (section->owner);
394033965Sjdp  ieee_data_type *output_ieee = IEEE_DATA (abfd);
394133965Sjdp  /* can only accumulate data from other ieee bfds */
394233965Sjdp  if (section->owner->xvec != abfd->xvec)
394333965Sjdp    return;
394433965Sjdp  /* Only bother once per bfd */
3945104834Sobrien  if (ieee->done_debug)
394633965Sjdp    return;
394733965Sjdp  ieee->done_debug = true;
394833965Sjdp
394933965Sjdp  /* Don't bother if there is no debug info */
395033965Sjdp  if (ieee->w.r.debug_information_part == 0)
395133965Sjdp    return;
395233965Sjdp
395333965Sjdp
395433965Sjdp  /* Add to chain */
395533965Sjdp  {
395689857Sobrien    bfd_size_type amt = sizeof (bfd_chain_type);
395789857Sobrien    bfd_chain_type *n = (bfd_chain_type *) bfd_alloc (abfd, amt);
395833965Sjdp    if (!n)
395933965Sjdp      abort ();		/* FIXME */
396033965Sjdp    n->this = section->owner;
396133965Sjdp    n->next = (bfd_chain_type *) NULL;
396233965Sjdp
396333965Sjdp    if (output_ieee->chain_head)
396433965Sjdp      {
396533965Sjdp	output_ieee->chain_head->next = n;
396633965Sjdp      }
396733965Sjdp    else
396833965Sjdp      {
396933965Sjdp	output_ieee->chain_root = n;
397033965Sjdp
397133965Sjdp      }
397233965Sjdp    output_ieee->chain_head = n;
397333965Sjdp  }
397433965Sjdp}
397533965Sjdp
397633965Sjdp#endif
397733965Sjdp
397833965Sjdp#define	ieee_close_and_cleanup _bfd_generic_close_and_cleanup
397933965Sjdp#define ieee_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
398033965Sjdp
398133965Sjdp#define ieee_slurp_armap bfd_true
398233965Sjdp#define ieee_slurp_extended_name_table bfd_true
398333965Sjdp#define ieee_construct_extended_name_table \
398433965Sjdp  ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
398533965Sjdp   bfd_true)
398633965Sjdp#define ieee_truncate_arname bfd_dont_truncate_arname
398733965Sjdp#define ieee_write_armap \
398833965Sjdp  ((boolean (*) \
398933965Sjdp    PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
399033965Sjdp   bfd_true)
399133965Sjdp#define ieee_read_ar_hdr bfd_nullvoidptr
399233965Sjdp#define ieee_update_armap_timestamp bfd_true
399333965Sjdp#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index
399433965Sjdp
399533965Sjdp#define ieee_bfd_is_local_label_name bfd_generic_is_local_label_name
399633965Sjdp#define ieee_get_lineno _bfd_nosymbols_get_lineno
399733965Sjdp#define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
399833965Sjdp#define ieee_read_minisymbols _bfd_generic_read_minisymbols
399933965Sjdp#define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
400033965Sjdp
400133965Sjdp#define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
400233965Sjdp
400333965Sjdp#define ieee_set_arch_mach _bfd_generic_set_arch_mach
400433965Sjdp
400533965Sjdp#define ieee_get_section_contents_in_window \
400633965Sjdp  _bfd_generic_get_section_contents_in_window
400733965Sjdp#define ieee_bfd_get_relocated_section_contents \
400833965Sjdp  bfd_generic_get_relocated_section_contents
400933965Sjdp#define ieee_bfd_relax_section bfd_generic_relax_section
401060484Sobrien#define ieee_bfd_gc_sections bfd_generic_gc_sections
401189857Sobrien#define ieee_bfd_merge_sections bfd_generic_merge_sections
4012104834Sobrien#define ieee_bfd_discard_group bfd_generic_discard_group
401333965Sjdp#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
4014104834Sobrien#define ieee_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
401533965Sjdp#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols
4016104834Sobrien#define ieee_bfd_link_just_syms _bfd_generic_link_just_syms
401733965Sjdp#define ieee_bfd_final_link _bfd_generic_final_link
401833965Sjdp#define ieee_bfd_link_split_section  _bfd_generic_link_split_section
401933965Sjdp
402033965Sjdp/*SUPPRESS 460 */
402133965Sjdpconst bfd_target ieee_vec =
402233965Sjdp{
402333965Sjdp  "ieee",			/* name */
402433965Sjdp  bfd_target_ieee_flavour,
402533965Sjdp  BFD_ENDIAN_UNKNOWN,		/* target byte order */
402633965Sjdp  BFD_ENDIAN_UNKNOWN,		/* target headers byte order */
402733965Sjdp  (HAS_RELOC | EXEC_P |		/* object flags */
402833965Sjdp   HAS_LINENO | HAS_DEBUG |
402933965Sjdp   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
403033965Sjdp  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
403133965Sjdp   | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* section flags */
403233965Sjdp  '_',				/* leading underscore */
403333965Sjdp  ' ',				/* ar_pad_char */
403433965Sjdp  16,				/* ar_max_namelen */
403533965Sjdp  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
403633965Sjdp  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
403733965Sjdp  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* data */
403833965Sjdp  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
403933965Sjdp  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
404033965Sjdp  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* hdrs */
404133965Sjdp
404233965Sjdp  {_bfd_dummy_target,
404333965Sjdp   ieee_object_p,		/* bfd_check_format */
404433965Sjdp   ieee_archive_p,
404533965Sjdp   _bfd_dummy_target,
404633965Sjdp  },
404733965Sjdp  {
404833965Sjdp    bfd_false,
404933965Sjdp    ieee_mkobject,
405033965Sjdp    _bfd_generic_mkarchive,
405133965Sjdp    bfd_false
405233965Sjdp  },
405333965Sjdp  {
405433965Sjdp    bfd_false,
405533965Sjdp    ieee_write_object_contents,
405633965Sjdp    _bfd_write_archive_contents,
405733965Sjdp    bfd_false,
405833965Sjdp  },
405933965Sjdp
406089857Sobrien  /* ieee_close_and_cleanup, ieee_bfd_free_cached_info, ieee_new_section_hook,
406189857Sobrien     ieee_get_section_contents, ieee_get_section_contents_in_window  */
406233965Sjdp  BFD_JUMP_TABLE_GENERIC (ieee),
406389857Sobrien
406433965Sjdp  BFD_JUMP_TABLE_COPY (_bfd_generic),
406533965Sjdp  BFD_JUMP_TABLE_CORE (_bfd_nocore),
406689857Sobrien
406789857Sobrien  /* ieee_slurp_armap, ieee_slurp_extended_name_table,
406889857Sobrien     ieee_construct_extended_name_table, ieee_truncate_arname,
406989857Sobrien     ieee_write_armap, ieee_read_ar_hdr, ieee_openr_next_archived_file,
407089857Sobrien     ieee_get_elt_at_index, ieee_generic_stat_arch_elt,
407189857Sobrien     ieee_update_armap_timestamp  */
407233965Sjdp  BFD_JUMP_TABLE_ARCHIVE (ieee),
407389857Sobrien
407489857Sobrien  /* ieee_get_symtab_upper_bound, ieee_get_symtab, ieee_make_empty_symbol,
407589857Sobrien     ieee_print_symbol, ieee_get_symbol_info, ieee_bfd_is_local_label_name,
407689857Sobrien     ieee_get_lineno, ieee_find_nearest_line, ieee_bfd_make_debug_symbol,
407789857Sobrien     ieee_read_minisymbols, ieee_minisymbol_to_symbol  */
407833965Sjdp  BFD_JUMP_TABLE_SYMBOLS (ieee),
407989857Sobrien
408089857Sobrien  /* ieee_get_reloc_upper_bound, ieee_canonicalize_reloc,
408189857Sobrien     ieee_bfd_reloc_type_lookup  */
408233965Sjdp  BFD_JUMP_TABLE_RELOCS (ieee),
408389857Sobrien
408489857Sobrien  /* ieee_set_arch_mach, ieee_set_section_contents  */
408533965Sjdp  BFD_JUMP_TABLE_WRITE (ieee),
408689857Sobrien
408789857Sobrien  /* ieee_sizeof_headers, ieee_bfd_get_relocated_section_contents,
408889857Sobrien     ieee_bfd_relax_section, ieee_bfd_link_hash_table_create,
4089104834Sobrien     _bfd_generic_link_hash_table_free,
409089857Sobrien     ieee_bfd_link_add_symbols, ieee_bfd_final_link,
409189857Sobrien     ieee_bfd_link_split_section, ieee_bfd_gc_sections,
409289857Sobrien     ieee_bfd_merge_sections  */
409333965Sjdp  BFD_JUMP_TABLE_LINK (ieee),
409489857Sobrien
409533965Sjdp  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
409633965Sjdp
409760484Sobrien  NULL,
409889857Sobrien
409933965Sjdp  (PTR) 0
410033965Sjdp};
4101