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, §ion);
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