xref: /openbsd-src/gnu/usr.bin/binutils/bfd/ieee.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
12159047fSniklas /* BFD back-end for ieee-695 objects.
2b55d4692Sfgsch    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3c074d1c9Sdrahn    2000, 2001, 2002, 2003
4b305b0f1Sespie    Free Software Foundation, Inc.
5b305b0f1Sespie 
62159047fSniklas    Written by Steve Chamberlain of Cygnus Support.
72159047fSniklas 
82159047fSniklas    This file is part of BFD, the Binary File Descriptor library.
92159047fSniklas 
102159047fSniklas    This program is free software; you can redistribute it and/or modify
112159047fSniklas    it under the terms of the GNU General Public License as published by
122159047fSniklas    the Free Software Foundation; either version 2 of the License, or
132159047fSniklas    (at your option) any later version.
142159047fSniklas 
152159047fSniklas    This program is distributed in the hope that it will be useful,
162159047fSniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
172159047fSniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
182159047fSniklas    GNU General Public License for more details.
192159047fSniklas 
202159047fSniklas    You should have received a copy of the GNU General Public License
212159047fSniklas    along with this program; if not, write to the Free Software
222159047fSniklas    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
232159047fSniklas 
242159047fSniklas #define KEEPMINUSPCININST 0
252159047fSniklas 
262159047fSniklas /* IEEE 695 format is a stream of records, which we parse using a simple one-
272159047fSniklas    token (which is one byte in this lexicon) lookahead recursive decent
282159047fSniklas    parser.  */
292159047fSniklas 
302159047fSniklas #include "bfd.h"
312159047fSniklas #include "sysdep.h"
322159047fSniklas #include "libbfd.h"
332159047fSniklas #include "ieee.h"
342159047fSniklas #include "libieee.h"
35c074d1c9Sdrahn #include "safe-ctype.h"
36c88b1d6cSniklas 
37c074d1c9Sdrahn struct output_buffer_struct
38c074d1c9Sdrahn {
39c074d1c9Sdrahn   unsigned char *ptrp;
40c074d1c9Sdrahn   int buffer;
41c074d1c9Sdrahn };
42b305b0f1Sespie 
43c074d1c9Sdrahn static bfd_boolean ieee_write_byte
44c074d1c9Sdrahn   PARAMS ((bfd *, int));
45c074d1c9Sdrahn static bfd_boolean ieee_write_2bytes
46c074d1c9Sdrahn   PARAMS ((bfd *, int));
47c074d1c9Sdrahn static bfd_boolean ieee_write_int
48c074d1c9Sdrahn   PARAMS ((bfd *, bfd_vma));
49c074d1c9Sdrahn static bfd_boolean ieee_write_id
50c074d1c9Sdrahn   PARAMS ((bfd *, const char *));
51c074d1c9Sdrahn static unsigned short read_2bytes
52c074d1c9Sdrahn   PARAMS ((common_header_type *));
53c074d1c9Sdrahn static void bfd_get_string
54c074d1c9Sdrahn   PARAMS ((common_header_type *, char *, size_t));
55c074d1c9Sdrahn static char *read_id
56c074d1c9Sdrahn   PARAMS ((common_header_type *));
57c074d1c9Sdrahn static bfd_boolean ieee_write_expression
58c074d1c9Sdrahn   PARAMS ((bfd *, bfd_vma, asymbol *, bfd_boolean, unsigned int));
59c074d1c9Sdrahn static void ieee_write_int5
60c074d1c9Sdrahn   PARAMS ((bfd_byte *, bfd_vma));
61c074d1c9Sdrahn static bfd_boolean ieee_write_int5_out
62c074d1c9Sdrahn   PARAMS ((bfd *, bfd_vma));
63c074d1c9Sdrahn static bfd_boolean parse_int
64c074d1c9Sdrahn   PARAMS ((common_header_type *, bfd_vma *));
65c074d1c9Sdrahn static int parse_i
66c074d1c9Sdrahn   PARAMS ((common_header_type *, bfd_boolean *));
67c074d1c9Sdrahn static bfd_vma must_parse_int
68c074d1c9Sdrahn   PARAMS ((common_header_type *));
69c074d1c9Sdrahn static void parse_expression
70c074d1c9Sdrahn   PARAMS ((ieee_data_type *, bfd_vma *, ieee_symbol_index_type *,
71c074d1c9Sdrahn 	   bfd_boolean *, unsigned int *, asection **));
72c074d1c9Sdrahn static file_ptr ieee_part_after
73c074d1c9Sdrahn   PARAMS ((ieee_data_type *, file_ptr));
74c074d1c9Sdrahn static ieee_symbol_type *get_symbol
75c074d1c9Sdrahn   PARAMS ((bfd *, ieee_data_type *, ieee_symbol_type *, unsigned int *,
76c074d1c9Sdrahn 	   ieee_symbol_type ***, unsigned int *, int));
77c074d1c9Sdrahn static bfd_boolean ieee_slurp_external_symbols
78c074d1c9Sdrahn   PARAMS ((bfd *));
79c074d1c9Sdrahn static bfd_boolean ieee_slurp_symbol_table
80c074d1c9Sdrahn   PARAMS ((bfd *));
81c074d1c9Sdrahn static long ieee_get_symtab_upper_bound
82c074d1c9Sdrahn   PARAMS ((bfd *));
83*007c2a45Smiod static long ieee_canonicalize_symtab
84c074d1c9Sdrahn   PARAMS ((bfd *, asymbol **));
85c074d1c9Sdrahn static asection *get_section_entry
86c074d1c9Sdrahn   PARAMS ((bfd *, ieee_data_type *i, unsigned int));
87c074d1c9Sdrahn static void ieee_slurp_sections
88c074d1c9Sdrahn   PARAMS ((bfd *));
89c074d1c9Sdrahn static bfd_boolean ieee_slurp_debug
90c074d1c9Sdrahn   PARAMS ((bfd *));
91c074d1c9Sdrahn const bfd_target *ieee_archive_p
92c074d1c9Sdrahn   PARAMS ((bfd *));
93c074d1c9Sdrahn const bfd_target *ieee_object_p
94c074d1c9Sdrahn   PARAMS ((bfd *));
95c074d1c9Sdrahn static void ieee_get_symbol_info
96c074d1c9Sdrahn   PARAMS ((bfd *, asymbol *, symbol_info *));
97c074d1c9Sdrahn static void ieee_print_symbol
98c074d1c9Sdrahn   PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
99c074d1c9Sdrahn static bfd_boolean do_one
100c074d1c9Sdrahn   PARAMS ((ieee_data_type *, ieee_per_section_type *, unsigned char *,
101c074d1c9Sdrahn 	   asection *, int));
102c074d1c9Sdrahn static bfd_boolean ieee_slurp_section_data
103c074d1c9Sdrahn   PARAMS ((bfd *));
104c074d1c9Sdrahn static bfd_boolean ieee_new_section_hook
105c074d1c9Sdrahn   PARAMS ((bfd *, asection *));
106c074d1c9Sdrahn static long ieee_get_reloc_upper_bound
107c074d1c9Sdrahn   PARAMS ((bfd *, sec_ptr));
108c074d1c9Sdrahn static bfd_boolean ieee_get_section_contents
109c074d1c9Sdrahn   PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
110c074d1c9Sdrahn static long ieee_canonicalize_reloc
111c074d1c9Sdrahn   PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
112c074d1c9Sdrahn static int comp
113c074d1c9Sdrahn   PARAMS ((const PTR, const PTR));
114c074d1c9Sdrahn static bfd_boolean ieee_write_section_part
115c074d1c9Sdrahn   PARAMS ((bfd *));
116c074d1c9Sdrahn static bfd_boolean do_with_relocs
117c074d1c9Sdrahn   PARAMS ((bfd *, asection *));
118c074d1c9Sdrahn static bfd_boolean do_as_repeat
119c074d1c9Sdrahn   PARAMS ((bfd *, asection *));
120c074d1c9Sdrahn static bfd_boolean do_without_relocs
121c074d1c9Sdrahn   PARAMS ((bfd *, asection *));
122c074d1c9Sdrahn static bfd_boolean ieee_mkobject
123c074d1c9Sdrahn   PARAMS ((bfd *));
124c074d1c9Sdrahn static void fill
125c074d1c9Sdrahn   PARAMS ((void));
126c074d1c9Sdrahn static void flush
127c074d1c9Sdrahn   PARAMS ((void));
128c074d1c9Sdrahn static void write_int
129c074d1c9Sdrahn   PARAMS ((int));
130c074d1c9Sdrahn static void copy_id
131c074d1c9Sdrahn   PARAMS ((void));
132c074d1c9Sdrahn static void copy_expression
133c074d1c9Sdrahn   PARAMS ((void));
134c074d1c9Sdrahn static void fill_int
135c074d1c9Sdrahn   PARAMS ((struct output_buffer_struct *));
136c074d1c9Sdrahn static void drop_int
137c074d1c9Sdrahn   PARAMS ((struct output_buffer_struct *));
138c074d1c9Sdrahn static void copy_int
139c074d1c9Sdrahn   PARAMS ((void));
140c074d1c9Sdrahn static void f1_record
141c074d1c9Sdrahn   PARAMS ((void));
142c074d1c9Sdrahn static void f0_record
143c074d1c9Sdrahn   PARAMS ((void));
144c074d1c9Sdrahn static void copy_till_end
145c074d1c9Sdrahn   PARAMS ((void));
146c074d1c9Sdrahn static void f2_record
147c074d1c9Sdrahn   PARAMS ((void));
148c074d1c9Sdrahn static void f8_record
149c074d1c9Sdrahn   PARAMS ((void));
150c074d1c9Sdrahn static void e2_record
151c074d1c9Sdrahn   PARAMS ((void));
152c074d1c9Sdrahn static void block
153c074d1c9Sdrahn   PARAMS ((void));
154c074d1c9Sdrahn static void relocate_debug
155c074d1c9Sdrahn   PARAMS ((bfd *, bfd *));
156c074d1c9Sdrahn static bfd_boolean ieee_write_debug_part
157c074d1c9Sdrahn   PARAMS ((bfd *));
158c074d1c9Sdrahn static bfd_boolean ieee_write_data_part
159c074d1c9Sdrahn   PARAMS ((bfd *));
160c074d1c9Sdrahn static bfd_boolean init_for_output
161c074d1c9Sdrahn   PARAMS ((bfd *));
162c074d1c9Sdrahn static bfd_boolean ieee_set_section_contents
163*007c2a45Smiod   PARAMS ((bfd *, sec_ptr, const PTR, file_ptr, bfd_size_type));
164c074d1c9Sdrahn static bfd_boolean ieee_write_external_part
165c074d1c9Sdrahn   PARAMS ((bfd *));
166c074d1c9Sdrahn static bfd_boolean ieee_write_me_part
167c074d1c9Sdrahn   PARAMS ((bfd *));
168c074d1c9Sdrahn static bfd_boolean ieee_write_processor
169c074d1c9Sdrahn   PARAMS ((bfd *));
170c074d1c9Sdrahn static bfd_boolean ieee_write_object_contents
171c074d1c9Sdrahn   PARAMS ((bfd *));
172c074d1c9Sdrahn static asymbol *ieee_make_empty_symbol
173c074d1c9Sdrahn   PARAMS ((bfd *));
174c074d1c9Sdrahn static bfd *ieee_openr_next_archived_file
175c074d1c9Sdrahn   PARAMS ((bfd *, bfd *));
176c074d1c9Sdrahn static bfd_boolean ieee_find_nearest_line
177c074d1c9Sdrahn   PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **,
178c074d1c9Sdrahn 	   const char **, unsigned int *));
179c074d1c9Sdrahn static int ieee_generic_stat_arch_elt
180c074d1c9Sdrahn   PARAMS ((bfd *, struct stat *));
181c074d1c9Sdrahn static int ieee_sizeof_headers
182c074d1c9Sdrahn   PARAMS ((bfd *, bfd_boolean));
1832159047fSniklas 
1842159047fSniklas /* Functions for writing to ieee files in the strange way that the
1852159047fSniklas    standard requires. */
1862159047fSniklas 
187c074d1c9Sdrahn static bfd_boolean
ieee_write_byte(abfd,barg)188c88b1d6cSniklas ieee_write_byte (abfd, barg)
1892159047fSniklas      bfd *abfd;
190c88b1d6cSniklas      int barg;
191c88b1d6cSniklas {
1922159047fSniklas   bfd_byte byte;
193c88b1d6cSniklas 
194c88b1d6cSniklas   byte = barg;
195c074d1c9Sdrahn   if (bfd_bwrite ((PTR) &byte, (bfd_size_type) 1, abfd) != 1)
196c074d1c9Sdrahn     return FALSE;
197c074d1c9Sdrahn   return TRUE;
1982159047fSniklas }
1992159047fSniklas 
200c074d1c9Sdrahn static bfd_boolean
ieee_write_2bytes(abfd,bytes)2012159047fSniklas ieee_write_2bytes (abfd, bytes)
2022159047fSniklas      bfd *abfd;
2032159047fSniklas      int bytes;
2042159047fSniklas {
2052159047fSniklas   bfd_byte buffer[2];
206c88b1d6cSniklas 
2072159047fSniklas   buffer[0] = bytes >> 8;
2082159047fSniklas   buffer[1] = bytes & 0xff;
209c074d1c9Sdrahn   if (bfd_bwrite ((PTR) buffer, (bfd_size_type) 2, abfd) != 2)
210c074d1c9Sdrahn     return FALSE;
211c074d1c9Sdrahn   return TRUE;
2122159047fSniklas }
2132159047fSniklas 
214c074d1c9Sdrahn static bfd_boolean
ieee_write_int(abfd,value)2152159047fSniklas ieee_write_int (abfd, value)
2162159047fSniklas      bfd *abfd;
2172159047fSniklas      bfd_vma value;
2182159047fSniklas {
219c88b1d6cSniklas   if (value <= 127)
2202159047fSniklas     {
221c88b1d6cSniklas       if (! ieee_write_byte (abfd, (bfd_byte) value))
222c074d1c9Sdrahn 	return FALSE;
2232159047fSniklas     }
2242159047fSniklas   else
2252159047fSniklas     {
2262159047fSniklas       unsigned int length;
227c88b1d6cSniklas 
2282159047fSniklas       /* How many significant bytes ?  */
229c074d1c9Sdrahn       /* FIXME FOR LONGER INTS.  */
2302159047fSniklas       if (value & 0xff000000)
2312159047fSniklas 	length = 4;
2322159047fSniklas       else if (value & 0x00ff0000)
2332159047fSniklas 	length = 3;
2342159047fSniklas       else if (value & 0x0000ff00)
2352159047fSniklas 	length = 2;
2362159047fSniklas       else
2372159047fSniklas 	length = 1;
2382159047fSniklas 
239c88b1d6cSniklas       if (! ieee_write_byte (abfd,
240c88b1d6cSniklas 			     (bfd_byte) ((int) ieee_number_repeat_start_enum
241c88b1d6cSniklas 					 + length)))
242c074d1c9Sdrahn 	return FALSE;
2432159047fSniklas       switch (length)
2442159047fSniklas 	{
2452159047fSniklas 	case 4:
246c88b1d6cSniklas 	  if (! ieee_write_byte (abfd, (bfd_byte) (value >> 24)))
247c074d1c9Sdrahn 	    return FALSE;
248c88b1d6cSniklas 	  /* Fall through.  */
2492159047fSniklas 	case 3:
250c88b1d6cSniklas 	  if (! ieee_write_byte (abfd, (bfd_byte) (value >> 16)))
251c074d1c9Sdrahn 	    return FALSE;
252c88b1d6cSniklas 	  /* Fall through.  */
2532159047fSniklas 	case 2:
254c88b1d6cSniklas 	  if (! ieee_write_byte (abfd, (bfd_byte) (value >> 8)))
255c074d1c9Sdrahn 	    return FALSE;
256c88b1d6cSniklas 	  /* Fall through.  */
2572159047fSniklas 	case 1:
258c88b1d6cSniklas 	  if (! ieee_write_byte (abfd, (bfd_byte) (value)))
259c074d1c9Sdrahn 	    return FALSE;
2602159047fSniklas 	}
2612159047fSniklas     }
2622159047fSniklas 
263c074d1c9Sdrahn   return TRUE;
264c88b1d6cSniklas }
265c88b1d6cSniklas 
266c074d1c9Sdrahn static bfd_boolean
ieee_write_id(abfd,id)2672159047fSniklas ieee_write_id (abfd, id)
2682159047fSniklas      bfd *abfd;
269c88b1d6cSniklas      const char *id;
2702159047fSniklas {
2712159047fSniklas   size_t length = strlen (id);
272c88b1d6cSniklas 
2732159047fSniklas   if (length <= 127)
2742159047fSniklas     {
275c88b1d6cSniklas       if (! ieee_write_byte (abfd, (bfd_byte) length))
276c074d1c9Sdrahn 	return FALSE;
2772159047fSniklas     }
2782159047fSniklas   else if (length < 255)
2792159047fSniklas     {
280c88b1d6cSniklas       if (! ieee_write_byte (abfd, ieee_extension_length_1_enum)
281c88b1d6cSniklas 	  || ! ieee_write_byte (abfd, (bfd_byte) length))
282c074d1c9Sdrahn 	return FALSE;
2832159047fSniklas     }
2842159047fSniklas   else if (length < 65535)
2852159047fSniklas     {
286c88b1d6cSniklas       if (! ieee_write_byte (abfd, ieee_extension_length_2_enum)
287c88b1d6cSniklas 	  || ! ieee_write_2bytes (abfd, (int) length))
288c074d1c9Sdrahn 	return FALSE;
2892159047fSniklas     }
2902159047fSniklas   else
2912159047fSniklas     {
292c88b1d6cSniklas       (*_bfd_error_handler)
293b305b0f1Sespie 	(_("%s: string too long (%d chars, max 65535)"),
294c88b1d6cSniklas 	 bfd_get_filename (abfd), length);
295c88b1d6cSniklas       bfd_set_error (bfd_error_invalid_operation);
296c074d1c9Sdrahn       return FALSE;
2972159047fSniklas     }
298c88b1d6cSniklas 
299c074d1c9Sdrahn   if (bfd_bwrite ((PTR) id, (bfd_size_type) length, abfd) != length)
300c074d1c9Sdrahn     return FALSE;
301c074d1c9Sdrahn   return TRUE;
3022159047fSniklas }
3032159047fSniklas 
304c074d1c9Sdrahn /* Functions for reading from ieee files in the strange way that the
305c074d1c9Sdrahn    standard requires.  */
3062159047fSniklas 
3072159047fSniklas #define this_byte(ieee) *((ieee)->input_p)
3082159047fSniklas #define next_byte(ieee) ((ieee)->input_p++)
3092159047fSniklas #define this_byte_and_next(ieee) (*((ieee)->input_p++))
3102159047fSniklas 
3112159047fSniklas static unsigned short
read_2bytes(ieee)3122159047fSniklas read_2bytes (ieee)
3132159047fSniklas      common_header_type *ieee;
3142159047fSniklas {
3152159047fSniklas   unsigned char c1 = this_byte_and_next (ieee);
3162159047fSniklas   unsigned char c2 = this_byte_and_next (ieee);
317c074d1c9Sdrahn 
3182159047fSniklas   return (c1 << 8) | c2;
3192159047fSniklas }
3202159047fSniklas 
3212159047fSniklas static void
bfd_get_string(ieee,string,length)3222159047fSniklas bfd_get_string (ieee, string, length)
3232159047fSniklas      common_header_type *ieee;
3242159047fSniklas      char *string;
3252159047fSniklas      size_t length;
3262159047fSniklas {
3272159047fSniklas   size_t i;
328c074d1c9Sdrahn 
3292159047fSniklas   for (i = 0; i < length; i++)
3302159047fSniklas     string[i] = this_byte_and_next (ieee);
3312159047fSniklas }
3322159047fSniklas 
3332159047fSniklas static char *
read_id(ieee)3342159047fSniklas read_id (ieee)
3352159047fSniklas      common_header_type *ieee;
3362159047fSniklas {
3372159047fSniklas   size_t length;
3382159047fSniklas   char *string;
339c074d1c9Sdrahn 
3402159047fSniklas   length = this_byte_and_next (ieee);
3412159047fSniklas   if (length <= 0x7f)
3422159047fSniklas     {
343c074d1c9Sdrahn       /* Simple string of length 0 to 127.  */
3442159047fSniklas     }
3452159047fSniklas   else if (length == 0xde)
3462159047fSniklas     {
347c074d1c9Sdrahn       /* Length is next byte, allowing 0..255.  */
3482159047fSniklas       length = this_byte_and_next (ieee);
3492159047fSniklas     }
3502159047fSniklas   else if (length == 0xdf)
3512159047fSniklas     {
352c074d1c9Sdrahn       /* Length is next two bytes, allowing 0..65535.  */
3532159047fSniklas       length = this_byte_and_next (ieee);
3542159047fSniklas       length = (length * 256) + this_byte_and_next (ieee);
3552159047fSniklas     }
356c074d1c9Sdrahn 
357c074d1c9Sdrahn   /* Buy memory and read string.  */
358c074d1c9Sdrahn   string = bfd_alloc (ieee->abfd, (bfd_size_type) length + 1);
3592159047fSniklas   if (!string)
3602159047fSniklas     return NULL;
3612159047fSniklas   bfd_get_string (ieee, string, length);
3622159047fSniklas   string[length] = 0;
3632159047fSniklas   return string;
3642159047fSniklas }
3652159047fSniklas 
366c074d1c9Sdrahn static bfd_boolean
ieee_write_expression(abfd,value,symbol,pcrel,index)3672159047fSniklas ieee_write_expression (abfd, value, symbol, pcrel, index)
3682159047fSniklas      bfd *abfd;
3692159047fSniklas      bfd_vma value;
3702159047fSniklas      asymbol *symbol;
371c074d1c9Sdrahn      bfd_boolean pcrel;
3722159047fSniklas      unsigned int index;
3732159047fSniklas {
3742159047fSniklas   unsigned int term_count = 0;
3752159047fSniklas 
3762159047fSniklas   if (value != 0)
3772159047fSniklas     {
378c88b1d6cSniklas       if (! ieee_write_int (abfd, value))
379c074d1c9Sdrahn 	return FALSE;
3802159047fSniklas       term_count++;
3812159047fSniklas     }
3822159047fSniklas 
383c074d1c9Sdrahn   /* Badly formatted binaries can have a missing symbol,
384c074d1c9Sdrahn      so test here to prevent a seg fault.  */
385c074d1c9Sdrahn   if (symbol != NULL)
386c074d1c9Sdrahn     {
3872159047fSniklas       if (bfd_is_com_section (symbol->section)
3882159047fSniklas 	  || bfd_is_und_section (symbol->section))
3892159047fSniklas 	{
390c074d1c9Sdrahn 	  /* Def of a common symbol.  */
391c88b1d6cSniklas 	  if (! ieee_write_byte (abfd, ieee_variable_X_enum)
392c88b1d6cSniklas 	      || ! ieee_write_int (abfd, symbol->value))
393c074d1c9Sdrahn 	    return FALSE;
3942159047fSniklas 	  term_count ++;
3952159047fSniklas 	}
3962159047fSniklas       else if (! bfd_is_abs_section (symbol->section))
3972159047fSniklas 	{
3982159047fSniklas 	  /* Ref to defined symbol -  */
3992159047fSniklas 
4002159047fSniklas 	  if (symbol->flags & BSF_GLOBAL)
4012159047fSniklas 	    {
402c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_variable_I_enum)
403c88b1d6cSniklas 		  || ! ieee_write_int (abfd, symbol->value))
404c074d1c9Sdrahn 		return FALSE;
4052159047fSniklas 	      term_count++;
4062159047fSniklas 	    }
4072159047fSniklas 	  else if (symbol->flags & (BSF_LOCAL | BSF_SECTION_SYM))
4082159047fSniklas 	    {
409c88b1d6cSniklas 	      /* This is a reference to a defined local symbol.  We can
410c88b1d6cSniklas 		 easily do a local as a section+offset.  */
411c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_variable_R_enum)
412c88b1d6cSniklas 		  || ! ieee_write_byte (abfd,
413c88b1d6cSniklas 					(bfd_byte) (symbol->section->index
414c88b1d6cSniklas 						    + IEEE_SECTION_NUMBER_BASE)))
415c074d1c9Sdrahn 		return FALSE;
416c074d1c9Sdrahn 
4172159047fSniklas 	      term_count++;
418c88b1d6cSniklas 	      if (symbol->value != 0)
419c88b1d6cSniklas 		{
420c88b1d6cSniklas 		  if (! ieee_write_int (abfd, symbol->value))
421c074d1c9Sdrahn 		    return FALSE;
422c88b1d6cSniklas 		  term_count++;
423c88b1d6cSniklas 		}
4242159047fSniklas 	    }
4252159047fSniklas 	  else
4262159047fSniklas 	    {
427c88b1d6cSniklas 	      (*_bfd_error_handler)
428b305b0f1Sespie 		(_("%s: unrecognized symbol `%s' flags 0x%x"),
429c88b1d6cSniklas 		 bfd_get_filename (abfd), bfd_asymbol_name (symbol),
430c88b1d6cSniklas 		 symbol->flags);
431c88b1d6cSniklas 	      bfd_set_error (bfd_error_invalid_operation);
432c074d1c9Sdrahn 	      return FALSE;
433c074d1c9Sdrahn 	    }
4342159047fSniklas 	}
4352159047fSniklas     }
4362159047fSniklas 
4372159047fSniklas   if (pcrel)
4382159047fSniklas     {
439c074d1c9Sdrahn       /* Subtract the pc from here by asking for PC of this section.  */
440c88b1d6cSniklas       if (! ieee_write_byte (abfd, ieee_variable_P_enum)
441c88b1d6cSniklas 	  || ! ieee_write_byte (abfd,
442c88b1d6cSniklas 				(bfd_byte) (index + IEEE_SECTION_NUMBER_BASE))
443c88b1d6cSniklas 	  || ! ieee_write_byte (abfd, ieee_function_minus_enum))
444c074d1c9Sdrahn 	return FALSE;
4452159047fSniklas     }
4462159047fSniklas 
447c88b1d6cSniklas   /* Handle the degenerate case of a 0 address.  */
448c88b1d6cSniklas   if (term_count == 0)
449c074d1c9Sdrahn     if (! ieee_write_int (abfd, (bfd_vma) 0))
450c074d1c9Sdrahn       return FALSE;
451c88b1d6cSniklas 
4522159047fSniklas   while (term_count > 1)
4532159047fSniklas     {
454c88b1d6cSniklas       if (! ieee_write_byte (abfd, ieee_function_plus_enum))
455c074d1c9Sdrahn 	return FALSE;
4562159047fSniklas       term_count--;
4572159047fSniklas     }
458c88b1d6cSniklas 
459c074d1c9Sdrahn   return TRUE;
4602159047fSniklas }
4612159047fSniklas 
462c074d1c9Sdrahn /* Writes any integer into the buffer supplied and always takes 5 bytes.  */
4632159047fSniklas 
4642159047fSniklas static void
ieee_write_int5(buffer,value)4652159047fSniklas ieee_write_int5 (buffer, value)
4662159047fSniklas      bfd_byte *buffer;
4672159047fSniklas      bfd_vma value;
4682159047fSniklas {
4692159047fSniklas   buffer[0] = (bfd_byte) ieee_number_repeat_4_enum;
4702159047fSniklas   buffer[1] = (value >> 24) & 0xff;
4712159047fSniklas   buffer[2] = (value >> 16) & 0xff;
4722159047fSniklas   buffer[3] = (value >> 8) & 0xff;
4732159047fSniklas   buffer[4] = (value >> 0) & 0xff;
4742159047fSniklas }
4752159047fSniklas 
476c074d1c9Sdrahn static bfd_boolean
ieee_write_int5_out(abfd,value)4772159047fSniklas ieee_write_int5_out (abfd, value)
4782159047fSniklas      bfd *abfd;
4792159047fSniklas      bfd_vma value;
4802159047fSniklas {
4812159047fSniklas   bfd_byte b[5];
482c88b1d6cSniklas 
4832159047fSniklas   ieee_write_int5 (b, value);
484c074d1c9Sdrahn   if (bfd_bwrite ((PTR) b, (bfd_size_type) 5, abfd) != 5)
485c074d1c9Sdrahn     return FALSE;
486c074d1c9Sdrahn   return TRUE;
4872159047fSniklas }
4882159047fSniklas 
489c074d1c9Sdrahn static bfd_boolean
parse_int(ieee,value_ptr)4902159047fSniklas parse_int (ieee, value_ptr)
4912159047fSniklas      common_header_type *ieee;
4922159047fSniklas      bfd_vma *value_ptr;
4932159047fSniklas {
4942159047fSniklas   int value = this_byte (ieee);
4952159047fSniklas   int result;
496c074d1c9Sdrahn 
4972159047fSniklas   if (value >= 0 && value <= 127)
4982159047fSniklas     {
4992159047fSniklas       *value_ptr = value;
5002159047fSniklas       next_byte (ieee);
501c074d1c9Sdrahn       return TRUE;
5022159047fSniklas     }
5032159047fSniklas   else if (value >= 0x80 && value <= 0x88)
5042159047fSniklas     {
5052159047fSniklas       unsigned int count = value & 0xf;
506c074d1c9Sdrahn 
5072159047fSniklas       result = 0;
5082159047fSniklas       next_byte (ieee);
5092159047fSniklas       while (count)
5102159047fSniklas 	{
5112159047fSniklas 	  result = (result << 8) | this_byte_and_next (ieee);
5122159047fSniklas 	  count--;
5132159047fSniklas 	}
5142159047fSniklas       *value_ptr = result;
515c074d1c9Sdrahn       return TRUE;
5162159047fSniklas     }
517c074d1c9Sdrahn   return FALSE;
5182159047fSniklas }
5192159047fSniklas 
5202159047fSniklas static int
parse_i(ieee,ok)5212159047fSniklas parse_i (ieee, ok)
5222159047fSniklas      common_header_type *ieee;
523c074d1c9Sdrahn      bfd_boolean *ok;
5242159047fSniklas {
5252159047fSniklas   bfd_vma x;
5262159047fSniklas   *ok = parse_int (ieee, &x);
5272159047fSniklas   return x;
5282159047fSniklas }
5292159047fSniklas 
5302159047fSniklas static bfd_vma
must_parse_int(ieee)5312159047fSniklas must_parse_int (ieee)
5322159047fSniklas      common_header_type *ieee;
5332159047fSniklas {
5342159047fSniklas   bfd_vma result;
535c074d1c9Sdrahn   BFD_ASSERT (parse_int (ieee, &result));
5362159047fSniklas   return result;
5372159047fSniklas }
5382159047fSniklas 
5392159047fSniklas typedef struct
5402159047fSniklas {
5412159047fSniklas   bfd_vma value;
5422159047fSniklas   asection *section;
5432159047fSniklas   ieee_symbol_index_type symbol;
5442159047fSniklas } ieee_value_type;
5452159047fSniklas 
5462159047fSniklas 
547c88b1d6cSniklas #if KEEPMINUSPCININST
5482159047fSniklas 
549c88b1d6cSniklas #define SRC_MASK(arg) arg
550c074d1c9Sdrahn #define PCREL_OFFSET FALSE
5512159047fSniklas 
552c88b1d6cSniklas #else
5532159047fSniklas 
554c88b1d6cSniklas #define SRC_MASK(arg) 0
555c074d1c9Sdrahn #define PCREL_OFFSET TRUE
5562159047fSniklas 
557c88b1d6cSniklas #endif
5582159047fSniklas 
559c88b1d6cSniklas static reloc_howto_type abs32_howto =
560c88b1d6cSniklas   HOWTO (1,
561c88b1d6cSniklas 	 0,
562c88b1d6cSniklas 	 2,
563c88b1d6cSniklas 	 32,
564c074d1c9Sdrahn 	 FALSE,
565c88b1d6cSniklas 	 0,
566c88b1d6cSniklas 	 complain_overflow_bitfield,
567c88b1d6cSniklas 	 0,
568c88b1d6cSniklas 	 "abs32",
569c074d1c9Sdrahn 	 TRUE,
570c88b1d6cSniklas 	 0xffffffff,
571c88b1d6cSniklas 	 0xffffffff,
572c074d1c9Sdrahn 	 FALSE);
5732159047fSniklas 
574c88b1d6cSniklas static reloc_howto_type abs16_howto =
575c88b1d6cSniklas   HOWTO (1,
576c88b1d6cSniklas 	 0,
577c88b1d6cSniklas 	 1,
578c88b1d6cSniklas 	 16,
579c074d1c9Sdrahn 	 FALSE,
580c88b1d6cSniklas 	 0,
581c88b1d6cSniklas 	 complain_overflow_bitfield,
582c88b1d6cSniklas 	 0,
583c88b1d6cSniklas 	 "abs16",
584c074d1c9Sdrahn 	 TRUE,
585c88b1d6cSniklas 	 0x0000ffff,
586c88b1d6cSniklas 	 0x0000ffff,
587c074d1c9Sdrahn 	 FALSE);
5882159047fSniklas 
589c88b1d6cSniklas static reloc_howto_type abs8_howto =
590c88b1d6cSniklas   HOWTO (1,
591c88b1d6cSniklas 	 0,
592c88b1d6cSniklas 	 0,
593c88b1d6cSniklas 	 8,
594c074d1c9Sdrahn 	 FALSE,
595c88b1d6cSniklas 	 0,
596c88b1d6cSniklas 	 complain_overflow_bitfield,
597c88b1d6cSniklas 	 0,
598c88b1d6cSniklas 	 "abs8",
599c074d1c9Sdrahn 	 TRUE,
600c88b1d6cSniklas 	 0x000000ff,
601c88b1d6cSniklas 	 0x000000ff,
602c074d1c9Sdrahn 	 FALSE);
603c88b1d6cSniklas 
604c88b1d6cSniklas static reloc_howto_type rel32_howto =
605c88b1d6cSniklas   HOWTO (1,
606c88b1d6cSniklas 	 0,
607c88b1d6cSniklas 	 2,
608c88b1d6cSniklas 	 32,
609c074d1c9Sdrahn 	 TRUE,
610c88b1d6cSniklas 	 0,
611c88b1d6cSniklas 	 complain_overflow_signed,
612c88b1d6cSniklas 	 0,
613c88b1d6cSniklas 	 "rel32",
614c074d1c9Sdrahn 	 TRUE,
615c88b1d6cSniklas 	 SRC_MASK (0xffffffff),
616c88b1d6cSniklas 	 0xffffffff,
617c88b1d6cSniklas 	 PCREL_OFFSET);
618c88b1d6cSniklas 
619c88b1d6cSniklas static reloc_howto_type rel16_howto =
620c88b1d6cSniklas   HOWTO (1,
621c88b1d6cSniklas 	 0,
622c88b1d6cSniklas 	 1,
623c88b1d6cSniklas 	 16,
624c074d1c9Sdrahn 	 TRUE,
625c88b1d6cSniklas 	 0,
626c88b1d6cSniklas 	 complain_overflow_signed,
627c88b1d6cSniklas 	 0,
628c88b1d6cSniklas 	 "rel16",
629c074d1c9Sdrahn 	 TRUE,
630c88b1d6cSniklas 	 SRC_MASK (0x0000ffff),
631c88b1d6cSniklas 	 0x0000ffff,
632c88b1d6cSniklas 	 PCREL_OFFSET);
633c88b1d6cSniklas 
634c88b1d6cSniklas static reloc_howto_type rel8_howto =
635c88b1d6cSniklas   HOWTO (1,
636c88b1d6cSniklas 	 0,
637c88b1d6cSniklas 	 0,
638c88b1d6cSniklas 	 8,
639c074d1c9Sdrahn 	 TRUE,
640c88b1d6cSniklas 	 0,
641c88b1d6cSniklas 	 complain_overflow_signed,
642c88b1d6cSniklas 	 0,
643c88b1d6cSniklas 	 "rel8",
644c074d1c9Sdrahn 	 TRUE,
645c88b1d6cSniklas 	 SRC_MASK (0x000000ff),
646c88b1d6cSniklas 	 0x000000ff,
647c88b1d6cSniklas 	 PCREL_OFFSET);
648c88b1d6cSniklas 
649c88b1d6cSniklas static ieee_symbol_index_type NOSYMBOL = {0, 0};
6502159047fSniklas 
6512159047fSniklas static void
parse_expression(ieee,value,symbol,pcrel,extra,section)6522159047fSniklas parse_expression (ieee, value, symbol, pcrel, extra, section)
6532159047fSniklas      ieee_data_type *ieee;
6542159047fSniklas      bfd_vma *value;
6552159047fSniklas      ieee_symbol_index_type *symbol;
656c074d1c9Sdrahn      bfd_boolean *pcrel;
6572159047fSniklas      unsigned int *extra;
6582159047fSniklas      asection **section;
6592159047fSniklas 
6602159047fSniklas {
6612159047fSniklas #define POS sp[1]
6622159047fSniklas #define TOS sp[0]
6632159047fSniklas #define NOS sp[-1]
6642159047fSniklas #define INC sp++;
6652159047fSniklas #define DEC sp--;
6662159047fSniklas 
667c074d1c9Sdrahn   bfd_boolean loop = TRUE;
6682159047fSniklas   ieee_value_type stack[10];
6692159047fSniklas 
670c074d1c9Sdrahn   /* The stack pointer always points to the next unused location.  */
6712159047fSniklas #define PUSH(x,y,z) TOS.symbol=x;TOS.section=y;TOS.value=z;INC;
6722159047fSniklas #define POP(x,y,z) DEC;x=TOS.symbol;y=TOS.section;z=TOS.value;
6732159047fSniklas   ieee_value_type *sp = stack;
674c074d1c9Sdrahn   asection *dummy;
6752159047fSniklas 
676c074d1c9Sdrahn   while (loop && ieee->h.input_p < ieee->h.last_byte)
6772159047fSniklas     {
6782159047fSniklas       switch (this_byte (&(ieee->h)))
6792159047fSniklas 	{
6802159047fSniklas 	case ieee_variable_P_enum:
681c074d1c9Sdrahn 	  /* P variable, current program counter for section n.  */
6822159047fSniklas 	  {
6832159047fSniklas 	    int section_n;
684c074d1c9Sdrahn 
6852159047fSniklas 	    next_byte (&(ieee->h));
686c074d1c9Sdrahn 	    *pcrel = TRUE;
6872159047fSniklas 	    section_n = must_parse_int (&(ieee->h));
688c88b1d6cSniklas 	    PUSH (NOSYMBOL, bfd_abs_section_ptr, 0);
6892159047fSniklas 	    break;
6902159047fSniklas 	  }
6912159047fSniklas 	case ieee_variable_L_enum:
692c074d1c9Sdrahn 	  /* L variable  address of section N.  */
6932159047fSniklas 	  next_byte (&(ieee->h));
6942159047fSniklas 	  PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
6952159047fSniklas 	  break;
6962159047fSniklas 	case ieee_variable_R_enum:
697c074d1c9Sdrahn 	  /* R variable, logical address of section module.  */
698c074d1c9Sdrahn 	  /* FIXME, this should be different to L.  */
6992159047fSniklas 	  next_byte (&(ieee->h));
7002159047fSniklas 	  PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
7012159047fSniklas 	  break;
7022159047fSniklas 	case ieee_variable_S_enum:
703c074d1c9Sdrahn 	  /* S variable, size in MAUS of section module.  */
7042159047fSniklas 	  next_byte (&(ieee->h));
7052159047fSniklas 	  PUSH (NOSYMBOL,
7062159047fSniklas 		0,
7072159047fSniklas 		ieee->section_table[must_parse_int (&(ieee->h))]->_raw_size);
7082159047fSniklas 	  break;
7092159047fSniklas 	case ieee_variable_I_enum:
710c074d1c9Sdrahn 	  /* Push the address of variable n.  */
711c88b1d6cSniklas 	  {
712c88b1d6cSniklas 	    ieee_symbol_index_type sy;
713c88b1d6cSniklas 	    next_byte (&(ieee->h));
714c88b1d6cSniklas 	    sy.index = (int) must_parse_int (&(ieee->h));
715c88b1d6cSniklas 	    sy.letter = 'I';
716c88b1d6cSniklas 
717c88b1d6cSniklas 	    PUSH (sy, bfd_abs_section_ptr, 0);
718c88b1d6cSniklas 	  }
719c88b1d6cSniklas 	  break;
7202159047fSniklas 	case ieee_variable_X_enum:
721c074d1c9Sdrahn 	  /* Push the address of external variable n.  */
7222159047fSniklas 	  {
7232159047fSniklas 	    ieee_symbol_index_type sy;
7242159047fSniklas 	    next_byte (&(ieee->h));
7252159047fSniklas 	    sy.index = (int) (must_parse_int (&(ieee->h)));
7262159047fSniklas 	    sy.letter = 'X';
7272159047fSniklas 
7282159047fSniklas 	    PUSH (sy, bfd_und_section_ptr, 0);
7292159047fSniklas 	  }
7302159047fSniklas 	  break;
7312159047fSniklas 	case ieee_function_minus_enum:
7322159047fSniklas 	  {
7332159047fSniklas 	    bfd_vma value1, value2;
7342159047fSniklas 	    asection *section1, *section_dummy;
7352159047fSniklas 	    ieee_symbol_index_type sy;
7362159047fSniklas 	    next_byte (&(ieee->h));
7372159047fSniklas 
7382159047fSniklas 	    POP (sy, section1, value1);
7392159047fSniklas 	    POP (sy, section_dummy, value2);
740c88b1d6cSniklas 	    PUSH (sy, section1 ? section1 : section_dummy, value2 - value1);
7412159047fSniklas 	  }
7422159047fSniklas 	  break;
7432159047fSniklas 	case ieee_function_plus_enum:
7442159047fSniklas 	  {
7452159047fSniklas 	    bfd_vma value1, value2;
7462159047fSniklas 	    asection *section1;
7472159047fSniklas 	    asection *section2;
7482159047fSniklas 	    ieee_symbol_index_type sy1;
7492159047fSniklas 	    ieee_symbol_index_type sy2;
7502159047fSniklas 	    next_byte (&(ieee->h));
7512159047fSniklas 
7522159047fSniklas 	    POP (sy1, section1, value1);
7532159047fSniklas 	    POP (sy2, section2, value2);
7542159047fSniklas 	    PUSH (sy1.letter ? sy1 : sy2,
7552159047fSniklas 		  bfd_is_abs_section (section1) ? section2 : section1,
7562159047fSniklas 		  value1 + value2);
7572159047fSniklas 	  }
7582159047fSniklas 	  break;
7592159047fSniklas 	default:
7602159047fSniklas 	  {
7612159047fSniklas 	    bfd_vma va;
7622159047fSniklas 	    BFD_ASSERT (this_byte (&(ieee->h)) < (int) ieee_variable_A_enum
7632159047fSniklas 		    || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum);
7642159047fSniklas 	    if (parse_int (&(ieee->h), &va))
7652159047fSniklas 	      {
7662159047fSniklas 		PUSH (NOSYMBOL, bfd_abs_section_ptr, va);
7672159047fSniklas 	      }
7682159047fSniklas 	    else
7692159047fSniklas 	      {
770c074d1c9Sdrahn 		/* Thats all that we can understand.  */
771c074d1c9Sdrahn 		loop = FALSE;
772c074d1c9Sdrahn 	      }
773c074d1c9Sdrahn 	  }
774c074d1c9Sdrahn 	}
775c074d1c9Sdrahn     }
7762159047fSniklas 
777c074d1c9Sdrahn   /* As far as I can see there is a bug in the Microtec IEEE output
778c074d1c9Sdrahn      which I'm using to scan, whereby the comma operator is omitted
779c074d1c9Sdrahn      sometimes in an expression, giving expressions with too many
780c074d1c9Sdrahn      terms.  We can tell if that's the case by ensuring that
781c074d1c9Sdrahn      sp == stack here.  If not, then we've pushed something too far,
782c074d1c9Sdrahn      so we keep adding.  */
7832159047fSniklas   while (sp != stack + 1)
7842159047fSniklas     {
7852159047fSniklas       asection *section1;
7862159047fSniklas       ieee_symbol_index_type sy1;
7872159047fSniklas       POP (sy1, section1, *extra);
7882159047fSniklas     }
7892159047fSniklas 
7902159047fSniklas   POP (*symbol, dummy, *value);
7912159047fSniklas   if (section)
7922159047fSniklas     *section = dummy;
7932159047fSniklas }
7942159047fSniklas 
7952159047fSniklas 
796c074d1c9Sdrahn #define ieee_seek(ieee, offset) \
797c074d1c9Sdrahn   do								\
798c074d1c9Sdrahn     {								\
799c074d1c9Sdrahn       ieee->h.input_p = ieee->h.first_byte + offset;		\
800c074d1c9Sdrahn       ieee->h.last_byte = (ieee->h.first_byte			\
801c074d1c9Sdrahn 			   + ieee_part_after (ieee, offset));	\
802c074d1c9Sdrahn     }								\
803c074d1c9Sdrahn   while (0)
8042159047fSniklas 
805c074d1c9Sdrahn #define ieee_pos(ieee) \
806c074d1c9Sdrahn   (ieee->h.input_p - ieee->h.first_byte)
8072159047fSniklas 
808c074d1c9Sdrahn /* Find the first part of the ieee file after HERE.  */
809c074d1c9Sdrahn 
810c074d1c9Sdrahn static file_ptr
ieee_part_after(ieee,here)811c074d1c9Sdrahn ieee_part_after (ieee, here)
812c074d1c9Sdrahn      ieee_data_type *ieee;
813c074d1c9Sdrahn      file_ptr here;
814c074d1c9Sdrahn {
815c074d1c9Sdrahn   int part;
816c074d1c9Sdrahn   file_ptr after = ieee->w.r.me_record;
817c074d1c9Sdrahn 
818c074d1c9Sdrahn   /* File parts can come in any order, except that module end is
819c074d1c9Sdrahn      guaranteed to be last (and the header first).  */
820c074d1c9Sdrahn   for (part = 0; part < N_W_VARIABLES; part++)
821c074d1c9Sdrahn     if (ieee->w.offset[part] > here && after > ieee->w.offset[part])
822c074d1c9Sdrahn       after = ieee->w.offset[part];
823c074d1c9Sdrahn 
824c074d1c9Sdrahn   return after;
825c074d1c9Sdrahn }
8262159047fSniklas 
8272159047fSniklas static unsigned int last_index;
828c074d1c9Sdrahn static char last_type;		/* Is the index for an X or a D.  */
8292159047fSniklas 
8302159047fSniklas static ieee_symbol_type *
get_symbol(abfd,ieee,last_symbol,symbol_count,pptr,max_index,this_type)831c074d1c9Sdrahn get_symbol (abfd, ieee, last_symbol, symbol_count, pptr, max_index, this_type)
832b305b0f1Sespie      bfd *abfd ATTRIBUTE_UNUSED;
8332159047fSniklas      ieee_data_type *ieee;
8342159047fSniklas      ieee_symbol_type *last_symbol;
8352159047fSniklas      unsigned int *symbol_count;
8362159047fSniklas      ieee_symbol_type ***pptr;
8372159047fSniklas      unsigned int *max_index;
838c074d1c9Sdrahn      int this_type;
8392159047fSniklas {
840c074d1c9Sdrahn   /* Need a new symbol.  */
8412159047fSniklas   unsigned int new_index = must_parse_int (&(ieee->h));
842c074d1c9Sdrahn 
8432159047fSniklas   if (new_index != last_index || this_type != last_type)
8442159047fSniklas     {
845c074d1c9Sdrahn       ieee_symbol_type *new_symbol;
846c074d1c9Sdrahn       bfd_size_type amt = sizeof (ieee_symbol_type);
847c074d1c9Sdrahn 
848c074d1c9Sdrahn       new_symbol = (ieee_symbol_type *) bfd_alloc (ieee->h.abfd, amt);
8492159047fSniklas       if (!new_symbol)
8502159047fSniklas 	return NULL;
8512159047fSniklas 
8522159047fSniklas       new_symbol->index = new_index;
8532159047fSniklas       last_index = new_index;
8542159047fSniklas       (*symbol_count)++;
8552159047fSniklas       **pptr = new_symbol;
8562159047fSniklas       *pptr = &new_symbol->next;
8572159047fSniklas       if (new_index > *max_index)
8582159047fSniklas 	*max_index = new_index;
859c074d1c9Sdrahn 
8602159047fSniklas       last_type = this_type;
861c88b1d6cSniklas       new_symbol->symbol.section = bfd_abs_section_ptr;
8622159047fSniklas       return new_symbol;
8632159047fSniklas     }
8642159047fSniklas   return last_symbol;
8652159047fSniklas }
8662159047fSniklas 
867c074d1c9Sdrahn static bfd_boolean
ieee_slurp_external_symbols(abfd)8682159047fSniklas ieee_slurp_external_symbols (abfd)
8692159047fSniklas      bfd *abfd;
8702159047fSniklas {
8712159047fSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
8722159047fSniklas   file_ptr offset = ieee->w.r.external_part;
8732159047fSniklas 
8742159047fSniklas   ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols;
8752159047fSniklas   ieee_symbol_type **prev_reference_ptr = &ieee->external_reference;
8762159047fSniklas   ieee_symbol_type *symbol = (ieee_symbol_type *) NULL;
8772159047fSniklas   unsigned int symbol_count = 0;
878c074d1c9Sdrahn   bfd_boolean loop = TRUE;
8792159047fSniklas   last_index = 0xffffff;
880c074d1c9Sdrahn   ieee->symbol_table_full = TRUE;
8812159047fSniklas 
882c074d1c9Sdrahn   ieee_seek (ieee, offset);
8832159047fSniklas 
8842159047fSniklas   while (loop)
8852159047fSniklas     {
8862159047fSniklas       switch (this_byte (&(ieee->h)))
8872159047fSniklas 	{
8882159047fSniklas 	case ieee_nn_record:
8892159047fSniklas 	  next_byte (&(ieee->h));
8902159047fSniklas 
8912159047fSniklas 	  symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
8922159047fSniklas 			       &prev_symbols_ptr,
893c88b1d6cSniklas 			       &ieee->external_symbol_max_index, 'I');
8942159047fSniklas 	  if (symbol == NULL)
895c074d1c9Sdrahn 	    return FALSE;
8962159047fSniklas 
8972159047fSniklas 	  symbol->symbol.the_bfd = abfd;
8982159047fSniklas 	  symbol->symbol.name = read_id (&(ieee->h));
8992159047fSniklas 	  symbol->symbol.udata.p = (PTR) NULL;
9002159047fSniklas 	  symbol->symbol.flags = BSF_NO_FLAGS;
9012159047fSniklas 	  break;
9022159047fSniklas 	case ieee_external_symbol_enum:
9032159047fSniklas 	  next_byte (&(ieee->h));
9042159047fSniklas 
9052159047fSniklas 	  symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
9062159047fSniklas 			       &prev_symbols_ptr,
9072159047fSniklas 			       &ieee->external_symbol_max_index, 'D');
9082159047fSniklas 	  if (symbol == NULL)
909c074d1c9Sdrahn 	    return FALSE;
9102159047fSniklas 
9112159047fSniklas 	  BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index);
9122159047fSniklas 
9132159047fSniklas 	  symbol->symbol.the_bfd = abfd;
9142159047fSniklas 	  symbol->symbol.name = read_id (&(ieee->h));
9152159047fSniklas 	  symbol->symbol.udata.p = (PTR) NULL;
9162159047fSniklas 	  symbol->symbol.flags = BSF_NO_FLAGS;
9172159047fSniklas 	  break;
9182159047fSniklas 	case ieee_attribute_record_enum >> 8:
9192159047fSniklas 	  {
9202159047fSniklas 	    unsigned int symbol_name_index;
9212159047fSniklas 	    unsigned int symbol_type_index;
9222159047fSniklas 	    unsigned int symbol_attribute_def;
9232159047fSniklas 	    bfd_vma value;
924c074d1c9Sdrahn 	    switch (read_2bytes (&ieee->h))
925c88b1d6cSniklas 	      {
926c88b1d6cSniklas 	      case ieee_attribute_record_enum:
9272159047fSniklas 		symbol_name_index = must_parse_int (&(ieee->h));
9282159047fSniklas 		symbol_type_index = must_parse_int (&(ieee->h));
9292159047fSniklas 		symbol_attribute_def = must_parse_int (&(ieee->h));
9302159047fSniklas 		switch (symbol_attribute_def)
9312159047fSniklas 		  {
932c88b1d6cSniklas 		  case 8:
933c88b1d6cSniklas 		  case 19:
934c88b1d6cSniklas 		    parse_int (&ieee->h, &value);
9352159047fSniklas 		    break;
9362159047fSniklas 		  default:
937c88b1d6cSniklas 		    (*_bfd_error_handler)
938b305b0f1Sespie 		      (_("%s: unimplemented ATI record %u for symbol %u"),
939c074d1c9Sdrahn 		       bfd_archive_filename (abfd), symbol_attribute_def,
940c88b1d6cSniklas 		       symbol_name_index);
941c88b1d6cSniklas 		    bfd_set_error (bfd_error_bad_value);
942c074d1c9Sdrahn 		    return FALSE;
943c88b1d6cSniklas 		    break;
944c88b1d6cSniklas 		  }
945c88b1d6cSniklas 		break;
946c88b1d6cSniklas 	      case ieee_external_reference_info_record_enum:
947c88b1d6cSniklas 		/* Skip over ATX record.  */
948c88b1d6cSniklas 		parse_int (&(ieee->h), &value);
949c88b1d6cSniklas 		parse_int (&(ieee->h), &value);
950c88b1d6cSniklas 		parse_int (&(ieee->h), &value);
9512159047fSniklas 		parse_int (&(ieee->h), &value);
9522159047fSniklas 		break;
953b305b0f1Sespie 	      case ieee_atn_record_enum:
954b305b0f1Sespie 		/* We may get call optimization information here,
955b305b0f1Sespie 		   which we just ignore.  The format is
956c074d1c9Sdrahn 		   {$F1}${CE}{index}{$00}{$3F}{$3F}{#_of_ASNs}.  */
957b305b0f1Sespie 		parse_int (&ieee->h, &value);
958b305b0f1Sespie 		parse_int (&ieee->h, &value);
959b305b0f1Sespie 		parse_int (&ieee->h, &value);
960b305b0f1Sespie 		if (value != 0x3f)
961b305b0f1Sespie 		  {
962b305b0f1Sespie 		    (*_bfd_error_handler)
963b305b0f1Sespie 		      (_("%s: unexpected ATN type %d in external part"),
964c074d1c9Sdrahn 			 bfd_archive_filename (abfd), (int) value);
965b305b0f1Sespie 		    bfd_set_error (bfd_error_bad_value);
966c074d1c9Sdrahn 		    return FALSE;
967b305b0f1Sespie 		  }
968b305b0f1Sespie 		parse_int (&ieee->h, &value);
969b305b0f1Sespie 		parse_int (&ieee->h, &value);
970b305b0f1Sespie 		while (value > 0)
971b305b0f1Sespie 		  {
972b305b0f1Sespie 		    bfd_vma val1;
973b305b0f1Sespie 
974b305b0f1Sespie 		    --value;
975b305b0f1Sespie 
976c074d1c9Sdrahn 		    switch (read_2bytes (&ieee->h))
977b305b0f1Sespie 		      {
978b305b0f1Sespie 		      case ieee_asn_record_enum:
979b305b0f1Sespie 			parse_int (&ieee->h, &val1);
980b305b0f1Sespie 			parse_int (&ieee->h, &val1);
981b305b0f1Sespie 			break;
982b305b0f1Sespie 
983b305b0f1Sespie 		      default:
984b305b0f1Sespie 			(*_bfd_error_handler)
985b305b0f1Sespie 			  (_("%s: unexpected type after ATN"),
986c074d1c9Sdrahn 			     bfd_archive_filename (abfd));
987b305b0f1Sespie 			bfd_set_error (bfd_error_bad_value);
988c074d1c9Sdrahn 			return FALSE;
989b305b0f1Sespie 		      }
990b305b0f1Sespie 		  }
9912159047fSniklas 	      }
9922159047fSniklas 	  }
9932159047fSniklas 	  break;
9942159047fSniklas 	case ieee_value_record_enum >> 8:
9952159047fSniklas 	  {
9962159047fSniklas 	    unsigned int symbol_name_index;
9972159047fSniklas 	    ieee_symbol_index_type symbol_ignore;
998c074d1c9Sdrahn 	    bfd_boolean pcrel_ignore;
9992159047fSniklas 	    unsigned int extra;
10002159047fSniklas 	    next_byte (&(ieee->h));
10012159047fSniklas 	    next_byte (&(ieee->h));
10022159047fSniklas 
10032159047fSniklas 	    symbol_name_index = must_parse_int (&(ieee->h));
10042159047fSniklas 	    parse_expression (ieee,
10052159047fSniklas 			      &symbol->symbol.value,
10062159047fSniklas 			      &symbol_ignore,
10072159047fSniklas 			      &pcrel_ignore,
10082159047fSniklas 			      &extra,
10092159047fSniklas 			      &symbol->symbol.section);
10102159047fSniklas 
1011b305b0f1Sespie 	    /* Fully linked IEEE-695 files tend to give every symbol
1012b305b0f1Sespie                an absolute value.  Try to convert that back into a
1013b305b0f1Sespie                section relative value.  FIXME: This won't always to
1014b305b0f1Sespie                the right thing.  */
1015b305b0f1Sespie 	    if (bfd_is_abs_section (symbol->symbol.section)
1016b305b0f1Sespie 		&& (abfd->flags & HAS_RELOC) == 0)
1017b305b0f1Sespie 	      {
1018b305b0f1Sespie 		bfd_vma val;
1019b305b0f1Sespie 		asection *s;
1020b305b0f1Sespie 
1021b305b0f1Sespie 		val = symbol->symbol.value;
1022b305b0f1Sespie 		for (s = abfd->sections; s != NULL; s = s->next)
1023b305b0f1Sespie 		  {
1024b305b0f1Sespie 		    if (val >= s->vma && val < s->vma + s->_raw_size)
1025b305b0f1Sespie 		      {
1026b305b0f1Sespie 			symbol->symbol.section = s;
1027b305b0f1Sespie 			symbol->symbol.value -= s->vma;
1028b305b0f1Sespie 			break;
1029b305b0f1Sespie 		      }
1030b305b0f1Sespie 		  }
1031b305b0f1Sespie 	      }
1032b305b0f1Sespie 
10332159047fSniklas 	    symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
10342159047fSniklas 
10352159047fSniklas 	  }
10362159047fSniklas 	  break;
10372159047fSniklas 	case ieee_weak_external_reference_enum:
10382159047fSniklas 	  {
10392159047fSniklas 	    bfd_vma size;
10402159047fSniklas 	    bfd_vma value;
10412159047fSniklas 	    next_byte (&(ieee->h));
1042c074d1c9Sdrahn 	    /* Throw away the external reference index.  */
10432159047fSniklas 	    (void) must_parse_int (&(ieee->h));
1044c074d1c9Sdrahn 	    /* Fetch the default size if not resolved.  */
10452159047fSniklas 	    size = must_parse_int (&(ieee->h));
1046*007c2a45Smiod 	    /* Fetch the default value if available.  */
1047c074d1c9Sdrahn 	    if (! parse_int (&(ieee->h), &value))
10482159047fSniklas 	      {
10492159047fSniklas 		value = 0;
10502159047fSniklas 	      }
1051c074d1c9Sdrahn 	    /* This turns into a common.  */
10522159047fSniklas 	    symbol->symbol.section = bfd_com_section_ptr;
10532159047fSniklas 	    symbol->symbol.value = size;
10542159047fSniklas 	  }
10552159047fSniklas 	  break;
10562159047fSniklas 
10572159047fSniklas 	case ieee_external_reference_enum:
10582159047fSniklas 	  next_byte (&(ieee->h));
10592159047fSniklas 
10602159047fSniklas 	  symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
10612159047fSniklas 			       &prev_reference_ptr,
10622159047fSniklas 			       &ieee->external_reference_max_index, 'X');
10632159047fSniklas 	  if (symbol == NULL)
1064c074d1c9Sdrahn 	    return FALSE;
10652159047fSniklas 
10662159047fSniklas 	  symbol->symbol.the_bfd = abfd;
10672159047fSniklas 	  symbol->symbol.name = read_id (&(ieee->h));
10682159047fSniklas 	  symbol->symbol.udata.p = (PTR) NULL;
10692159047fSniklas 	  symbol->symbol.section = bfd_und_section_ptr;
10702159047fSniklas 	  symbol->symbol.value = (bfd_vma) 0;
10712159047fSniklas 	  symbol->symbol.flags = 0;
10722159047fSniklas 
10732159047fSniklas 	  BFD_ASSERT (symbol->index >= ieee->external_reference_min_index);
10742159047fSniklas 	  break;
10752159047fSniklas 
10762159047fSniklas 	default:
1077c074d1c9Sdrahn 	  loop = FALSE;
10782159047fSniklas 	}
10792159047fSniklas     }
10802159047fSniklas 
10812159047fSniklas   if (ieee->external_symbol_max_index != 0)
10822159047fSniklas     {
10832159047fSniklas       ieee->external_symbol_count =
10842159047fSniklas 	ieee->external_symbol_max_index -
10852159047fSniklas 	ieee->external_symbol_min_index + 1;
10862159047fSniklas     }
10872159047fSniklas   else
10882159047fSniklas     {
10892159047fSniklas       ieee->external_symbol_count = 0;
10902159047fSniklas     }
10912159047fSniklas 
10922159047fSniklas   if (ieee->external_reference_max_index != 0)
10932159047fSniklas     {
10942159047fSniklas       ieee->external_reference_count =
10952159047fSniklas 	ieee->external_reference_max_index -
10962159047fSniklas 	ieee->external_reference_min_index + 1;
10972159047fSniklas     }
10982159047fSniklas   else
10992159047fSniklas     {
11002159047fSniklas       ieee->external_reference_count = 0;
11012159047fSniklas     }
11022159047fSniklas 
11032159047fSniklas   abfd->symcount =
11042159047fSniklas     ieee->external_reference_count + ieee->external_symbol_count;
11052159047fSniklas 
11062159047fSniklas   if (symbol_count != abfd->symcount)
11072159047fSniklas     {
11082159047fSniklas       /* There are gaps in the table -- */
1109c074d1c9Sdrahn       ieee->symbol_table_full = FALSE;
11102159047fSniklas     }
11112159047fSniklas 
11122159047fSniklas   *prev_symbols_ptr = (ieee_symbol_type *) NULL;
11132159047fSniklas   *prev_reference_ptr = (ieee_symbol_type *) NULL;
11142159047fSniklas 
1115c074d1c9Sdrahn   return TRUE;
11162159047fSniklas }
11172159047fSniklas 
1118c074d1c9Sdrahn static bfd_boolean
ieee_slurp_symbol_table(abfd)11192159047fSniklas ieee_slurp_symbol_table (abfd)
11202159047fSniklas      bfd *abfd;
11212159047fSniklas {
1122c074d1c9Sdrahn   if (! IEEE_DATA (abfd)->read_symbols)
11232159047fSniklas     {
11242159047fSniklas       if (! ieee_slurp_external_symbols (abfd))
1125c074d1c9Sdrahn 	return FALSE;
1126c074d1c9Sdrahn       IEEE_DATA (abfd)->read_symbols = TRUE;
11272159047fSniklas     }
1128c074d1c9Sdrahn   return TRUE;
11292159047fSniklas }
11302159047fSniklas 
1131c074d1c9Sdrahn static long
ieee_get_symtab_upper_bound(abfd)11322159047fSniklas ieee_get_symtab_upper_bound (abfd)
11332159047fSniklas      bfd *abfd;
11342159047fSniklas {
11352159047fSniklas   if (! ieee_slurp_symbol_table (abfd))
11362159047fSniklas     return -1;
11372159047fSniklas 
11382159047fSniklas   return (abfd->symcount != 0) ?
11392159047fSniklas     (abfd->symcount + 1) * (sizeof (ieee_symbol_type *)) : 0;
11402159047fSniklas }
11412159047fSniklas 
1142c074d1c9Sdrahn /* Move from our internal lists to the canon table, and insert in
1143c074d1c9Sdrahn    symbol index order.  */
11442159047fSniklas 
11452159047fSniklas extern const bfd_target ieee_vec;
11462159047fSniklas 
1147c074d1c9Sdrahn static long
ieee_canonicalize_symtab(abfd,location)1148*007c2a45Smiod ieee_canonicalize_symtab (abfd, location)
11492159047fSniklas      bfd *abfd;
11502159047fSniklas      asymbol **location;
11512159047fSniklas {
11522159047fSniklas   ieee_symbol_type *symp;
11532159047fSniklas   static bfd dummy_bfd;
11542159047fSniklas   static asymbol empty_symbol =
1155b305b0f1Sespie   {
1156b305b0f1Sespie     &dummy_bfd,
1157b305b0f1Sespie     " ieee empty",
1158b305b0f1Sespie     (symvalue) 0,
1159b305b0f1Sespie     BSF_DEBUGGING,
1160b305b0f1Sespie     bfd_abs_section_ptr
1161b305b0f1Sespie #ifdef __STDC__
1162b305b0f1Sespie     /* K&R compilers can't initialise unions.  */
1163b305b0f1Sespie     , { 0 }
1164b305b0f1Sespie #endif
1165b305b0f1Sespie   };
11662159047fSniklas 
11672159047fSniklas   if (abfd->symcount)
11682159047fSniklas     {
11692159047fSniklas       ieee_data_type *ieee = IEEE_DATA (abfd);
11702159047fSniklas       dummy_bfd.xvec = &ieee_vec;
11712159047fSniklas       if (! ieee_slurp_symbol_table (abfd))
11722159047fSniklas 	return -1;
11732159047fSniklas 
1174c074d1c9Sdrahn       if (! ieee->symbol_table_full)
11752159047fSniklas 	{
1176c074d1c9Sdrahn 	  /* Arrgh - there are gaps in the table, run through and fill them
1177c074d1c9Sdrahn 	     up with pointers to a null place.  */
11782159047fSniklas 	  unsigned int i;
1179c074d1c9Sdrahn 
11802159047fSniklas 	  for (i = 0; i < abfd->symcount; i++)
11812159047fSniklas 	    location[i] = &empty_symbol;
11822159047fSniklas 	}
11832159047fSniklas 
11842159047fSniklas       ieee->external_symbol_base_offset = -ieee->external_symbol_min_index;
11852159047fSniklas       for (symp = IEEE_DATA (abfd)->external_symbols;
11862159047fSniklas 	   symp != (ieee_symbol_type *) NULL;
11872159047fSniklas 	   symp = symp->next)
1188c074d1c9Sdrahn 	/* Place into table at correct index locations.  */
11892159047fSniklas 	location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol;
11902159047fSniklas 
1191c074d1c9Sdrahn       /* The external refs are indexed in a bit.  */
11922159047fSniklas       ieee->external_reference_base_offset =
11932159047fSniklas 	-ieee->external_reference_min_index + ieee->external_symbol_count;
11942159047fSniklas 
11952159047fSniklas       for (symp = IEEE_DATA (abfd)->external_reference;
11962159047fSniklas 	   symp != (ieee_symbol_type *) NULL;
11972159047fSniklas 	   symp = symp->next)
11982159047fSniklas 	location[symp->index + ieee->external_reference_base_offset] =
11992159047fSniklas 	  &symp->symbol;
1200c074d1c9Sdrahn     }
12012159047fSniklas 
12022159047fSniklas   if (abfd->symcount)
12032159047fSniklas     location[abfd->symcount] = (asymbol *) NULL;
1204c074d1c9Sdrahn 
12052159047fSniklas   return abfd->symcount;
12062159047fSniklas }
12072159047fSniklas 
12082159047fSniklas static asection *
get_section_entry(abfd,ieee,index)12092159047fSniklas get_section_entry (abfd, ieee, index)
12102159047fSniklas      bfd *abfd;
12112159047fSniklas      ieee_data_type *ieee;
12122159047fSniklas      unsigned int index;
12132159047fSniklas {
12140c6d0228Sniklas   if (index >= ieee->section_table_size)
12150c6d0228Sniklas     {
12160c6d0228Sniklas       unsigned int c, i;
12170c6d0228Sniklas       asection **n;
1218c074d1c9Sdrahn       bfd_size_type amt;
12190c6d0228Sniklas 
12200c6d0228Sniklas       c = ieee->section_table_size;
12210c6d0228Sniklas       if (c == 0)
12220c6d0228Sniklas 	c = 20;
12230c6d0228Sniklas       while (c <= index)
12240c6d0228Sniklas 	c *= 2;
12250c6d0228Sniklas 
1226c074d1c9Sdrahn       amt = c;
1227c074d1c9Sdrahn       amt *= sizeof (asection *);
1228c074d1c9Sdrahn       n = (asection **) bfd_realloc (ieee->section_table, amt);
12290c6d0228Sniklas       if (n == NULL)
12300c6d0228Sniklas 	return NULL;
12310c6d0228Sniklas 
12320c6d0228Sniklas       for (i = ieee->section_table_size; i < c; i++)
12330c6d0228Sniklas 	n[i] = NULL;
12340c6d0228Sniklas 
12350c6d0228Sniklas       ieee->section_table = n;
12360c6d0228Sniklas       ieee->section_table_size = c;
12370c6d0228Sniklas     }
12380c6d0228Sniklas 
12392159047fSniklas   if (ieee->section_table[index] == (asection *) NULL)
12402159047fSniklas     {
1241c074d1c9Sdrahn       char *tmp = bfd_alloc (abfd, (bfd_size_type) 11);
12422159047fSniklas       asection *section;
12432159047fSniklas 
12442159047fSniklas       if (!tmp)
12452159047fSniklas 	return NULL;
12462159047fSniklas       sprintf (tmp, " fsec%4d", index);
12472159047fSniklas       section = bfd_make_section (abfd, tmp);
12482159047fSniklas       ieee->section_table[index] = section;
12492159047fSniklas       section->flags = SEC_NO_FLAGS;
12502159047fSniklas       section->target_index = index;
12512159047fSniklas       ieee->section_table[index] = section;
12522159047fSniklas     }
12532159047fSniklas   return ieee->section_table[index];
12542159047fSniklas }
12552159047fSniklas 
12562159047fSniklas static void
ieee_slurp_sections(abfd)12572159047fSniklas ieee_slurp_sections (abfd)
12582159047fSniklas      bfd *abfd;
12592159047fSniklas {
12602159047fSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
12612159047fSniklas   file_ptr offset = ieee->w.r.section_part;
12622159047fSniklas   char *name;
12632159047fSniklas 
12642159047fSniklas   if (offset != 0)
12652159047fSniklas     {
12662159047fSniklas       bfd_byte section_type[3];
1267c074d1c9Sdrahn       ieee_seek (ieee, offset);
1268c074d1c9Sdrahn       while (TRUE)
12692159047fSniklas 	{
12702159047fSniklas 	  switch (this_byte (&(ieee->h)))
12712159047fSniklas 	    {
12722159047fSniklas 	    case ieee_section_type_enum:
12732159047fSniklas 	      {
1274c074d1c9Sdrahn 		asection *section;
12752159047fSniklas 		unsigned int section_index;
12762159047fSniklas 		next_byte (&(ieee->h));
12772159047fSniklas 		section_index = must_parse_int (&(ieee->h));
12782159047fSniklas 
12792159047fSniklas 		section = get_section_entry (abfd, ieee, section_index);
12802159047fSniklas 
12812159047fSniklas 		section_type[0] = this_byte_and_next (&(ieee->h));
1282c88b1d6cSniklas 
1283c88b1d6cSniklas 		/* Set minimal section attributes. Attributes are
1284c88b1d6cSniklas 		   extended later, based on section contents.  */
12852159047fSniklas 		switch (section_type[0])
12862159047fSniklas 		  {
12872159047fSniklas 		  case 0xC1:
1288c074d1c9Sdrahn 		    /* Normal attributes for absolute sections.  */
12892159047fSniklas 		    section_type[1] = this_byte (&(ieee->h));
1290c88b1d6cSniklas 		    section->flags = SEC_ALLOC;
12912159047fSniklas 		    switch (section_type[1])
12922159047fSniklas 		      {
1293c074d1c9Sdrahn 		      case 0xD3:	/* AS Absolute section attributes.  */
12942159047fSniklas 			next_byte (&(ieee->h));
12952159047fSniklas 			section_type[2] = this_byte (&(ieee->h));
12962159047fSniklas 			switch (section_type[2])
12972159047fSniklas 			  {
12982159047fSniklas 			  case 0xD0:
1299c074d1c9Sdrahn 			    /* Normal code.  */
13002159047fSniklas 			    next_byte (&(ieee->h));
1301c88b1d6cSniklas 			    section->flags |= SEC_CODE;
13022159047fSniklas 			    break;
13032159047fSniklas 			  case 0xC4:
1304c074d1c9Sdrahn 			    /* Normal data.  */
1305c88b1d6cSniklas 			    next_byte (&(ieee->h));
1306c88b1d6cSniklas 			    section->flags |= SEC_DATA;
13072159047fSniklas 			    break;
13082159047fSniklas 			  case 0xD2:
13092159047fSniklas 			    next_byte (&(ieee->h));
1310c074d1c9Sdrahn 			    /* Normal rom data.  */
1311c88b1d6cSniklas 			    section->flags |= SEC_ROM | SEC_DATA;
13122159047fSniklas 			    break;
13132159047fSniklas 			  default:
13142159047fSniklas 			    break;
13152159047fSniklas 			  }
13162159047fSniklas 		      }
13172159047fSniklas 		    break;
1318c074d1c9Sdrahn 		  case 0xC3:	/* Named relocatable sections (type C).  */
13192159047fSniklas 		    section_type[1] = this_byte (&(ieee->h));
1320c88b1d6cSniklas 		    section->flags = SEC_ALLOC;
13212159047fSniklas 		    switch (section_type[1])
13222159047fSniklas 		      {
1323c074d1c9Sdrahn 		      case 0xD0:	/* Normal code (CP).  */
13242159047fSniklas 			next_byte (&(ieee->h));
1325c88b1d6cSniklas 			section->flags |= SEC_CODE;
13262159047fSniklas 			break;
1327c074d1c9Sdrahn 		      case 0xC4:	/* Normal data (CD).  */
13282159047fSniklas 			next_byte (&(ieee->h));
1329c88b1d6cSniklas 			section->flags |= SEC_DATA;
13302159047fSniklas 			break;
1331c074d1c9Sdrahn 		      case 0xD2:	/* Normal rom data (CR).  */
13322159047fSniklas 			next_byte (&(ieee->h));
1333c88b1d6cSniklas 			section->flags |= SEC_ROM | SEC_DATA;
13342159047fSniklas 			break;
13352159047fSniklas 		      default:
13362159047fSniklas 			break;
13372159047fSniklas 		      }
13382159047fSniklas 		  }
13392159047fSniklas 
13402159047fSniklas 		/* Read section name, use it if non empty.  */
13412159047fSniklas 		name = read_id (&ieee->h);
13422159047fSniklas 		if (name[0])
13432159047fSniklas 		  section->name = name;
13442159047fSniklas 
1345c074d1c9Sdrahn 		/* Skip these fields, which we don't care about.  */
13462159047fSniklas 		{
13472159047fSniklas 		  bfd_vma parent, brother, context;
13482159047fSniklas 		  parse_int (&(ieee->h), &parent);
13492159047fSniklas 		  parse_int (&(ieee->h), &brother);
13502159047fSniklas 		  parse_int (&(ieee->h), &context);
13512159047fSniklas 		}
13522159047fSniklas 	      }
13532159047fSniklas 	      break;
13542159047fSniklas 	    case ieee_section_alignment_enum:
13552159047fSniklas 	      {
13562159047fSniklas 		unsigned int section_index;
13572159047fSniklas 		bfd_vma value;
13582159047fSniklas 		asection *section;
13592159047fSniklas 		next_byte (&(ieee->h));
13602159047fSniklas 		section_index = must_parse_int (&ieee->h);
13612159047fSniklas 		section = get_section_entry (abfd, ieee, section_index);
13622159047fSniklas 		if (section_index > ieee->section_count)
13632159047fSniklas 		  {
13642159047fSniklas 		    ieee->section_count = section_index;
13652159047fSniklas 		  }
13662159047fSniklas 		section->alignment_power =
13672159047fSniklas 		  bfd_log2 (must_parse_int (&ieee->h));
13682159047fSniklas 		(void) parse_int (&(ieee->h), &value);
13692159047fSniklas 	      }
13702159047fSniklas 	      break;
13712159047fSniklas 	    case ieee_e2_first_byte_enum:
13722159047fSniklas 	      {
1373c074d1c9Sdrahn 		asection *section;
1374c074d1c9Sdrahn 		ieee_record_enum_type t;
13752159047fSniklas 
1376c074d1c9Sdrahn 		t = (ieee_record_enum_type) (read_2bytes (&(ieee->h)));
13772159047fSniklas 		switch (t)
13782159047fSniklas 		  {
13792159047fSniklas 		  case ieee_section_size_enum:
13802159047fSniklas 		    section = ieee->section_table[must_parse_int (&(ieee->h))];
13812159047fSniklas 		    section->_raw_size = must_parse_int (&(ieee->h));
13822159047fSniklas 		    break;
13832159047fSniklas 		  case ieee_physical_region_size_enum:
13842159047fSniklas 		    section = ieee->section_table[must_parse_int (&(ieee->h))];
13852159047fSniklas 		    section->_raw_size = must_parse_int (&(ieee->h));
13862159047fSniklas 		    break;
13872159047fSniklas 		  case ieee_region_base_address_enum:
13882159047fSniklas 		    section = ieee->section_table[must_parse_int (&(ieee->h))];
13892159047fSniklas 		    section->vma = must_parse_int (&(ieee->h));
1390c88b1d6cSniklas 		    section->lma = section->vma;
13912159047fSniklas 		    break;
13922159047fSniklas 		  case ieee_mau_size_enum:
13932159047fSniklas 		    must_parse_int (&(ieee->h));
13942159047fSniklas 		    must_parse_int (&(ieee->h));
13952159047fSniklas 		    break;
13962159047fSniklas 		  case ieee_m_value_enum:
13972159047fSniklas 		    must_parse_int (&(ieee->h));
13982159047fSniklas 		    must_parse_int (&(ieee->h));
13992159047fSniklas 		    break;
14002159047fSniklas 		  case ieee_section_base_address_enum:
14012159047fSniklas 		    section = ieee->section_table[must_parse_int (&(ieee->h))];
14022159047fSniklas 		    section->vma = must_parse_int (&(ieee->h));
1403c88b1d6cSniklas 		    section->lma = section->vma;
14042159047fSniklas 		    break;
14052159047fSniklas 		  case ieee_section_offset_enum:
14062159047fSniklas 		    (void) must_parse_int (&(ieee->h));
14072159047fSniklas 		    (void) must_parse_int (&(ieee->h));
14082159047fSniklas 		    break;
14092159047fSniklas 		  default:
14102159047fSniklas 		    return;
14112159047fSniklas 		  }
14122159047fSniklas 	      }
14132159047fSniklas 	      break;
14142159047fSniklas 	    default:
14152159047fSniklas 	      return;
14162159047fSniklas 	    }
14172159047fSniklas 	}
14182159047fSniklas     }
14192159047fSniklas }
14202159047fSniklas 
1421c88b1d6cSniklas /* Make a section for the debugging information, if any.  We don't try
1422c88b1d6cSniklas    to interpret the debugging information; we just point the section
1423c88b1d6cSniklas    at the area in the file so that program which understand can dig it
1424c88b1d6cSniklas    out.  */
1425c88b1d6cSniklas 
1426c074d1c9Sdrahn static bfd_boolean
ieee_slurp_debug(abfd)1427c88b1d6cSniklas ieee_slurp_debug (abfd)
1428c88b1d6cSniklas      bfd *abfd;
1429c88b1d6cSniklas {
1430c88b1d6cSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
1431c88b1d6cSniklas   asection *sec;
1432b305b0f1Sespie   file_ptr debug_end;
1433c88b1d6cSniklas 
1434c88b1d6cSniklas   if (ieee->w.r.debug_information_part == 0)
1435c074d1c9Sdrahn     return TRUE;
1436c88b1d6cSniklas 
1437c88b1d6cSniklas   sec = bfd_make_section (abfd, ".debug");
1438c88b1d6cSniklas   if (sec == NULL)
1439c074d1c9Sdrahn     return FALSE;
1440c88b1d6cSniklas   sec->flags |= SEC_DEBUGGING | SEC_HAS_CONTENTS;
1441c88b1d6cSniklas   sec->filepos = ieee->w.r.debug_information_part;
1442b305b0f1Sespie 
1443c074d1c9Sdrahn   debug_end = ieee_part_after (ieee, ieee->w.r.debug_information_part);
1444b305b0f1Sespie   sec->_raw_size = debug_end - ieee->w.r.debug_information_part;
1445c88b1d6cSniklas 
1446c074d1c9Sdrahn   return TRUE;
1447c88b1d6cSniklas }
1448c88b1d6cSniklas 
1449c074d1c9Sdrahn /* Archive stuff.  */
14502159047fSniklas 
14512159047fSniklas const bfd_target *
ieee_archive_p(abfd)14522159047fSniklas ieee_archive_p (abfd)
14532159047fSniklas      bfd *abfd;
14542159047fSniklas {
14552159047fSniklas   char *library;
14562159047fSniklas   unsigned int i;
14572159047fSniklas   unsigned char buffer[512];
14582159047fSniklas   file_ptr buffer_offset = 0;
14592159047fSniklas   ieee_ar_data_type *save = abfd->tdata.ieee_ar_data;
14602159047fSniklas   ieee_ar_data_type *ieee;
1461c074d1c9Sdrahn   bfd_size_type alc_elts;
1462b305b0f1Sespie   ieee_ar_obstack_type *elts = NULL;
1463c074d1c9Sdrahn   bfd_size_type amt = sizeof (ieee_ar_data_type);
1464b305b0f1Sespie 
1465c074d1c9Sdrahn   abfd->tdata.ieee_ar_data = (ieee_ar_data_type *) bfd_alloc (abfd, amt);
14662159047fSniklas   if (!abfd->tdata.ieee_ar_data)
1467c074d1c9Sdrahn     goto error_ret_restore;
14682159047fSniklas   ieee = IEEE_AR_DATA (abfd);
14692159047fSniklas 
1470c074d1c9Sdrahn   /* Ignore the return value here.  It doesn't matter if we don't read
1471c074d1c9Sdrahn      the entire buffer.  We might have a very small ieee file.  */
1472c074d1c9Sdrahn   bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd);
14732159047fSniklas 
14742159047fSniklas   ieee->h.first_byte = buffer;
14752159047fSniklas   ieee->h.input_p = buffer;
14762159047fSniklas 
14772159047fSniklas   ieee->h.abfd = abfd;
14782159047fSniklas 
14792159047fSniklas   if (this_byte (&(ieee->h)) != Module_Beginning)
1480b305b0f1Sespie     goto got_wrong_format_error;
14812159047fSniklas 
14822159047fSniklas   next_byte (&(ieee->h));
14832159047fSniklas   library = read_id (&(ieee->h));
14842159047fSniklas   if (strcmp (library, "LIBRARY") != 0)
1485b305b0f1Sespie     goto got_wrong_format_error;
1486b55d4692Sfgsch 
1487b55d4692Sfgsch   /* Throw away the filename.  */
14882159047fSniklas   read_id (&(ieee->h));
14892159047fSniklas 
14902159047fSniklas   ieee->element_count = 0;
14912159047fSniklas   ieee->element_index = 0;
14922159047fSniklas 
1493b55d4692Sfgsch   next_byte (&(ieee->h));	/* Drop the ad part.  */
1494b55d4692Sfgsch   must_parse_int (&(ieee->h));	/* And the two dummy numbers.  */
14952159047fSniklas   must_parse_int (&(ieee->h));
14962159047fSniklas 
1497b305b0f1Sespie   alc_elts = 10;
1498b305b0f1Sespie   elts = (ieee_ar_obstack_type *) bfd_malloc (alc_elts * sizeof *elts);
1499b305b0f1Sespie   if (elts == NULL)
1500b305b0f1Sespie     goto error_return;
1501b305b0f1Sespie 
1502b55d4692Sfgsch   /* Read the index of the BB table.  */
1503b305b0f1Sespie   while (1)
15042159047fSniklas     {
1505b305b0f1Sespie       int rec;
1506b305b0f1Sespie       ieee_ar_obstack_type *t;
1507b305b0f1Sespie 
1508b305b0f1Sespie       rec = read_2bytes (&(ieee->h));
1509b305b0f1Sespie       if (rec != (int) ieee_assign_value_to_variable_enum)
1510b305b0f1Sespie 	break;
1511b305b0f1Sespie 
1512b305b0f1Sespie       if (ieee->element_count >= alc_elts)
15132159047fSniklas 	{
1514b305b0f1Sespie 	  ieee_ar_obstack_type *n;
1515b305b0f1Sespie 
1516b305b0f1Sespie 	  alc_elts *= 2;
1517b305b0f1Sespie 	  n = ((ieee_ar_obstack_type *)
1518b305b0f1Sespie 	       bfd_realloc (elts, alc_elts * sizeof *elts));
1519b305b0f1Sespie 	  if (n == NULL)
1520b305b0f1Sespie 	    goto error_return;
1521b305b0f1Sespie 	  elts = n;
1522b305b0f1Sespie 	}
1523b305b0f1Sespie 
1524b305b0f1Sespie       t = &elts[ieee->element_count];
15252159047fSniklas       ieee->element_count++;
15262159047fSniklas 
1527b305b0f1Sespie       must_parse_int (&(ieee->h));
1528b305b0f1Sespie       t->file_offset = must_parse_int (&(ieee->h));
1529b305b0f1Sespie       t->abfd = (bfd *) NULL;
15302159047fSniklas 
1531b55d4692Sfgsch       /* Make sure that we don't go over the end of the buffer.  */
1532c074d1c9Sdrahn       if ((size_t) ieee_pos (IEEE_DATA (abfd)) > sizeof (buffer) / 2)
15332159047fSniklas 	{
1534b55d4692Sfgsch 	  /* Past half way, reseek and reprime.  */
1535c074d1c9Sdrahn 	  buffer_offset += ieee_pos (IEEE_DATA (abfd));
15362159047fSniklas 	  if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0)
1537b305b0f1Sespie 	    goto error_return;
1538b55d4692Sfgsch 
1539c074d1c9Sdrahn 	  /* Again ignore return value of bfd_bread.  */
1540c074d1c9Sdrahn 	  bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd);
15412159047fSniklas 	  ieee->h.first_byte = buffer;
15422159047fSniklas 	  ieee->h.input_p = buffer;
15432159047fSniklas 	}
15442159047fSniklas     }
15452159047fSniklas 
1546c074d1c9Sdrahn   amt = ieee->element_count;
1547c074d1c9Sdrahn   amt *= sizeof *ieee->elements;
1548c074d1c9Sdrahn   ieee->elements = (ieee_ar_obstack_type *) bfd_alloc (abfd, amt);
1549b305b0f1Sespie   if (ieee->elements == NULL)
1550b305b0f1Sespie     goto error_return;
1551b55d4692Sfgsch 
1552c074d1c9Sdrahn   memcpy (ieee->elements, elts, (size_t) amt);
1553b305b0f1Sespie   free (elts);
1554b305b0f1Sespie   elts = NULL;
15552159047fSniklas 
1556b55d4692Sfgsch   /* Now scan the area again, and replace BB offsets with file offsets.  */
15572159047fSniklas   for (i = 2; i < ieee->element_count; i++)
15582159047fSniklas     {
15592159047fSniklas       if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0)
1560b305b0f1Sespie 	goto error_return;
1561b55d4692Sfgsch 
1562c074d1c9Sdrahn       /* Again ignore return value of bfd_bread.  */
1563c074d1c9Sdrahn       bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd);
15642159047fSniklas       ieee->h.first_byte = buffer;
15652159047fSniklas       ieee->h.input_p = buffer;
15662159047fSniklas 
1567b55d4692Sfgsch       next_byte (&(ieee->h));		/* Drop F8.  */
1568b55d4692Sfgsch       next_byte (&(ieee->h));		/* Drop 14.  */
1569b55d4692Sfgsch       must_parse_int (&(ieee->h));	/* Drop size of block.  */
1570b55d4692Sfgsch 
15712159047fSniklas       if (must_parse_int (&(ieee->h)) != 0)
1572b55d4692Sfgsch 	/* This object has been deleted.  */
15732159047fSniklas 	ieee->elements[i].file_offset = 0;
15742159047fSniklas       else
15752159047fSniklas 	ieee->elements[i].file_offset = must_parse_int (&(ieee->h));
15762159047fSniklas     }
15772159047fSniklas 
15782159047fSniklas   /*  abfd->has_armap = ;*/
1579b305b0f1Sespie 
15802159047fSniklas   return abfd->xvec;
1581b305b0f1Sespie 
1582b305b0f1Sespie  got_wrong_format_error:
1583b305b0f1Sespie   bfd_set_error (bfd_error_wrong_format);
1584b305b0f1Sespie  error_return:
1585b305b0f1Sespie   if (elts != NULL)
1586b305b0f1Sespie     free (elts);
1587c074d1c9Sdrahn   bfd_release (abfd, ieee);
1588c074d1c9Sdrahn  error_ret_restore:
1589c074d1c9Sdrahn   abfd->tdata.ieee_ar_data = save;
1590b55d4692Sfgsch 
1591b305b0f1Sespie   return NULL;
15922159047fSniklas }
15932159047fSniklas 
15942159047fSniklas const bfd_target *
ieee_object_p(abfd)15952159047fSniklas ieee_object_p (abfd)
15962159047fSniklas      bfd *abfd;
15972159047fSniklas {
15982159047fSniklas   char *processor;
15992159047fSniklas   unsigned int part;
16002159047fSniklas   ieee_data_type *ieee;
16012159047fSniklas   unsigned char buffer[300];
16022159047fSniklas   ieee_data_type *save = IEEE_DATA (abfd);
1603c074d1c9Sdrahn   bfd_size_type amt;
16042159047fSniklas 
16052159047fSniklas   abfd->tdata.ieee_data = 0;
16062159047fSniklas   ieee_mkobject (abfd);
16072159047fSniklas 
16082159047fSniklas   ieee = IEEE_DATA (abfd);
16092159047fSniklas   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
16102159047fSniklas     goto fail;
1611c074d1c9Sdrahn   /* Read the first few bytes in to see if it makes sense.  Ignore
1612c074d1c9Sdrahn      bfd_bread return value;  The file might be very small.  */
1613c074d1c9Sdrahn   bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd);
16142159047fSniklas 
16152159047fSniklas   ieee->h.input_p = buffer;
16162159047fSniklas   if (this_byte_and_next (&(ieee->h)) != Module_Beginning)
16172159047fSniklas     goto got_wrong_format;
16182159047fSniklas 
1619c074d1c9Sdrahn   ieee->read_symbols = FALSE;
1620c074d1c9Sdrahn   ieee->read_data = FALSE;
16212159047fSniklas   ieee->section_count = 0;
16222159047fSniklas   ieee->external_symbol_max_index = 0;
16232159047fSniklas   ieee->external_symbol_min_index = IEEE_PUBLIC_BASE;
16242159047fSniklas   ieee->external_reference_min_index = IEEE_REFERENCE_BASE;
16252159047fSniklas   ieee->external_reference_max_index = 0;
16262159047fSniklas   ieee->h.abfd = abfd;
16270c6d0228Sniklas   ieee->section_table = NULL;
16280c6d0228Sniklas   ieee->section_table_size = 0;
16292159047fSniklas 
16302159047fSniklas   processor = ieee->mb.processor = read_id (&(ieee->h));
16312159047fSniklas   if (strcmp (processor, "LIBRARY") == 0)
16322159047fSniklas     goto got_wrong_format;
16332159047fSniklas   ieee->mb.module_name = read_id (&(ieee->h));
1634c074d1c9Sdrahn   if (abfd->filename == (const char *) NULL)
16352159047fSniklas     abfd->filename = ieee->mb.module_name;
1636c074d1c9Sdrahn 
1637c074d1c9Sdrahn   /* Determine the architecture and machine type of the object file.  */
16382159047fSniklas   {
1639b305b0f1Sespie     const bfd_arch_info_type *arch;
1640b305b0f1Sespie     char family[10];
1641b305b0f1Sespie 
1642*007c2a45Smiod     /* IEEE does not specify the format of the processor identification
1643b305b0f1Sespie        string, so the compiler is free to put in it whatever it wants.
1644b305b0f1Sespie        We try here to recognize different processors belonging to the
1645b305b0f1Sespie        m68k family.  Code for other processors can be added here.  */
1646b305b0f1Sespie     if ((processor[0] == '6') && (processor[1] == '8'))
1647b305b0f1Sespie       {
1648b305b0f1Sespie 	if (processor[2] == '3')	    /* 683xx integrated processors */
1649b305b0f1Sespie 	  {
1650b305b0f1Sespie 	    switch (processor[3])
1651b305b0f1Sespie 	      {
1652b305b0f1Sespie 	      case '0':			    /* 68302, 68306, 68307 */
1653b305b0f1Sespie 	      case '2':			    /* 68322, 68328 */
1654b305b0f1Sespie 	      case '5':			    /* 68356 */
1655b305b0f1Sespie 		strcpy (family, "68000");   /* MC68000-based controllers */
1656b305b0f1Sespie 		break;
1657b305b0f1Sespie 
1658b305b0f1Sespie 	      case '3':			    /* 68330, 68331, 68332, 68333,
1659b305b0f1Sespie 					       68334, 68335, 68336, 68338 */
1660b305b0f1Sespie 	      case '6':			    /* 68360 */
1661b305b0f1Sespie 	      case '7':			    /* 68376 */
1662b305b0f1Sespie 		strcpy (family, "68332");   /* CPU32 and CPU32+ */
1663b305b0f1Sespie 		break;
1664b305b0f1Sespie 
1665b305b0f1Sespie 	      case '4':
1666b305b0f1Sespie 		if (processor[4] == '9')    /* 68349 */
1667b305b0f1Sespie 		  strcpy (family, "68030"); /* CPU030 */
1668b305b0f1Sespie 		else		            /* 68340, 68341 */
1669b305b0f1Sespie 		  strcpy (family, "68332"); /* CPU32 and CPU32+ */
1670b305b0f1Sespie 		break;
1671b305b0f1Sespie 
1672b305b0f1Sespie 	      default:			    /* Does not exist yet */
1673b305b0f1Sespie 		strcpy (family, "68332");   /* Guess it will be CPU32 */
1674b305b0f1Sespie 	      }
1675b305b0f1Sespie 	  }
1676c074d1c9Sdrahn 	else if (TOUPPER (processor[3]) == 'F')  /* 68F333 */
1677b305b0f1Sespie 	  strcpy (family, "68332");	           /* CPU32 */
1678c074d1c9Sdrahn 	else if ((TOUPPER (processor[3]) == 'C') /* Embedded controllers.  */
1679c074d1c9Sdrahn 		 && ((TOUPPER (processor[2]) == 'E')
1680c074d1c9Sdrahn 		     || (TOUPPER (processor[2]) == 'H')
1681c074d1c9Sdrahn 		     || (TOUPPER (processor[2]) == 'L')))
1682b305b0f1Sespie 	  {
1683b305b0f1Sespie 	    strcpy (family, "68");
1684b305b0f1Sespie 	    strncat (family, processor + 4, 7);
1685b305b0f1Sespie 	    family[9] = '\0';
1686b305b0f1Sespie 	  }
1687c074d1c9Sdrahn 	else				 /* "Regular" processors.  */
1688b305b0f1Sespie 	  {
1689b305b0f1Sespie 	    strncpy (family, processor, 9);
1690b305b0f1Sespie 	    family[9] = '\0';
1691b305b0f1Sespie 	  }
1692b305b0f1Sespie       }
1693b305b0f1Sespie     else if ((strncmp (processor, "cpu32", 5) == 0) /* CPU32 and CPU32+ */
1694b305b0f1Sespie 	     || (strncmp (processor, "CPU32", 5) == 0))
1695b305b0f1Sespie       strcpy (family, "68332");
1696b305b0f1Sespie     else
1697b305b0f1Sespie       {
1698b305b0f1Sespie 	strncpy (family, processor, 9);
1699b305b0f1Sespie 	family[9] = '\0';
1700b305b0f1Sespie       }
1701b305b0f1Sespie 
1702b305b0f1Sespie     arch = bfd_scan_arch (family);
17032159047fSniklas     if (arch == 0)
17042159047fSniklas       goto got_wrong_format;
17052159047fSniklas     abfd->arch_info = arch;
17062159047fSniklas   }
17072159047fSniklas 
17082159047fSniklas   if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum)
17092159047fSniklas     goto fail;
1710c074d1c9Sdrahn 
17112159047fSniklas   next_byte (&(ieee->h));
17122159047fSniklas 
1713c074d1c9Sdrahn   if (! parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau))
17142159047fSniklas     goto fail;
17152159047fSniklas 
1716c074d1c9Sdrahn   if (! parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address))
1717c074d1c9Sdrahn     goto fail;
1718c074d1c9Sdrahn 
1719c074d1c9Sdrahn   /* If there is a byte order info, take it.  */
1720c074d1c9Sdrahn   if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum
1721c074d1c9Sdrahn       || this_byte (&(ieee->h)) == (int) ieee_variable_M_enum)
17222159047fSniklas     next_byte (&(ieee->h));
17232159047fSniklas 
17242159047fSniklas   for (part = 0; part < N_W_VARIABLES; part++)
17252159047fSniklas     {
1726c074d1c9Sdrahn       bfd_boolean ok;
1727c074d1c9Sdrahn 
17282159047fSniklas       if (read_2bytes (&(ieee->h)) != (int) ieee_assign_value_to_variable_enum)
17292159047fSniklas 	goto fail;
1730c074d1c9Sdrahn 
17312159047fSniklas       if (this_byte_and_next (&(ieee->h)) != part)
17322159047fSniklas 	goto fail;
17332159047fSniklas 
17342159047fSniklas       ieee->w.offset[part] = parse_i (&(ieee->h), &ok);
1735c074d1c9Sdrahn       if (! ok)
17362159047fSniklas 	goto fail;
17372159047fSniklas     }
17382159047fSniklas 
1739c88b1d6cSniklas   if (ieee->w.r.external_part != 0)
17402159047fSniklas     abfd->flags = HAS_SYMS;
1741c88b1d6cSniklas 
17422159047fSniklas   /* By now we know that this is a real IEEE file, we're going to read
17432159047fSniklas      the whole thing into memory so that we can run up and down it
17442159047fSniklas      quickly.  We can work out how big the file is from the trailer
1745c074d1c9Sdrahn      record.  */
17462159047fSniklas 
1747c074d1c9Sdrahn   amt = ieee->w.r.me_record + 1;
1748c88b1d6cSniklas   IEEE_DATA (abfd)->h.first_byte =
1749c074d1c9Sdrahn     (unsigned char *) bfd_alloc (ieee->h.abfd, amt);
17502159047fSniklas   if (!IEEE_DATA (abfd)->h.first_byte)
17512159047fSniklas     goto fail;
17522159047fSniklas   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
17532159047fSniklas     goto fail;
17542159047fSniklas   /* FIXME: Check return value.  I'm not sure whether it needs to read
17552159047fSniklas      the entire buffer or not.  */
1756c074d1c9Sdrahn   bfd_bread ((PTR) (IEEE_DATA (abfd)->h.first_byte),
1757c074d1c9Sdrahn 	    (bfd_size_type) ieee->w.r.me_record + 1, abfd);
17582159047fSniklas 
17592159047fSniklas   ieee_slurp_sections (abfd);
1760c88b1d6cSniklas 
1761c88b1d6cSniklas   if (! ieee_slurp_debug (abfd))
1762c88b1d6cSniklas     goto fail;
1763c88b1d6cSniklas 
1764c88b1d6cSniklas   /* Parse section data to activate file and section flags implied by
1765c88b1d6cSniklas      section contents. */
1766c88b1d6cSniklas   if (! ieee_slurp_section_data (abfd))
1767c88b1d6cSniklas     goto fail;
1768c88b1d6cSniklas 
17692159047fSniklas   return abfd->xvec;
17702159047fSniklas got_wrong_format:
17712159047fSniklas   bfd_set_error (bfd_error_wrong_format);
17722159047fSniklas fail:
1773c074d1c9Sdrahn   bfd_release (abfd, ieee);
17742159047fSniklas   abfd->tdata.ieee_data = save;
17752159047fSniklas   return (const bfd_target *) NULL;
17762159047fSniklas }
17772159047fSniklas 
1778c074d1c9Sdrahn static void
ieee_get_symbol_info(ignore_abfd,symbol,ret)17792159047fSniklas ieee_get_symbol_info (ignore_abfd, symbol, ret)
1780b305b0f1Sespie      bfd *ignore_abfd ATTRIBUTE_UNUSED;
17812159047fSniklas      asymbol *symbol;
17822159047fSniklas      symbol_info *ret;
17832159047fSniklas {
17842159047fSniklas   bfd_symbol_info (symbol, ret);
17852159047fSniklas   if (symbol->name[0] == ' ')
17862159047fSniklas     ret->name = "* empty table entry ";
17872159047fSniklas   if (!symbol->section)
17882159047fSniklas     ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
17892159047fSniklas }
17902159047fSniklas 
1791c074d1c9Sdrahn static void
ieee_print_symbol(abfd,afile,symbol,how)1792c074d1c9Sdrahn ieee_print_symbol (abfd, afile, symbol, how)
1793c074d1c9Sdrahn      bfd *abfd;
17942159047fSniklas      PTR afile;
17952159047fSniklas      asymbol *symbol;
17962159047fSniklas      bfd_print_symbol_type how;
17972159047fSniklas {
17982159047fSniklas   FILE *file = (FILE *) afile;
17992159047fSniklas 
18002159047fSniklas   switch (how)
18012159047fSniklas     {
18022159047fSniklas     case bfd_print_symbol_name:
18032159047fSniklas       fprintf (file, "%s", symbol->name);
18042159047fSniklas       break;
18052159047fSniklas     case bfd_print_symbol_more:
18062159047fSniklas #if 0
18072159047fSniklas       fprintf (file, "%4x %2x", aout_symbol (symbol)->desc & 0xffff,
18082159047fSniklas 	       aout_symbol (symbol)->other & 0xff);
18092159047fSniklas #endif
18102159047fSniklas       BFD_FAIL ();
18112159047fSniklas       break;
18122159047fSniklas     case bfd_print_symbol_all:
18132159047fSniklas       {
1814c88b1d6cSniklas 	const char *section_name =
1815c88b1d6cSniklas 	  (symbol->section == (asection *) NULL
1816c88b1d6cSniklas 	   ? "*abs"
1817c88b1d6cSniklas 	   : symbol->section->name);
1818c074d1c9Sdrahn 
18192159047fSniklas 	if (symbol->name[0] == ' ')
18202159047fSniklas 	  {
18212159047fSniklas 	    fprintf (file, "* empty table entry ");
18222159047fSniklas 	  }
18232159047fSniklas 	else
18242159047fSniklas 	  {
1825c074d1c9Sdrahn 	    bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
18262159047fSniklas 
18272159047fSniklas 	    fprintf (file, " %-5s %04x %02x %s",
18282159047fSniklas 		     section_name,
18292159047fSniklas 		     (unsigned) ieee_symbol (symbol)->index,
1830c88b1d6cSniklas 		     (unsigned) 0,
18312159047fSniklas 		     symbol->name);
18322159047fSniklas 	  }
18332159047fSniklas       }
18342159047fSniklas       break;
18352159047fSniklas     }
18362159047fSniklas }
18372159047fSniklas 
1838c074d1c9Sdrahn static bfd_boolean
do_one(ieee,current_map,location_ptr,s,iterations)1839c88b1d6cSniklas do_one (ieee, current_map, location_ptr, s, iterations)
18402159047fSniklas      ieee_data_type *ieee;
18412159047fSniklas      ieee_per_section_type *current_map;
18422159047fSniklas      unsigned char *location_ptr;
18432159047fSniklas      asection *s;
1844c88b1d6cSniklas      int iterations;
18452159047fSniklas {
18462159047fSniklas   switch (this_byte (&(ieee->h)))
18472159047fSniklas     {
18482159047fSniklas     case ieee_load_constant_bytes_enum:
18492159047fSniklas       {
18502159047fSniklas 	unsigned int number_of_maus;
18512159047fSniklas 	unsigned int i;
1852c074d1c9Sdrahn 
18532159047fSniklas 	next_byte (&(ieee->h));
18542159047fSniklas 	number_of_maus = must_parse_int (&(ieee->h));
18552159047fSniklas 
18562159047fSniklas 	for (i = 0; i < number_of_maus; i++)
18572159047fSniklas 	  {
18582159047fSniklas 	    location_ptr[current_map->pc++] = this_byte (&(ieee->h));
18592159047fSniklas 	    next_byte (&(ieee->h));
18602159047fSniklas 	  }
18612159047fSniklas       }
18622159047fSniklas       break;
18632159047fSniklas 
18642159047fSniklas     case ieee_load_with_relocation_enum:
18652159047fSniklas       {
1866c074d1c9Sdrahn 	bfd_boolean loop = TRUE;
1867c074d1c9Sdrahn 
18682159047fSniklas 	next_byte (&(ieee->h));
18692159047fSniklas 	while (loop)
18702159047fSniklas 	  {
18712159047fSniklas 	    switch (this_byte (&(ieee->h)))
18722159047fSniklas 	      {
18732159047fSniklas 	      case ieee_variable_R_enum:
18742159047fSniklas 
18752159047fSniklas 	      case ieee_function_signed_open_b_enum:
18762159047fSniklas 	      case ieee_function_unsigned_open_b_enum:
18772159047fSniklas 	      case ieee_function_either_open_b_enum:
18782159047fSniklas 		{
18792159047fSniklas 		  unsigned int extra = 4;
1880c074d1c9Sdrahn 		  bfd_boolean pcrel = FALSE;
18812159047fSniklas 		  asection *section;
1882c074d1c9Sdrahn 		  ieee_reloc_type *r;
1883c074d1c9Sdrahn 		  bfd_size_type amt = sizeof (ieee_reloc_type);
1884c074d1c9Sdrahn 
1885c074d1c9Sdrahn 		  r = (ieee_reloc_type *) bfd_alloc (ieee->h.abfd, amt);
18862159047fSniklas 		  if (!r)
1887c074d1c9Sdrahn 		    return FALSE;
18882159047fSniklas 
18892159047fSniklas 		  *(current_map->reloc_tail_ptr) = r;
18902159047fSniklas 		  current_map->reloc_tail_ptr = &r->next;
18912159047fSniklas 		  r->next = (ieee_reloc_type *) NULL;
18922159047fSniklas 		  next_byte (&(ieee->h));
18932159047fSniklas /*			    abort();*/
18942159047fSniklas 		  r->relent.sym_ptr_ptr = 0;
18952159047fSniklas 		  parse_expression (ieee,
18962159047fSniklas 				    &r->relent.addend,
18972159047fSniklas 				    &r->symbol,
18982159047fSniklas 				    &pcrel, &extra, &section);
18992159047fSniklas 		  r->relent.address = current_map->pc;
1900c88b1d6cSniklas 		  s->flags |= SEC_RELOC;
1901c88b1d6cSniklas 		  s->owner->flags |= HAS_RELOC;
19022159047fSniklas 		  s->reloc_count++;
1903b305b0f1Sespie 		  if (r->relent.sym_ptr_ptr == NULL && section != NULL)
19042159047fSniklas 		    r->relent.sym_ptr_ptr = section->symbol_ptr_ptr;
19052159047fSniklas 
19062159047fSniklas 		  if (this_byte (&(ieee->h)) == (int) ieee_comma)
19072159047fSniklas 		    {
19082159047fSniklas 		      next_byte (&(ieee->h));
1909c074d1c9Sdrahn 		      /* Fetch number of bytes to pad.  */
19102159047fSniklas 		      extra = must_parse_int (&(ieee->h));
19112159047fSniklas 		    };
19122159047fSniklas 
19132159047fSniklas 		  switch (this_byte (&(ieee->h)))
19142159047fSniklas 		    {
19152159047fSniklas 		    case ieee_function_signed_close_b_enum:
19162159047fSniklas 		      next_byte (&(ieee->h));
19172159047fSniklas 		      break;
19182159047fSniklas 		    case ieee_function_unsigned_close_b_enum:
19192159047fSniklas 		      next_byte (&(ieee->h));
19202159047fSniklas 		      break;
19212159047fSniklas 		    case ieee_function_either_close_b_enum:
19222159047fSniklas 		      next_byte (&(ieee->h));
19232159047fSniklas 		      break;
19242159047fSniklas 		    default:
19252159047fSniklas 		      break;
19262159047fSniklas 		    }
1927c074d1c9Sdrahn 		  /* Build a relocation entry for this type.  */
19282159047fSniklas 		  /* If pc rel then stick -ve pc into instruction
19292159047fSniklas 		     and take out of reloc ..
19302159047fSniklas 
1931c88b1d6cSniklas 		     I've changed this. It's all too complicated. I
1932c88b1d6cSniklas 		     keep 0 in the instruction now.  */
19332159047fSniklas 
19342159047fSniklas 		  switch (extra)
19352159047fSniklas 		    {
19362159047fSniklas 		    case 0:
19372159047fSniklas 		    case 4:
19382159047fSniklas 
1939c074d1c9Sdrahn 		      if (pcrel)
19402159047fSniklas 			{
19412159047fSniklas #if KEEPMINUSPCININST
1942c074d1c9Sdrahn 			  bfd_put_32 (ieee->h.abfd, -current_map->pc,
1943c074d1c9Sdrahn 				      location_ptr + current_map->pc);
19442159047fSniklas 			  r->relent.howto = &rel32_howto;
1945c074d1c9Sdrahn 			  r->relent.addend -= current_map->pc;
19462159047fSniklas #else
1947c074d1c9Sdrahn 			  bfd_put_32 (ieee->h.abfd, (bfd_vma) 0, location_ptr +
19482159047fSniklas 				      current_map->pc);
19492159047fSniklas 			  r->relent.howto = &rel32_howto;
19502159047fSniklas #endif
19512159047fSniklas 			}
19522159047fSniklas 		      else
19532159047fSniklas 			{
1954c074d1c9Sdrahn 			  bfd_put_32 (ieee->h.abfd, (bfd_vma) 0,
1955c074d1c9Sdrahn 				      location_ptr + current_map->pc);
19562159047fSniklas 			  r->relent.howto = &abs32_howto;
19572159047fSniklas 			}
19582159047fSniklas 		      current_map->pc += 4;
19592159047fSniklas 		      break;
19602159047fSniklas 		    case 2:
1961c074d1c9Sdrahn 		      if (pcrel)
19622159047fSniklas 			{
19632159047fSniklas #if KEEPMINUSPCININST
1964c074d1c9Sdrahn 			  bfd_put_16 (ieee->h.abfd, (bfd_vma) -current_map->pc,
1965c074d1c9Sdrahn 				      location_ptr + current_map->pc);
19662159047fSniklas 			  r->relent.addend -= current_map->pc;
19672159047fSniklas 			  r->relent.howto = &rel16_howto;
19682159047fSniklas #else
19692159047fSniklas 
1970c074d1c9Sdrahn 			  bfd_put_16 (ieee->h.abfd, (bfd_vma) 0,
1971c074d1c9Sdrahn 				      location_ptr + current_map->pc);
19722159047fSniklas 			  r->relent.howto = &rel16_howto;
19732159047fSniklas #endif
19742159047fSniklas 			}
19752159047fSniklas 
19762159047fSniklas 		      else
19772159047fSniklas 			{
1978c074d1c9Sdrahn 			  bfd_put_16 (ieee->h.abfd, (bfd_vma) 0,
1979c074d1c9Sdrahn 				      location_ptr + current_map->pc);
19802159047fSniklas 			  r->relent.howto = &abs16_howto;
19812159047fSniklas 			}
19822159047fSniklas 		      current_map->pc += 2;
19832159047fSniklas 		      break;
19842159047fSniklas 		    case 1:
1985c074d1c9Sdrahn 		      if (pcrel)
19862159047fSniklas 			{
19872159047fSniklas #if KEEPMINUSPCININST
19882159047fSniklas 			  bfd_put_8 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc);
19892159047fSniklas 			  r->relent.addend -= current_map->pc;
19902159047fSniklas 			  r->relent.howto = &rel8_howto;
19912159047fSniklas #else
19922159047fSniklas 			  bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
19932159047fSniklas 			  r->relent.howto = &rel8_howto;
19942159047fSniklas #endif
19952159047fSniklas 			}
19962159047fSniklas 		      else
19972159047fSniklas 			{
19982159047fSniklas 			  bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
19992159047fSniklas 			  r->relent.howto = &abs8_howto;
20002159047fSniklas 			}
20012159047fSniklas 		      current_map->pc += 1;
20022159047fSniklas 		      break;
20032159047fSniklas 
20042159047fSniklas 		    default:
20052159047fSniklas 		      BFD_FAIL ();
2006c074d1c9Sdrahn 		      return FALSE;
20072159047fSniklas 		    }
20082159047fSniklas 		}
20092159047fSniklas 		break;
20102159047fSniklas 	      default:
20112159047fSniklas 		{
20122159047fSniklas 		  bfd_vma this_size;
2013c074d1c9Sdrahn 		  if (parse_int (&(ieee->h), &this_size))
20142159047fSniklas 		    {
20152159047fSniklas 		      unsigned int i;
20162159047fSniklas 		      for (i = 0; i < this_size; i++)
20172159047fSniklas 			{
20182159047fSniklas 			  location_ptr[current_map->pc++] = this_byte (&(ieee->h));
20192159047fSniklas 			  next_byte (&(ieee->h));
20202159047fSniklas 			}
20212159047fSniklas 		    }
20222159047fSniklas 		  else
20232159047fSniklas 		    {
2024c074d1c9Sdrahn 		      loop = FALSE;
20252159047fSniklas 		    }
20262159047fSniklas 		}
20272159047fSniklas 	      }
2028c88b1d6cSniklas 
2029c88b1d6cSniklas 	    /* Prevent more than the first load-item of an LR record
2030c88b1d6cSniklas 	       from being repeated (MRI convention). */
2031c88b1d6cSniklas 	    if (iterations != 1)
2032c074d1c9Sdrahn 	      loop = FALSE;
20332159047fSniklas 	  }
20342159047fSniklas       }
20352159047fSniklas     }
2036c074d1c9Sdrahn   return TRUE;
20372159047fSniklas }
20382159047fSniklas 
2039c074d1c9Sdrahn /* Read in all the section data and relocation stuff too.  */
2040c074d1c9Sdrahn 
2041c074d1c9Sdrahn static bfd_boolean
ieee_slurp_section_data(abfd)20422159047fSniklas ieee_slurp_section_data (abfd)
20432159047fSniklas      bfd *abfd;
20442159047fSniklas {
20452159047fSniklas   bfd_byte *location_ptr = (bfd_byte *) NULL;
20462159047fSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
20472159047fSniklas   unsigned int section_number;
20482159047fSniklas 
20492159047fSniklas   ieee_per_section_type *current_map = (ieee_per_section_type *) NULL;
20502159047fSniklas   asection *s;
2051c074d1c9Sdrahn   /* Seek to the start of the data area.  */
2052c074d1c9Sdrahn   if (ieee->read_data)
2053c074d1c9Sdrahn     return TRUE;
2054c074d1c9Sdrahn   ieee->read_data = TRUE;
2055c074d1c9Sdrahn   ieee_seek (ieee, ieee->w.r.data_part);
20562159047fSniklas 
2057c074d1c9Sdrahn   /* Allocate enough space for all the section contents.  */
20582159047fSniklas   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
20592159047fSniklas     {
2060c074d1c9Sdrahn       ieee_per_section_type *per = ieee_per_section (s);
2061c88b1d6cSniklas       if ((s->flags & SEC_DEBUGGING) != 0)
2062c88b1d6cSniklas 	continue;
20632159047fSniklas       per->data = (bfd_byte *) bfd_alloc (ieee->h.abfd, s->_raw_size);
20642159047fSniklas       if (!per->data)
2065c074d1c9Sdrahn 	return FALSE;
20662159047fSniklas       per->reloc_tail_ptr =
20672159047fSniklas 	(ieee_reloc_type **) & (s->relocation);
20682159047fSniklas     }
20692159047fSniklas 
2070c074d1c9Sdrahn   while (TRUE)
20712159047fSniklas     {
20722159047fSniklas       switch (this_byte (&(ieee->h)))
20732159047fSniklas 	{
2074c074d1c9Sdrahn 	  /* IF we see anything strange then quit.  */
20752159047fSniklas 	default:
2076c074d1c9Sdrahn 	  return TRUE;
20772159047fSniklas 
20782159047fSniklas 	case ieee_set_current_section_enum:
20792159047fSniklas 	  next_byte (&(ieee->h));
20802159047fSniklas 	  section_number = must_parse_int (&(ieee->h));
20812159047fSniklas 	  s = ieee->section_table[section_number];
2082c88b1d6cSniklas 	  s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
2083c074d1c9Sdrahn 	  current_map = ieee_per_section (s);
20842159047fSniklas 	  location_ptr = current_map->data - s->vma;
2085c074d1c9Sdrahn 	  /* The document I have says that Microtec's compilers reset
2086c074d1c9Sdrahn 	     this after a sec section, even though the standard says not
2087c074d1c9Sdrahn 	     to, SO...  */
20882159047fSniklas 	  current_map->pc = s->vma;
20892159047fSniklas 	  break;
20902159047fSniklas 
20912159047fSniklas 	case ieee_e2_first_byte_enum:
20922159047fSniklas 	  next_byte (&(ieee->h));
20932159047fSniklas 	  switch (this_byte (&(ieee->h)))
20942159047fSniklas 	    {
20952159047fSniklas 	    case ieee_set_current_pc_enum & 0xff:
20962159047fSniklas 	      {
20972159047fSniklas 		bfd_vma value;
20982159047fSniklas 		ieee_symbol_index_type symbol;
20992159047fSniklas 		unsigned int extra;
2100c074d1c9Sdrahn 		bfd_boolean pcrel;
2101c074d1c9Sdrahn 
21022159047fSniklas 		next_byte (&(ieee->h));
2103c074d1c9Sdrahn 		must_parse_int (&(ieee->h));	/* Throw away section #.  */
21042159047fSniklas 		parse_expression (ieee, &value,
21052159047fSniklas 				  &symbol,
21062159047fSniklas 				  &pcrel, &extra,
21072159047fSniklas 				  0);
21082159047fSniklas 		current_map->pc = value;
21092159047fSniklas 		BFD_ASSERT ((unsigned) (value - s->vma) <= s->_raw_size);
21102159047fSniklas 	      }
21112159047fSniklas 	      break;
21122159047fSniklas 
21132159047fSniklas 	    case ieee_value_starting_address_enum & 0xff:
2114b305b0f1Sespie 	      next_byte (&(ieee->h));
2115b305b0f1Sespie 	      if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum)
2116b305b0f1Sespie 		next_byte (&(ieee->h));
2117b305b0f1Sespie 	      abfd->start_address = must_parse_int (&(ieee->h));
21182159047fSniklas 	      /* We've got to the end of the data now -  */
2119c074d1c9Sdrahn 	      return TRUE;
21202159047fSniklas 	    default:
21212159047fSniklas 	      BFD_FAIL ();
2122c074d1c9Sdrahn 	      return FALSE;
21232159047fSniklas 	    }
21242159047fSniklas 	  break;
21252159047fSniklas 	case ieee_repeat_data_enum:
21262159047fSniklas 	  {
21272159047fSniklas 	    /* Repeat the following LD or LR n times - we do this by
21282159047fSniklas 	       remembering the stream pointer before running it and
21292159047fSniklas 	       resetting it and running it n times. We special case
2130c074d1c9Sdrahn 	       the repetition of a repeat_data/load_constant.  */
21312159047fSniklas 	    unsigned int iterations;
21322159047fSniklas 	    unsigned char *start;
2133c074d1c9Sdrahn 
21342159047fSniklas 	    next_byte (&(ieee->h));
21352159047fSniklas 	    iterations = must_parse_int (&(ieee->h));
21362159047fSniklas 	    start = ieee->h.input_p;
2137c074d1c9Sdrahn 	    if (start[0] == (int) ieee_load_constant_bytes_enum
2138c074d1c9Sdrahn 		&& start[1] == 1)
21392159047fSniklas 	      {
21402159047fSniklas 		while (iterations != 0)
21412159047fSniklas 		  {
21422159047fSniklas 		    location_ptr[current_map->pc++] = start[2];
21432159047fSniklas 		    iterations--;
21442159047fSniklas 		  }
21452159047fSniklas 		next_byte (&(ieee->h));
21462159047fSniklas 		next_byte (&(ieee->h));
21472159047fSniklas 		next_byte (&(ieee->h));
21482159047fSniklas 	      }
21492159047fSniklas 	    else
21502159047fSniklas 	      {
21512159047fSniklas 		while (iterations != 0)
21522159047fSniklas 		  {
21532159047fSniklas 		    ieee->h.input_p = start;
2154c88b1d6cSniklas 		    if (!do_one (ieee, current_map, location_ptr, s,
2155c074d1c9Sdrahn 				 (int) iterations))
2156c074d1c9Sdrahn 		      return FALSE;
21572159047fSniklas 		    iterations--;
21582159047fSniklas 		  }
21592159047fSniklas 	      }
21602159047fSniklas 	  }
21612159047fSniklas 	  break;
21622159047fSniklas 	case ieee_load_constant_bytes_enum:
21632159047fSniklas 	case ieee_load_with_relocation_enum:
2164c88b1d6cSniklas 	  if (!do_one (ieee, current_map, location_ptr, s, 1))
2165c074d1c9Sdrahn 	    return FALSE;
21662159047fSniklas 	}
21672159047fSniklas     }
21682159047fSniklas }
21692159047fSniklas 
2170c074d1c9Sdrahn static bfd_boolean
ieee_new_section_hook(abfd,newsect)21712159047fSniklas ieee_new_section_hook (abfd, newsect)
21722159047fSniklas      bfd *abfd;
21732159047fSniklas      asection *newsect;
21742159047fSniklas {
2175c074d1c9Sdrahn   newsect->used_by_bfd
2176c074d1c9Sdrahn     = (PTR) bfd_alloc (abfd, (bfd_size_type) sizeof (ieee_per_section_type));
21772159047fSniklas   if (!newsect->used_by_bfd)
2178c074d1c9Sdrahn     return FALSE;
21792159047fSniklas   ieee_per_section (newsect)->data = (bfd_byte *) NULL;
21802159047fSniklas   ieee_per_section (newsect)->section = newsect;
2181c074d1c9Sdrahn   return TRUE;
21822159047fSniklas }
21832159047fSniklas 
2184c074d1c9Sdrahn static long
ieee_get_reloc_upper_bound(abfd,asect)21852159047fSniklas ieee_get_reloc_upper_bound (abfd, asect)
21862159047fSniklas      bfd *abfd;
21872159047fSniklas      sec_ptr asect;
21882159047fSniklas {
2189c88b1d6cSniklas   if ((asect->flags & SEC_DEBUGGING) != 0)
2190c88b1d6cSniklas     return 0;
21912159047fSniklas   if (! ieee_slurp_section_data (abfd))
21922159047fSniklas     return -1;
21932159047fSniklas   return (asect->reloc_count + 1) * sizeof (arelent *);
21942159047fSniklas }
21952159047fSniklas 
2196c074d1c9Sdrahn static bfd_boolean
ieee_get_section_contents(abfd,section,location,offset,count)21972159047fSniklas ieee_get_section_contents (abfd, section, location, offset, count)
21982159047fSniklas      bfd *abfd;
21992159047fSniklas      sec_ptr section;
22002159047fSniklas      PTR location;
22012159047fSniklas      file_ptr offset;
22022159047fSniklas      bfd_size_type count;
22032159047fSniklas {
2204c074d1c9Sdrahn   ieee_per_section_type *p = ieee_per_section (section);
2205c88b1d6cSniklas   if ((section->flags & SEC_DEBUGGING) != 0)
2206c88b1d6cSniklas     return _bfd_generic_get_section_contents (abfd, section, location,
2207c88b1d6cSniklas 					      offset, count);
22082159047fSniklas   ieee_slurp_section_data (abfd);
22092159047fSniklas   (void) memcpy ((PTR) location, (PTR) (p->data + offset), (unsigned) count);
2210c074d1c9Sdrahn   return TRUE;
22112159047fSniklas }
22122159047fSniklas 
2213c074d1c9Sdrahn static long
ieee_canonicalize_reloc(abfd,section,relptr,symbols)22142159047fSniklas ieee_canonicalize_reloc (abfd, section, relptr, symbols)
22152159047fSniklas      bfd *abfd;
22162159047fSniklas      sec_ptr section;
22172159047fSniklas      arelent **relptr;
22182159047fSniklas      asymbol **symbols;
22192159047fSniklas {
22202159047fSniklas   ieee_reloc_type *src = (ieee_reloc_type *) (section->relocation);
22212159047fSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
22222159047fSniklas 
2223c88b1d6cSniklas   if ((section->flags & SEC_DEBUGGING) != 0)
2224c88b1d6cSniklas     return 0;
2225c88b1d6cSniklas 
22262159047fSniklas   while (src != (ieee_reloc_type *) NULL)
22272159047fSniklas     {
2228c074d1c9Sdrahn       /* Work out which symbol to attach it this reloc to.  */
22292159047fSniklas       switch (src->symbol.letter)
22302159047fSniklas 	{
2231c88b1d6cSniklas 	case 'I':
2232c88b1d6cSniklas 	  src->relent.sym_ptr_ptr =
2233c88b1d6cSniklas 	    symbols + src->symbol.index + ieee->external_symbol_base_offset;
2234c88b1d6cSniklas 	  break;
22352159047fSniklas 	case 'X':
22362159047fSniklas 	  src->relent.sym_ptr_ptr =
22372159047fSniklas 	    symbols + src->symbol.index + ieee->external_reference_base_offset;
22382159047fSniklas 	  break;
22392159047fSniklas 	case 0:
2240b305b0f1Sespie 	  if (src->relent.sym_ptr_ptr != NULL)
22412159047fSniklas 	    src->relent.sym_ptr_ptr =
22422159047fSniklas 	      src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr;
22432159047fSniklas 	  break;
22442159047fSniklas 	default:
22452159047fSniklas 
22462159047fSniklas 	  BFD_FAIL ();
22472159047fSniklas 	}
22482159047fSniklas       *relptr++ = &src->relent;
22492159047fSniklas       src = src->next;
22502159047fSniklas     }
22512159047fSniklas   *relptr = (arelent *) NULL;
22522159047fSniklas   return section->reloc_count;
22532159047fSniklas }
22542159047fSniklas 
22552159047fSniklas static int
comp(ap,bp)22562159047fSniklas comp (ap, bp)
2257c074d1c9Sdrahn      const PTR ap;
2258c074d1c9Sdrahn      const PTR bp;
22592159047fSniklas {
22602159047fSniklas   arelent *a = *((arelent **) ap);
22612159047fSniklas   arelent *b = *((arelent **) bp);
22622159047fSniklas   return a->address - b->address;
22632159047fSniklas }
22642159047fSniklas 
2265c88b1d6cSniklas /* Write the section headers.  */
22662159047fSniklas 
2267c074d1c9Sdrahn static bfd_boolean
ieee_write_section_part(abfd)22682159047fSniklas ieee_write_section_part (abfd)
22692159047fSniklas      bfd *abfd;
22702159047fSniklas {
22712159047fSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
22722159047fSniklas   asection *s;
22732159047fSniklas   ieee->w.r.section_part = bfd_tell (abfd);
22742159047fSniklas   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
22752159047fSniklas     {
2276c88b1d6cSniklas       if (! bfd_is_abs_section (s)
2277c88b1d6cSniklas 	  && (s->flags & SEC_DEBUGGING) == 0)
22782159047fSniklas 	{
2279c88b1d6cSniklas 	  if (! ieee_write_byte (abfd, ieee_section_type_enum)
2280c88b1d6cSniklas 	      || ! ieee_write_byte (abfd,
2281c88b1d6cSniklas 				    (bfd_byte) (s->index
2282c88b1d6cSniklas 						+ IEEE_SECTION_NUMBER_BASE)))
2283c074d1c9Sdrahn 	    return FALSE;
22842159047fSniklas 
22852159047fSniklas 	  if (abfd->flags & EXEC_P)
22862159047fSniklas 	    {
2287c074d1c9Sdrahn 	      /* This image is executable, so output absolute sections.  */
2288c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_variable_A_enum)
2289c88b1d6cSniklas 		  || ! ieee_write_byte (abfd, ieee_variable_S_enum))
2290c074d1c9Sdrahn 		return FALSE;
22912159047fSniklas 	    }
22922159047fSniklas 	  else
22932159047fSniklas 	    {
2294c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_variable_C_enum))
2295c074d1c9Sdrahn 		return FALSE;
22962159047fSniklas 	    }
22972159047fSniklas 
22982159047fSniklas 	  switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM))
22992159047fSniklas 	    {
23002159047fSniklas 	    case SEC_CODE | SEC_LOAD:
23012159047fSniklas 	    case SEC_CODE:
2302c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_variable_P_enum))
2303c074d1c9Sdrahn 		return FALSE;
23042159047fSniklas 	      break;
23052159047fSniklas 	    case SEC_DATA:
23062159047fSniklas 	    default:
2307c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_variable_D_enum))
2308c074d1c9Sdrahn 		return FALSE;
23092159047fSniklas 	      break;
23102159047fSniklas 	    case SEC_ROM:
23112159047fSniklas 	    case SEC_ROM | SEC_DATA:
23122159047fSniklas 	    case SEC_ROM | SEC_LOAD:
23132159047fSniklas 	    case SEC_ROM | SEC_DATA | SEC_LOAD:
2314c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_variable_R_enum))
2315c074d1c9Sdrahn 		return FALSE;
23162159047fSniklas 	    }
23172159047fSniklas 
23182159047fSniklas 
2319c88b1d6cSniklas 	  if (! ieee_write_id (abfd, s->name))
2320c074d1c9Sdrahn 	    return FALSE;
23212159047fSniklas #if 0
23222159047fSniklas 	  ieee_write_int (abfd, 0);	/* Parent */
23232159047fSniklas 	  ieee_write_int (abfd, 0);	/* Brother */
23242159047fSniklas 	  ieee_write_int (abfd, 0);	/* Context */
23252159047fSniklas #endif
2326c074d1c9Sdrahn 	  /* Alignment.  */
2327c88b1d6cSniklas 	  if (! ieee_write_byte (abfd, ieee_section_alignment_enum)
2328c88b1d6cSniklas 	      || ! ieee_write_byte (abfd,
2329c88b1d6cSniklas 				    (bfd_byte) (s->index
2330c88b1d6cSniklas 						+ IEEE_SECTION_NUMBER_BASE))
2331c074d1c9Sdrahn 	      || ! ieee_write_int (abfd, (bfd_vma) 1 << s->alignment_power))
2332c074d1c9Sdrahn 	    return FALSE;
23332159047fSniklas 
2334c074d1c9Sdrahn 	  /* Size.  */
2335c88b1d6cSniklas 	  if (! ieee_write_2bytes (abfd, ieee_section_size_enum)
2336c88b1d6cSniklas 	      || ! ieee_write_byte (abfd,
2337c88b1d6cSniklas 				    (bfd_byte) (s->index
2338c88b1d6cSniklas 						+ IEEE_SECTION_NUMBER_BASE))
2339c88b1d6cSniklas 	      || ! ieee_write_int (abfd, s->_raw_size))
2340c074d1c9Sdrahn 	    return FALSE;
23412159047fSniklas 	  if (abfd->flags & EXEC_P)
23422159047fSniklas 	    {
2343c074d1c9Sdrahn 	      /* Relocateable sections don't have asl records.  */
2344c074d1c9Sdrahn 	      /* Vma.  */
2345c88b1d6cSniklas 	      if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum)
2346c88b1d6cSniklas 		  || ! ieee_write_byte (abfd,
2347c88b1d6cSniklas 					((bfd_byte)
2348c88b1d6cSniklas 					 (s->index
2349c88b1d6cSniklas 					  + IEEE_SECTION_NUMBER_BASE)))
2350e93f7393Sniklas 		  || ! ieee_write_int (abfd, s->lma))
2351c074d1c9Sdrahn 		return FALSE;
2352c88b1d6cSniklas 	    }
23532159047fSniklas 	}
23542159047fSniklas     }
23552159047fSniklas 
2356c074d1c9Sdrahn   return TRUE;
23572159047fSniklas }
23582159047fSniklas 
23592159047fSniklas 
2360c074d1c9Sdrahn static bfd_boolean
do_with_relocs(abfd,s)23612159047fSniklas do_with_relocs (abfd, s)
23622159047fSniklas      bfd *abfd;
23632159047fSniklas      asection *s;
23642159047fSniklas {
2365c88b1d6cSniklas   unsigned int number_of_maus_in_address =
2366c88b1d6cSniklas     bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd);
23672159047fSniklas   unsigned int relocs_to_go = s->reloc_count;
23682159047fSniklas   bfd_byte *stream = ieee_per_section (s)->data;
23692159047fSniklas   arelent **p = s->orelocation;
23702159047fSniklas   bfd_size_type current_byte_index = 0;
23712159047fSniklas 
23722159047fSniklas   qsort (s->orelocation,
23732159047fSniklas 	 relocs_to_go,
23742159047fSniklas 	 sizeof (arelent **),
23752159047fSniklas 	 comp);
23762159047fSniklas 
2377c074d1c9Sdrahn   /* Output the section preheader.  */
2378c88b1d6cSniklas   if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
2379c88b1d6cSniklas       || ! ieee_write_byte (abfd,
2380c88b1d6cSniklas 			    (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))
2381c88b1d6cSniklas       || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum)
2382c88b1d6cSniklas       || ! ieee_write_byte (abfd,
2383c88b1d6cSniklas 			    (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)))
2384c074d1c9Sdrahn     return FALSE;
2385c074d1c9Sdrahn 
2386c88b1d6cSniklas   if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0)
2387c88b1d6cSniklas     {
2388e93f7393Sniklas       if (! ieee_write_int (abfd, s->lma))
2389c074d1c9Sdrahn 	return FALSE;
2390c88b1d6cSniklas     }
2391c88b1d6cSniklas   else
2392c88b1d6cSniklas     {
2393c074d1c9Sdrahn       if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0))
2394c074d1c9Sdrahn 	return FALSE;
2395c88b1d6cSniklas     }
23962159047fSniklas 
23972159047fSniklas   if (relocs_to_go == 0)
23982159047fSniklas     {
2399c88b1d6cSniklas       /* If there aren't any relocations then output the load constant
2400c074d1c9Sdrahn 	 byte opcode rather than the load with relocation opcode.  */
24012159047fSniklas       while (current_byte_index < s->_raw_size)
24022159047fSniklas 	{
24032159047fSniklas 	  bfd_size_type run;
2404c88b1d6cSniklas 	  unsigned int MAXRUN = 127;
2405c074d1c9Sdrahn 
24062159047fSniklas 	  run = MAXRUN;
24072159047fSniklas 	  if (run > s->_raw_size - current_byte_index)
24082159047fSniklas 	    run = s->_raw_size - current_byte_index;
24092159047fSniklas 
24102159047fSniklas 	  if (run != 0)
24112159047fSniklas 	    {
2412c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum))
2413c074d1c9Sdrahn 		return FALSE;
2414c074d1c9Sdrahn 	      /* Output a stream of bytes.  */
2415c88b1d6cSniklas 	      if (! ieee_write_int (abfd, run))
2416c074d1c9Sdrahn 		return FALSE;
2417c074d1c9Sdrahn 	      if (bfd_bwrite ((PTR) (stream + current_byte_index), run, abfd)
24182159047fSniklas 		  != run)
2419c074d1c9Sdrahn 		return FALSE;
24202159047fSniklas 	      current_byte_index += run;
24212159047fSniklas 	    }
24222159047fSniklas 	}
24232159047fSniklas     }
24242159047fSniklas   else
24252159047fSniklas     {
2426c88b1d6cSniklas       if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum))
2427c074d1c9Sdrahn 	return FALSE;
24282159047fSniklas 
24292159047fSniklas       /* Output the data stream as the longest sequence of bytes
24302159047fSniklas 	 possible, allowing for the a reasonable packet size and
2431c88b1d6cSniklas 	 relocation stuffs.  */
24322159047fSniklas 
24332159047fSniklas       if ((PTR) stream == (PTR) NULL)
24342159047fSniklas 	{
2435c074d1c9Sdrahn 	  /* Outputting a section without data, fill it up.  */
2436c074d1c9Sdrahn 	  stream = (unsigned char *) bfd_zalloc (abfd, s->_raw_size);
24372159047fSniklas 	  if (!stream)
2438c074d1c9Sdrahn 	    return FALSE;
24392159047fSniklas 	}
24402159047fSniklas       while (current_byte_index < s->_raw_size)
24412159047fSniklas 	{
24422159047fSniklas 	  bfd_size_type run;
2443c88b1d6cSniklas 	  unsigned int MAXRUN = 127;
2444c074d1c9Sdrahn 
24452159047fSniklas 	  if (relocs_to_go)
24462159047fSniklas 	    {
24472159047fSniklas 	      run = (*p)->address - current_byte_index;
2448c88b1d6cSniklas 	      if (run > MAXRUN)
2449c88b1d6cSniklas 		run = MAXRUN;
24502159047fSniklas 	    }
24512159047fSniklas 	  else
24522159047fSniklas 	    run = MAXRUN;
2453c074d1c9Sdrahn 
24542159047fSniklas 	  if (run > s->_raw_size - current_byte_index)
24552159047fSniklas 	    run = s->_raw_size - current_byte_index;
24562159047fSniklas 
24572159047fSniklas 	  if (run != 0)
24582159047fSniklas 	    {
2459c074d1c9Sdrahn 	      /* Output a stream of bytes.  */
2460c88b1d6cSniklas 	      if (! ieee_write_int (abfd, run))
2461c074d1c9Sdrahn 		return FALSE;
2462c074d1c9Sdrahn 	      if (bfd_bwrite ((PTR) (stream + current_byte_index), run, abfd)
24632159047fSniklas 		  != run)
2464c074d1c9Sdrahn 		return FALSE;
24652159047fSniklas 	      current_byte_index += run;
24662159047fSniklas 	    }
2467c074d1c9Sdrahn 
2468c074d1c9Sdrahn 	  /* Output any relocations here.  */
24692159047fSniklas 	  if (relocs_to_go && (*p) && (*p)->address == current_byte_index)
24702159047fSniklas 	    {
2471c88b1d6cSniklas 	      while (relocs_to_go
2472c88b1d6cSniklas 		     && (*p) && (*p)->address == current_byte_index)
24732159047fSniklas 		{
24742159047fSniklas 		  arelent *r = *p;
2475c88b1d6cSniklas 		  bfd_signed_vma ov;
24762159047fSniklas #if 0
24772159047fSniklas 		  if (r->howto->pc_relative)
24782159047fSniklas 		    r->addend += current_byte_index;
24792159047fSniklas #endif
24802159047fSniklas 		  switch (r->howto->size)
24812159047fSniklas 		    {
24822159047fSniklas 		    case 2:
24832159047fSniklas 
2484c88b1d6cSniklas 		      ov = bfd_get_signed_32 (abfd,
24852159047fSniklas 					      stream + current_byte_index);
24862159047fSniklas 		      current_byte_index += 4;
24872159047fSniklas 		      break;
24882159047fSniklas 		    case 1:
2489c88b1d6cSniklas 		      ov = bfd_get_signed_16 (abfd,
24902159047fSniklas 					      stream + current_byte_index);
24912159047fSniklas 		      current_byte_index += 2;
24922159047fSniklas 		      break;
24932159047fSniklas 		    case 0:
2494c88b1d6cSniklas 		      ov = bfd_get_signed_8 (abfd,
24952159047fSniklas 					     stream + current_byte_index);
24962159047fSniklas 		      current_byte_index++;
24972159047fSniklas 		      break;
24982159047fSniklas 		    default:
24992159047fSniklas 		      ov = 0;
25002159047fSniklas 		      BFD_FAIL ();
2501c074d1c9Sdrahn 		      return FALSE;
25022159047fSniklas 		    }
2503c88b1d6cSniklas 
2504c88b1d6cSniklas 		  ov &= r->howto->src_mask;
2505c88b1d6cSniklas 
2506c88b1d6cSniklas 		  if (r->howto->pc_relative
2507c88b1d6cSniklas 		      && ! r->howto->pcrel_offset)
2508c88b1d6cSniklas 		    ov += r->address;
2509c88b1d6cSniklas 
2510c88b1d6cSniklas 		  if (! ieee_write_byte (abfd,
2511c88b1d6cSniklas 					 ieee_function_either_open_b_enum))
2512c074d1c9Sdrahn 		    return FALSE;
2513c88b1d6cSniklas 
25142159047fSniklas /*		  abort();*/
25152159047fSniklas 
25162159047fSniklas 		  if (r->sym_ptr_ptr != (asymbol **) NULL)
25172159047fSniklas 		    {
2518c88b1d6cSniklas 		      if (! ieee_write_expression (abfd, r->addend + ov,
25192159047fSniklas 						   *(r->sym_ptr_ptr),
2520c88b1d6cSniklas 						   r->howto->pc_relative,
2521c074d1c9Sdrahn 						   (unsigned) s->index))
2522c074d1c9Sdrahn 			return FALSE;
25232159047fSniklas 		    }
25242159047fSniklas 		  else
25252159047fSniklas 		    {
2526c88b1d6cSniklas 		      if (! ieee_write_expression (abfd, r->addend + ov,
25272159047fSniklas 						   (asymbol *) NULL,
2528c88b1d6cSniklas 						   r->howto->pc_relative,
2529c074d1c9Sdrahn 						   (unsigned) s->index))
2530c074d1c9Sdrahn 			return FALSE;
25312159047fSniklas 		    }
25322159047fSniklas 
2533c88b1d6cSniklas 		  if (number_of_maus_in_address
2534c88b1d6cSniklas 		      != bfd_get_reloc_size (r->howto))
25352159047fSniklas 		    {
2536c074d1c9Sdrahn 		      bfd_vma rsize = bfd_get_reloc_size (r->howto);
2537c074d1c9Sdrahn 		      if (! ieee_write_int (abfd, rsize))
2538c074d1c9Sdrahn 			return FALSE;
25392159047fSniklas 		    }
2540c88b1d6cSniklas 		  if (! ieee_write_byte (abfd,
2541c88b1d6cSniklas 					 ieee_function_either_close_b_enum))
2542c074d1c9Sdrahn 		    return FALSE;
25432159047fSniklas 
25442159047fSniklas 		  relocs_to_go--;
25452159047fSniklas 		  p++;
25462159047fSniklas 		}
25472159047fSniklas 
25482159047fSniklas 	    }
25492159047fSniklas 	}
25502159047fSniklas     }
2551c88b1d6cSniklas 
2552c074d1c9Sdrahn   return TRUE;
25532159047fSniklas }
25542159047fSniklas 
2555c88b1d6cSniklas /* If there are no relocations in the output section then we can be
2556c88b1d6cSniklas    clever about how we write.  We block items up into a max of 127
2557c88b1d6cSniklas    bytes.  */
25582159047fSniklas 
2559c074d1c9Sdrahn static bfd_boolean
do_as_repeat(abfd,s)25602159047fSniklas do_as_repeat (abfd, s)
25612159047fSniklas      bfd *abfd;
25622159047fSniklas      asection *s;
25632159047fSniklas {
25642159047fSniklas   if (s->_raw_size)
25652159047fSniklas     {
2566c88b1d6cSniklas       if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
2567c88b1d6cSniklas 	  || ! ieee_write_byte (abfd,
2568c88b1d6cSniklas 				(bfd_byte) (s->index
2569c88b1d6cSniklas 					    + IEEE_SECTION_NUMBER_BASE))
2570c88b1d6cSniklas 	  || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8)
2571c88b1d6cSniklas 	  || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff)
2572c88b1d6cSniklas 	  || ! ieee_write_byte (abfd,
2573c88b1d6cSniklas 				(bfd_byte) (s->index
2574c074d1c9Sdrahn 					    + IEEE_SECTION_NUMBER_BASE)))
2575c074d1c9Sdrahn 	return FALSE;
2576c074d1c9Sdrahn 
2577c074d1c9Sdrahn       if ((abfd->flags & EXEC_P) != 0)
2578c074d1c9Sdrahn 	{
2579c074d1c9Sdrahn 	  if (! ieee_write_int (abfd, s->lma))
2580c074d1c9Sdrahn 	    return FALSE;
2581c074d1c9Sdrahn 	}
2582c074d1c9Sdrahn       else
2583c074d1c9Sdrahn 	{
2584c074d1c9Sdrahn 	  if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0))
2585c074d1c9Sdrahn 	    return FALSE;
2586c074d1c9Sdrahn 	}
2587c074d1c9Sdrahn 
2588c074d1c9Sdrahn       if (! ieee_write_byte (abfd, ieee_repeat_data_enum)
2589c88b1d6cSniklas 	  || ! ieee_write_int (abfd, s->_raw_size)
2590c88b1d6cSniklas 	  || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)
2591c88b1d6cSniklas 	  || ! ieee_write_byte (abfd, 1)
2592c88b1d6cSniklas 	  || ! ieee_write_byte (abfd, 0))
2593c074d1c9Sdrahn 	return FALSE;
25942159047fSniklas     }
25952159047fSniklas 
2596c074d1c9Sdrahn   return TRUE;
2597c88b1d6cSniklas }
2598c88b1d6cSniklas 
2599c074d1c9Sdrahn static bfd_boolean
do_without_relocs(abfd,s)26002159047fSniklas do_without_relocs (abfd, s)
26012159047fSniklas      bfd *abfd;
26022159047fSniklas      asection *s;
26032159047fSniklas {
26042159047fSniklas   bfd_byte *stream = ieee_per_section (s)->data;
26052159047fSniklas 
26062159047fSniklas   if (stream == 0 || ((s->flags & SEC_LOAD) == 0))
26072159047fSniklas     {
2608c88b1d6cSniklas       if (! do_as_repeat (abfd, s))
2609c074d1c9Sdrahn 	return FALSE;
26102159047fSniklas     }
26112159047fSniklas   else
26122159047fSniklas     {
26132159047fSniklas       unsigned int i;
2614c074d1c9Sdrahn 
26152159047fSniklas       for (i = 0; i < s->_raw_size; i++)
26162159047fSniklas 	{
26172159047fSniklas 	  if (stream[i] != 0)
26182159047fSniklas 	    {
2619c88b1d6cSniklas 	      if (! do_with_relocs (abfd, s))
2620c074d1c9Sdrahn 		return FALSE;
2621c074d1c9Sdrahn 	      return TRUE;
26222159047fSniklas 	    }
26232159047fSniklas 	}
2624c88b1d6cSniklas       if (! do_as_repeat (abfd, s))
2625c074d1c9Sdrahn 	return FALSE;
26262159047fSniklas     }
26272159047fSniklas 
2628c074d1c9Sdrahn   return TRUE;
26292159047fSniklas }
26302159047fSniklas 
26312159047fSniklas 
26322159047fSniklas static unsigned char *output_ptr_start;
26332159047fSniklas static unsigned char *output_ptr;
26342159047fSniklas static unsigned char *output_ptr_end;
26352159047fSniklas static unsigned char *input_ptr_start;
26362159047fSniklas static unsigned char *input_ptr;
26372159047fSniklas static unsigned char *input_ptr_end;
26382159047fSniklas static bfd *input_bfd;
26392159047fSniklas static bfd *output_bfd;
26402159047fSniklas static int output_buffer;
26412159047fSniklas 
2642c074d1c9Sdrahn static bfd_boolean
ieee_mkobject(abfd)2643c074d1c9Sdrahn ieee_mkobject (abfd)
2644c074d1c9Sdrahn      bfd *abfd;
2645c074d1c9Sdrahn {
2646c074d1c9Sdrahn   bfd_size_type amt;
2647c074d1c9Sdrahn 
2648c074d1c9Sdrahn   output_ptr_start = NULL;
2649c074d1c9Sdrahn   output_ptr = NULL;
2650c074d1c9Sdrahn   output_ptr_end = NULL;
2651c074d1c9Sdrahn   input_ptr_start = NULL;
2652c074d1c9Sdrahn   input_ptr = NULL;
2653c074d1c9Sdrahn   input_ptr_end = NULL;
2654c074d1c9Sdrahn   input_bfd = NULL;
2655c074d1c9Sdrahn   output_bfd = NULL;
2656c074d1c9Sdrahn   output_buffer = 0;
2657c074d1c9Sdrahn   amt = sizeof (ieee_data_type);
2658c074d1c9Sdrahn   abfd->tdata.ieee_data = (ieee_data_type *) bfd_zalloc (abfd, amt);
2659c074d1c9Sdrahn   return abfd->tdata.ieee_data != NULL;
2660c074d1c9Sdrahn }
2661c074d1c9Sdrahn 
26622159047fSniklas static void
fill()26632159047fSniklas fill ()
26642159047fSniklas {
2665c074d1c9Sdrahn   bfd_size_type amt = input_ptr_end - input_ptr_start;
26662159047fSniklas   /* FIXME: Check return value.  I'm not sure whether it needs to read
26672159047fSniklas      the entire buffer or not.  */
2668c074d1c9Sdrahn   bfd_bread ((PTR) input_ptr_start, amt, input_bfd);
26692159047fSniklas   input_ptr = input_ptr_start;
26702159047fSniklas }
2671c074d1c9Sdrahn 
26722159047fSniklas static void
flush()26732159047fSniklas flush ()
26742159047fSniklas {
2675c074d1c9Sdrahn   bfd_size_type amt = output_ptr - output_ptr_start;
2676c074d1c9Sdrahn 
2677c074d1c9Sdrahn   if (bfd_bwrite ((PTR) (output_ptr_start), amt, output_bfd) != amt)
26782159047fSniklas     abort ();
26792159047fSniklas   output_ptr = output_ptr_start;
26802159047fSniklas   output_buffer++;
26812159047fSniklas }
26822159047fSniklas 
26832159047fSniklas #define THIS() ( *input_ptr )
26842159047fSniklas #define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); }
26852159047fSniklas #define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end)  flush(); }
26862159047fSniklas 
26872159047fSniklas static void
write_int(value)26882159047fSniklas write_int (value)
26892159047fSniklas      int value;
26902159047fSniklas {
26912159047fSniklas   if (value >= 0 && value <= 127)
26922159047fSniklas     {
26932159047fSniklas       OUT (value);
26942159047fSniklas     }
26952159047fSniklas   else
26962159047fSniklas     {
26972159047fSniklas       unsigned int length;
26982159047fSniklas       /* How many significant bytes ?  */
2699c074d1c9Sdrahn       /* FIXME FOR LONGER INTS.  */
27002159047fSniklas       if (value & 0xff000000)
27012159047fSniklas 	length = 4;
27022159047fSniklas       else if (value & 0x00ff0000)
27032159047fSniklas 	length = 3;
27042159047fSniklas       else if (value & 0x0000ff00)
27052159047fSniklas 	length = 2;
27062159047fSniklas       else
27072159047fSniklas 	length = 1;
27082159047fSniklas 
27092159047fSniklas       OUT ((int) ieee_number_repeat_start_enum + length);
27102159047fSniklas       switch (length)
27112159047fSniklas 	{
27122159047fSniklas 	case 4:
27132159047fSniklas 	  OUT (value >> 24);
27142159047fSniklas 	case 3:
27152159047fSniklas 	  OUT (value >> 16);
27162159047fSniklas 	case 2:
27172159047fSniklas 	  OUT (value >> 8);
27182159047fSniklas 	case 1:
27192159047fSniklas 	  OUT (value);
27202159047fSniklas 	}
27212159047fSniklas     }
27222159047fSniklas }
27232159047fSniklas 
27242159047fSniklas static void
copy_id()27252159047fSniklas copy_id ()
27262159047fSniklas {
27272159047fSniklas   int length = THIS ();
27282159047fSniklas   char ch;
2729c074d1c9Sdrahn 
27302159047fSniklas   OUT (length);
27312159047fSniklas   NEXT ();
27322159047fSniklas   while (length--)
27332159047fSniklas     {
27342159047fSniklas       ch = THIS ();
27352159047fSniklas       OUT (ch);
27362159047fSniklas       NEXT ();
27372159047fSniklas     }
27382159047fSniklas }
27392159047fSniklas 
27402159047fSniklas #define VAR(x) ((x | 0x80))
27412159047fSniklas static void
copy_expression()27422159047fSniklas copy_expression ()
27432159047fSniklas {
27442159047fSniklas   int stack[10];
27452159047fSniklas   int *tos = stack;
2746c074d1c9Sdrahn   int value;
2747c074d1c9Sdrahn 
27482159047fSniklas   while (1)
27492159047fSniklas     {
27502159047fSniklas       switch (THIS ())
27512159047fSniklas 	{
27522159047fSniklas 	case 0x84:
27532159047fSniklas 	  NEXT ();
27542159047fSniklas 	  value = THIS ();
27552159047fSniklas 	  NEXT ();
27562159047fSniklas 	  value = (value << 8) | THIS ();
27572159047fSniklas 	  NEXT ();
27582159047fSniklas 	  value = (value << 8) | THIS ();
27592159047fSniklas 	  NEXT ();
27602159047fSniklas 	  value = (value << 8) | THIS ();
27612159047fSniklas 	  NEXT ();
27622159047fSniklas 	  *tos++ = value;
27632159047fSniklas 	  break;
27642159047fSniklas 	case 0x83:
27652159047fSniklas 	  NEXT ();
27662159047fSniklas 	  value = THIS ();
27672159047fSniklas 	  NEXT ();
27682159047fSniklas 	  value = (value << 8) | THIS ();
27692159047fSniklas 	  NEXT ();
27702159047fSniklas 	  value = (value << 8) | THIS ();
27712159047fSniklas 	  NEXT ();
27722159047fSniklas 	  *tos++ = value;
27732159047fSniklas 	  break;
27742159047fSniklas 	case 0x82:
27752159047fSniklas 	  NEXT ();
27762159047fSniklas 	  value = THIS ();
27772159047fSniklas 	  NEXT ();
27782159047fSniklas 	  value = (value << 8) | THIS ();
27792159047fSniklas 	  NEXT ();
27802159047fSniklas 	  *tos++ = value;
27812159047fSniklas 	  break;
27822159047fSniklas 	case 0x81:
27832159047fSniklas 	  NEXT ();
27842159047fSniklas 	  value = THIS ();
27852159047fSniklas 	  NEXT ();
27862159047fSniklas 	  *tos++ = value;
27872159047fSniklas 	  break;
27882159047fSniklas 	case 0x80:
27892159047fSniklas 	  NEXT ();
27902159047fSniklas 	  *tos++ = 0;
27912159047fSniklas 	  break;
27922159047fSniklas 	default:
27932159047fSniklas 	  if (THIS () > 0x84)
27942159047fSniklas 	    {
2795c074d1c9Sdrahn 	      /* Not a number, just bug out with the answer.  */
27962159047fSniklas 	      write_int (*(--tos));
27972159047fSniklas 	      return;
27982159047fSniklas 	    }
27992159047fSniklas 	  *tos++ = THIS ();
28002159047fSniklas 	  NEXT ();
28012159047fSniklas 	  break;
28022159047fSniklas 	case 0xa5:
2803c074d1c9Sdrahn 	  /* PLUS anything.  */
2804c074d1c9Sdrahn 	  value = *(--tos);
28052159047fSniklas 	  value += *(--tos);
28062159047fSniklas 	  *tos++ = value;
28072159047fSniklas 	  NEXT ();
28082159047fSniklas 	  break;
28092159047fSniklas 	case VAR ('R'):
28102159047fSniklas 	  {
28112159047fSniklas 	    int section_number;
28122159047fSniklas 	    ieee_data_type *ieee;
28132159047fSniklas 	    asection *s;
2814c074d1c9Sdrahn 
28152159047fSniklas 	    NEXT ();
28162159047fSniklas 	    section_number = THIS ();
28172159047fSniklas 
28182159047fSniklas 	    NEXT ();
28192159047fSniklas 	    ieee = IEEE_DATA (input_bfd);
28202159047fSniklas 	    s = ieee->section_table[section_number];
28212159047fSniklas 	    value = 0;
2822c074d1c9Sdrahn 	    if (s->output_section)
2823c074d1c9Sdrahn 	      value = s->output_section->lma;
28242159047fSniklas 	    value += s->output_offset;
28252159047fSniklas 	    *tos++ = value;
28262159047fSniklas 	  }
28272159047fSniklas 	  break;
28282159047fSniklas 	case 0x90:
28292159047fSniklas 	  {
28302159047fSniklas 	    NEXT ();
28312159047fSniklas 	    write_int (*(--tos));
28322159047fSniklas 	    OUT (0x90);
28332159047fSniklas 	    return;
28342159047fSniklas 	  }
28352159047fSniklas 	}
28362159047fSniklas     }
28372159047fSniklas }
28382159047fSniklas 
28392159047fSniklas /* Drop the int in the buffer, and copy a null into the gap, which we
28402159047fSniklas    will overwrite later */
28412159047fSniklas 
28422159047fSniklas static void
fill_int(buf)28432159047fSniklas fill_int (buf)
28442159047fSniklas      struct output_buffer_struct *buf;
28452159047fSniklas {
28462159047fSniklas   if (buf->buffer == output_buffer)
28472159047fSniklas     {
2848c074d1c9Sdrahn       /* Still a chance to output the size.  */
28492159047fSniklas       int value = output_ptr - buf->ptrp + 3;
28502159047fSniklas       buf->ptrp[0] = value >> 24;
28512159047fSniklas       buf->ptrp[1] = value >> 16;
28522159047fSniklas       buf->ptrp[2] = value >> 8;
28532159047fSniklas       buf->ptrp[3] = value >> 0;
28542159047fSniklas     }
28552159047fSniklas }
28562159047fSniklas 
28572159047fSniklas static void
drop_int(buf)28582159047fSniklas drop_int (buf)
28592159047fSniklas      struct output_buffer_struct *buf;
28602159047fSniklas {
28612159047fSniklas   int type = THIS ();
28622159047fSniklas   int ch;
2863c074d1c9Sdrahn 
28642159047fSniklas   if (type <= 0x84)
28652159047fSniklas     {
28662159047fSniklas       NEXT ();
28672159047fSniklas       switch (type)
28682159047fSniklas 	{
28692159047fSniklas 	case 0x84:
28702159047fSniklas 	  ch = THIS ();
28712159047fSniklas 	  NEXT ();
28722159047fSniklas 	case 0x83:
28732159047fSniklas 	  ch = THIS ();
28742159047fSniklas 	  NEXT ();
28752159047fSniklas 	case 0x82:
28762159047fSniklas 	  ch = THIS ();
28772159047fSniklas 	  NEXT ();
28782159047fSniklas 	case 0x81:
28792159047fSniklas 	  ch = THIS ();
28802159047fSniklas 	  NEXT ();
28812159047fSniklas 	case 0x80:
28822159047fSniklas 	  break;
28832159047fSniklas 	}
28842159047fSniklas     }
28852159047fSniklas   OUT (0x84);
28862159047fSniklas   buf->ptrp = output_ptr;
28872159047fSniklas   buf->buffer = output_buffer;
28882159047fSniklas   OUT (0);
28892159047fSniklas   OUT (0);
28902159047fSniklas   OUT (0);
28912159047fSniklas   OUT (0);
28922159047fSniklas }
28932159047fSniklas 
28942159047fSniklas static void
copy_int()28952159047fSniklas copy_int ()
28962159047fSniklas {
28972159047fSniklas   int type = THIS ();
28982159047fSniklas   int ch;
28992159047fSniklas   if (type <= 0x84)
29002159047fSniklas     {
29012159047fSniklas       OUT (type);
29022159047fSniklas       NEXT ();
29032159047fSniklas       switch (type)
29042159047fSniklas 	{
29052159047fSniklas 	case 0x84:
29062159047fSniklas 	  ch = THIS ();
29072159047fSniklas 	  NEXT ();
29082159047fSniklas 	  OUT (ch);
29092159047fSniklas 	case 0x83:
29102159047fSniklas 	  ch = THIS ();
29112159047fSniklas 	  NEXT ();
29122159047fSniklas 	  OUT (ch);
29132159047fSniklas 	case 0x82:
29142159047fSniklas 	  ch = THIS ();
29152159047fSniklas 	  NEXT ();
29162159047fSniklas 	  OUT (ch);
29172159047fSniklas 	case 0x81:
29182159047fSniklas 	  ch = THIS ();
29192159047fSniklas 	  NEXT ();
29202159047fSniklas 	  OUT (ch);
29212159047fSniklas 	case 0x80:
29222159047fSniklas 	  break;
29232159047fSniklas 	}
29242159047fSniklas     }
29252159047fSniklas }
29262159047fSniklas 
29272159047fSniklas #define ID copy_id()
29282159047fSniklas #define INT copy_int()
29292159047fSniklas #define EXP copy_expression()
29302159047fSniklas #define INTn(q) copy_int()
29312159047fSniklas #define EXPn(q) copy_expression()
29322159047fSniklas 
29332159047fSniklas static void
f1_record()29342159047fSniklas f1_record ()
29352159047fSniklas {
29362159047fSniklas   int ch;
2937c074d1c9Sdrahn 
2938c074d1c9Sdrahn   /* ATN record.  */
29392159047fSniklas   NEXT ();
29402159047fSniklas   ch = THIS ();
29412159047fSniklas   switch (ch)
29422159047fSniklas     {
29432159047fSniklas     default:
29442159047fSniklas       OUT (0xf1);
29452159047fSniklas       OUT (ch);
29462159047fSniklas       break;
29472159047fSniklas     case 0xc9:
29482159047fSniklas       NEXT ();
29492159047fSniklas       OUT (0xf1);
29502159047fSniklas       OUT (0xc9);
29512159047fSniklas       INT;
29522159047fSniklas       INT;
29532159047fSniklas       ch = THIS ();
29542159047fSniklas       switch (ch)
29552159047fSniklas 	{
29562159047fSniklas 	case 0x16:
29572159047fSniklas 	  NEXT ();
29582159047fSniklas 	  break;
29592159047fSniklas 	case 0x01:
29602159047fSniklas 	  NEXT ();
29612159047fSniklas 	  break;
29622159047fSniklas 	case 0x00:
29632159047fSniklas 	  NEXT ();
29642159047fSniklas 	  INT;
29652159047fSniklas 	  break;
29662159047fSniklas 	case 0x03:
29672159047fSniklas 	  NEXT ();
29682159047fSniklas 	  INT;
29692159047fSniklas 	  break;
29702159047fSniklas 	case 0x13:
29712159047fSniklas 	  EXPn (instruction address);
29722159047fSniklas 	  break;
29732159047fSniklas 	default:
29742159047fSniklas 	  break;
29752159047fSniklas 	}
29762159047fSniklas       break;
29772159047fSniklas     case 0xd8:
2978c074d1c9Sdrahn       /* EXternal ref.  */
29792159047fSniklas       NEXT ();
29802159047fSniklas       OUT (0xf1);
29812159047fSniklas       OUT (0xd8);
29822159047fSniklas       EXP;
29832159047fSniklas       EXP;
29842159047fSniklas       EXP;
29852159047fSniklas       EXP;
29862159047fSniklas       break;
29872159047fSniklas     case 0xce:
29882159047fSniklas       NEXT ();
29892159047fSniklas       OUT (0xf1);
29902159047fSniklas       OUT (0xce);
29912159047fSniklas       INT;
29922159047fSniklas       INT;
29932159047fSniklas       ch = THIS ();
29942159047fSniklas       INT;
29952159047fSniklas       switch (ch)
29962159047fSniklas 	{
29972159047fSniklas 	case 0x01:
29982159047fSniklas 	  INT;
29992159047fSniklas 	  INT;
30002159047fSniklas 	  break;
30012159047fSniklas 	case 0x02:
30022159047fSniklas 	  INT;
30032159047fSniklas 	  break;
30042159047fSniklas 	case 0x04:
30052159047fSniklas 	  EXPn (external function);
30062159047fSniklas 	  break;
30072159047fSniklas 	case 0x05:
30082159047fSniklas 	  break;
30092159047fSniklas 	case 0x07:
30102159047fSniklas 	  INTn (line number);
30112159047fSniklas 	  INT;
30122159047fSniklas 	case 0x08:
30132159047fSniklas 	  break;
30142159047fSniklas 	case 0x0a:
30152159047fSniklas 	  INTn (locked register);
30162159047fSniklas 	  INT;
30172159047fSniklas 	  break;
30182159047fSniklas 	case 0x3f:
30192159047fSniklas 	  copy_till_end ();
30202159047fSniklas 	  break;
30212159047fSniklas 	case 0x3e:
30222159047fSniklas 	  copy_till_end ();
30232159047fSniklas 	  break;
30242159047fSniklas 	case 0x40:
30252159047fSniklas 	  copy_till_end ();
30262159047fSniklas 	  break;
30272159047fSniklas 	case 0x41:
30282159047fSniklas 	  ID;
30292159047fSniklas 	  break;
30302159047fSniklas 	}
30312159047fSniklas     }
30322159047fSniklas }
30332159047fSniklas 
30342159047fSniklas static void
f0_record()30352159047fSniklas f0_record ()
30362159047fSniklas {
3037c074d1c9Sdrahn   /* Attribute record.  */
30382159047fSniklas   NEXT ();
30392159047fSniklas   OUT (0xf0);
30402159047fSniklas   INTn (Symbol name);
30412159047fSniklas   ID;
30422159047fSniklas }
30432159047fSniklas 
30442159047fSniklas static void
copy_till_end()30452159047fSniklas copy_till_end ()
30462159047fSniklas {
30472159047fSniklas   int ch = THIS ();
3048c074d1c9Sdrahn 
30492159047fSniklas   while (1)
30502159047fSniklas     {
30512159047fSniklas       while (ch <= 0x80)
30522159047fSniklas 	{
30532159047fSniklas 	  OUT (ch);
30542159047fSniklas 	  NEXT ();
30552159047fSniklas 	  ch = THIS ();
30562159047fSniklas 	}
30572159047fSniklas       switch (ch)
30582159047fSniklas 	{
30592159047fSniklas 	case 0x84:
30602159047fSniklas 	  OUT (THIS ());
30612159047fSniklas 	  NEXT ();
30622159047fSniklas 	case 0x83:
30632159047fSniklas 	  OUT (THIS ());
30642159047fSniklas 	  NEXT ();
30652159047fSniklas 	case 0x82:
30662159047fSniklas 	  OUT (THIS ());
30672159047fSniklas 	  NEXT ();
30682159047fSniklas 	case 0x81:
30692159047fSniklas 	  OUT (THIS ());
30702159047fSniklas 	  NEXT ();
30712159047fSniklas 	  OUT (THIS ());
30722159047fSniklas 	  NEXT ();
30732159047fSniklas 
30742159047fSniklas 	  ch = THIS ();
30752159047fSniklas 	  break;
30762159047fSniklas 	default:
30772159047fSniklas 	  return;
30782159047fSniklas 	}
30792159047fSniklas     }
30802159047fSniklas 
30812159047fSniklas }
30822159047fSniklas 
30832159047fSniklas static void
f2_record()30842159047fSniklas f2_record ()
30852159047fSniklas {
30862159047fSniklas   NEXT ();
30872159047fSniklas   OUT (0xf2);
30882159047fSniklas   INT;
30892159047fSniklas   NEXT ();
30902159047fSniklas   OUT (0xce);
30912159047fSniklas   INT;
30922159047fSniklas   copy_till_end ();
30932159047fSniklas }
30942159047fSniklas 
30952159047fSniklas 
30962159047fSniklas static void
f8_record()30972159047fSniklas f8_record ()
30982159047fSniklas {
30992159047fSniklas   int ch;
31002159047fSniklas   NEXT ();
31012159047fSniklas   ch = THIS ();
31022159047fSniklas   switch (ch)
31032159047fSniklas     {
31042159047fSniklas     case 0x01:
31052159047fSniklas     case 0x02:
31062159047fSniklas     case 0x03:
3107c074d1c9Sdrahn       /* Unique typedefs for module.  */
3108c074d1c9Sdrahn       /* GLobal typedefs.   */
3109c074d1c9Sdrahn       /* High level module scope beginning.  */
31102159047fSniklas       {
31112159047fSniklas 	struct output_buffer_struct ob;
3112c074d1c9Sdrahn 
31132159047fSniklas 	NEXT ();
31142159047fSniklas 	OUT (0xf8);
31152159047fSniklas 	OUT (ch);
31162159047fSniklas 	drop_int (&ob);
31172159047fSniklas 	ID;
31182159047fSniklas 
31192159047fSniklas 	block ();
31202159047fSniklas 
31212159047fSniklas 	NEXT ();
31222159047fSniklas 	fill_int (&ob);
31232159047fSniklas 	OUT (0xf9);
31242159047fSniklas       }
31252159047fSniklas       break;
31262159047fSniklas     case 0x04:
3127c074d1c9Sdrahn       /* Global function.  */
31282159047fSniklas       {
31292159047fSniklas 	struct output_buffer_struct ob;
3130c074d1c9Sdrahn 
31312159047fSniklas 	NEXT ();
31322159047fSniklas 	OUT (0xf8);
31332159047fSniklas 	OUT (0x04);
31342159047fSniklas 	drop_int (&ob);
31352159047fSniklas 	ID;
31362159047fSniklas 	INTn (stack size);
31372159047fSniklas 	INTn (ret val);
31382159047fSniklas 	EXPn (offset);
31392159047fSniklas 
31402159047fSniklas 	block ();
31412159047fSniklas 
31422159047fSniklas 	NEXT ();
31432159047fSniklas 	OUT (0xf9);
31442159047fSniklas 	EXPn (size of block);
31452159047fSniklas 	fill_int (&ob);
31462159047fSniklas       }
31472159047fSniklas       break;
31482159047fSniklas 
31492159047fSniklas     case 0x05:
3150c074d1c9Sdrahn       /* File name for source line numbers.  */
31512159047fSniklas       {
31522159047fSniklas 	struct output_buffer_struct ob;
3153c074d1c9Sdrahn 
31542159047fSniklas 	NEXT ();
31552159047fSniklas 	OUT (0xf8);
31562159047fSniklas 	OUT (0x05);
31572159047fSniklas 	drop_int (&ob);
31582159047fSniklas 	ID;
31592159047fSniklas 	INTn (year);
31602159047fSniklas 	INTn (month);
31612159047fSniklas 	INTn (day);
31622159047fSniklas 	INTn (hour);
31632159047fSniklas 	INTn (monute);
31642159047fSniklas 	INTn (second);
31652159047fSniklas 	block ();
31662159047fSniklas 	NEXT ();
31672159047fSniklas 	OUT (0xf9);
31682159047fSniklas 	fill_int (&ob);
31692159047fSniklas       }
31702159047fSniklas       break;
31712159047fSniklas 
31722159047fSniklas     case 0x06:
3173c074d1c9Sdrahn       /* Local function.  */
31742159047fSniklas       {
31752159047fSniklas 	struct output_buffer_struct ob;
3176c074d1c9Sdrahn 
31772159047fSniklas 	NEXT ();
31782159047fSniklas 	OUT (0xf8);
31792159047fSniklas 	OUT (0x06);
31802159047fSniklas 	drop_int (&ob);
31812159047fSniklas 	ID;
31822159047fSniklas 	INTn (stack size);
31832159047fSniklas 	INTn (type return);
31842159047fSniklas 	EXPn (offset);
31852159047fSniklas 	block ();
31862159047fSniklas 	NEXT ();
31872159047fSniklas 	OUT (0xf9);
31882159047fSniklas 	EXPn (size);
31892159047fSniklas 	fill_int (&ob);
31902159047fSniklas       }
31912159047fSniklas       break;
31922159047fSniklas 
31932159047fSniklas     case 0x0a:
31942159047fSniklas       /* Assembler module scope beginning -  */
31952159047fSniklas       {
31962159047fSniklas 	struct output_buffer_struct ob;
31972159047fSniklas 
31982159047fSniklas 	NEXT ();
31992159047fSniklas 	OUT (0xf8);
32002159047fSniklas 	OUT (0x0a);
32012159047fSniklas 	drop_int (&ob);
32022159047fSniklas 	ID;
32032159047fSniklas 	ID;
32042159047fSniklas 	INT;
32052159047fSniklas 	ID;
32062159047fSniklas 	INT;
32072159047fSniklas 	INT;
32082159047fSniklas 	INT;
32092159047fSniklas 	INT;
32102159047fSniklas 	INT;
32112159047fSniklas 	INT;
32122159047fSniklas 
32132159047fSniklas 	block ();
32142159047fSniklas 
32152159047fSniklas 	NEXT ();
32162159047fSniklas 	OUT (0xf9);
32172159047fSniklas 	fill_int (&ob);
32182159047fSniklas       }
32192159047fSniklas       break;
32202159047fSniklas     case 0x0b:
32212159047fSniklas       {
32222159047fSniklas 	struct output_buffer_struct ob;
3223c074d1c9Sdrahn 
32242159047fSniklas 	NEXT ();
32252159047fSniklas 	OUT (0xf8);
32262159047fSniklas 	OUT (0x0b);
32272159047fSniklas 	drop_int (&ob);
32282159047fSniklas 	ID;
32292159047fSniklas 	INT;
32302159047fSniklas 	INTn (section index);
32312159047fSniklas 	EXPn (offset);
32322159047fSniklas 	INTn (stuff);
32332159047fSniklas 
32342159047fSniklas 	block ();
32352159047fSniklas 
32362159047fSniklas 	OUT (0xf9);
32372159047fSniklas 	NEXT ();
32382159047fSniklas 	EXPn (Size in Maus);
32392159047fSniklas 	fill_int (&ob);
32402159047fSniklas       }
32412159047fSniklas       break;
32422159047fSniklas     }
32432159047fSniklas }
32442159047fSniklas 
32452159047fSniklas static void
e2_record()32462159047fSniklas e2_record ()
32472159047fSniklas {
32482159047fSniklas   OUT (0xe2);
32492159047fSniklas   NEXT ();
32502159047fSniklas   OUT (0xce);
32512159047fSniklas   NEXT ();
32522159047fSniklas   INT;
32532159047fSniklas   EXP;
32542159047fSniklas }
32552159047fSniklas 
32562159047fSniklas static void
block()32572159047fSniklas block ()
32582159047fSniklas {
32592159047fSniklas   int ch;
3260c074d1c9Sdrahn 
32612159047fSniklas   while (1)
32622159047fSniklas     {
32632159047fSniklas       ch = THIS ();
32642159047fSniklas       switch (ch)
32652159047fSniklas 	{
32662159047fSniklas 	case 0xe1:
32672159047fSniklas 	case 0xe5:
32682159047fSniklas 	  return;
32692159047fSniklas 	case 0xf9:
32702159047fSniklas 	  return;
32712159047fSniklas 	case 0xf0:
32722159047fSniklas 	  f0_record ();
32732159047fSniklas 	  break;
32742159047fSniklas 	case 0xf1:
32752159047fSniklas 	  f1_record ();
32762159047fSniklas 	  break;
32772159047fSniklas 	case 0xf2:
32782159047fSniklas 	  f2_record ();
32792159047fSniklas 	  break;
32802159047fSniklas 	case 0xf8:
32812159047fSniklas 	  f8_record ();
32822159047fSniklas 	  break;
32832159047fSniklas 	case 0xe2:
32842159047fSniklas 	  e2_record ();
32852159047fSniklas 	  break;
32862159047fSniklas 
32872159047fSniklas 	}
32882159047fSniklas     }
32892159047fSniklas }
32902159047fSniklas 
32912159047fSniklas 
3292c074d1c9Sdrahn /* Moves all the debug information from the source bfd to the output
3293c074d1c9Sdrahn    bfd, and relocates any expressions it finds.  */
32942159047fSniklas 
32952159047fSniklas static void
relocate_debug(output,input)32962159047fSniklas relocate_debug (output, input)
3297b305b0f1Sespie      bfd *output ATTRIBUTE_UNUSED;
32982159047fSniklas      bfd *input;
32992159047fSniklas {
33002159047fSniklas #define IBS 400
33012159047fSniklas #define OBS 400
33022159047fSniklas   unsigned char input_buffer[IBS];
33032159047fSniklas 
33042159047fSniklas   input_ptr_start = input_ptr = input_buffer;
33052159047fSniklas   input_ptr_end = input_buffer + IBS;
33062159047fSniklas   input_bfd = input;
33072159047fSniklas   /* FIXME: Check return value.  I'm not sure whether it needs to read
33082159047fSniklas      the entire buffer or not.  */
3309c074d1c9Sdrahn   bfd_bread ((PTR) input_ptr_start, (bfd_size_type) IBS, input);
33102159047fSniklas   block ();
33112159047fSniklas }
33122159047fSniklas 
3313b55d4692Sfgsch /* Gather together all the debug information from each input BFD into
3314b55d4692Sfgsch    one place, relocating it and emitting it as we go.  */
33152159047fSniklas 
3316c074d1c9Sdrahn static bfd_boolean
ieee_write_debug_part(abfd)33172159047fSniklas ieee_write_debug_part (abfd)
33182159047fSniklas      bfd *abfd;
33192159047fSniklas {
33202159047fSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
33212159047fSniklas   bfd_chain_type *chain = ieee->chain_root;
3322c074d1c9Sdrahn   unsigned char obuff[OBS];
3323c074d1c9Sdrahn   bfd_boolean some_debug = FALSE;
33242159047fSniklas   file_ptr here = bfd_tell (abfd);
33252159047fSniklas 
3326c074d1c9Sdrahn   output_ptr_start = output_ptr = obuff;
3327c074d1c9Sdrahn   output_ptr_end = obuff + OBS;
3328c074d1c9Sdrahn   output_ptr = obuff;
33292159047fSniklas   output_bfd = abfd;
33302159047fSniklas 
33312159047fSniklas   if (chain == (bfd_chain_type *) NULL)
33322159047fSniklas     {
3333c88b1d6cSniklas       asection *s;
3334c88b1d6cSniklas 
3335c88b1d6cSniklas       for (s = abfd->sections; s != NULL; s = s->next)
3336c88b1d6cSniklas 	if ((s->flags & SEC_DEBUGGING) != 0)
3337c88b1d6cSniklas 	  break;
3338c88b1d6cSniklas       if (s == NULL)
33392159047fSniklas 	{
33402159047fSniklas 	  ieee->w.r.debug_information_part = 0;
3341c074d1c9Sdrahn 	  return TRUE;
33422159047fSniklas 	}
33432159047fSniklas 
3344c88b1d6cSniklas       ieee->w.r.debug_information_part = here;
3345c074d1c9Sdrahn       if (bfd_bwrite (s->contents, s->_raw_size, abfd) != s->_raw_size)
3346c074d1c9Sdrahn 	return FALSE;
33472159047fSniklas     }
33482159047fSniklas   else
33492159047fSniklas     {
33502159047fSniklas       while (chain != (bfd_chain_type *) NULL)
33512159047fSniklas 	{
33522159047fSniklas 	  bfd *entry = chain->this;
33532159047fSniklas 	  ieee_data_type *entry_ieee = IEEE_DATA (entry);
3354c074d1c9Sdrahn 
33552159047fSniklas 	  if (entry_ieee->w.r.debug_information_part)
33562159047fSniklas 	    {
33572159047fSniklas 	      if (bfd_seek (entry, entry_ieee->w.r.debug_information_part,
3358c074d1c9Sdrahn 			    SEEK_SET) != 0)
3359c074d1c9Sdrahn 		return FALSE;
33602159047fSniklas 	      relocate_debug (abfd, entry);
33612159047fSniklas 	    }
33622159047fSniklas 
33632159047fSniklas 	  chain = chain->next;
33642159047fSniklas 	}
3365c074d1c9Sdrahn 
33662159047fSniklas       if (some_debug)
33672159047fSniklas 	ieee->w.r.debug_information_part = here;
33682159047fSniklas       else
33692159047fSniklas 	ieee->w.r.debug_information_part = 0;
3370c88b1d6cSniklas 
33712159047fSniklas       flush ();
33722159047fSniklas     }
33732159047fSniklas 
3374c074d1c9Sdrahn   return TRUE;
3375c88b1d6cSniklas }
3376c88b1d6cSniklas 
3377c88b1d6cSniklas /* Write the data in an ieee way.  */
3378c88b1d6cSniklas 
3379c074d1c9Sdrahn static bfd_boolean
ieee_write_data_part(abfd)33802159047fSniklas ieee_write_data_part (abfd)
33812159047fSniklas      bfd *abfd;
33822159047fSniklas {
33832159047fSniklas   asection *s;
3384c074d1c9Sdrahn 
33852159047fSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
33862159047fSniklas   ieee->w.r.data_part = bfd_tell (abfd);
3387c074d1c9Sdrahn 
33882159047fSniklas   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
33892159047fSniklas     {
3390c88b1d6cSniklas       /* Skip sections that have no loadable contents (.bss,
3391c88b1d6cSniklas          debugging, etc.)  */
3392c88b1d6cSniklas       if ((s->flags & SEC_LOAD) == 0)
3393c88b1d6cSniklas 	continue;
3394c88b1d6cSniklas 
33952159047fSniklas       /* Sort the reloc records so we can insert them in the correct
33962159047fSniklas 	 places */
33972159047fSniklas       if (s->reloc_count != 0)
33982159047fSniklas 	{
3399c88b1d6cSniklas 	  if (! do_with_relocs (abfd, s))
3400c074d1c9Sdrahn 	    return FALSE;
34012159047fSniklas 	}
34022159047fSniklas       else
34032159047fSniklas 	{
3404c88b1d6cSniklas 	  if (! do_without_relocs (abfd, s))
3405c074d1c9Sdrahn 	    return FALSE;
34062159047fSniklas 	}
34072159047fSniklas     }
3408c88b1d6cSniklas 
3409c074d1c9Sdrahn   return TRUE;
34102159047fSniklas }
34112159047fSniklas 
34122159047fSniklas 
3413c074d1c9Sdrahn static bfd_boolean
init_for_output(abfd)34142159047fSniklas init_for_output (abfd)
34152159047fSniklas      bfd *abfd;
34162159047fSniklas {
34172159047fSniklas   asection *s;
3418c074d1c9Sdrahn 
34192159047fSniklas   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
34202159047fSniklas     {
3421c88b1d6cSniklas       if ((s->flags & SEC_DEBUGGING) != 0)
3422c88b1d6cSniklas 	continue;
34232159047fSniklas       if (s->_raw_size != 0)
34242159047fSniklas 	{
3425c074d1c9Sdrahn 	  bfd_size_type size = s->_raw_size;
3426c074d1c9Sdrahn 	  ieee_per_section (s)->data = (bfd_byte *) (bfd_alloc (abfd, size));
34272159047fSniklas 	  if (!ieee_per_section (s)->data)
3428c074d1c9Sdrahn 	    return FALSE;
34292159047fSniklas 	}
34302159047fSniklas     }
3431c074d1c9Sdrahn   return TRUE;
34322159047fSniklas }
34332159047fSniklas 
3434c074d1c9Sdrahn /* Exec and core file sections.  */
34352159047fSniklas 
3436c074d1c9Sdrahn /* Set section contents is complicated with IEEE since the format is
3437c074d1c9Sdrahn    not a byte image, but a record stream.  */
3438c074d1c9Sdrahn 
3439c074d1c9Sdrahn static bfd_boolean
ieee_set_section_contents(abfd,section,location,offset,count)34402159047fSniklas ieee_set_section_contents (abfd, section, location, offset, count)
34412159047fSniklas      bfd *abfd;
34422159047fSniklas      sec_ptr section;
3443*007c2a45Smiod      const PTR location;
34442159047fSniklas      file_ptr offset;
34452159047fSniklas      bfd_size_type count;
34462159047fSniklas {
3447c88b1d6cSniklas   if ((section->flags & SEC_DEBUGGING) != 0)
3448c88b1d6cSniklas     {
3449c88b1d6cSniklas       if (section->contents == NULL)
3450c88b1d6cSniklas 	{
3451c074d1c9Sdrahn 	  bfd_size_type size = section->_raw_size;
3452c074d1c9Sdrahn 	  section->contents = (unsigned char *) bfd_alloc (abfd, size);
3453c88b1d6cSniklas 	  if (section->contents == NULL)
3454c074d1c9Sdrahn 	    return FALSE;
3455c88b1d6cSniklas 	}
3456c88b1d6cSniklas       /* bfd_set_section_contents has already checked that everything
3457c88b1d6cSniklas          is within range.  */
3458c074d1c9Sdrahn       memcpy (section->contents + offset, location, (size_t) count);
3459c074d1c9Sdrahn       return TRUE;
3460c88b1d6cSniklas     }
3461c88b1d6cSniklas 
34622159047fSniklas   if (ieee_per_section (section)->data == (bfd_byte *) NULL)
34632159047fSniklas     {
34642159047fSniklas       if (!init_for_output (abfd))
3465c074d1c9Sdrahn 	return FALSE;
34662159047fSniklas     }
34672159047fSniklas   memcpy ((PTR) (ieee_per_section (section)->data + offset),
34682159047fSniklas 	  (PTR) location,
34692159047fSniklas 	  (unsigned int) count);
3470c074d1c9Sdrahn   return TRUE;
34712159047fSniklas }
34722159047fSniklas 
3473c88b1d6cSniklas /* Write the external symbols of a file.  IEEE considers two sorts of
3474c88b1d6cSniklas    external symbols, public, and referenced.  It uses to internal
3475c88b1d6cSniklas    forms to index them as well.  When we write them out we turn their
3476c88b1d6cSniklas    symbol values into indexes from the right base.  */
3477c88b1d6cSniklas 
3478c074d1c9Sdrahn static bfd_boolean
ieee_write_external_part(abfd)34792159047fSniklas ieee_write_external_part (abfd)
34802159047fSniklas      bfd *abfd;
34812159047fSniklas {
34822159047fSniklas   asymbol **q;
34832159047fSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
34842159047fSniklas   unsigned int reference_index = IEEE_REFERENCE_BASE;
34852159047fSniklas   unsigned int public_index = IEEE_PUBLIC_BASE + 2;
34862159047fSniklas   file_ptr here = bfd_tell (abfd);
3487c074d1c9Sdrahn   bfd_boolean hadone = FALSE;
3488c074d1c9Sdrahn 
34892159047fSniklas   if (abfd->outsymbols != (asymbol **) NULL)
34902159047fSniklas     {
34912159047fSniklas 
34922159047fSniklas       for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++)
34932159047fSniklas 	{
34942159047fSniklas 	  asymbol *p = *q;
3495c074d1c9Sdrahn 
34962159047fSniklas 	  if (bfd_is_und_section (p->section))
34972159047fSniklas 	    {
3498c074d1c9Sdrahn 	      /* This must be a symbol reference.  */
3499c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_external_reference_enum)
3500c074d1c9Sdrahn 		  || ! ieee_write_int (abfd, (bfd_vma) reference_index)
3501c88b1d6cSniklas 		  || ! ieee_write_id (abfd, p->name))
3502c074d1c9Sdrahn 		return FALSE;
35032159047fSniklas 	      p->value = reference_index;
35042159047fSniklas 	      reference_index++;
3505c074d1c9Sdrahn 	      hadone = TRUE;
35062159047fSniklas 	    }
35072159047fSniklas 	  else if (bfd_is_com_section (p->section))
35082159047fSniklas 	    {
3509c074d1c9Sdrahn 	      /* This is a weak reference.  */
3510c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_external_reference_enum)
3511c074d1c9Sdrahn 		  || ! ieee_write_int (abfd, (bfd_vma) reference_index)
3512c88b1d6cSniklas 		  || ! ieee_write_id (abfd, p->name)
3513c88b1d6cSniklas 		  || ! ieee_write_byte (abfd,
3514c88b1d6cSniklas 					ieee_weak_external_reference_enum)
3515c074d1c9Sdrahn 		  || ! ieee_write_int (abfd, (bfd_vma) reference_index)
3516c88b1d6cSniklas 		  || ! ieee_write_int (abfd, p->value))
3517c074d1c9Sdrahn 		return FALSE;
35182159047fSniklas 	      p->value = reference_index;
35192159047fSniklas 	      reference_index++;
3520c074d1c9Sdrahn 	      hadone = TRUE;
35212159047fSniklas 	    }
35222159047fSniklas 	  else if (p->flags & BSF_GLOBAL)
35232159047fSniklas 	    {
3524c074d1c9Sdrahn 	      /* This must be a symbol definition.  */
3525c88b1d6cSniklas 	      if (! ieee_write_byte (abfd, ieee_external_symbol_enum)
3526c074d1c9Sdrahn 		  || ! ieee_write_int (abfd, (bfd_vma) public_index)
3527c88b1d6cSniklas 		  || ! ieee_write_id (abfd, p->name)
3528c88b1d6cSniklas 		  || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum)
3529c074d1c9Sdrahn 		  || ! ieee_write_int (abfd, (bfd_vma) public_index)
3530c88b1d6cSniklas 		  || ! ieee_write_byte (abfd, 15) /* instruction address */
3531c88b1d6cSniklas 		  || ! ieee_write_byte (abfd, 19) /* static symbol */
3532c88b1d6cSniklas 		  || ! ieee_write_byte (abfd, 1)) /* one of them */
3533c074d1c9Sdrahn 		return FALSE;
35342159047fSniklas 
3535c074d1c9Sdrahn 	      /* Write out the value.  */
3536c88b1d6cSniklas 	      if (! ieee_write_2bytes (abfd, ieee_value_record_enum)
3537c074d1c9Sdrahn 		  || ! ieee_write_int (abfd, (bfd_vma) public_index))
3538c074d1c9Sdrahn 		return FALSE;
35392159047fSniklas 	      if (! bfd_is_abs_section (p->section))
35402159047fSniklas 		{
35412159047fSniklas 		  if (abfd->flags & EXEC_P)
35422159047fSniklas 		    {
35432159047fSniklas 		      /* If fully linked, then output all symbols
3544c074d1c9Sdrahn 			 relocated.  */
3545c88b1d6cSniklas 		      if (! (ieee_write_int
3546c88b1d6cSniklas 			     (abfd,
3547c88b1d6cSniklas 			      (p->value
3548c88b1d6cSniklas 			       + p->section->output_offset
3549c88b1d6cSniklas 			       + p->section->output_section->vma))))
3550c074d1c9Sdrahn 			return FALSE;
35512159047fSniklas 		    }
35522159047fSniklas 		  else
35532159047fSniklas 		    {
3554c88b1d6cSniklas 		      if (! (ieee_write_expression
3555c88b1d6cSniklas 			     (abfd,
35562159047fSniklas 			      p->value + p->section->output_offset,
3557c88b1d6cSniklas 			      p->section->output_section->symbol,
3558c074d1c9Sdrahn 			      FALSE, 0)))
3559c074d1c9Sdrahn 			return FALSE;
35602159047fSniklas 		    }
35612159047fSniklas 		}
35622159047fSniklas 	      else
35632159047fSniklas 		{
3564c88b1d6cSniklas 		  if (! ieee_write_expression (abfd,
35652159047fSniklas 					       p->value,
35662159047fSniklas 					       bfd_abs_section_ptr->symbol,
3567c074d1c9Sdrahn 					       FALSE, 0))
3568c074d1c9Sdrahn 		    return FALSE;
35692159047fSniklas 		}
35702159047fSniklas 	      p->value = public_index;
35712159047fSniklas 	      public_index++;
3572c074d1c9Sdrahn 	      hadone = TRUE;
35732159047fSniklas 	    }
35742159047fSniklas 	  else
35752159047fSniklas 	    {
3576c074d1c9Sdrahn 	      /* This can happen - when there are gaps in the symbols read
3577c074d1c9Sdrahn 	         from an input ieee file.  */
35782159047fSniklas 	    }
35792159047fSniklas 	}
35802159047fSniklas     }
35812159047fSniklas   if (hadone)
35822159047fSniklas     ieee->w.r.external_part = here;
35832159047fSniklas 
3584c074d1c9Sdrahn   return TRUE;
35852159047fSniklas }
35862159047fSniklas 
35872159047fSniklas 
3588c074d1c9Sdrahn static const unsigned char exten[] =
35892159047fSniklas {
35902159047fSniklas   0xf0, 0x20, 0x00,
3591c074d1c9Sdrahn   0xf1, 0xce, 0x20, 0x00, 37, 3, 3,	/* Set version 3 rev 3.  */
3592c074d1c9Sdrahn   0xf1, 0xce, 0x20, 0x00, 39, 2,	/* Keep symbol in  original case.  */
3593*007c2a45Smiod   0xf1, 0xce, 0x20, 0x00, 38		/* Set object type relocatable to x.  */
35942159047fSniklas };
35952159047fSniklas 
3596c074d1c9Sdrahn static const unsigned char envi[] =
35972159047fSniklas {
35982159047fSniklas   0xf0, 0x21, 0x00,
35992159047fSniklas 
36002159047fSniklas /*    0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11,
36012159047fSniklas     0x19, 0x2c,
36022159047fSniklas */
36032159047fSniklas   0xf1, 0xce, 0x21, 00, 52, 0x00,	/* exec ok */
36042159047fSniklas 
36052159047fSniklas   0xf1, 0xce, 0x21, 0, 53, 0x03,/* host unix */
36062159047fSniklas /*    0xf1, 0xce, 0x21, 0, 54, 2,1,1	tool & version # */
36072159047fSniklas };
36082159047fSniklas 
3609c074d1c9Sdrahn static bfd_boolean
ieee_write_me_part(abfd)36102159047fSniklas ieee_write_me_part (abfd)
36112159047fSniklas      bfd *abfd;
36122159047fSniklas {
36132159047fSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
36142159047fSniklas   ieee->w.r.trailer_part = bfd_tell (abfd);
36152159047fSniklas   if (abfd->start_address)
36162159047fSniklas     {
3617c88b1d6cSniklas       if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum)
3618c88b1d6cSniklas 	  || ! ieee_write_byte (abfd, ieee_function_either_open_b_enum)
3619c88b1d6cSniklas 	  || ! ieee_write_int (abfd, abfd->start_address)
3620c88b1d6cSniklas 	  || ! ieee_write_byte (abfd, ieee_function_either_close_b_enum))
3621c074d1c9Sdrahn 	return FALSE;
36222159047fSniklas     }
36232159047fSniklas   ieee->w.r.me_record = bfd_tell (abfd);
3624c88b1d6cSniklas   if (! ieee_write_byte (abfd, ieee_module_end_enum))
3625c074d1c9Sdrahn     return FALSE;
3626c074d1c9Sdrahn   return TRUE;
36272159047fSniklas }
36282159047fSniklas 
3629c88b1d6cSniklas /* Write out the IEEE processor ID.  */
3630c88b1d6cSniklas 
3631c074d1c9Sdrahn static bfd_boolean
ieee_write_processor(abfd)3632c88b1d6cSniklas ieee_write_processor (abfd)
3633c88b1d6cSniklas      bfd *abfd;
3634c88b1d6cSniklas {
3635c88b1d6cSniklas   const bfd_arch_info_type *arch;
3636c88b1d6cSniklas 
3637c88b1d6cSniklas   arch = bfd_get_arch_info (abfd);
3638c88b1d6cSniklas   switch (arch->arch)
3639c88b1d6cSniklas     {
3640c88b1d6cSniklas     default:
3641c88b1d6cSniklas       if (! ieee_write_id (abfd, bfd_printable_name (abfd)))
3642c074d1c9Sdrahn 	return FALSE;
3643c88b1d6cSniklas       break;
3644c88b1d6cSniklas 
3645c88b1d6cSniklas     case bfd_arch_a29k:
3646c88b1d6cSniklas       if (! ieee_write_id (abfd, "29000"))
3647c074d1c9Sdrahn 	return FALSE;
3648c88b1d6cSniklas       break;
3649c88b1d6cSniklas 
3650c88b1d6cSniklas     case bfd_arch_h8300:
3651c88b1d6cSniklas       if (! ieee_write_id (abfd, "H8/300"))
3652c074d1c9Sdrahn 	return FALSE;
3653c88b1d6cSniklas       break;
3654c88b1d6cSniklas 
3655c88b1d6cSniklas     case bfd_arch_h8500:
3656c88b1d6cSniklas       if (! ieee_write_id (abfd, "H8/500"))
3657c074d1c9Sdrahn 	return FALSE;
3658c88b1d6cSniklas       break;
3659c88b1d6cSniklas 
3660c88b1d6cSniklas     case bfd_arch_i960:
3661c88b1d6cSniklas       switch (arch->mach)
3662c88b1d6cSniklas 	{
3663c88b1d6cSniklas 	default:
3664c88b1d6cSniklas 	case bfd_mach_i960_core:
3665c88b1d6cSniklas 	case bfd_mach_i960_ka_sa:
3666c88b1d6cSniklas 	  if (! ieee_write_id (abfd, "80960KA"))
3667c074d1c9Sdrahn 	    return FALSE;
3668c88b1d6cSniklas 	  break;
3669c88b1d6cSniklas 
3670c88b1d6cSniklas 	case bfd_mach_i960_kb_sb:
3671c88b1d6cSniklas 	  if (! ieee_write_id (abfd, "80960KB"))
3672c074d1c9Sdrahn 	    return FALSE;
3673c88b1d6cSniklas 	  break;
3674c88b1d6cSniklas 
3675c88b1d6cSniklas 	case bfd_mach_i960_ca:
3676c88b1d6cSniklas 	  if (! ieee_write_id (abfd, "80960CA"))
3677c074d1c9Sdrahn 	    return FALSE;
3678c88b1d6cSniklas 	  break;
3679c88b1d6cSniklas 
3680c88b1d6cSniklas 	case bfd_mach_i960_mc:
3681c88b1d6cSniklas 	case bfd_mach_i960_xa:
3682c88b1d6cSniklas 	  if (! ieee_write_id (abfd, "80960MC"))
3683c074d1c9Sdrahn 	    return FALSE;
3684c88b1d6cSniklas 	  break;
3685c88b1d6cSniklas 	}
3686c88b1d6cSniklas       break;
3687c88b1d6cSniklas 
3688c88b1d6cSniklas     case bfd_arch_m68k:
3689c88b1d6cSniklas       {
3690b305b0f1Sespie 	const char *id;
3691c88b1d6cSniklas 
3692b305b0f1Sespie 	switch (arch->mach)
3693b305b0f1Sespie 	  {
3694b305b0f1Sespie 	  default:		id = "68020"; break;
3695b305b0f1Sespie 	  case bfd_mach_m68000: id = "68000"; break;
3696b305b0f1Sespie 	  case bfd_mach_m68008: id = "68008"; break;
3697b305b0f1Sespie 	  case bfd_mach_m68010: id = "68010"; break;
3698b305b0f1Sespie 	  case bfd_mach_m68020: id = "68020"; break;
3699b305b0f1Sespie 	  case bfd_mach_m68030: id = "68030"; break;
3700b305b0f1Sespie 	  case bfd_mach_m68040: id = "68040"; break;
3701b305b0f1Sespie 	  case bfd_mach_m68060: id = "68060"; break;
3702b305b0f1Sespie 	  case bfd_mach_cpu32:  id = "cpu32"; break;
3703b55d4692Sfgsch 	  case bfd_mach_mcf5200:id = "5200";  break;
3704b55d4692Sfgsch 	  case bfd_mach_mcf5206e:id = "5206e"; break;
3705b55d4692Sfgsch 	  case bfd_mach_mcf5307:id = "5307";  break;
3706b55d4692Sfgsch 	  case bfd_mach_mcf5407:id = "5407";  break;
3707*007c2a45Smiod 	  case bfd_mach_mcf528x:id = "5282";  break;
3708b305b0f1Sespie 	  }
3709b305b0f1Sespie 
3710b305b0f1Sespie 	if (! ieee_write_id (abfd, id))
3711c074d1c9Sdrahn 	  return FALSE;
3712c88b1d6cSniklas       }
3713c88b1d6cSniklas       break;
3714c88b1d6cSniklas     }
3715c88b1d6cSniklas 
3716c074d1c9Sdrahn   return TRUE;
37172159047fSniklas }
37182159047fSniklas 
3719c074d1c9Sdrahn static bfd_boolean
ieee_write_object_contents(abfd)37202159047fSniklas ieee_write_object_contents (abfd)
37212159047fSniklas      bfd *abfd;
37222159047fSniklas {
37232159047fSniklas   ieee_data_type *ieee = IEEE_DATA (abfd);
37242159047fSniklas   unsigned int i;
37252159047fSniklas   file_ptr old;
3726c88b1d6cSniklas 
3727c074d1c9Sdrahn   /* Fast forward over the header area.  */
37282159047fSniklas   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
3729c074d1c9Sdrahn     return FALSE;
37302159047fSniklas 
3731c88b1d6cSniklas   if (! ieee_write_byte (abfd, ieee_module_beginning_enum)
3732c88b1d6cSniklas       || ! ieee_write_processor (abfd)
3733c88b1d6cSniklas       || ! ieee_write_id (abfd, abfd->filename))
3734c074d1c9Sdrahn     return FALSE;
37352159047fSniklas 
3736c074d1c9Sdrahn   /* Fast forward over the variable bits.  */
3737c88b1d6cSniklas   if (! ieee_write_byte (abfd, ieee_address_descriptor_enum))
3738c074d1c9Sdrahn     return FALSE;
37392159047fSniklas 
3740c074d1c9Sdrahn   /* Bits per MAU.  */
3741c88b1d6cSniklas   if (! ieee_write_byte (abfd, (bfd_byte) (bfd_arch_bits_per_byte (abfd))))
3742c074d1c9Sdrahn     return FALSE;
3743c074d1c9Sdrahn   /* MAU's per address.  */
3744c88b1d6cSniklas   if (! ieee_write_byte (abfd,
3745c88b1d6cSniklas 			 (bfd_byte) (bfd_arch_bits_per_address (abfd)
3746c88b1d6cSniklas 				     / bfd_arch_bits_per_byte (abfd))))
3747c074d1c9Sdrahn     return FALSE;
37482159047fSniklas 
37492159047fSniklas   old = bfd_tell (abfd);
37502159047fSniklas   if (bfd_seek (abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR) != 0)
3751c074d1c9Sdrahn     return FALSE;
37522159047fSniklas 
37532159047fSniklas   ieee->w.r.extension_record = bfd_tell (abfd);
3754c074d1c9Sdrahn   if (bfd_bwrite ((char *) exten, (bfd_size_type) sizeof (exten), abfd)
3755c074d1c9Sdrahn       != sizeof (exten))
3756c074d1c9Sdrahn     return FALSE;
37572159047fSniklas   if (abfd->flags & EXEC_P)
3758c88b1d6cSniklas     {
3759c88b1d6cSniklas       if (! ieee_write_byte (abfd, 0x1)) /* Absolute */
3760c074d1c9Sdrahn 	return FALSE;
3761c88b1d6cSniklas     }
37622159047fSniklas   else
3763c88b1d6cSniklas     {
3764c88b1d6cSniklas       if (! ieee_write_byte (abfd, 0x2)) /* Relocateable */
3765c074d1c9Sdrahn 	return FALSE;
3766c88b1d6cSniklas     }
37672159047fSniklas 
37682159047fSniklas   ieee->w.r.environmental_record = bfd_tell (abfd);
3769c074d1c9Sdrahn   if (bfd_bwrite ((char *) envi, (bfd_size_type) sizeof (envi), abfd)
3770c074d1c9Sdrahn       != sizeof (envi))
3771c074d1c9Sdrahn     return FALSE;
3772c88b1d6cSniklas 
3773c88b1d6cSniklas   /* The HP emulator database requires a timestamp in the file.  */
3774c88b1d6cSniklas   {
3775c88b1d6cSniklas     time_t now;
3776c88b1d6cSniklas     const struct tm *t;
3777c88b1d6cSniklas 
3778c88b1d6cSniklas     time (&now);
3779c88b1d6cSniklas     t = (struct tm *) localtime (&now);
3780c88b1d6cSniklas     if (! ieee_write_2bytes (abfd, (int) ieee_atn_record_enum)
3781c88b1d6cSniklas 	|| ! ieee_write_byte (abfd, 0x21)
3782c88b1d6cSniklas 	|| ! ieee_write_byte (abfd, 0)
3783c88b1d6cSniklas 	|| ! ieee_write_byte (abfd, 50)
3784c074d1c9Sdrahn 	|| ! ieee_write_int (abfd, (bfd_vma) (t->tm_year + 1900))
3785c074d1c9Sdrahn 	|| ! ieee_write_int (abfd, (bfd_vma) (t->tm_mon + 1))
3786c074d1c9Sdrahn 	|| ! ieee_write_int (abfd, (bfd_vma) t->tm_mday)
3787c074d1c9Sdrahn 	|| ! ieee_write_int (abfd, (bfd_vma) t->tm_hour)
3788c074d1c9Sdrahn 	|| ! ieee_write_int (abfd, (bfd_vma) t->tm_min)
3789c074d1c9Sdrahn 	|| ! ieee_write_int (abfd, (bfd_vma) t->tm_sec))
3790c074d1c9Sdrahn       return FALSE;
3791c88b1d6cSniklas   }
3792c88b1d6cSniklas 
37932159047fSniklas   output_bfd = abfd;
3794c88b1d6cSniklas 
37952159047fSniklas   flush ();
37962159047fSniklas 
3797c88b1d6cSniklas   if (! ieee_write_section_part (abfd))
3798c074d1c9Sdrahn     return FALSE;
3799c88b1d6cSniklas   /* First write the symbols.  This changes their values into table
3800c88b1d6cSniklas     indeces so we cant use it after this point.  */
3801c88b1d6cSniklas   if (! ieee_write_external_part (abfd))
3802c074d1c9Sdrahn     return FALSE;
38032159047fSniklas 
3804c88b1d6cSniklas   /* Write any debugs we have been told about.  */
3805c88b1d6cSniklas   if (! ieee_write_debug_part (abfd))
3806c074d1c9Sdrahn     return FALSE;
38072159047fSniklas 
3808c88b1d6cSniklas   /* Can only write the data once the symbols have been written, since
38092159047fSniklas      the data contains relocation information which points to the
3810c88b1d6cSniklas      symbols.  */
3811c88b1d6cSniklas   if (! ieee_write_data_part (abfd))
3812c074d1c9Sdrahn     return FALSE;
38132159047fSniklas 
3814c88b1d6cSniklas   /* At the end we put the end!  */
3815c88b1d6cSniklas   if (! ieee_write_me_part (abfd))
3816c074d1c9Sdrahn     return FALSE;
38172159047fSniklas 
3818c074d1c9Sdrahn   /* Generate the header.  */
38192159047fSniklas   if (bfd_seek (abfd, old, SEEK_SET) != 0)
3820c074d1c9Sdrahn     return FALSE;
38212159047fSniklas 
38222159047fSniklas   for (i = 0; i < N_W_VARIABLES; i++)
38232159047fSniklas     {
3824c88b1d6cSniklas       if (! ieee_write_2bytes (abfd, ieee_assign_value_to_variable_enum)
3825c88b1d6cSniklas 	  || ! ieee_write_byte (abfd, (bfd_byte) i)
3826c074d1c9Sdrahn 	  || ! ieee_write_int5_out (abfd, (bfd_vma) ieee->w.offset[i]))
3827c074d1c9Sdrahn 	return FALSE;
38282159047fSniklas     }
3829c88b1d6cSniklas 
3830c074d1c9Sdrahn   return TRUE;
38312159047fSniklas }
38322159047fSniklas 
38332159047fSniklas /* Native-level interface to symbols. */
38342159047fSniklas 
38352159047fSniklas /* We read the symbols into a buffer, which is discarded when this
38362159047fSniklas    function exits.  We read the strings into a buffer large enough to
38372159047fSniklas    hold them all plus all the cached symbol entries.  */
38382159047fSniklas 
3839c074d1c9Sdrahn static asymbol *
ieee_make_empty_symbol(abfd)38402159047fSniklas ieee_make_empty_symbol (abfd)
38412159047fSniklas      bfd *abfd;
38422159047fSniklas {
3843c074d1c9Sdrahn   bfd_size_type amt = sizeof (ieee_symbol_type);
3844c074d1c9Sdrahn   ieee_symbol_type *new = (ieee_symbol_type *) bfd_zalloc (abfd, amt);
3845c074d1c9Sdrahn 
38462159047fSniklas   if (!new)
38472159047fSniklas     return NULL;
38482159047fSniklas   new->symbol.the_bfd = abfd;
38492159047fSniklas   return &new->symbol;
38502159047fSniklas }
38512159047fSniklas 
38522159047fSniklas static bfd *
ieee_openr_next_archived_file(arch,prev)38532159047fSniklas ieee_openr_next_archived_file (arch, prev)
38542159047fSniklas      bfd *arch;
38552159047fSniklas      bfd *prev;
38562159047fSniklas {
38572159047fSniklas   ieee_ar_data_type *ar = IEEE_AR_DATA (arch);
3858c074d1c9Sdrahn 
3859c074d1c9Sdrahn   /* Take the next one from the arch state, or reset.  */
38602159047fSniklas   if (prev == (bfd *) NULL)
3861c074d1c9Sdrahn     /* Reset the index - the first two entries are bogus.  */
38622159047fSniklas     ar->element_index = 2;
3863c074d1c9Sdrahn 
3864c074d1c9Sdrahn   while (TRUE)
38652159047fSniklas     {
38662159047fSniklas       ieee_ar_obstack_type *p = ar->elements + ar->element_index;
3867c074d1c9Sdrahn 
38682159047fSniklas       ar->element_index++;
38692159047fSniklas       if (ar->element_index <= ar->element_count)
38702159047fSniklas 	{
38712159047fSniklas 	  if (p->file_offset != (file_ptr) 0)
38722159047fSniklas 	    {
38732159047fSniklas 	      if (p->abfd == (bfd *) NULL)
38742159047fSniklas 		{
38752159047fSniklas 		  p->abfd = _bfd_create_empty_archive_element_shell (arch);
38762159047fSniklas 		  p->abfd->origin = p->file_offset;
38772159047fSniklas 		}
38782159047fSniklas 	      return p->abfd;
38792159047fSniklas 	    }
38802159047fSniklas 	}
38812159047fSniklas       else
38822159047fSniklas 	{
38832159047fSniklas 	  bfd_set_error (bfd_error_no_more_archived_files);
38842159047fSniklas 	  return (bfd *) NULL;
38852159047fSniklas 	}
38862159047fSniklas     }
38872159047fSniklas }
38882159047fSniklas 
3889c074d1c9Sdrahn static bfd_boolean
ieee_find_nearest_line(abfd,section,symbols,offset,filename_ptr,functionname_ptr,line_ptr)3890c074d1c9Sdrahn ieee_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
3891c074d1c9Sdrahn 			functionname_ptr, line_ptr)
3892b305b0f1Sespie      bfd *abfd ATTRIBUTE_UNUSED;
3893b305b0f1Sespie      asection *section ATTRIBUTE_UNUSED;
3894b305b0f1Sespie      asymbol **symbols ATTRIBUTE_UNUSED;
3895b305b0f1Sespie      bfd_vma offset ATTRIBUTE_UNUSED;
3896b305b0f1Sespie      const char **filename_ptr ATTRIBUTE_UNUSED;
3897b305b0f1Sespie      const char **functionname_ptr ATTRIBUTE_UNUSED;
3898b305b0f1Sespie      unsigned int *line_ptr ATTRIBUTE_UNUSED;
38992159047fSniklas {
3900c074d1c9Sdrahn   return FALSE;
39012159047fSniklas }
39022159047fSniklas 
39032159047fSniklas static int
ieee_generic_stat_arch_elt(abfd,buf)39042159047fSniklas ieee_generic_stat_arch_elt (abfd, buf)
39052159047fSniklas      bfd *abfd;
39062159047fSniklas      struct stat *buf;
39072159047fSniklas {
3908b305b0f1Sespie   ieee_ar_data_type *ar = (ieee_ar_data_type *) NULL;
3909c88b1d6cSniklas   ieee_data_type *ieee;
3910c88b1d6cSniklas 
3911b305b0f1Sespie   if (abfd->my_archive != NULL)
3912b305b0f1Sespie     ar = abfd->my_archive->tdata.ieee_ar_data;
39132159047fSniklas   if (ar == (ieee_ar_data_type *) NULL)
39142159047fSniklas     {
39152159047fSniklas       bfd_set_error (bfd_error_invalid_operation);
39162159047fSniklas       return -1;
39172159047fSniklas     }
3918c88b1d6cSniklas 
3919c88b1d6cSniklas   if (IEEE_DATA (abfd) == NULL)
39202159047fSniklas     {
3921c88b1d6cSniklas       if (ieee_object_p (abfd) == NULL)
3922c88b1d6cSniklas 	{
3923c88b1d6cSniklas 	  bfd_set_error (bfd_error_wrong_format);
3924c88b1d6cSniklas 	  return -1;
39252159047fSniklas 	}
39262159047fSniklas     }
39272159047fSniklas 
3928c88b1d6cSniklas   ieee = IEEE_DATA (abfd);
3929c88b1d6cSniklas 
3930c88b1d6cSniklas   buf->st_size = ieee->w.r.me_record + 1;
3931c88b1d6cSniklas   buf->st_mode = 0644;
3932c88b1d6cSniklas   return 0;
3933c88b1d6cSniklas }
3934c88b1d6cSniklas 
39352159047fSniklas static int
ieee_sizeof_headers(abfd,x)39362159047fSniklas ieee_sizeof_headers (abfd, x)
3937b305b0f1Sespie      bfd *abfd ATTRIBUTE_UNUSED;
3938c074d1c9Sdrahn      bfd_boolean x ATTRIBUTE_UNUSED;
39392159047fSniklas {
39402159047fSniklas   return 0;
39412159047fSniklas }
39422159047fSniklas 
39432159047fSniklas 
39442159047fSniklas /* The debug info routines are never used.  */
39452159047fSniklas #if 0
39462159047fSniklas 
39472159047fSniklas static void
39482159047fSniklas ieee_bfd_debug_info_start (abfd)
39492159047fSniklas      bfd *abfd;
39502159047fSniklas {
39512159047fSniklas 
39522159047fSniklas }
39532159047fSniklas 
39542159047fSniklas static void
39552159047fSniklas ieee_bfd_debug_info_end (abfd)
39562159047fSniklas      bfd *abfd;
39572159047fSniklas {
39582159047fSniklas 
39592159047fSniklas }
39602159047fSniklas 
39612159047fSniklas 
39622159047fSniklas /* Add this section to the list of sections we have debug info for, to
3963c074d1c9Sdrahn    be ready to output it at close time.  */
39642159047fSniklas static void
39652159047fSniklas ieee_bfd_debug_info_accumulate (abfd, section)
39662159047fSniklas      bfd *abfd;
39672159047fSniklas      asection *section;
39682159047fSniklas {
39692159047fSniklas   ieee_data_type *ieee = IEEE_DATA (section->owner);
39702159047fSniklas   ieee_data_type *output_ieee = IEEE_DATA (abfd);
3971c074d1c9Sdrahn 
3972c074d1c9Sdrahn   /* Can only accumulate data from other ieee bfds.  */
39732159047fSniklas   if (section->owner->xvec != abfd->xvec)
39742159047fSniklas     return;
3975c074d1c9Sdrahn   /* Only bother once per bfd.  */
3976c074d1c9Sdrahn   if (ieee->done_debug)
39772159047fSniklas     return;
3978c074d1c9Sdrahn   ieee->done_debug = TRUE;
39792159047fSniklas 
3980c074d1c9Sdrahn   /* Don't bother if there is no debug info.  */
39812159047fSniklas   if (ieee->w.r.debug_information_part == 0)
39822159047fSniklas     return;
39832159047fSniklas 
3984c074d1c9Sdrahn   /* Add to chain.  */
39852159047fSniklas   {
3986c074d1c9Sdrahn     bfd_size_type amt = sizeof (bfd_chain_type);
3987c074d1c9Sdrahn     bfd_chain_type *n = (bfd_chain_type *) bfd_alloc (abfd, amt);
3988c074d1c9Sdrahn 
39892159047fSniklas     if (!n)
39902159047fSniklas       abort ();		/* FIXME */
39912159047fSniklas     n->this = section->owner;
39922159047fSniklas     n->next = (bfd_chain_type *) NULL;
39932159047fSniklas 
39942159047fSniklas     if (output_ieee->chain_head)
39952159047fSniklas       output_ieee->chain_head->next = n;
39962159047fSniklas     else
39972159047fSniklas       output_ieee->chain_root = n;
39982159047fSniklas 
39992159047fSniklas     output_ieee->chain_head = n;
40002159047fSniklas   }
40012159047fSniklas }
40022159047fSniklas 
40032159047fSniklas #endif
40042159047fSniklas 
40052159047fSniklas #define	ieee_close_and_cleanup _bfd_generic_close_and_cleanup
40062159047fSniklas #define ieee_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
40072159047fSniklas 
40082159047fSniklas #define ieee_slurp_armap bfd_true
40092159047fSniklas #define ieee_slurp_extended_name_table bfd_true
40102159047fSniklas #define ieee_construct_extended_name_table \
4011c074d1c9Sdrahn   ((bfd_boolean (*) \
4012c074d1c9Sdrahn     PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
40132159047fSniklas    bfd_true)
40142159047fSniklas #define ieee_truncate_arname bfd_dont_truncate_arname
40152159047fSniklas #define ieee_write_armap \
4016c074d1c9Sdrahn   ((bfd_boolean (*) \
40172159047fSniklas     PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
40182159047fSniklas    bfd_true)
40192159047fSniklas #define ieee_read_ar_hdr bfd_nullvoidptr
40202159047fSniklas #define ieee_update_armap_timestamp bfd_true
4021c88b1d6cSniklas #define ieee_get_elt_at_index _bfd_generic_get_elt_at_index
40222159047fSniklas 
4023b305b0f1Sespie #define ieee_bfd_is_local_label_name bfd_generic_is_local_label_name
40242159047fSniklas #define ieee_get_lineno _bfd_nosymbols_get_lineno
40252159047fSniklas #define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
40262159047fSniklas #define ieee_read_minisymbols _bfd_generic_read_minisymbols
40272159047fSniklas #define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
40282159047fSniklas 
40292159047fSniklas #define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
40302159047fSniklas 
40312159047fSniklas #define ieee_set_arch_mach _bfd_generic_set_arch_mach
40322159047fSniklas 
40332159047fSniklas #define ieee_get_section_contents_in_window \
40342159047fSniklas   _bfd_generic_get_section_contents_in_window
40352159047fSniklas #define ieee_bfd_get_relocated_section_contents \
40362159047fSniklas   bfd_generic_get_relocated_section_contents
40372159047fSniklas #define ieee_bfd_relax_section bfd_generic_relax_section
4038b305b0f1Sespie #define ieee_bfd_gc_sections bfd_generic_gc_sections
4039c074d1c9Sdrahn #define ieee_bfd_merge_sections bfd_generic_merge_sections
4040c074d1c9Sdrahn #define ieee_bfd_discard_group bfd_generic_discard_group
40412159047fSniklas #define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
4042c074d1c9Sdrahn #define ieee_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
40432159047fSniklas #define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols
4044c074d1c9Sdrahn #define ieee_bfd_link_just_syms _bfd_generic_link_just_syms
40452159047fSniklas #define ieee_bfd_final_link _bfd_generic_final_link
40462159047fSniklas #define ieee_bfd_link_split_section  _bfd_generic_link_split_section
40472159047fSniklas 
40482159047fSniklas const bfd_target ieee_vec =
40492159047fSniklas {
40502159047fSniklas   "ieee",			/* name */
40512159047fSniklas   bfd_target_ieee_flavour,
4052c88b1d6cSniklas   BFD_ENDIAN_UNKNOWN,		/* target byte order */
4053c88b1d6cSniklas   BFD_ENDIAN_UNKNOWN,		/* target headers byte order */
40542159047fSniklas   (HAS_RELOC | EXEC_P |		/* object flags */
40552159047fSniklas    HAS_LINENO | HAS_DEBUG |
40562159047fSniklas    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
40572159047fSniklas   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
40582159047fSniklas    | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* section flags */
4059e93f7393Sniklas   '_',				/* leading underscore */
40602159047fSniklas   ' ',				/* ar_pad_char */
40612159047fSniklas   16,				/* ar_max_namelen */
40622159047fSniklas   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
40632159047fSniklas   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
40642159047fSniklas   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* data */
40652159047fSniklas   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
40662159047fSniklas   bfd_getb32, bfd_getb_signed_32, bfd_putb32,
40672159047fSniklas   bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* hdrs */
40682159047fSniklas 
40692159047fSniklas   {_bfd_dummy_target,
40702159047fSniklas    ieee_object_p,		/* bfd_check_format */
40712159047fSniklas    ieee_archive_p,
40722159047fSniklas    _bfd_dummy_target,
40732159047fSniklas   },
40742159047fSniklas   {
40752159047fSniklas     bfd_false,
40762159047fSniklas     ieee_mkobject,
40772159047fSniklas     _bfd_generic_mkarchive,
40782159047fSniklas     bfd_false
40792159047fSniklas   },
40802159047fSniklas   {
40812159047fSniklas     bfd_false,
40822159047fSniklas     ieee_write_object_contents,
40832159047fSniklas     _bfd_write_archive_contents,
40842159047fSniklas     bfd_false,
40852159047fSniklas   },
40862159047fSniklas 
4087c074d1c9Sdrahn   /* ieee_close_and_cleanup, ieee_bfd_free_cached_info, ieee_new_section_hook,
4088c074d1c9Sdrahn      ieee_get_section_contents, ieee_get_section_contents_in_window  */
40892159047fSniklas   BFD_JUMP_TABLE_GENERIC (ieee),
4090c074d1c9Sdrahn 
40912159047fSniklas   BFD_JUMP_TABLE_COPY (_bfd_generic),
40922159047fSniklas   BFD_JUMP_TABLE_CORE (_bfd_nocore),
4093c074d1c9Sdrahn 
4094c074d1c9Sdrahn   /* ieee_slurp_armap, ieee_slurp_extended_name_table,
4095c074d1c9Sdrahn      ieee_construct_extended_name_table, ieee_truncate_arname,
4096c074d1c9Sdrahn      ieee_write_armap, ieee_read_ar_hdr, ieee_openr_next_archived_file,
4097c074d1c9Sdrahn      ieee_get_elt_at_index, ieee_generic_stat_arch_elt,
4098c074d1c9Sdrahn      ieee_update_armap_timestamp  */
40992159047fSniklas   BFD_JUMP_TABLE_ARCHIVE (ieee),
4100c074d1c9Sdrahn 
4101*007c2a45Smiod   /* ieee_get_symtab_upper_bound, ieee_canonicalize_symtab,
4102*007c2a45Smiod      ieee_make_empty_symbol, ieee_print_symbol, ieee_get_symbol_info,
4103*007c2a45Smiod      ieee_bfd_is_local_label_name, ieee_get_lineno,
4104*007c2a45Smiod      ieee_find_nearest_line, ieee_bfd_make_debug_symbol,
4105c074d1c9Sdrahn      ieee_read_minisymbols, ieee_minisymbol_to_symbol */
41062159047fSniklas   BFD_JUMP_TABLE_SYMBOLS (ieee),
4107c074d1c9Sdrahn 
4108c074d1c9Sdrahn   /* ieee_get_reloc_upper_bound, ieee_canonicalize_reloc,
4109c074d1c9Sdrahn      ieee_bfd_reloc_type_lookup  */
41102159047fSniklas   BFD_JUMP_TABLE_RELOCS (ieee),
4111c074d1c9Sdrahn 
4112c074d1c9Sdrahn   /* ieee_set_arch_mach, ieee_set_section_contents  */
41132159047fSniklas   BFD_JUMP_TABLE_WRITE (ieee),
4114c074d1c9Sdrahn 
4115c074d1c9Sdrahn   /* ieee_sizeof_headers, ieee_bfd_get_relocated_section_contents,
4116c074d1c9Sdrahn      ieee_bfd_relax_section, ieee_bfd_link_hash_table_create,
4117c074d1c9Sdrahn      _bfd_generic_link_hash_table_free,
4118c074d1c9Sdrahn      ieee_bfd_link_add_symbols, ieee_bfd_final_link,
4119c074d1c9Sdrahn      ieee_bfd_link_split_section, ieee_bfd_gc_sections,
4120c074d1c9Sdrahn      ieee_bfd_merge_sections  */
41212159047fSniklas   BFD_JUMP_TABLE_LINK (ieee),
4122c074d1c9Sdrahn 
41232159047fSniklas   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
41242159047fSniklas 
4125b305b0f1Sespie   NULL,
4126b305b0f1Sespie 
41272159047fSniklas   (PTR) 0
41282159047fSniklas };
4129