daily update
[deliverable/binutils-gdb.git] / bfd / ieee.c
CommitLineData
252b5132 1/* BFD back-end for ieee-695 objects.
4b95cf5c 2 Copyright (C) 1990-2014 Free Software Foundation, Inc.
252b5132
RH
3
4 Written by Steve Chamberlain of Cygnus Support.
5
ca09e32b 6 This file is part of BFD, the Binary File Descriptor library.
252b5132 7
ca09e32b
NC
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
cd123cb7 10 the Free Software Foundation; either version 3 of the License, or
ca09e32b 11 (at your option) any later version.
252b5132 12
ca09e32b
NC
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
252b5132 17
ca09e32b
NC
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
cd123cb7
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
252b5132
RH
23
24#define KEEPMINUSPCININST 0
25
26/* IEEE 695 format is a stream of records, which we parse using a simple one-
27 token (which is one byte in this lexicon) lookahead recursive decent
28 parser. */
29
252b5132 30#include "sysdep.h"
3db64b00 31#include "bfd.h"
252b5132
RH
32#include "libbfd.h"
33#include "ieee.h"
34#include "libieee.h"
3882b010 35#include "safe-ctype.h"
1be5090b 36#include "libiberty.h"
252b5132 37
47fda0d3
AM
38struct output_buffer_struct
39{
40 unsigned char *ptrp;
41 int buffer;
42};
43
46e94266
NC
44static unsigned char *output_ptr_start;
45static unsigned char *output_ptr;
46static unsigned char *output_ptr_end;
47static unsigned char *input_ptr_start;
48static unsigned char *input_ptr;
49static unsigned char *input_ptr_end;
50static bfd *input_bfd;
51static bfd *output_bfd;
52static int output_buffer;
53
54
55static void block (void);
56
252b5132 57/* Functions for writing to ieee files in the strange way that the
c8e7bf0d 58 standard requires. */
252b5132 59
b34976b6 60static bfd_boolean
c8e7bf0d 61ieee_write_byte (bfd *abfd, int barg)
252b5132
RH
62{
63 bfd_byte byte;
64
65 byte = barg;
c8e7bf0d 66 if (bfd_bwrite ((void *) &byte, (bfd_size_type) 1, abfd) != 1)
b34976b6
AM
67 return FALSE;
68 return TRUE;
252b5132
RH
69}
70
b34976b6 71static bfd_boolean
c8e7bf0d 72ieee_write_2bytes (bfd *abfd, int bytes)
252b5132
RH
73{
74 bfd_byte buffer[2];
75
76 buffer[0] = bytes >> 8;
77 buffer[1] = bytes & 0xff;
c8e7bf0d 78 if (bfd_bwrite ((void *) buffer, (bfd_size_type) 2, abfd) != 2)
b34976b6
AM
79 return FALSE;
80 return TRUE;
252b5132
RH
81}
82
b34976b6 83static bfd_boolean
c8e7bf0d 84ieee_write_int (bfd *abfd, bfd_vma value)
252b5132
RH
85{
86 if (value <= 127)
87 {
88 if (! ieee_write_byte (abfd, (bfd_byte) value))
b34976b6 89 return FALSE;
252b5132
RH
90 }
91 else
92 {
93 unsigned int length;
94
49ae03bf
NC
95 /* How many significant bytes ? */
96 /* FIXME FOR LONGER INTS. */
252b5132
RH
97 if (value & 0xff000000)
98 length = 4;
99 else if (value & 0x00ff0000)
100 length = 3;
101 else if (value & 0x0000ff00)
102 length = 2;
103 else
104 length = 1;
105
106 if (! ieee_write_byte (abfd,
107 (bfd_byte) ((int) ieee_number_repeat_start_enum
108 + length)))
b34976b6 109 return FALSE;
252b5132
RH
110 switch (length)
111 {
112 case 4:
113 if (! ieee_write_byte (abfd, (bfd_byte) (value >> 24)))
b34976b6 114 return FALSE;
252b5132
RH
115 /* Fall through. */
116 case 3:
117 if (! ieee_write_byte (abfd, (bfd_byte) (value >> 16)))
b34976b6 118 return FALSE;
252b5132
RH
119 /* Fall through. */
120 case 2:
121 if (! ieee_write_byte (abfd, (bfd_byte) (value >> 8)))
b34976b6 122 return FALSE;
252b5132
RH
123 /* Fall through. */
124 case 1:
125 if (! ieee_write_byte (abfd, (bfd_byte) (value)))
b34976b6 126 return FALSE;
252b5132
RH
127 }
128 }
129
b34976b6 130 return TRUE;
252b5132
RH
131}
132
b34976b6 133static bfd_boolean
c8e7bf0d 134ieee_write_id (bfd *abfd, const char *id)
252b5132
RH
135{
136 size_t length = strlen (id);
137
138 if (length <= 127)
139 {
140 if (! ieee_write_byte (abfd, (bfd_byte) length))
b34976b6 141 return FALSE;
252b5132
RH
142 }
143 else if (length < 255)
144 {
145 if (! ieee_write_byte (abfd, ieee_extension_length_1_enum)
146 || ! ieee_write_byte (abfd, (bfd_byte) length))
b34976b6 147 return FALSE;
252b5132
RH
148 }
149 else if (length < 65535)
150 {
151 if (! ieee_write_byte (abfd, ieee_extension_length_2_enum)
152 || ! ieee_write_2bytes (abfd, (int) length))
b34976b6 153 return FALSE;
252b5132
RH
154 }
155 else
156 {
157 (*_bfd_error_handler)
158 (_("%s: string too long (%d chars, max 65535)"),
159 bfd_get_filename (abfd), length);
160 bfd_set_error (bfd_error_invalid_operation);
b34976b6 161 return FALSE;
252b5132
RH
162 }
163
c8e7bf0d 164 if (bfd_bwrite ((void *) id, (bfd_size_type) length, abfd) != length)
b34976b6
AM
165 return FALSE;
166 return TRUE;
252b5132
RH
167}
168\f
49ae03bf
NC
169/* Functions for reading from ieee files in the strange way that the
170 standard requires. */
252b5132 171
c8e7bf0d
NC
172#define this_byte(ieee) *((ieee)->input_p)
173#define next_byte(ieee) ((ieee)->input_p++)
252b5132
RH
174#define this_byte_and_next(ieee) (*((ieee)->input_p++))
175
176static unsigned short
c8e7bf0d 177read_2bytes (common_header_type *ieee)
252b5132
RH
178{
179 unsigned char c1 = this_byte_and_next (ieee);
180 unsigned char c2 = this_byte_and_next (ieee);
49ae03bf 181
252b5132
RH
182 return (c1 << 8) | c2;
183}
184
185static void
c8e7bf0d 186bfd_get_string (common_header_type *ieee, char *string, size_t length)
252b5132
RH
187{
188 size_t i;
49ae03bf 189
252b5132 190 for (i = 0; i < length; i++)
49ae03bf 191 string[i] = this_byte_and_next (ieee);
252b5132
RH
192}
193
194static char *
c8e7bf0d 195read_id (common_header_type *ieee)
252b5132
RH
196{
197 size_t length;
198 char *string;
49ae03bf 199
252b5132
RH
200 length = this_byte_and_next (ieee);
201 if (length <= 0x7f)
c8e7bf0d
NC
202 /* Simple string of length 0 to 127. */
203 ;
204
252b5132 205 else if (length == 0xde)
c8e7bf0d
NC
206 /* Length is next byte, allowing 0..255. */
207 length = this_byte_and_next (ieee);
208
252b5132
RH
209 else if (length == 0xdf)
210 {
49ae03bf 211 /* Length is next two bytes, allowing 0..65535. */
252b5132
RH
212 length = this_byte_and_next (ieee);
213 length = (length * 256) + this_byte_and_next (ieee);
214 }
49ae03bf
NC
215
216 /* Buy memory and read string. */
dc810e39 217 string = bfd_alloc (ieee->abfd, (bfd_size_type) length + 1);
252b5132
RH
218 if (!string)
219 return NULL;
220 bfd_get_string (ieee, string, length);
221 string[length] = 0;
222 return string;
223}
224
b34976b6 225static bfd_boolean
c8e7bf0d
NC
226ieee_write_expression (bfd *abfd,
227 bfd_vma value,
228 asymbol *symbol,
229 bfd_boolean pcrel,
91d6fa6a 230 unsigned int sindex)
252b5132
RH
231{
232 unsigned int term_count = 0;
233
234 if (value != 0)
235 {
236 if (! ieee_write_int (abfd, value))
b34976b6 237 return FALSE;
252b5132
RH
238 term_count++;
239 }
240
49ae03bf
NC
241 /* Badly formatted binaries can have a missing symbol,
242 so test here to prevent a seg fault. */
243 if (symbol != NULL)
252b5132 244 {
49ae03bf
NC
245 if (bfd_is_com_section (symbol->section)
246 || bfd_is_und_section (symbol->section))
252b5132 247 {
49ae03bf
NC
248 /* Def of a common symbol. */
249 if (! ieee_write_byte (abfd, ieee_variable_X_enum)
252b5132 250 || ! ieee_write_int (abfd, symbol->value))
b34976b6 251 return FALSE;
49ae03bf 252 term_count ++;
252b5132 253 }
49ae03bf 254 else if (! bfd_is_abs_section (symbol->section))
252b5132 255 {
49ae03bf 256 /* Ref to defined symbol - */
49ae03bf 257 if (symbol->flags & BSF_GLOBAL)
252b5132 258 {
49ae03bf
NC
259 if (! ieee_write_byte (abfd, ieee_variable_I_enum)
260 || ! ieee_write_int (abfd, symbol->value))
b34976b6 261 return FALSE;
252b5132
RH
262 term_count++;
263 }
49ae03bf
NC
264 else if (symbol->flags & (BSF_LOCAL | BSF_SECTION_SYM))
265 {
266 /* This is a reference to a defined local symbol. We can
267 easily do a local as a section+offset. */
268 if (! ieee_write_byte (abfd, ieee_variable_R_enum)
269 || ! ieee_write_byte (abfd,
270 (bfd_byte) (symbol->section->index
271 + IEEE_SECTION_NUMBER_BASE)))
272 return FALSE;
273
274 term_count++;
275 if (symbol->value != 0)
276 {
277 if (! ieee_write_int (abfd, symbol->value))
278 return FALSE;
279 term_count++;
280 }
281 }
282 else
283 {
284 (*_bfd_error_handler)
285 (_("%s: unrecognized symbol `%s' flags 0x%x"),
286 bfd_get_filename (abfd), bfd_asymbol_name (symbol),
287 symbol->flags);
288 bfd_set_error (bfd_error_invalid_operation);
289 return FALSE;
290 }
252b5132
RH
291 }
292 }
293
294 if (pcrel)
295 {
49ae03bf 296 /* Subtract the pc from here by asking for PC of this section. */
252b5132
RH
297 if (! ieee_write_byte (abfd, ieee_variable_P_enum)
298 || ! ieee_write_byte (abfd,
91d6fa6a 299 (bfd_byte) (sindex + IEEE_SECTION_NUMBER_BASE))
252b5132 300 || ! ieee_write_byte (abfd, ieee_function_minus_enum))
b34976b6 301 return FALSE;
252b5132
RH
302 }
303
304 /* Handle the degenerate case of a 0 address. */
305 if (term_count == 0)
49ae03bf
NC
306 if (! ieee_write_int (abfd, (bfd_vma) 0))
307 return FALSE;
252b5132
RH
308
309 while (term_count > 1)
310 {
311 if (! ieee_write_byte (abfd, ieee_function_plus_enum))
b34976b6 312 return FALSE;
252b5132
RH
313 term_count--;
314 }
315
b34976b6 316 return TRUE;
252b5132
RH
317}
318\f
49ae03bf 319/* Writes any integer into the buffer supplied and always takes 5 bytes. */
252b5132 320
252b5132 321static void
c8e7bf0d 322ieee_write_int5 (bfd_byte *buffer, bfd_vma value)
252b5132
RH
323{
324 buffer[0] = (bfd_byte) ieee_number_repeat_4_enum;
325 buffer[1] = (value >> 24) & 0xff;
326 buffer[2] = (value >> 16) & 0xff;
327 buffer[3] = (value >> 8) & 0xff;
328 buffer[4] = (value >> 0) & 0xff;
329}
330
b34976b6 331static bfd_boolean
c8e7bf0d 332ieee_write_int5_out (bfd *abfd, bfd_vma value)
252b5132
RH
333{
334 bfd_byte b[5];
335
336 ieee_write_int5 (b, value);
c8e7bf0d 337 if (bfd_bwrite ((void *) b, (bfd_size_type) 5, abfd) != 5)
b34976b6
AM
338 return FALSE;
339 return TRUE;
252b5132
RH
340}
341
b34976b6 342static bfd_boolean
c8e7bf0d 343parse_int (common_header_type *ieee, bfd_vma *value_ptr)
252b5132
RH
344{
345 int value = this_byte (ieee);
346 int result;
49ae03bf 347
252b5132
RH
348 if (value >= 0 && value <= 127)
349 {
350 *value_ptr = value;
351 next_byte (ieee);
b34976b6 352 return TRUE;
252b5132
RH
353 }
354 else if (value >= 0x80 && value <= 0x88)
355 {
356 unsigned int count = value & 0xf;
49ae03bf 357
252b5132
RH
358 result = 0;
359 next_byte (ieee);
360 while (count)
361 {
362 result = (result << 8) | this_byte_and_next (ieee);
363 count--;
364 }
365 *value_ptr = result;
b34976b6 366 return TRUE;
252b5132 367 }
b34976b6 368 return FALSE;
252b5132
RH
369}
370
371static int
c8e7bf0d 372parse_i (common_header_type *ieee, bfd_boolean *ok)
252b5132 373{
1b0b5b1b 374 bfd_vma x = 0;
252b5132
RH
375 *ok = parse_int (ieee, &x);
376 return x;
377}
378
379static bfd_vma
46e94266 380must_parse_int (common_header_type *ieee)
252b5132 381{
1b0b5b1b 382 bfd_vma result = 0;
82e51918 383 BFD_ASSERT (parse_int (ieee, &result));
252b5132
RH
384 return result;
385}
386
387typedef struct
388{
389 bfd_vma value;
390 asection *section;
391 ieee_symbol_index_type symbol;
392} ieee_value_type;
393
394
395#if KEEPMINUSPCININST
396
397#define SRC_MASK(arg) arg
b34976b6 398#define PCREL_OFFSET FALSE
252b5132
RH
399
400#else
401
402#define SRC_MASK(arg) 0
b34976b6 403#define PCREL_OFFSET TRUE
252b5132
RH
404
405#endif
406
407static reloc_howto_type abs32_howto =
408 HOWTO (1,
409 0,
410 2,
411 32,
b34976b6 412 FALSE,
252b5132
RH
413 0,
414 complain_overflow_bitfield,
415 0,
416 "abs32",
b34976b6 417 TRUE,
252b5132
RH
418 0xffffffff,
419 0xffffffff,
b34976b6 420 FALSE);
252b5132
RH
421
422static reloc_howto_type abs16_howto =
423 HOWTO (1,
424 0,
425 1,
426 16,
b34976b6 427 FALSE,
252b5132
RH
428 0,
429 complain_overflow_bitfield,
430 0,
431 "abs16",
b34976b6 432 TRUE,
252b5132
RH
433 0x0000ffff,
434 0x0000ffff,
b34976b6 435 FALSE);
252b5132
RH
436
437static reloc_howto_type abs8_howto =
438 HOWTO (1,
439 0,
440 0,
441 8,
b34976b6 442 FALSE,
252b5132
RH
443 0,
444 complain_overflow_bitfield,
445 0,
446 "abs8",
b34976b6 447 TRUE,
252b5132
RH
448 0x000000ff,
449 0x000000ff,
b34976b6 450 FALSE);
252b5132
RH
451
452static reloc_howto_type rel32_howto =
453 HOWTO (1,
454 0,
455 2,
456 32,
b34976b6 457 TRUE,
252b5132
RH
458 0,
459 complain_overflow_signed,
460 0,
461 "rel32",
b34976b6 462 TRUE,
252b5132
RH
463 SRC_MASK (0xffffffff),
464 0xffffffff,
465 PCREL_OFFSET);
466
467static reloc_howto_type rel16_howto =
468 HOWTO (1,
469 0,
470 1,
471 16,
b34976b6 472 TRUE,
252b5132
RH
473 0,
474 complain_overflow_signed,
475 0,
476 "rel16",
b34976b6 477 TRUE,
252b5132
RH
478 SRC_MASK (0x0000ffff),
479 0x0000ffff,
480 PCREL_OFFSET);
481
482static reloc_howto_type rel8_howto =
483 HOWTO (1,
484 0,
485 0,
486 8,
b34976b6 487 TRUE,
252b5132
RH
488 0,
489 complain_overflow_signed,
490 0,
491 "rel8",
b34976b6 492 TRUE,
252b5132
RH
493 SRC_MASK (0x000000ff),
494 0x000000ff,
495 PCREL_OFFSET);
496
497static ieee_symbol_index_type NOSYMBOL = {0, 0};
498
499static void
c8e7bf0d
NC
500parse_expression (ieee_data_type *ieee,
501 bfd_vma *value,
502 ieee_symbol_index_type *symbol,
503 bfd_boolean *pcrel,
504 unsigned int *extra,
505 asection **section)
252b5132
RH
506
507{
c8e7bf0d
NC
508 bfd_boolean loop = TRUE;
509 ieee_value_type stack[10];
510 ieee_value_type *sp = stack;
511 asection *dummy;
512
252b5132
RH
513#define POS sp[1]
514#define TOS sp[0]
515#define NOS sp[-1]
516#define INC sp++;
517#define DEC sp--;
518
49ae03bf 519 /* The stack pointer always points to the next unused location. */
c8e7bf0d
NC
520#define PUSH(x,y,z) TOS.symbol = x; TOS.section = y; TOS.value = z; INC;
521#define POP(x,y,z) DEC; x = TOS.symbol; y = TOS.section; z = TOS.value;
252b5132 522
47fda0d3 523 while (loop && ieee->h.input_p < ieee->h.last_byte)
252b5132
RH
524 {
525 switch (this_byte (&(ieee->h)))
526 {
527 case ieee_variable_P_enum:
49ae03bf 528 /* P variable, current program counter for section n. */
252b5132
RH
529 {
530 int section_n;
49ae03bf 531
252b5132 532 next_byte (&(ieee->h));
b34976b6 533 *pcrel = TRUE;
252b5132 534 section_n = must_parse_int (&(ieee->h));
c7e2358a 535 (void) section_n;
252b5132
RH
536 PUSH (NOSYMBOL, bfd_abs_section_ptr, 0);
537 break;
538 }
539 case ieee_variable_L_enum:
49ae03bf 540 /* L variable address of section N. */
252b5132
RH
541 next_byte (&(ieee->h));
542 PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
543 break;
544 case ieee_variable_R_enum:
49ae03bf
NC
545 /* R variable, logical address of section module. */
546 /* FIXME, this should be different to L. */
252b5132
RH
547 next_byte (&(ieee->h));
548 PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
549 break;
550 case ieee_variable_S_enum:
49ae03bf 551 /* S variable, size in MAUS of section module. */
252b5132
RH
552 next_byte (&(ieee->h));
553 PUSH (NOSYMBOL,
554 0,
eea6121a 555 ieee->section_table[must_parse_int (&(ieee->h))]->size);
252b5132
RH
556 break;
557 case ieee_variable_I_enum:
49ae03bf 558 /* Push the address of variable n. */
252b5132
RH
559 {
560 ieee_symbol_index_type sy;
c8e7bf0d 561
252b5132
RH
562 next_byte (&(ieee->h));
563 sy.index = (int) must_parse_int (&(ieee->h));
564 sy.letter = 'I';
565
566 PUSH (sy, bfd_abs_section_ptr, 0);
567 }
568 break;
569 case ieee_variable_X_enum:
49ae03bf 570 /* Push the address of external variable n. */
252b5132
RH
571 {
572 ieee_symbol_index_type sy;
c8e7bf0d 573
252b5132
RH
574 next_byte (&(ieee->h));
575 sy.index = (int) (must_parse_int (&(ieee->h)));
576 sy.letter = 'X';
577
578 PUSH (sy, bfd_und_section_ptr, 0);
579 }
580 break;
581 case ieee_function_minus_enum:
582 {
583 bfd_vma value1, value2;
584 asection *section1, *section_dummy;
585 ieee_symbol_index_type sy;
c8e7bf0d 586
252b5132
RH
587 next_byte (&(ieee->h));
588
589 POP (sy, section1, value1);
590 POP (sy, section_dummy, value2);
591 PUSH (sy, section1 ? section1 : section_dummy, value2 - value1);
592 }
593 break;
594 case ieee_function_plus_enum:
595 {
596 bfd_vma value1, value2;
597 asection *section1;
598 asection *section2;
599 ieee_symbol_index_type sy1;
600 ieee_symbol_index_type sy2;
c8e7bf0d 601
252b5132
RH
602 next_byte (&(ieee->h));
603
604 POP (sy1, section1, value1);
605 POP (sy2, section2, value2);
606 PUSH (sy1.letter ? sy1 : sy2,
607 bfd_is_abs_section (section1) ? section2 : section1,
608 value1 + value2);
609 }
610 break;
611 default:
612 {
613 bfd_vma va;
c8e7bf0d 614
252b5132
RH
615 BFD_ASSERT (this_byte (&(ieee->h)) < (int) ieee_variable_A_enum
616 || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum);
617 if (parse_int (&(ieee->h), &va))
618 {
619 PUSH (NOSYMBOL, bfd_abs_section_ptr, va);
620 }
621 else
c8e7bf0d
NC
622 /* Thats all that we can understand. */
623 loop = FALSE;
252b5132
RH
624 }
625 }
626 }
47fda0d3
AM
627
628 /* As far as I can see there is a bug in the Microtec IEEE output
629 which I'm using to scan, whereby the comma operator is omitted
630 sometimes in an expression, giving expressions with too many
631 terms. We can tell if that's the case by ensuring that
632 sp == stack here. If not, then we've pushed something too far,
633 so we keep adding. */
47fda0d3
AM
634 while (sp != stack + 1)
635 {
636 asection *section1;
637 ieee_symbol_index_type sy1;
c8e7bf0d 638
47fda0d3 639 POP (sy1, section1, *extra);
c7e2358a
AM
640 (void) section1;
641 (void) sy1;
47fda0d3
AM
642 }
643
644 POP (*symbol, dummy, *value);
645 if (section)
646 *section = dummy;
252b5132
RH
647}
648
649
47fda0d3
AM
650#define ieee_seek(ieee, offset) \
651 do \
652 { \
653 ieee->h.input_p = ieee->h.first_byte + offset; \
654 ieee->h.last_byte = (ieee->h.first_byte \
655 + ieee_part_after (ieee, offset)); \
656 } \
657 while (0)
658
659#define ieee_pos(ieee) \
660 (ieee->h.input_p - ieee->h.first_byte)
252b5132 661
47fda0d3
AM
662/* Find the first part of the ieee file after HERE. */
663
664static file_ptr
c8e7bf0d 665ieee_part_after (ieee_data_type *ieee, file_ptr here)
47fda0d3
AM
666{
667 int part;
668 file_ptr after = ieee->w.r.me_record;
669
670 /* File parts can come in any order, except that module end is
671 guaranteed to be last (and the header first). */
672 for (part = 0; part < N_W_VARIABLES; part++)
673 if (ieee->w.offset[part] > here && after > ieee->w.offset[part])
674 after = ieee->w.offset[part];
675
676 return after;
677}
252b5132
RH
678
679static unsigned int last_index;
49ae03bf 680static char last_type; /* Is the index for an X or a D. */
252b5132
RH
681
682static ieee_symbol_type *
c8e7bf0d
NC
683get_symbol (bfd *abfd ATTRIBUTE_UNUSED,
684 ieee_data_type *ieee,
685 ieee_symbol_type *last_symbol,
686 unsigned int *symbol_count,
687 ieee_symbol_type ***pptr,
688 unsigned int *max_index,
689 int this_type)
252b5132 690{
49ae03bf 691 /* Need a new symbol. */
252b5132 692 unsigned int new_index = must_parse_int (&(ieee->h));
49ae03bf 693
252b5132
RH
694 if (new_index != last_index || this_type != last_type)
695 {
dc810e39
AM
696 ieee_symbol_type *new_symbol;
697 bfd_size_type amt = sizeof (ieee_symbol_type);
698
c8e7bf0d 699 new_symbol = bfd_alloc (ieee->h.abfd, amt);
252b5132
RH
700 if (!new_symbol)
701 return NULL;
702
703 new_symbol->index = new_index;
704 last_index = new_index;
705 (*symbol_count)++;
706 **pptr = new_symbol;
707 *pptr = &new_symbol->next;
708 if (new_index > *max_index)
49ae03bf
NC
709 *max_index = new_index;
710
252b5132
RH
711 last_type = this_type;
712 new_symbol->symbol.section = bfd_abs_section_ptr;
713 return new_symbol;
714 }
715 return last_symbol;
716}
717
b34976b6 718static bfd_boolean
c8e7bf0d 719ieee_slurp_external_symbols (bfd *abfd)
252b5132
RH
720{
721 ieee_data_type *ieee = IEEE_DATA (abfd);
722 file_ptr offset = ieee->w.r.external_part;
723
724 ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols;
725 ieee_symbol_type **prev_reference_ptr = &ieee->external_reference;
c8e7bf0d 726 ieee_symbol_type *symbol = NULL;
252b5132 727 unsigned int symbol_count = 0;
b34976b6 728 bfd_boolean loop = TRUE;
c8e7bf0d 729
252b5132 730 last_index = 0xffffff;
b34976b6 731 ieee->symbol_table_full = TRUE;
252b5132 732
47fda0d3 733 ieee_seek (ieee, offset);
252b5132
RH
734
735 while (loop)
736 {
737 switch (this_byte (&(ieee->h)))
738 {
739 case ieee_nn_record:
740 next_byte (&(ieee->h));
741
742 symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
c8e7bf0d
NC
743 & prev_symbols_ptr,
744 & ieee->external_symbol_max_index, 'I');
252b5132 745 if (symbol == NULL)
b34976b6 746 return FALSE;
252b5132
RH
747
748 symbol->symbol.the_bfd = abfd;
749 symbol->symbol.name = read_id (&(ieee->h));
c8e7bf0d 750 symbol->symbol.udata.p = NULL;
252b5132
RH
751 symbol->symbol.flags = BSF_NO_FLAGS;
752 break;
753 case ieee_external_symbol_enum:
754 next_byte (&(ieee->h));
755
756 symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
757 &prev_symbols_ptr,
758 &ieee->external_symbol_max_index, 'D');
759 if (symbol == NULL)
b34976b6 760 return FALSE;
252b5132
RH
761
762 BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index);
763
764 symbol->symbol.the_bfd = abfd;
765 symbol->symbol.name = read_id (&(ieee->h));
c8e7bf0d 766 symbol->symbol.udata.p = NULL;
252b5132
RH
767 symbol->symbol.flags = BSF_NO_FLAGS;
768 break;
769 case ieee_attribute_record_enum >> 8:
770 {
771 unsigned int symbol_name_index;
772 unsigned int symbol_type_index;
773 unsigned int symbol_attribute_def;
1b0b5b1b 774 bfd_vma value = 0;
c8e7bf0d 775
47fda0d3 776 switch (read_2bytes (&ieee->h))
252b5132
RH
777 {
778 case ieee_attribute_record_enum:
779 symbol_name_index = must_parse_int (&(ieee->h));
780 symbol_type_index = must_parse_int (&(ieee->h));
c7e2358a 781 (void) symbol_type_index;
252b5132
RH
782 symbol_attribute_def = must_parse_int (&(ieee->h));
783 switch (symbol_attribute_def)
784 {
785 case 8:
786 case 19:
787 parse_int (&ieee->h, &value);
788 break;
789 default:
790 (*_bfd_error_handler)
d003868e
AM
791 (_("%B: unimplemented ATI record %u for symbol %u"),
792 abfd, symbol_attribute_def, symbol_name_index);
252b5132 793 bfd_set_error (bfd_error_bad_value);
b34976b6 794 return FALSE;
252b5132
RH
795 break;
796 }
797 break;
798 case ieee_external_reference_info_record_enum:
49ae03bf 799 /* Skip over ATX record. */
252b5132
RH
800 parse_int (&(ieee->h), &value);
801 parse_int (&(ieee->h), &value);
802 parse_int (&(ieee->h), &value);
803 parse_int (&(ieee->h), &value);
804 break;
805 case ieee_atn_record_enum:
806 /* We may get call optimization information here,
807 which we just ignore. The format is
49ae03bf 808 {$F1}${CE}{index}{$00}{$3F}{$3F}{#_of_ASNs}. */
252b5132
RH
809 parse_int (&ieee->h, &value);
810 parse_int (&ieee->h, &value);
811 parse_int (&ieee->h, &value);
812 if (value != 0x3f)
813 {
814 (*_bfd_error_handler)
d003868e
AM
815 (_("%B: unexpected ATN type %d in external part"),
816 abfd, (int) value);
252b5132 817 bfd_set_error (bfd_error_bad_value);
b34976b6 818 return FALSE;
252b5132
RH
819 }
820 parse_int (&ieee->h, &value);
821 parse_int (&ieee->h, &value);
822 while (value > 0)
823 {
824 bfd_vma val1;
825
826 --value;
827
47fda0d3 828 switch (read_2bytes (&ieee->h))
252b5132
RH
829 {
830 case ieee_asn_record_enum:
831 parse_int (&ieee->h, &val1);
832 parse_int (&ieee->h, &val1);
833 break;
834
835 default:
836 (*_bfd_error_handler)
d003868e 837 (_("%B: unexpected type after ATN"), abfd);
252b5132 838 bfd_set_error (bfd_error_bad_value);
b34976b6 839 return FALSE;
252b5132
RH
840 }
841 }
842 }
843 }
844 break;
845 case ieee_value_record_enum >> 8:
846 {
847 unsigned int symbol_name_index;
848 ieee_symbol_index_type symbol_ignore;
b34976b6 849 bfd_boolean pcrel_ignore;
252b5132 850 unsigned int extra;
c8e7bf0d 851
252b5132
RH
852 next_byte (&(ieee->h));
853 next_byte (&(ieee->h));
854
855 symbol_name_index = must_parse_int (&(ieee->h));
c7e2358a 856 (void) symbol_name_index;
252b5132
RH
857 parse_expression (ieee,
858 &symbol->symbol.value,
859 &symbol_ignore,
860 &pcrel_ignore,
861 &extra,
862 &symbol->symbol.section);
863
864 /* Fully linked IEEE-695 files tend to give every symbol
865 an absolute value. Try to convert that back into a
866 section relative value. FIXME: This won't always to
867 the right thing. */
868 if (bfd_is_abs_section (symbol->symbol.section)
869 && (abfd->flags & HAS_RELOC) == 0)
870 {
871 bfd_vma val;
872 asection *s;
873
874 val = symbol->symbol.value;
875 for (s = abfd->sections; s != NULL; s = s->next)
876 {
eea6121a 877 if (val >= s->vma && val < s->vma + s->size)
252b5132
RH
878 {
879 symbol->symbol.section = s;
880 symbol->symbol.value -= s->vma;
881 break;
882 }
883 }
884 }
885
886 symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
887
888 }
889 break;
890 case ieee_weak_external_reference_enum:
891 {
892 bfd_vma size;
893 bfd_vma value;
c8e7bf0d 894
252b5132 895 next_byte (&(ieee->h));
49ae03bf 896 /* Throw away the external reference index. */
252b5132 897 (void) must_parse_int (&(ieee->h));
49ae03bf 898 /* Fetch the default size if not resolved. */
252b5132 899 size = must_parse_int (&(ieee->h));
7dee875e 900 /* Fetch the default value if available. */
82e51918 901 if (! parse_int (&(ieee->h), &value))
c8e7bf0d 902 value = 0;
49ae03bf 903 /* This turns into a common. */
252b5132
RH
904 symbol->symbol.section = bfd_com_section_ptr;
905 symbol->symbol.value = size;
906 }
907 break;
908
909 case ieee_external_reference_enum:
910 next_byte (&(ieee->h));
911
912 symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
913 &prev_reference_ptr,
914 &ieee->external_reference_max_index, 'X');
915 if (symbol == NULL)
b34976b6 916 return FALSE;
252b5132
RH
917
918 symbol->symbol.the_bfd = abfd;
919 symbol->symbol.name = read_id (&(ieee->h));
c8e7bf0d 920 symbol->symbol.udata.p = NULL;
252b5132
RH
921 symbol->symbol.section = bfd_und_section_ptr;
922 symbol->symbol.value = (bfd_vma) 0;
923 symbol->symbol.flags = 0;
924
925 BFD_ASSERT (symbol->index >= ieee->external_reference_min_index);
926 break;
927
928 default:
b34976b6 929 loop = FALSE;
252b5132
RH
930 }
931 }
932
933 if (ieee->external_symbol_max_index != 0)
934 {
935 ieee->external_symbol_count =
936 ieee->external_symbol_max_index -
937 ieee->external_symbol_min_index + 1;
938 }
939 else
c8e7bf0d 940 ieee->external_symbol_count = 0;
252b5132
RH
941
942 if (ieee->external_reference_max_index != 0)
943 {
944 ieee->external_reference_count =
945 ieee->external_reference_max_index -
946 ieee->external_reference_min_index + 1;
947 }
948 else
c8e7bf0d 949 ieee->external_reference_count = 0;
252b5132
RH
950
951 abfd->symcount =
952 ieee->external_reference_count + ieee->external_symbol_count;
953
954 if (symbol_count != abfd->symcount)
c8e7bf0d
NC
955 /* There are gaps in the table -- */
956 ieee->symbol_table_full = FALSE;
252b5132 957
c8e7bf0d
NC
958 *prev_symbols_ptr = NULL;
959 *prev_reference_ptr = NULL;
252b5132 960
b34976b6 961 return TRUE;
252b5132
RH
962}
963
b34976b6 964static bfd_boolean
c8e7bf0d 965ieee_slurp_symbol_table (bfd *abfd)
252b5132 966{
82e51918 967 if (! IEEE_DATA (abfd)->read_symbols)
252b5132
RH
968 {
969 if (! ieee_slurp_external_symbols (abfd))
b34976b6
AM
970 return FALSE;
971 IEEE_DATA (abfd)->read_symbols = TRUE;
252b5132 972 }
b34976b6 973 return TRUE;
252b5132
RH
974}
975
47fda0d3 976static long
46e94266 977ieee_get_symtab_upper_bound (bfd *abfd)
252b5132
RH
978{
979 if (! ieee_slurp_symbol_table (abfd))
980 return -1;
981
982 return (abfd->symcount != 0) ?
983 (abfd->symcount + 1) * (sizeof (ieee_symbol_type *)) : 0;
984}
985
49ae03bf
NC
986/* Move from our internal lists to the canon table, and insert in
987 symbol index order. */
252b5132
RH
988
989extern const bfd_target ieee_vec;
990
47fda0d3 991static long
c8e7bf0d 992ieee_canonicalize_symtab (bfd *abfd, asymbol **location)
252b5132
RH
993{
994 ieee_symbol_type *symp;
995 static bfd dummy_bfd;
996 static asymbol empty_symbol =
dcdea4f4
AM
997 {
998 &dummy_bfd,
999 " ieee empty",
1000 (symvalue) 0,
1001 BSF_DEBUGGING,
1002 bfd_abs_section_ptr
1003#ifdef __STDC__
1004 /* K&R compilers can't initialise unions. */
1005 , { 0 }
1006#endif
1007 };
252b5132
RH
1008
1009 if (abfd->symcount)
1010 {
1011 ieee_data_type *ieee = IEEE_DATA (abfd);
c8e7bf0d 1012
252b5132
RH
1013 dummy_bfd.xvec = &ieee_vec;
1014 if (! ieee_slurp_symbol_table (abfd))
1015 return -1;
1016
82e51918 1017 if (! ieee->symbol_table_full)
252b5132 1018 {
49ae03bf
NC
1019 /* Arrgh - there are gaps in the table, run through and fill them
1020 up with pointers to a null place. */
252b5132 1021 unsigned int i;
49ae03bf 1022
252b5132 1023 for (i = 0; i < abfd->symcount; i++)
49ae03bf 1024 location[i] = &empty_symbol;
252b5132
RH
1025 }
1026
1027 ieee->external_symbol_base_offset = -ieee->external_symbol_min_index;
1028 for (symp = IEEE_DATA (abfd)->external_symbols;
1029 symp != (ieee_symbol_type *) NULL;
1030 symp = symp->next)
49ae03bf
NC
1031 /* Place into table at correct index locations. */
1032 location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol;
252b5132 1033
49ae03bf 1034 /* The external refs are indexed in a bit. */
252b5132
RH
1035 ieee->external_reference_base_offset =
1036 -ieee->external_reference_min_index + ieee->external_symbol_count;
1037
1038 for (symp = IEEE_DATA (abfd)->external_reference;
1039 symp != (ieee_symbol_type *) NULL;
1040 symp = symp->next)
49ae03bf
NC
1041 location[symp->index + ieee->external_reference_base_offset] =
1042 &symp->symbol;
252b5132 1043 }
49ae03bf 1044
252b5132 1045 if (abfd->symcount)
49ae03bf
NC
1046 location[abfd->symcount] = (asymbol *) NULL;
1047
252b5132
RH
1048 return abfd->symcount;
1049}
1050
1051static asection *
91d6fa6a 1052get_section_entry (bfd *abfd, ieee_data_type *ieee, unsigned int sindex)
252b5132 1053{
91d6fa6a 1054 if (sindex >= ieee->section_table_size)
252b5132
RH
1055 {
1056 unsigned int c, i;
1057 asection **n;
dc810e39 1058 bfd_size_type amt;
252b5132
RH
1059
1060 c = ieee->section_table_size;
1061 if (c == 0)
1062 c = 20;
91d6fa6a 1063 while (c <= sindex)
252b5132
RH
1064 c *= 2;
1065
dc810e39
AM
1066 amt = c;
1067 amt *= sizeof (asection *);
c8e7bf0d 1068 n = bfd_realloc (ieee->section_table, amt);
252b5132
RH
1069 if (n == NULL)
1070 return NULL;
1071
1072 for (i = ieee->section_table_size; i < c; i++)
1073 n[i] = NULL;
1074
1075 ieee->section_table = n;
1076 ieee->section_table_size = c;
1077 }
1078
91d6fa6a 1079 if (ieee->section_table[sindex] == (asection *) NULL)
252b5132 1080 {
dc810e39 1081 char *tmp = bfd_alloc (abfd, (bfd_size_type) 11);
252b5132
RH
1082 asection *section;
1083
1084 if (!tmp)
1085 return NULL;
91d6fa6a 1086 sprintf (tmp, " fsec%4d", sindex);
252b5132 1087 section = bfd_make_section (abfd, tmp);
91d6fa6a
NC
1088 ieee->section_table[sindex] = section;
1089 section->target_index = sindex;
1090 ieee->section_table[sindex] = section;
252b5132 1091 }
91d6fa6a 1092 return ieee->section_table[sindex];
252b5132
RH
1093}
1094
1095static void
c8e7bf0d 1096ieee_slurp_sections (bfd *abfd)
252b5132
RH
1097{
1098 ieee_data_type *ieee = IEEE_DATA (abfd);
1099 file_ptr offset = ieee->w.r.section_part;
252b5132
RH
1100 char *name;
1101
1102 if (offset != 0)
1103 {
1104 bfd_byte section_type[3];
c8e7bf0d 1105
47fda0d3 1106 ieee_seek (ieee, offset);
b34976b6 1107 while (TRUE)
252b5132
RH
1108 {
1109 switch (this_byte (&(ieee->h)))
1110 {
1111 case ieee_section_type_enum:
1112 {
dc810e39 1113 asection *section;
252b5132 1114 unsigned int section_index;
c8e7bf0d 1115
252b5132
RH
1116 next_byte (&(ieee->h));
1117 section_index = must_parse_int (&(ieee->h));
1118
1119 section = get_section_entry (abfd, ieee, section_index);
1120
1121 section_type[0] = this_byte_and_next (&(ieee->h));
1122
1123 /* Set minimal section attributes. Attributes are
49ae03bf 1124 extended later, based on section contents. */
252b5132
RH
1125 switch (section_type[0])
1126 {
1127 case 0xC1:
49ae03bf 1128 /* Normal attributes for absolute sections. */
252b5132
RH
1129 section_type[1] = this_byte (&(ieee->h));
1130 section->flags = SEC_ALLOC;
1131 switch (section_type[1])
1132 {
c8e7bf0d
NC
1133 /* AS Absolute section attributes. */
1134 case 0xD3:
252b5132
RH
1135 next_byte (&(ieee->h));
1136 section_type[2] = this_byte (&(ieee->h));
1137 switch (section_type[2])
1138 {
1139 case 0xD0:
49ae03bf 1140 /* Normal code. */
252b5132
RH
1141 next_byte (&(ieee->h));
1142 section->flags |= SEC_CODE;
1143 break;
1144 case 0xC4:
49ae03bf 1145 /* Normal data. */
252b5132
RH
1146 next_byte (&(ieee->h));
1147 section->flags |= SEC_DATA;
1148 break;
1149 case 0xD2:
1150 next_byte (&(ieee->h));
49ae03bf 1151 /* Normal rom data. */
252b5132
RH
1152 section->flags |= SEC_ROM | SEC_DATA;
1153 break;
1154 default:
1155 break;
1156 }
1157 }
1158 break;
c8e7bf0d
NC
1159
1160 /* Named relocatable sections (type C). */
1161 case 0xC3:
252b5132
RH
1162 section_type[1] = this_byte (&(ieee->h));
1163 section->flags = SEC_ALLOC;
1164 switch (section_type[1])
1165 {
49ae03bf 1166 case 0xD0: /* Normal code (CP). */
252b5132
RH
1167 next_byte (&(ieee->h));
1168 section->flags |= SEC_CODE;
1169 break;
49ae03bf 1170 case 0xC4: /* Normal data (CD). */
252b5132
RH
1171 next_byte (&(ieee->h));
1172 section->flags |= SEC_DATA;
1173 break;
49ae03bf 1174 case 0xD2: /* Normal rom data (CR). */
252b5132
RH
1175 next_byte (&(ieee->h));
1176 section->flags |= SEC_ROM | SEC_DATA;
1177 break;
1178 default:
1179 break;
1180 }
1181 }
1182
49ae03bf 1183 /* Read section name, use it if non empty. */
252b5132
RH
1184 name = read_id (&ieee->h);
1185 if (name[0])
1186 section->name = name;
1187
49ae03bf 1188 /* Skip these fields, which we don't care about. */
252b5132
RH
1189 {
1190 bfd_vma parent, brother, context;
c8e7bf0d 1191
252b5132
RH
1192 parse_int (&(ieee->h), &parent);
1193 parse_int (&(ieee->h), &brother);
1194 parse_int (&(ieee->h), &context);
1195 }
1196 }
1197 break;
1198 case ieee_section_alignment_enum:
1199 {
1200 unsigned int section_index;
1201 bfd_vma value;
1202 asection *section;
c8e7bf0d 1203
252b5132
RH
1204 next_byte (&(ieee->h));
1205 section_index = must_parse_int (&ieee->h);
1206 section = get_section_entry (abfd, ieee, section_index);
1207 if (section_index > ieee->section_count)
c8e7bf0d
NC
1208 ieee->section_count = section_index;
1209
252b5132
RH
1210 section->alignment_power =
1211 bfd_log2 (must_parse_int (&ieee->h));
1212 (void) parse_int (&(ieee->h), &value);
1213 }
1214 break;
1215 case ieee_e2_first_byte_enum:
1216 {
dc810e39
AM
1217 asection *section;
1218 ieee_record_enum_type t;
252b5132 1219
dc810e39 1220 t = (ieee_record_enum_type) (read_2bytes (&(ieee->h)));
252b5132
RH
1221 switch (t)
1222 {
1223 case ieee_section_size_enum:
1224 section = ieee->section_table[must_parse_int (&(ieee->h))];
eea6121a 1225 section->size = must_parse_int (&(ieee->h));
252b5132
RH
1226 break;
1227 case ieee_physical_region_size_enum:
1228 section = ieee->section_table[must_parse_int (&(ieee->h))];
eea6121a 1229 section->size = must_parse_int (&(ieee->h));
252b5132
RH
1230 break;
1231 case ieee_region_base_address_enum:
1232 section = ieee->section_table[must_parse_int (&(ieee->h))];
1233 section->vma = must_parse_int (&(ieee->h));
1234 section->lma = section->vma;
1235 break;
1236 case ieee_mau_size_enum:
1237 must_parse_int (&(ieee->h));
1238 must_parse_int (&(ieee->h));
1239 break;
1240 case ieee_m_value_enum:
1241 must_parse_int (&(ieee->h));
1242 must_parse_int (&(ieee->h));
1243 break;
1244 case ieee_section_base_address_enum:
1245 section = ieee->section_table[must_parse_int (&(ieee->h))];
1246 section->vma = must_parse_int (&(ieee->h));
1247 section->lma = section->vma;
1248 break;
1249 case ieee_section_offset_enum:
1250 (void) must_parse_int (&(ieee->h));
1251 (void) must_parse_int (&(ieee->h));
1252 break;
1253 default:
1254 return;
1255 }
1256 }
1257 break;
1258 default:
1259 return;
1260 }
1261 }
1262 }
1263}
1264
1265/* Make a section for the debugging information, if any. We don't try
1266 to interpret the debugging information; we just point the section
1267 at the area in the file so that program which understand can dig it
1268 out. */
1269
b34976b6 1270static bfd_boolean
c8e7bf0d 1271ieee_slurp_debug (bfd *abfd)
252b5132
RH
1272{
1273 ieee_data_type *ieee = IEEE_DATA (abfd);
1274 asection *sec;
a8c5faf7 1275 file_ptr debug_end;
117ed4f8 1276 flagword flags;
252b5132
RH
1277
1278 if (ieee->w.r.debug_information_part == 0)
b34976b6 1279 return TRUE;
252b5132 1280
117ed4f8
AM
1281 flags = SEC_DEBUGGING | SEC_HAS_CONTENTS;
1282 sec = bfd_make_section_with_flags (abfd, ".debug", flags);
252b5132 1283 if (sec == NULL)
b34976b6 1284 return FALSE;
252b5132 1285 sec->filepos = ieee->w.r.debug_information_part;
a8c5faf7 1286
47fda0d3 1287 debug_end = ieee_part_after (ieee, ieee->w.r.debug_information_part);
eea6121a 1288 sec->size = debug_end - ieee->w.r.debug_information_part;
252b5132 1289
b34976b6 1290 return TRUE;
252b5132
RH
1291}
1292\f
49ae03bf 1293/* Archive stuff. */
252b5132 1294
46e94266 1295static const bfd_target *
c8e7bf0d 1296ieee_archive_p (bfd *abfd)
252b5132
RH
1297{
1298 char *library;
1299 unsigned int i;
1300 unsigned char buffer[512];
1301 file_ptr buffer_offset = 0;
1302 ieee_ar_data_type *save = abfd->tdata.ieee_ar_data;
1303 ieee_ar_data_type *ieee;
dc810e39 1304 bfd_size_type alc_elts;
252b5132 1305 ieee_ar_obstack_type *elts = NULL;
dc810e39 1306 bfd_size_type amt = sizeof (ieee_ar_data_type);
252b5132 1307
c8e7bf0d 1308 abfd->tdata.ieee_ar_data = bfd_alloc (abfd, amt);
252b5132 1309 if (!abfd->tdata.ieee_ar_data)
487e54f2 1310 goto error_ret_restore;
252b5132
RH
1311 ieee = IEEE_AR_DATA (abfd);
1312
47fda0d3
AM
1313 /* Ignore the return value here. It doesn't matter if we don't read
1314 the entire buffer. We might have a very small ieee file. */
c8e7bf0d 1315 bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd);
252b5132
RH
1316
1317 ieee->h.first_byte = buffer;
1318 ieee->h.input_p = buffer;
1319
1320 ieee->h.abfd = abfd;
1321
1322 if (this_byte (&(ieee->h)) != Module_Beginning)
c4920b97 1323 goto got_wrong_format_error;
252b5132
RH
1324
1325 next_byte (&(ieee->h));
1326 library = read_id (&(ieee->h));
1327 if (strcmp (library, "LIBRARY") != 0)
c4920b97
NC
1328 goto got_wrong_format_error;
1329
1330 /* Throw away the filename. */
252b5132
RH
1331 read_id (&(ieee->h));
1332
1333 ieee->element_count = 0;
1334 ieee->element_index = 0;
1335
c4920b97
NC
1336 next_byte (&(ieee->h)); /* Drop the ad part. */
1337 must_parse_int (&(ieee->h)); /* And the two dummy numbers. */
252b5132
RH
1338 must_parse_int (&(ieee->h));
1339
1340 alc_elts = 10;
c8e7bf0d 1341 elts = bfd_malloc (alc_elts * sizeof *elts);
252b5132
RH
1342 if (elts == NULL)
1343 goto error_return;
1344
c4920b97 1345 /* Read the index of the BB table. */
252b5132
RH
1346 while (1)
1347 {
1348 int rec;
1349 ieee_ar_obstack_type *t;
1350
1351 rec = read_2bytes (&(ieee->h));
1352 if (rec != (int) ieee_assign_value_to_variable_enum)
1353 break;
1354
1355 if (ieee->element_count >= alc_elts)
1356 {
1357 ieee_ar_obstack_type *n;
1358
1359 alc_elts *= 2;
c8e7bf0d 1360 n = bfd_realloc (elts, alc_elts * sizeof (* elts));
252b5132
RH
1361 if (n == NULL)
1362 goto error_return;
1363 elts = n;
1364 }
1365
1366 t = &elts[ieee->element_count];
1367 ieee->element_count++;
1368
1369 must_parse_int (&(ieee->h));
1370 t->file_offset = must_parse_int (&(ieee->h));
1371 t->abfd = (bfd *) NULL;
1372
c4920b97 1373 /* Make sure that we don't go over the end of the buffer. */
47fda0d3 1374 if ((size_t) ieee_pos (IEEE_DATA (abfd)) > sizeof (buffer) / 2)
252b5132 1375 {
c4920b97 1376 /* Past half way, reseek and reprime. */
47fda0d3 1377 buffer_offset += ieee_pos (IEEE_DATA (abfd));
252b5132
RH
1378 if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0)
1379 goto error_return;
c4920b97 1380
dc810e39 1381 /* Again ignore return value of bfd_bread. */
c8e7bf0d 1382 bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd);
252b5132
RH
1383 ieee->h.first_byte = buffer;
1384 ieee->h.input_p = buffer;
1385 }
1386 }
1387
dc810e39
AM
1388 amt = ieee->element_count;
1389 amt *= sizeof *ieee->elements;
c8e7bf0d 1390 ieee->elements = bfd_alloc (abfd, amt);
252b5132
RH
1391 if (ieee->elements == NULL)
1392 goto error_return;
c4920b97 1393
dc810e39 1394 memcpy (ieee->elements, elts, (size_t) amt);
252b5132
RH
1395 free (elts);
1396 elts = NULL;
1397
c4920b97 1398 /* Now scan the area again, and replace BB offsets with file offsets. */
252b5132
RH
1399 for (i = 2; i < ieee->element_count; i++)
1400 {
1401 if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0)
1402 goto error_return;
c4920b97 1403
dc810e39 1404 /* Again ignore return value of bfd_bread. */
c8e7bf0d 1405 bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd);
252b5132
RH
1406 ieee->h.first_byte = buffer;
1407 ieee->h.input_p = buffer;
1408
c4920b97
NC
1409 next_byte (&(ieee->h)); /* Drop F8. */
1410 next_byte (&(ieee->h)); /* Drop 14. */
1411 must_parse_int (&(ieee->h)); /* Drop size of block. */
dc810e39 1412
252b5132 1413 if (must_parse_int (&(ieee->h)) != 0)
c4920b97
NC
1414 /* This object has been deleted. */
1415 ieee->elements[i].file_offset = 0;
252b5132 1416 else
c4920b97 1417 ieee->elements[i].file_offset = must_parse_int (&(ieee->h));
252b5132
RH
1418 }
1419
1420 /* abfd->has_armap = ;*/
1421
1422 return abfd->xvec;
1423
911c6dae
AM
1424 got_wrong_format_error:
1425 bfd_set_error (bfd_error_wrong_format);
252b5132
RH
1426 error_return:
1427 if (elts != NULL)
1428 free (elts);
487e54f2
AM
1429 bfd_release (abfd, ieee);
1430 error_ret_restore:
1431 abfd->tdata.ieee_ar_data = save;
c4920b97 1432
252b5132
RH
1433 return NULL;
1434}
1435
46e94266
NC
1436static bfd_boolean
1437ieee_mkobject (bfd *abfd)
252b5132 1438{
dc810e39 1439 bfd_size_type amt;
252b5132 1440
46e94266
NC
1441 output_ptr_start = NULL;
1442 output_ptr = NULL;
1443 output_ptr_end = NULL;
1444 input_ptr_start = NULL;
1445 input_ptr = NULL;
1446 input_ptr_end = NULL;
1447 input_bfd = NULL;
1448 output_bfd = NULL;
1449 output_buffer = 0;
1450 amt = sizeof (ieee_data_type);
1451 abfd->tdata.ieee_data = bfd_zalloc (abfd, amt);
1452 return abfd->tdata.ieee_data != NULL;
252b5132
RH
1453}
1454
b34976b6 1455static bfd_boolean
c8e7bf0d
NC
1456do_one (ieee_data_type *ieee,
1457 ieee_per_section_type *current_map,
1458 unsigned char *location_ptr,
1459 asection *s,
1460 int iterations)
252b5132
RH
1461{
1462 switch (this_byte (&(ieee->h)))
1463 {
1464 case ieee_load_constant_bytes_enum:
1465 {
1466 unsigned int number_of_maus;
1467 unsigned int i;
49ae03bf 1468
252b5132
RH
1469 next_byte (&(ieee->h));
1470 number_of_maus = must_parse_int (&(ieee->h));
1471
1472 for (i = 0; i < number_of_maus; i++)
1473 {
1474 location_ptr[current_map->pc++] = this_byte (&(ieee->h));
1475 next_byte (&(ieee->h));
1476 }
1477 }
1478 break;
1479
1480 case ieee_load_with_relocation_enum:
1481 {
b34976b6 1482 bfd_boolean loop = TRUE;
49ae03bf 1483
252b5132
RH
1484 next_byte (&(ieee->h));
1485 while (loop)
1486 {
1487 switch (this_byte (&(ieee->h)))
1488 {
1489 case ieee_variable_R_enum:
1490
1491 case ieee_function_signed_open_b_enum:
1492 case ieee_function_unsigned_open_b_enum:
1493 case ieee_function_either_open_b_enum:
1494 {
1495 unsigned int extra = 4;
b34976b6 1496 bfd_boolean pcrel = FALSE;
252b5132 1497 asection *section;
dc810e39 1498 ieee_reloc_type *r;
dc810e39 1499
116c20d2 1500 r = bfd_alloc (ieee->h.abfd, sizeof (* r));
252b5132 1501 if (!r)
b34976b6 1502 return FALSE;
252b5132
RH
1503
1504 *(current_map->reloc_tail_ptr) = r;
1505 current_map->reloc_tail_ptr = &r->next;
1506 r->next = (ieee_reloc_type *) NULL;
1507 next_byte (&(ieee->h));
1508/* abort();*/
1509 r->relent.sym_ptr_ptr = 0;
1510 parse_expression (ieee,
1511 &r->relent.addend,
1512 &r->symbol,
1513 &pcrel, &extra, &section);
1514 r->relent.address = current_map->pc;
1515 s->flags |= SEC_RELOC;
1516 s->owner->flags |= HAS_RELOC;
1517 s->reloc_count++;
1518 if (r->relent.sym_ptr_ptr == NULL && section != NULL)
1519 r->relent.sym_ptr_ptr = section->symbol_ptr_ptr;
1520
1521 if (this_byte (&(ieee->h)) == (int) ieee_comma)
1522 {
1523 next_byte (&(ieee->h));
49ae03bf 1524 /* Fetch number of bytes to pad. */
252b5132
RH
1525 extra = must_parse_int (&(ieee->h));
1526 };
1527
1528 switch (this_byte (&(ieee->h)))
1529 {
1530 case ieee_function_signed_close_b_enum:
1531 next_byte (&(ieee->h));
1532 break;
1533 case ieee_function_unsigned_close_b_enum:
1534 next_byte (&(ieee->h));
1535 break;
1536 case ieee_function_either_close_b_enum:
1537 next_byte (&(ieee->h));
1538 break;
1539 default:
1540 break;
1541 }
49ae03bf 1542 /* Build a relocation entry for this type. */
252b5132
RH
1543 /* If pc rel then stick -ve pc into instruction
1544 and take out of reloc ..
1545
1546 I've changed this. It's all too complicated. I
1547 keep 0 in the instruction now. */
1548
1549 switch (extra)
1550 {
1551 case 0:
1552 case 4:
1553
82e51918 1554 if (pcrel)
252b5132
RH
1555 {
1556#if KEEPMINUSPCININST
dc810e39
AM
1557 bfd_put_32 (ieee->h.abfd, -current_map->pc,
1558 location_ptr + current_map->pc);
252b5132 1559 r->relent.howto = &rel32_howto;
dc810e39 1560 r->relent.addend -= current_map->pc;
252b5132 1561#else
dc810e39 1562 bfd_put_32 (ieee->h.abfd, (bfd_vma) 0, location_ptr +
252b5132
RH
1563 current_map->pc);
1564 r->relent.howto = &rel32_howto;
1565#endif
1566 }
1567 else
1568 {
dc810e39
AM
1569 bfd_put_32 (ieee->h.abfd, (bfd_vma) 0,
1570 location_ptr + current_map->pc);
252b5132
RH
1571 r->relent.howto = &abs32_howto;
1572 }
1573 current_map->pc += 4;
1574 break;
1575 case 2:
82e51918 1576 if (pcrel)
252b5132
RH
1577 {
1578#if KEEPMINUSPCININST
dc810e39
AM
1579 bfd_put_16 (ieee->h.abfd, (bfd_vma) -current_map->pc,
1580 location_ptr + current_map->pc);
252b5132
RH
1581 r->relent.addend -= current_map->pc;
1582 r->relent.howto = &rel16_howto;
1583#else
1584
dc810e39
AM
1585 bfd_put_16 (ieee->h.abfd, (bfd_vma) 0,
1586 location_ptr + current_map->pc);
252b5132
RH
1587 r->relent.howto = &rel16_howto;
1588#endif
1589 }
1590
1591 else
1592 {
dc810e39
AM
1593 bfd_put_16 (ieee->h.abfd, (bfd_vma) 0,
1594 location_ptr + current_map->pc);
252b5132
RH
1595 r->relent.howto = &abs16_howto;
1596 }
1597 current_map->pc += 2;
1598 break;
1599 case 1:
82e51918 1600 if (pcrel)
252b5132
RH
1601 {
1602#if KEEPMINUSPCININST
1603 bfd_put_8 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc);
1604 r->relent.addend -= current_map->pc;
1605 r->relent.howto = &rel8_howto;
1606#else
1607 bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
1608 r->relent.howto = &rel8_howto;
1609#endif
1610 }
1611 else
1612 {
1613 bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
1614 r->relent.howto = &abs8_howto;
1615 }
1616 current_map->pc += 1;
1617 break;
1618
1619 default:
1620 BFD_FAIL ();
b34976b6 1621 return FALSE;
252b5132
RH
1622 }
1623 }
1624 break;
1625 default:
1626 {
1627 bfd_vma this_size;
c8e7bf0d 1628
82e51918 1629 if (parse_int (&(ieee->h), &this_size))
252b5132
RH
1630 {
1631 unsigned int i;
c8e7bf0d 1632
252b5132
RH
1633 for (i = 0; i < this_size; i++)
1634 {
1635 location_ptr[current_map->pc++] = this_byte (&(ieee->h));
1636 next_byte (&(ieee->h));
1637 }
1638 }
1639 else
c8e7bf0d 1640 loop = FALSE;
252b5132
RH
1641 }
1642 }
1643
1644 /* Prevent more than the first load-item of an LR record
c8e7bf0d 1645 from being repeated (MRI convention). */
252b5132 1646 if (iterations != 1)
b34976b6 1647 loop = FALSE;
252b5132
RH
1648 }
1649 }
1650 }
b34976b6 1651 return TRUE;
252b5132
RH
1652}
1653
49ae03bf
NC
1654/* Read in all the section data and relocation stuff too. */
1655
b34976b6 1656static bfd_boolean
c8e7bf0d 1657ieee_slurp_section_data (bfd *abfd)
252b5132
RH
1658{
1659 bfd_byte *location_ptr = (bfd_byte *) NULL;
1660 ieee_data_type *ieee = IEEE_DATA (abfd);
1661 unsigned int section_number;
c8e7bf0d 1662 ieee_per_section_type *current_map = NULL;
252b5132 1663 asection *s;
68ffbac6 1664
49ae03bf 1665 /* Seek to the start of the data area. */
82e51918 1666 if (ieee->read_data)
b34976b6
AM
1667 return TRUE;
1668 ieee->read_data = TRUE;
47fda0d3 1669 ieee_seek (ieee, ieee->w.r.data_part);
252b5132 1670
49ae03bf 1671 /* Allocate enough space for all the section contents. */
252b5132
RH
1672 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
1673 {
68bfbfcc 1674 ieee_per_section_type *per = ieee_per_section (s);
6edfbbad 1675 arelent **relpp;
c8e7bf0d 1676
252b5132
RH
1677 if ((s->flags & SEC_DEBUGGING) != 0)
1678 continue;
c8e7bf0d 1679 per->data = bfd_alloc (ieee->h.abfd, s->size);
252b5132 1680 if (!per->data)
b34976b6 1681 return FALSE;
6edfbbad
DJ
1682 relpp = &s->relocation;
1683 per->reloc_tail_ptr = (ieee_reloc_type **) relpp;
252b5132
RH
1684 }
1685
b34976b6 1686 while (TRUE)
252b5132
RH
1687 {
1688 switch (this_byte (&(ieee->h)))
1689 {
49ae03bf 1690 /* IF we see anything strange then quit. */
252b5132 1691 default:
b34976b6 1692 return TRUE;
252b5132
RH
1693
1694 case ieee_set_current_section_enum:
1695 next_byte (&(ieee->h));
1696 section_number = must_parse_int (&(ieee->h));
1697 s = ieee->section_table[section_number];
1698 s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
68bfbfcc 1699 current_map = ieee_per_section (s);
252b5132 1700 location_ptr = current_map->data - s->vma;
49ae03bf
NC
1701 /* The document I have says that Microtec's compilers reset
1702 this after a sec section, even though the standard says not
1703 to, SO... */
252b5132
RH
1704 current_map->pc = s->vma;
1705 break;
1706
1707 case ieee_e2_first_byte_enum:
1708 next_byte (&(ieee->h));
1709 switch (this_byte (&(ieee->h)))
1710 {
1711 case ieee_set_current_pc_enum & 0xff:
1712 {
1713 bfd_vma value;
1714 ieee_symbol_index_type symbol;
1715 unsigned int extra;
b34976b6 1716 bfd_boolean pcrel;
49ae03bf 1717
252b5132 1718 next_byte (&(ieee->h));
49ae03bf 1719 must_parse_int (&(ieee->h)); /* Throw away section #. */
252b5132
RH
1720 parse_expression (ieee, &value,
1721 &symbol,
1722 &pcrel, &extra,
1723 0);
1724 current_map->pc = value;
eea6121a 1725 BFD_ASSERT ((unsigned) (value - s->vma) <= s->size);
252b5132
RH
1726 }
1727 break;
1728
1729 case ieee_value_starting_address_enum & 0xff:
1730 next_byte (&(ieee->h));
1731 if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum)
1732 next_byte (&(ieee->h));
1733 abfd->start_address = must_parse_int (&(ieee->h));
49ae03bf 1734 /* We've got to the end of the data now - */
b34976b6 1735 return TRUE;
252b5132
RH
1736 default:
1737 BFD_FAIL ();
b34976b6 1738 return FALSE;
252b5132
RH
1739 }
1740 break;
1741 case ieee_repeat_data_enum:
1742 {
1743 /* Repeat the following LD or LR n times - we do this by
49ae03bf
NC
1744 remembering the stream pointer before running it and
1745 resetting it and running it n times. We special case
1746 the repetition of a repeat_data/load_constant. */
252b5132
RH
1747 unsigned int iterations;
1748 unsigned char *start;
49ae03bf 1749
252b5132
RH
1750 next_byte (&(ieee->h));
1751 iterations = must_parse_int (&(ieee->h));
1752 start = ieee->h.input_p;
49ae03bf
NC
1753 if (start[0] == (int) ieee_load_constant_bytes_enum
1754 && start[1] == 1)
252b5132
RH
1755 {
1756 while (iterations != 0)
1757 {
1758 location_ptr[current_map->pc++] = start[2];
1759 iterations--;
1760 }
1761 next_byte (&(ieee->h));
1762 next_byte (&(ieee->h));
1763 next_byte (&(ieee->h));
1764 }
1765 else
1766 {
1767 while (iterations != 0)
1768 {
1769 ieee->h.input_p = start;
1770 if (!do_one (ieee, current_map, location_ptr, s,
dc810e39 1771 (int) iterations))
b34976b6 1772 return FALSE;
252b5132
RH
1773 iterations--;
1774 }
1775 }
1776 }
1777 break;
1778 case ieee_load_constant_bytes_enum:
1779 case ieee_load_with_relocation_enum:
49ae03bf
NC
1780 if (!do_one (ieee, current_map, location_ptr, s, 1))
1781 return FALSE;
252b5132
RH
1782 }
1783 }
1784}
1785
46e94266
NC
1786static const bfd_target *
1787ieee_object_p (bfd *abfd)
1788{
1789 char *processor;
1790 unsigned int part;
1791 ieee_data_type *ieee;
1792 unsigned char buffer[300];
1793 ieee_data_type *save = IEEE_DATA (abfd);
1794 bfd_size_type amt;
1795
1796 abfd->tdata.ieee_data = 0;
1797 ieee_mkobject (abfd);
1798
1799 ieee = IEEE_DATA (abfd);
1800 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
1801 goto fail;
1802 /* Read the first few bytes in to see if it makes sense. Ignore
1803 bfd_bread return value; The file might be very small. */
1804 bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd);
1805
1806 ieee->h.input_p = buffer;
1807 if (this_byte_and_next (&(ieee->h)) != Module_Beginning)
1808 goto got_wrong_format;
1809
1810 ieee->read_symbols = FALSE;
1811 ieee->read_data = FALSE;
1812 ieee->section_count = 0;
1813 ieee->external_symbol_max_index = 0;
1814 ieee->external_symbol_min_index = IEEE_PUBLIC_BASE;
1815 ieee->external_reference_min_index = IEEE_REFERENCE_BASE;
1816 ieee->external_reference_max_index = 0;
1817 ieee->h.abfd = abfd;
1818 ieee->section_table = NULL;
1819 ieee->section_table_size = 0;
1820
1821 processor = ieee->mb.processor = read_id (&(ieee->h));
1822 if (strcmp (processor, "LIBRARY") == 0)
1823 goto got_wrong_format;
1824 ieee->mb.module_name = read_id (&(ieee->h));
1825 if (abfd->filename == (const char *) NULL)
1be5090b 1826 abfd->filename = xstrdup (ieee->mb.module_name);
46e94266
NC
1827
1828 /* Determine the architecture and machine type of the object file. */
1829 {
1830 const bfd_arch_info_type *arch;
1831 char family[10];
1832
1833 /* IEEE does not specify the format of the processor identification
1834 string, so the compiler is free to put in it whatever it wants.
1835 We try here to recognize different processors belonging to the
1836 m68k family. Code for other processors can be added here. */
1837 if ((processor[0] == '6') && (processor[1] == '8'))
1838 {
1839 if (processor[2] == '3') /* 683xx integrated processors. */
1840 {
1841 switch (processor[3])
1842 {
1843 case '0': /* 68302, 68306, 68307 */
1844 case '2': /* 68322, 68328 */
1845 case '5': /* 68356 */
1846 strcpy (family, "68000"); /* MC68000-based controllers. */
1847 break;
1848
1849 case '3': /* 68330, 68331, 68332, 68333,
1850 68334, 68335, 68336, 68338 */
1851 case '6': /* 68360 */
1852 case '7': /* 68376 */
1853 strcpy (family, "68332"); /* CPU32 and CPU32+ */
1854 break;
1855
1856 case '4':
1857 if (processor[4] == '9') /* 68349 */
1858 strcpy (family, "68030"); /* CPU030 */
1859 else /* 68340, 68341 */
1860 strcpy (family, "68332"); /* CPU32 and CPU32+ */
1861 break;
1862
1863 default: /* Does not exist yet. */
1864 strcpy (family, "68332"); /* Guess it will be CPU32 */
1865 }
1866 }
1867 else if (TOUPPER (processor[3]) == 'F') /* 68F333 */
1868 strcpy (family, "68332"); /* CPU32 */
1869 else if ((TOUPPER (processor[3]) == 'C') /* Embedded controllers. */
1870 && ((TOUPPER (processor[2]) == 'E')
1871 || (TOUPPER (processor[2]) == 'H')
1872 || (TOUPPER (processor[2]) == 'L')))
1873 {
1874 strcpy (family, "68");
1875 strncat (family, processor + 4, 7);
1876 family[9] = '\0';
1877 }
1878 else /* "Regular" processors. */
1879 {
1880 strncpy (family, processor, 9);
1881 family[9] = '\0';
1882 }
1883 }
0112cd26
NC
1884 else if ((CONST_STRNEQ (processor, "cpu32")) /* CPU32 and CPU32+ */
1885 || (CONST_STRNEQ (processor, "CPU32")))
46e94266
NC
1886 strcpy (family, "68332");
1887 else
1888 {
1889 strncpy (family, processor, 9);
1890 family[9] = '\0';
1891 }
1892
1893 arch = bfd_scan_arch (family);
1894 if (arch == 0)
1895 goto got_wrong_format;
1896 abfd->arch_info = arch;
1897 }
1898
1899 if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum)
1900 goto fail;
1901
1902 next_byte (&(ieee->h));
1903
1904 if (! parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau))
1905 goto fail;
1906
1907 if (! parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address))
1908 goto fail;
1909
1910 /* If there is a byte order info, take it. */
1911 if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum
1912 || this_byte (&(ieee->h)) == (int) ieee_variable_M_enum)
1913 next_byte (&(ieee->h));
1914
1915 for (part = 0; part < N_W_VARIABLES; part++)
1916 {
1917 bfd_boolean ok;
1918
1919 if (read_2bytes (&(ieee->h)) != (int) ieee_assign_value_to_variable_enum)
1920 goto fail;
1921
1922 if (this_byte_and_next (&(ieee->h)) != part)
1923 goto fail;
1924
1925 ieee->w.offset[part] = parse_i (&(ieee->h), &ok);
1926 if (! ok)
1927 goto fail;
1928 }
1929
1930 if (ieee->w.r.external_part != 0)
1931 abfd->flags = HAS_SYMS;
1932
1933 /* By now we know that this is a real IEEE file, we're going to read
1934 the whole thing into memory so that we can run up and down it
1935 quickly. We can work out how big the file is from the trailer
1936 record. */
1937
1938 amt = ieee->w.r.me_record + 1;
1939 IEEE_DATA (abfd)->h.first_byte = bfd_alloc (ieee->h.abfd, amt);
1940 if (!IEEE_DATA (abfd)->h.first_byte)
1941 goto fail;
1942 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
1943 goto fail;
1944 /* FIXME: Check return value. I'm not sure whether it needs to read
1945 the entire buffer or not. */
1946 bfd_bread ((void *) (IEEE_DATA (abfd)->h.first_byte),
1947 (bfd_size_type) ieee->w.r.me_record + 1, abfd);
1948
1949 ieee_slurp_sections (abfd);
1950
1951 if (! ieee_slurp_debug (abfd))
1952 goto fail;
1953
1954 /* Parse section data to activate file and section flags implied by
1955 section contents. */
1956 if (! ieee_slurp_section_data (abfd))
1957 goto fail;
1958
1959 return abfd->xvec;
1960got_wrong_format:
1961 bfd_set_error (bfd_error_wrong_format);
1962fail:
1963 bfd_release (abfd, ieee);
1964 abfd->tdata.ieee_data = save;
1965 return (const bfd_target *) NULL;
1966}
1967
1968static void
1969ieee_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
1970 asymbol *symbol,
1971 symbol_info *ret)
1972{
1973 bfd_symbol_info (symbol, ret);
1974 if (symbol->name[0] == ' ')
1975 ret->name = "* empty table entry ";
1976 if (!symbol->section)
1977 ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
1978}
1979
1980static void
1981ieee_print_symbol (bfd *abfd,
1982 void * afile,
1983 asymbol *symbol,
1984 bfd_print_symbol_type how)
1985{
1986 FILE *file = (FILE *) afile;
1987
1988 switch (how)
1989 {
1990 case bfd_print_symbol_name:
1991 fprintf (file, "%s", symbol->name);
1992 break;
1993 case bfd_print_symbol_more:
1994 BFD_FAIL ();
1995 break;
1996 case bfd_print_symbol_all:
1997 {
1998 const char *section_name =
1999 (symbol->section == (asection *) NULL
2000 ? "*abs"
2001 : symbol->section->name);
2002
2003 if (symbol->name[0] == ' ')
2004 fprintf (file, "* empty table entry ");
2005 else
2006 {
2007 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
2008
2009 fprintf (file, " %-5s %04x %02x %s",
2010 section_name,
2011 (unsigned) ieee_symbol (symbol)->index,
2012 (unsigned) 0,
2013 symbol->name);
2014 }
2015 }
2016 break;
2017 }
2018}
2019
2020static bfd_boolean
2021ieee_new_section_hook (bfd *abfd, asection *newsect)
252b5132 2022{
252b5132 2023 if (!newsect->used_by_bfd)
f592407e
AM
2024 {
2025 newsect->used_by_bfd = bfd_alloc (abfd, sizeof (ieee_per_section_type));
2026 if (!newsect->used_by_bfd)
2027 return FALSE;
2028 }
c8e7bf0d 2029 ieee_per_section (newsect)->data = NULL;
252b5132 2030 ieee_per_section (newsect)->section = newsect;
f592407e 2031 return _bfd_generic_new_section_hook (abfd, newsect);
252b5132
RH
2032}
2033
47fda0d3 2034static long
c8e7bf0d 2035ieee_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
252b5132
RH
2036{
2037 if ((asect->flags & SEC_DEBUGGING) != 0)
2038 return 0;
2039 if (! ieee_slurp_section_data (abfd))
2040 return -1;
2041 return (asect->reloc_count + 1) * sizeof (arelent *);
2042}
2043
b34976b6 2044static bfd_boolean
c8e7bf0d
NC
2045ieee_get_section_contents (bfd *abfd,
2046 sec_ptr section,
2047 void * location,
2048 file_ptr offset,
2049 bfd_size_type count)
252b5132 2050{
68bfbfcc 2051 ieee_per_section_type *p = ieee_per_section (section);
252b5132
RH
2052 if ((section->flags & SEC_DEBUGGING) != 0)
2053 return _bfd_generic_get_section_contents (abfd, section, location,
2054 offset, count);
2055 ieee_slurp_section_data (abfd);
c8e7bf0d 2056 (void) memcpy ((void *) location, (void *) (p->data + offset), (unsigned) count);
b34976b6 2057 return TRUE;
252b5132
RH
2058}
2059
47fda0d3 2060static long
c8e7bf0d
NC
2061ieee_canonicalize_reloc (bfd *abfd,
2062 sec_ptr section,
2063 arelent **relptr,
2064 asymbol **symbols)
252b5132 2065{
252b5132
RH
2066 ieee_reloc_type *src = (ieee_reloc_type *) (section->relocation);
2067 ieee_data_type *ieee = IEEE_DATA (abfd);
2068
2069 if ((section->flags & SEC_DEBUGGING) != 0)
2070 return 0;
2071
2072 while (src != (ieee_reloc_type *) NULL)
2073 {
49ae03bf 2074 /* Work out which symbol to attach it this reloc to. */
252b5132
RH
2075 switch (src->symbol.letter)
2076 {
2077 case 'I':
2078 src->relent.sym_ptr_ptr =
2079 symbols + src->symbol.index + ieee->external_symbol_base_offset;
2080 break;
2081 case 'X':
2082 src->relent.sym_ptr_ptr =
2083 symbols + src->symbol.index + ieee->external_reference_base_offset;
2084 break;
2085 case 0:
2086 if (src->relent.sym_ptr_ptr != NULL)
2087 src->relent.sym_ptr_ptr =
2088 src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr;
2089 break;
2090 default:
2091
2092 BFD_FAIL ();
2093 }
2094 *relptr++ = &src->relent;
2095 src = src->next;
2096 }
c8e7bf0d 2097 *relptr = NULL;
252b5132
RH
2098 return section->reloc_count;
2099}
2100
2101static int
c8e7bf0d 2102comp (const void * ap, const void * bp)
252b5132
RH
2103{
2104 arelent *a = *((arelent **) ap);
2105 arelent *b = *((arelent **) bp);
2106 return a->address - b->address;
2107}
2108
2109/* Write the section headers. */
2110
b34976b6 2111static bfd_boolean
c8e7bf0d 2112ieee_write_section_part (bfd *abfd)
252b5132
RH
2113{
2114 ieee_data_type *ieee = IEEE_DATA (abfd);
2115 asection *s;
c8e7bf0d 2116
252b5132
RH
2117 ieee->w.r.section_part = bfd_tell (abfd);
2118 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
2119 {
2120 if (! bfd_is_abs_section (s)
2121 && (s->flags & SEC_DEBUGGING) == 0)
2122 {
2123 if (! ieee_write_byte (abfd, ieee_section_type_enum)
2124 || ! ieee_write_byte (abfd,
2125 (bfd_byte) (s->index
2126 + IEEE_SECTION_NUMBER_BASE)))
b34976b6 2127 return FALSE;
252b5132
RH
2128
2129 if (abfd->flags & EXEC_P)
2130 {
49ae03bf 2131 /* This image is executable, so output absolute sections. */
252b5132
RH
2132 if (! ieee_write_byte (abfd, ieee_variable_A_enum)
2133 || ! ieee_write_byte (abfd, ieee_variable_S_enum))
b34976b6 2134 return FALSE;
252b5132
RH
2135 }
2136 else
2137 {
2138 if (! ieee_write_byte (abfd, ieee_variable_C_enum))
b34976b6 2139 return FALSE;
252b5132
RH
2140 }
2141
2142 switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM))
2143 {
2144 case SEC_CODE | SEC_LOAD:
2145 case SEC_CODE:
2146 if (! ieee_write_byte (abfd, ieee_variable_P_enum))
b34976b6 2147 return FALSE;
252b5132
RH
2148 break;
2149 case SEC_DATA:
2150 default:
2151 if (! ieee_write_byte (abfd, ieee_variable_D_enum))
b34976b6 2152 return FALSE;
252b5132
RH
2153 break;
2154 case SEC_ROM:
2155 case SEC_ROM | SEC_DATA:
2156 case SEC_ROM | SEC_LOAD:
2157 case SEC_ROM | SEC_DATA | SEC_LOAD:
2158 if (! ieee_write_byte (abfd, ieee_variable_R_enum))
b34976b6 2159 return FALSE;
252b5132
RH
2160 }
2161
2162
2163 if (! ieee_write_id (abfd, s->name))
b34976b6 2164 return FALSE;
49ae03bf 2165 /* Alignment. */
252b5132
RH
2166 if (! ieee_write_byte (abfd, ieee_section_alignment_enum)
2167 || ! ieee_write_byte (abfd,
2168 (bfd_byte) (s->index
2169 + IEEE_SECTION_NUMBER_BASE))
dc810e39 2170 || ! ieee_write_int (abfd, (bfd_vma) 1 << s->alignment_power))
b34976b6 2171 return FALSE;
252b5132 2172
49ae03bf 2173 /* Size. */
252b5132
RH
2174 if (! ieee_write_2bytes (abfd, ieee_section_size_enum)
2175 || ! ieee_write_byte (abfd,
2176 (bfd_byte) (s->index
2177 + IEEE_SECTION_NUMBER_BASE))
eea6121a 2178 || ! ieee_write_int (abfd, s->size))
b34976b6 2179 return FALSE;
252b5132
RH
2180 if (abfd->flags & EXEC_P)
2181 {
49ae03bf
NC
2182 /* Relocateable sections don't have asl records. */
2183 /* Vma. */
252b5132
RH
2184 if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum)
2185 || ! ieee_write_byte (abfd,
2186 ((bfd_byte)
2187 (s->index
2188 + IEEE_SECTION_NUMBER_BASE)))
2189 || ! ieee_write_int (abfd, s->lma))
b34976b6 2190 return FALSE;
252b5132
RH
2191 }
2192 }
2193 }
2194
b34976b6 2195 return TRUE;
252b5132
RH
2196}
2197
b34976b6 2198static bfd_boolean
c8e7bf0d 2199do_with_relocs (bfd *abfd, asection *s)
252b5132
RH
2200{
2201 unsigned int number_of_maus_in_address =
2202 bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd);
2203 unsigned int relocs_to_go = s->reloc_count;
2204 bfd_byte *stream = ieee_per_section (s)->data;
2205 arelent **p = s->orelocation;
2206 bfd_size_type current_byte_index = 0;
2207
2208 qsort (s->orelocation,
2209 relocs_to_go,
2210 sizeof (arelent **),
2211 comp);
2212
49ae03bf 2213 /* Output the section preheader. */
252b5132
RH
2214 if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
2215 || ! ieee_write_byte (abfd,
2216 (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))
2217 || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum)
2218 || ! ieee_write_byte (abfd,
2219 (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)))
b34976b6 2220 return FALSE;
47fda0d3 2221
252b5132
RH
2222 if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0)
2223 {
2224 if (! ieee_write_int (abfd, s->lma))
b34976b6 2225 return FALSE;
252b5132
RH
2226 }
2227 else
2228 {
dc810e39 2229 if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0))
b34976b6 2230 return FALSE;
252b5132
RH
2231 }
2232
2233 if (relocs_to_go == 0)
2234 {
2235 /* If there aren't any relocations then output the load constant
49ae03bf 2236 byte opcode rather than the load with relocation opcode. */
eea6121a 2237 while (current_byte_index < s->size)
252b5132
RH
2238 {
2239 bfd_size_type run;
2240 unsigned int MAXRUN = 127;
49ae03bf 2241
252b5132 2242 run = MAXRUN;
eea6121a
AM
2243 if (run > s->size - current_byte_index)
2244 run = s->size - current_byte_index;
252b5132
RH
2245
2246 if (run != 0)
2247 {
2248 if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum))
b34976b6 2249 return FALSE;
49ae03bf 2250 /* Output a stream of bytes. */
252b5132 2251 if (! ieee_write_int (abfd, run))
b34976b6 2252 return FALSE;
c8e7bf0d 2253 if (bfd_bwrite ((void *) (stream + current_byte_index), run, abfd)
252b5132 2254 != run)
b34976b6 2255 return FALSE;
252b5132
RH
2256 current_byte_index += run;
2257 }
2258 }
2259 }
2260 else
2261 {
2262 if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum))
b34976b6 2263 return FALSE;
252b5132
RH
2264
2265 /* Output the data stream as the longest sequence of bytes
2266 possible, allowing for the a reasonable packet size and
2267 relocation stuffs. */
c8e7bf0d 2268 if (stream == NULL)
252b5132 2269 {
49ae03bf 2270 /* Outputting a section without data, fill it up. */
c8e7bf0d 2271 stream = bfd_zalloc (abfd, s->size);
252b5132 2272 if (!stream)
b34976b6 2273 return FALSE;
252b5132 2274 }
eea6121a 2275 while (current_byte_index < s->size)
252b5132
RH
2276 {
2277 bfd_size_type run;
2278 unsigned int MAXRUN = 127;
49ae03bf 2279
252b5132
RH
2280 if (relocs_to_go)
2281 {
2282 run = (*p)->address - current_byte_index;
2283 if (run > MAXRUN)
2284 run = MAXRUN;
2285 }
2286 else
49ae03bf
NC
2287 run = MAXRUN;
2288
eea6121a
AM
2289 if (run > s->size - current_byte_index)
2290 run = s->size - current_byte_index;
252b5132
RH
2291
2292 if (run != 0)
2293 {
49ae03bf 2294 /* Output a stream of bytes. */
252b5132 2295 if (! ieee_write_int (abfd, run))
b34976b6 2296 return FALSE;
c8e7bf0d 2297 if (bfd_bwrite ((void *) (stream + current_byte_index), run, abfd)
252b5132 2298 != run)
b34976b6 2299 return FALSE;
252b5132
RH
2300 current_byte_index += run;
2301 }
49ae03bf
NC
2302
2303 /* Output any relocations here. */
252b5132
RH
2304 if (relocs_to_go && (*p) && (*p)->address == current_byte_index)
2305 {
2306 while (relocs_to_go
2307 && (*p) && (*p)->address == current_byte_index)
2308 {
2309 arelent *r = *p;
2310 bfd_signed_vma ov;
252b5132
RH
2311 switch (r->howto->size)
2312 {
2313 case 2:
252b5132
RH
2314 ov = bfd_get_signed_32 (abfd,
2315 stream + current_byte_index);
2316 current_byte_index += 4;
2317 break;
2318 case 1:
2319 ov = bfd_get_signed_16 (abfd,
2320 stream + current_byte_index);
2321 current_byte_index += 2;
2322 break;
2323 case 0:
2324 ov = bfd_get_signed_8 (abfd,
2325 stream + current_byte_index);
2326 current_byte_index++;
2327 break;
2328 default:
2329 ov = 0;
2330 BFD_FAIL ();
b34976b6 2331 return FALSE;
252b5132
RH
2332 }
2333
2334 ov &= r->howto->src_mask;
2335
2336 if (r->howto->pc_relative
2337 && ! r->howto->pcrel_offset)
2338 ov += r->address;
2339
2340 if (! ieee_write_byte (abfd,
2341 ieee_function_either_open_b_enum))
b34976b6 2342 return FALSE;
252b5132 2343
252b5132
RH
2344 if (r->sym_ptr_ptr != (asymbol **) NULL)
2345 {
2346 if (! ieee_write_expression (abfd, r->addend + ov,
2347 *(r->sym_ptr_ptr),
2348 r->howto->pc_relative,
dc810e39 2349 (unsigned) s->index))
b34976b6 2350 return FALSE;
252b5132
RH
2351 }
2352 else
2353 {
2354 if (! ieee_write_expression (abfd, r->addend + ov,
2355 (asymbol *) NULL,
2356 r->howto->pc_relative,
dc810e39 2357 (unsigned) s->index))
b34976b6 2358 return FALSE;
252b5132
RH
2359 }
2360
2361 if (number_of_maus_in_address
2362 != bfd_get_reloc_size (r->howto))
2363 {
dc810e39
AM
2364 bfd_vma rsize = bfd_get_reloc_size (r->howto);
2365 if (! ieee_write_int (abfd, rsize))
b34976b6 2366 return FALSE;
252b5132
RH
2367 }
2368 if (! ieee_write_byte (abfd,
2369 ieee_function_either_close_b_enum))
b34976b6 2370 return FALSE;
252b5132
RH
2371
2372 relocs_to_go--;
2373 p++;
2374 }
2375
2376 }
2377 }
2378 }
2379
b34976b6 2380 return TRUE;
252b5132
RH
2381}
2382
2383/* If there are no relocations in the output section then we can be
2384 clever about how we write. We block items up into a max of 127
2385 bytes. */
2386
b34976b6 2387static bfd_boolean
c8e7bf0d 2388do_as_repeat (bfd *abfd, asection *s)
252b5132 2389{
eea6121a 2390 if (s->size)
252b5132
RH
2391 {
2392 if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
2393 || ! ieee_write_byte (abfd,
2394 (bfd_byte) (s->index
2395 + IEEE_SECTION_NUMBER_BASE))
2396 || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8)
2397 || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff)
2398 || ! ieee_write_byte (abfd,
2399 (bfd_byte) (s->index
47fda0d3 2400 + IEEE_SECTION_NUMBER_BASE)))
b34976b6 2401 return FALSE;
47fda0d3
AM
2402
2403 if ((abfd->flags & EXEC_P) != 0)
2404 {
2405 if (! ieee_write_int (abfd, s->lma))
b34976b6 2406 return FALSE;
47fda0d3
AM
2407 }
2408 else
2409 {
dc810e39 2410 if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0))
b34976b6 2411 return FALSE;
47fda0d3
AM
2412 }
2413
2414 if (! ieee_write_byte (abfd, ieee_repeat_data_enum)
eea6121a 2415 || ! ieee_write_int (abfd, s->size)
252b5132
RH
2416 || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)
2417 || ! ieee_write_byte (abfd, 1)
2418 || ! ieee_write_byte (abfd, 0))
b34976b6 2419 return FALSE;
252b5132
RH
2420 }
2421
b34976b6 2422 return TRUE;
252b5132
RH
2423}
2424
b34976b6 2425static bfd_boolean
c8e7bf0d 2426do_without_relocs (bfd *abfd, asection *s)
252b5132
RH
2427{
2428 bfd_byte *stream = ieee_per_section (s)->data;
2429
2430 if (stream == 0 || ((s->flags & SEC_LOAD) == 0))
2431 {
2432 if (! do_as_repeat (abfd, s))
b34976b6 2433 return FALSE;
252b5132
RH
2434 }
2435 else
2436 {
2437 unsigned int i;
49ae03bf 2438
eea6121a 2439 for (i = 0; i < s->size; i++)
252b5132
RH
2440 {
2441 if (stream[i] != 0)
2442 {
2443 if (! do_with_relocs (abfd, s))
b34976b6
AM
2444 return FALSE;
2445 return TRUE;
252b5132
RH
2446 }
2447 }
2448 if (! do_as_repeat (abfd, s))
b34976b6 2449 return FALSE;
252b5132
RH
2450 }
2451
b34976b6 2452 return TRUE;
252b5132
RH
2453}
2454
252b5132 2455static void
c8e7bf0d 2456fill (void)
252b5132 2457{
dc810e39 2458 bfd_size_type amt = input_ptr_end - input_ptr_start;
252b5132
RH
2459 /* FIXME: Check return value. I'm not sure whether it needs to read
2460 the entire buffer or not. */
c8e7bf0d 2461 bfd_bread ((void *) input_ptr_start, amt, input_bfd);
252b5132
RH
2462 input_ptr = input_ptr_start;
2463}
47fda0d3 2464
252b5132 2465static void
c8e7bf0d 2466flush (void)
252b5132 2467{
dc810e39 2468 bfd_size_type amt = output_ptr - output_ptr_start;
49ae03bf 2469
c8e7bf0d 2470 if (bfd_bwrite ((void *) (output_ptr_start), amt, output_bfd) != amt)
252b5132
RH
2471 abort ();
2472 output_ptr = output_ptr_start;
2473 output_buffer++;
2474}
2475
2476#define THIS() ( *input_ptr )
c8e7bf0d
NC
2477#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill (); }
2478#define OUT(x) { *output_ptr++ = (x); if (output_ptr == output_ptr_end) flush (); }
252b5132
RH
2479
2480static void
c8e7bf0d 2481write_int (int value)
252b5132
RH
2482{
2483 if (value >= 0 && value <= 127)
2484 {
2485 OUT (value);
2486 }
2487 else
2488 {
2489 unsigned int length;
c8e7bf0d 2490
49ae03bf
NC
2491 /* How many significant bytes ? */
2492 /* FIXME FOR LONGER INTS. */
252b5132 2493 if (value & 0xff000000)
49ae03bf 2494 length = 4;
252b5132 2495 else if (value & 0x00ff0000)
49ae03bf 2496 length = 3;
252b5132 2497 else if (value & 0x0000ff00)
49ae03bf 2498 length = 2;
252b5132
RH
2499 else
2500 length = 1;
2501
2502 OUT ((int) ieee_number_repeat_start_enum + length);
2503 switch (length)
2504 {
2505 case 4:
2506 OUT (value >> 24);
2507 case 3:
2508 OUT (value >> 16);
2509 case 2:
2510 OUT (value >> 8);
2511 case 1:
2512 OUT (value);
2513 }
252b5132
RH
2514 }
2515}
2516
2517static void
46e94266 2518copy_id (void)
252b5132
RH
2519{
2520 int length = THIS ();
2521 char ch;
49ae03bf 2522
252b5132
RH
2523 OUT (length);
2524 NEXT ();
2525 while (length--)
2526 {
2527 ch = THIS ();
2528 OUT (ch);
2529 NEXT ();
2530 }
2531}
2532
2533#define VAR(x) ((x | 0x80))
2534static void
46e94266 2535copy_expression (void)
252b5132
RH
2536{
2537 int stack[10];
2538 int *tos = stack;
dc810e39 2539 int value;
49ae03bf 2540
252b5132
RH
2541 while (1)
2542 {
2543 switch (THIS ())
2544 {
2545 case 0x84:
2546 NEXT ();
2547 value = THIS ();
2548 NEXT ();
2549 value = (value << 8) | THIS ();
2550 NEXT ();
2551 value = (value << 8) | THIS ();
2552 NEXT ();
2553 value = (value << 8) | THIS ();
2554 NEXT ();
2555 *tos++ = value;
2556 break;
2557 case 0x83:
2558 NEXT ();
2559 value = THIS ();
2560 NEXT ();
2561 value = (value << 8) | THIS ();
2562 NEXT ();
2563 value = (value << 8) | THIS ();
2564 NEXT ();
2565 *tos++ = value;
2566 break;
2567 case 0x82:
2568 NEXT ();
2569 value = THIS ();
2570 NEXT ();
2571 value = (value << 8) | THIS ();
2572 NEXT ();
2573 *tos++ = value;
2574 break;
2575 case 0x81:
2576 NEXT ();
2577 value = THIS ();
2578 NEXT ();
2579 *tos++ = value;
2580 break;
2581 case 0x80:
2582 NEXT ();
2583 *tos++ = 0;
2584 break;
2585 default:
2586 if (THIS () > 0x84)
2587 {
49ae03bf 2588 /* Not a number, just bug out with the answer. */
252b5132
RH
2589 write_int (*(--tos));
2590 return;
2591 }
2592 *tos++ = THIS ();
2593 NEXT ();
252b5132
RH
2594 break;
2595 case 0xa5:
49ae03bf 2596 /* PLUS anything. */
dc810e39
AM
2597 value = *(--tos);
2598 value += *(--tos);
2599 *tos++ = value;
2600 NEXT ();
252b5132
RH
2601 break;
2602 case VAR ('R'):
2603 {
2604 int section_number;
2605 ieee_data_type *ieee;
2606 asection *s;
49ae03bf 2607
252b5132
RH
2608 NEXT ();
2609 section_number = THIS ();
2610
2611 NEXT ();
2612 ieee = IEEE_DATA (input_bfd);
2613 s = ieee->section_table[section_number];
dc810e39 2614 value = 0;
252b5132 2615 if (s->output_section)
dc810e39 2616 value = s->output_section->lma;
252b5132
RH
2617 value += s->output_offset;
2618 *tos++ = value;
252b5132
RH
2619 }
2620 break;
2621 case 0x90:
2622 {
2623 NEXT ();
2624 write_int (*(--tos));
2625 OUT (0x90);
2626 return;
252b5132
RH
2627 }
2628 }
2629 }
252b5132
RH
2630}
2631
2632/* Drop the int in the buffer, and copy a null into the gap, which we
c8e7bf0d 2633 will overwrite later. */
252b5132 2634
252b5132 2635static void
46e94266 2636fill_int (struct output_buffer_struct *buf)
252b5132
RH
2637{
2638 if (buf->buffer == output_buffer)
2639 {
49ae03bf 2640 /* Still a chance to output the size. */
252b5132
RH
2641 int value = output_ptr - buf->ptrp + 3;
2642 buf->ptrp[0] = value >> 24;
2643 buf->ptrp[1] = value >> 16;
2644 buf->ptrp[2] = value >> 8;
2645 buf->ptrp[3] = value >> 0;
2646 }
2647}
2648
2649static void
46e94266 2650drop_int (struct output_buffer_struct *buf)
252b5132
RH
2651{
2652 int type = THIS ();
2653 int ch;
49ae03bf 2654
252b5132
RH
2655 if (type <= 0x84)
2656 {
2657 NEXT ();
2658 switch (type)
2659 {
2660 case 0x84:
2661 ch = THIS ();
2662 NEXT ();
2663 case 0x83:
2664 ch = THIS ();
2665 NEXT ();
2666 case 0x82:
2667 ch = THIS ();
2668 NEXT ();
2669 case 0x81:
2670 ch = THIS ();
2671 NEXT ();
2672 case 0x80:
2673 break;
2674 }
2675 }
c7e2358a 2676 (void) ch;
252b5132
RH
2677 OUT (0x84);
2678 buf->ptrp = output_ptr;
2679 buf->buffer = output_buffer;
2680 OUT (0);
2681 OUT (0);
2682 OUT (0);
2683 OUT (0);
2684}
2685
2686static void
46e94266 2687copy_int (void)
252b5132
RH
2688{
2689 int type = THIS ();
2690 int ch;
2691 if (type <= 0x84)
2692 {
2693 OUT (type);
2694 NEXT ();
2695 switch (type)
2696 {
2697 case 0x84:
2698 ch = THIS ();
2699 NEXT ();
2700 OUT (ch);
2701 case 0x83:
2702 ch = THIS ();
2703 NEXT ();
2704 OUT (ch);
2705 case 0x82:
2706 ch = THIS ();
2707 NEXT ();
2708 OUT (ch);
2709 case 0x81:
2710 ch = THIS ();
2711 NEXT ();
2712 OUT (ch);
2713 case 0x80:
2714 break;
2715 }
2716 }
2717}
2718
46e94266
NC
2719#define ID copy_id ()
2720#define INT copy_int ()
2721#define EXP copy_expression ()
2722#define INTn(q) copy_int ()
2723#define EXPn(q) copy_expression ()
252b5132
RH
2724
2725static void
46e94266
NC
2726copy_till_end (void)
2727{
2728 int ch = THIS ();
2729
2730 while (1)
2731 {
2732 while (ch <= 0x80)
2733 {
2734 OUT (ch);
2735 NEXT ();
2736 ch = THIS ();
2737 }
2738 switch (ch)
2739 {
2740 case 0x84:
2741 OUT (THIS ());
2742 NEXT ();
2743 case 0x83:
2744 OUT (THIS ());
2745 NEXT ();
2746 case 0x82:
2747 OUT (THIS ());
2748 NEXT ();
2749 case 0x81:
2750 OUT (THIS ());
2751 NEXT ();
2752 OUT (THIS ());
2753 NEXT ();
2754
2755 ch = THIS ();
2756 break;
2757 default:
2758 return;
2759 }
2760 }
2761
2762}
2763
2764static void
2765f1_record (void)
252b5132
RH
2766{
2767 int ch;
49ae03bf
NC
2768
2769 /* ATN record. */
252b5132
RH
2770 NEXT ();
2771 ch = THIS ();
2772 switch (ch)
2773 {
2774 default:
2775 OUT (0xf1);
2776 OUT (ch);
2777 break;
2778 case 0xc9:
2779 NEXT ();
2780 OUT (0xf1);
2781 OUT (0xc9);
2782 INT;
2783 INT;
2784 ch = THIS ();
2785 switch (ch)
2786 {
2787 case 0x16:
2788 NEXT ();
2789 break;
2790 case 0x01:
2791 NEXT ();
2792 break;
2793 case 0x00:
2794 NEXT ();
2795 INT;
2796 break;
2797 case 0x03:
2798 NEXT ();
2799 INT;
2800 break;
2801 case 0x13:
2802 EXPn (instruction address);
2803 break;
2804 default:
2805 break;
2806 }
2807 break;
2808 case 0xd8:
49ae03bf 2809 /* EXternal ref. */
252b5132
RH
2810 NEXT ();
2811 OUT (0xf1);
2812 OUT (0xd8);
2813 EXP;
2814 EXP;
2815 EXP;
2816 EXP;
2817 break;
2818 case 0xce:
2819 NEXT ();
2820 OUT (0xf1);
2821 OUT (0xce);
2822 INT;
2823 INT;
2824 ch = THIS ();
2825 INT;
2826 switch (ch)
2827 {
2828 case 0x01:
2829 INT;
2830 INT;
2831 break;
2832 case 0x02:
2833 INT;
2834 break;
2835 case 0x04:
2836 EXPn (external function);
2837 break;
2838 case 0x05:
2839 break;
2840 case 0x07:
2841 INTn (line number);
2842 INT;
2843 case 0x08:
2844 break;
2845 case 0x0a:
2846 INTn (locked register);
2847 INT;
2848 break;
2849 case 0x3f:
2850 copy_till_end ();
2851 break;
2852 case 0x3e:
2853 copy_till_end ();
2854 break;
2855 case 0x40:
2856 copy_till_end ();
2857 break;
2858 case 0x41:
2859 ID;
2860 break;
2861 }
2862 }
252b5132
RH
2863}
2864
2865static void
46e94266 2866f0_record (void)
252b5132 2867{
49ae03bf 2868 /* Attribute record. */
252b5132
RH
2869 NEXT ();
2870 OUT (0xf0);
2871 INTn (Symbol name);
2872 ID;
2873}
2874
2875static void
46e94266 2876f2_record (void)
252b5132
RH
2877{
2878 NEXT ();
2879 OUT (0xf2);
2880 INT;
2881 NEXT ();
2882 OUT (0xce);
2883 INT;
2884 copy_till_end ();
2885}
2886
252b5132 2887static void
46e94266 2888f8_record (void)
252b5132
RH
2889{
2890 int ch;
2891 NEXT ();
2892 ch = THIS ();
2893 switch (ch)
2894 {
2895 case 0x01:
2896 case 0x02:
2897 case 0x03:
49ae03bf
NC
2898 /* Unique typedefs for module. */
2899 /* GLobal typedefs. */
2900 /* High level module scope beginning. */
252b5132
RH
2901 {
2902 struct output_buffer_struct ob;
49ae03bf 2903
252b5132
RH
2904 NEXT ();
2905 OUT (0xf8);
2906 OUT (ch);
2907 drop_int (&ob);
2908 ID;
2909
2910 block ();
2911
2912 NEXT ();
2913 fill_int (&ob);
2914 OUT (0xf9);
2915 }
2916 break;
2917 case 0x04:
49ae03bf 2918 /* Global function. */
252b5132
RH
2919 {
2920 struct output_buffer_struct ob;
49ae03bf 2921
252b5132
RH
2922 NEXT ();
2923 OUT (0xf8);
2924 OUT (0x04);
2925 drop_int (&ob);
2926 ID;
2927 INTn (stack size);
2928 INTn (ret val);
2929 EXPn (offset);
2930
2931 block ();
2932
2933 NEXT ();
2934 OUT (0xf9);
2935 EXPn (size of block);
2936 fill_int (&ob);
2937 }
2938 break;
2939
2940 case 0x05:
49ae03bf 2941 /* File name for source line numbers. */
252b5132
RH
2942 {
2943 struct output_buffer_struct ob;
49ae03bf 2944
252b5132
RH
2945 NEXT ();
2946 OUT (0xf8);
2947 OUT (0x05);
2948 drop_int (&ob);
2949 ID;
2950 INTn (year);
2951 INTn (month);
2952 INTn (day);
2953 INTn (hour);
2954 INTn (monute);
2955 INTn (second);
2956 block ();
2957 NEXT ();
2958 OUT (0xf9);
2959 fill_int (&ob);
2960 }
2961 break;
2962
2963 case 0x06:
49ae03bf 2964 /* Local function. */
252b5132
RH
2965 {
2966 struct output_buffer_struct ob;
49ae03bf 2967
252b5132
RH
2968 NEXT ();
2969 OUT (0xf8);
2970 OUT (0x06);
2971 drop_int (&ob);
2972 ID;
2973 INTn (stack size);
2974 INTn (type return);
2975 EXPn (offset);
2976 block ();
2977 NEXT ();
2978 OUT (0xf9);
2979 EXPn (size);
2980 fill_int (&ob);
2981 }
2982 break;
2983
2984 case 0x0a:
49ae03bf 2985 /* Assembler module scope beginning - */
252b5132
RH
2986 {
2987 struct output_buffer_struct ob;
2988
2989 NEXT ();
2990 OUT (0xf8);
2991 OUT (0x0a);
2992 drop_int (&ob);
2993 ID;
2994 ID;
2995 INT;
2996 ID;
2997 INT;
2998 INT;
2999 INT;
3000 INT;
3001 INT;
3002 INT;
3003
3004 block ();
3005
3006 NEXT ();
3007 OUT (0xf9);
3008 fill_int (&ob);
3009 }
3010 break;
3011 case 0x0b:
3012 {
3013 struct output_buffer_struct ob;
49ae03bf 3014
252b5132
RH
3015 NEXT ();
3016 OUT (0xf8);
3017 OUT (0x0b);
3018 drop_int (&ob);
3019 ID;
3020 INT;
3021 INTn (section index);
3022 EXPn (offset);
3023 INTn (stuff);
3024
3025 block ();
3026
3027 OUT (0xf9);
3028 NEXT ();
3029 EXPn (Size in Maus);
3030 fill_int (&ob);
3031 }
3032 break;
3033 }
3034}
3035
3036static void
46e94266 3037e2_record (void)
252b5132
RH
3038{
3039 OUT (0xe2);
3040 NEXT ();
3041 OUT (0xce);
3042 NEXT ();
3043 INT;
3044 EXP;
3045}
3046
3047static void
46e94266 3048block (void)
252b5132
RH
3049{
3050 int ch;
49ae03bf 3051
252b5132
RH
3052 while (1)
3053 {
3054 ch = THIS ();
3055 switch (ch)
3056 {
3057 case 0xe1:
3058 case 0xe5:
3059 return;
3060 case 0xf9:
3061 return;
3062 case 0xf0:
3063 f0_record ();
3064 break;
3065 case 0xf1:
3066 f1_record ();
3067 break;
3068 case 0xf2:
3069 f2_record ();
3070 break;
3071 case 0xf8:
3072 f8_record ();
3073 break;
3074 case 0xe2:
3075 e2_record ();
3076 break;
3077
3078 }
3079 }
3080}
3081
49ae03bf
NC
3082/* Moves all the debug information from the source bfd to the output
3083 bfd, and relocates any expressions it finds. */
252b5132
RH
3084
3085static void
46e94266
NC
3086relocate_debug (bfd *output ATTRIBUTE_UNUSED,
3087 bfd *input)
252b5132
RH
3088{
3089#define IBS 400
3090#define OBS 400
3091 unsigned char input_buffer[IBS];
3092
3093 input_ptr_start = input_ptr = input_buffer;
3094 input_ptr_end = input_buffer + IBS;
3095 input_bfd = input;
3096 /* FIXME: Check return value. I'm not sure whether it needs to read
3097 the entire buffer or not. */
c8e7bf0d 3098 bfd_bread ((void *) input_ptr_start, (bfd_size_type) IBS, input);
252b5132
RH
3099 block ();
3100}
3101
dce61835
KH
3102/* Gather together all the debug information from each input BFD into
3103 one place, relocating it and emitting it as we go. */
252b5132 3104
b34976b6 3105static bfd_boolean
46e94266 3106ieee_write_debug_part (bfd *abfd)
252b5132
RH
3107{
3108 ieee_data_type *ieee = IEEE_DATA (abfd);
3109 bfd_chain_type *chain = ieee->chain_root;
dc810e39 3110 unsigned char obuff[OBS];
b34976b6 3111 bfd_boolean some_debug = FALSE;
252b5132
RH
3112 file_ptr here = bfd_tell (abfd);
3113
dc810e39
AM
3114 output_ptr_start = output_ptr = obuff;
3115 output_ptr_end = obuff + OBS;
3116 output_ptr = obuff;
252b5132
RH
3117 output_bfd = abfd;
3118
3119 if (chain == (bfd_chain_type *) NULL)
3120 {
3121 asection *s;
3122
3123 for (s = abfd->sections; s != NULL; s = s->next)
3124 if ((s->flags & SEC_DEBUGGING) != 0)
3125 break;
3126 if (s == NULL)
3127 {
3128 ieee->w.r.debug_information_part = 0;
b34976b6 3129 return TRUE;
252b5132
RH
3130 }
3131
3132 ieee->w.r.debug_information_part = here;
eea6121a 3133 if (bfd_bwrite (s->contents, s->size, abfd) != s->size)
b34976b6 3134 return FALSE;
252b5132
RH
3135 }
3136 else
3137 {
3138 while (chain != (bfd_chain_type *) NULL)
3139 {
3140 bfd *entry = chain->this;
3141 ieee_data_type *entry_ieee = IEEE_DATA (entry);
49ae03bf 3142
252b5132
RH
3143 if (entry_ieee->w.r.debug_information_part)
3144 {
3145 if (bfd_seek (entry, entry_ieee->w.r.debug_information_part,
dc810e39 3146 SEEK_SET) != 0)
b34976b6 3147 return FALSE;
252b5132
RH
3148 relocate_debug (abfd, entry);
3149 }
3150
3151 chain = chain->next;
3152 }
49ae03bf 3153
252b5132 3154 if (some_debug)
49ae03bf 3155 ieee->w.r.debug_information_part = here;
252b5132 3156 else
49ae03bf 3157 ieee->w.r.debug_information_part = 0;
252b5132
RH
3158
3159 flush ();
3160 }
3161
b34976b6 3162 return TRUE;
252b5132
RH
3163}
3164
3165/* Write the data in an ieee way. */
3166
b34976b6 3167static bfd_boolean
46e94266 3168ieee_write_data_part (bfd *abfd)
252b5132
RH
3169{
3170 asection *s;
49ae03bf 3171
252b5132
RH
3172 ieee_data_type *ieee = IEEE_DATA (abfd);
3173 ieee->w.r.data_part = bfd_tell (abfd);
49ae03bf 3174
252b5132
RH
3175 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
3176 {
3177 /* Skip sections that have no loadable contents (.bss,
3178 debugging, etc.) */
3179 if ((s->flags & SEC_LOAD) == 0)
3180 continue;
3181
3182 /* Sort the reloc records so we can insert them in the correct
c8e7bf0d 3183 places. */
252b5132
RH
3184 if (s->reloc_count != 0)
3185 {
3186 if (! do_with_relocs (abfd, s))
b34976b6 3187 return FALSE;
252b5132
RH
3188 }
3189 else
3190 {
3191 if (! do_without_relocs (abfd, s))
b34976b6 3192 return FALSE;
252b5132
RH
3193 }
3194 }
3195
b34976b6 3196 return TRUE;
252b5132
RH
3197}
3198
b34976b6 3199static bfd_boolean
46e94266 3200init_for_output (bfd *abfd)
252b5132
RH
3201{
3202 asection *s;
49ae03bf 3203
252b5132
RH
3204 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
3205 {
3206 if ((s->flags & SEC_DEBUGGING) != 0)
3207 continue;
eea6121a 3208 if (s->size != 0)
252b5132 3209 {
eea6121a 3210 bfd_size_type size = s->size;
c8e7bf0d 3211 ieee_per_section (s)->data = bfd_alloc (abfd, size);
252b5132 3212 if (!ieee_per_section (s)->data)
b34976b6 3213 return FALSE;
252b5132
RH
3214 }
3215 }
b34976b6 3216 return TRUE;
252b5132
RH
3217}
3218\f
49ae03bf
NC
3219/* Exec and core file sections. */
3220
3221/* Set section contents is complicated with IEEE since the format is
3222 not a byte image, but a record stream. */
252b5132 3223
b34976b6 3224static bfd_boolean
46e94266
NC
3225ieee_set_section_contents (bfd *abfd,
3226 sec_ptr section,
3227 const void * location,
3228 file_ptr offset,
3229 bfd_size_type count)
252b5132
RH
3230{
3231 if ((section->flags & SEC_DEBUGGING) != 0)
3232 {
3233 if (section->contents == NULL)
3234 {
eea6121a 3235 bfd_size_type size = section->size;
c8e7bf0d 3236 section->contents = bfd_alloc (abfd, size);
252b5132 3237 if (section->contents == NULL)
b34976b6 3238 return FALSE;
252b5132
RH
3239 }
3240 /* bfd_set_section_contents has already checked that everything
3241 is within range. */
dc810e39 3242 memcpy (section->contents + offset, location, (size_t) count);
b34976b6 3243 return TRUE;
252b5132
RH
3244 }
3245
3246 if (ieee_per_section (section)->data == (bfd_byte *) NULL)
3247 {
3248 if (!init_for_output (abfd))
b34976b6 3249 return FALSE;
252b5132 3250 }
c8e7bf0d
NC
3251 memcpy ((void *) (ieee_per_section (section)->data + offset),
3252 (void *) location,
252b5132 3253 (unsigned int) count);
b34976b6 3254 return TRUE;
252b5132
RH
3255}
3256
3257/* Write the external symbols of a file. IEEE considers two sorts of
3258 external symbols, public, and referenced. It uses to internal
3259 forms to index them as well. When we write them out we turn their
3260 symbol values into indexes from the right base. */
3261
b34976b6 3262static bfd_boolean
46e94266 3263ieee_write_external_part (bfd *abfd)
252b5132
RH
3264{
3265 asymbol **q;
3266 ieee_data_type *ieee = IEEE_DATA (abfd);
252b5132
RH
3267 unsigned int reference_index = IEEE_REFERENCE_BASE;
3268 unsigned int public_index = IEEE_PUBLIC_BASE + 2;
3269 file_ptr here = bfd_tell (abfd);
b34976b6 3270 bfd_boolean hadone = FALSE;
49ae03bf 3271
252b5132
RH
3272 if (abfd->outsymbols != (asymbol **) NULL)
3273 {
3274
3275 for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++)
3276 {
3277 asymbol *p = *q;
49ae03bf 3278
252b5132
RH
3279 if (bfd_is_und_section (p->section))
3280 {
49ae03bf 3281 /* This must be a symbol reference. */
252b5132 3282 if (! ieee_write_byte (abfd, ieee_external_reference_enum)
dc810e39 3283 || ! ieee_write_int (abfd, (bfd_vma) reference_index)
252b5132 3284 || ! ieee_write_id (abfd, p->name))
b34976b6 3285 return FALSE;
252b5132
RH
3286 p->value = reference_index;
3287 reference_index++;
b34976b6 3288 hadone = TRUE;
252b5132
RH
3289 }
3290 else if (bfd_is_com_section (p->section))
3291 {
49ae03bf 3292 /* This is a weak reference. */
252b5132 3293 if (! ieee_write_byte (abfd, ieee_external_reference_enum)
dc810e39 3294 || ! ieee_write_int (abfd, (bfd_vma) reference_index)
252b5132
RH
3295 || ! ieee_write_id (abfd, p->name)
3296 || ! ieee_write_byte (abfd,
3297 ieee_weak_external_reference_enum)
dc810e39 3298 || ! ieee_write_int (abfd, (bfd_vma) reference_index)
252b5132 3299 || ! ieee_write_int (abfd, p->value))
b34976b6 3300 return FALSE;
252b5132
RH
3301 p->value = reference_index;
3302 reference_index++;
b34976b6 3303 hadone = TRUE;
252b5132
RH
3304 }
3305 else if (p->flags & BSF_GLOBAL)
3306 {
49ae03bf 3307 /* This must be a symbol definition. */
252b5132 3308 if (! ieee_write_byte (abfd, ieee_external_symbol_enum)
dc810e39 3309 || ! ieee_write_int (abfd, (bfd_vma) public_index)
252b5132
RH
3310 || ! ieee_write_id (abfd, p->name)
3311 || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum)
dc810e39 3312 || ! ieee_write_int (abfd, (bfd_vma) public_index)
c8e7bf0d
NC
3313 || ! ieee_write_byte (abfd, 15) /* Instruction address. */
3314 || ! ieee_write_byte (abfd, 19) /* Static symbol. */
3315 || ! ieee_write_byte (abfd, 1)) /* One of them. */
b34976b6 3316 return FALSE;
252b5132 3317
49ae03bf 3318 /* Write out the value. */
252b5132 3319 if (! ieee_write_2bytes (abfd, ieee_value_record_enum)
dc810e39 3320 || ! ieee_write_int (abfd, (bfd_vma) public_index))
b34976b6 3321 return FALSE;
252b5132
RH
3322 if (! bfd_is_abs_section (p->section))
3323 {
3324 if (abfd->flags & EXEC_P)
3325 {
3326 /* If fully linked, then output all symbols
49ae03bf 3327 relocated. */
252b5132
RH
3328 if (! (ieee_write_int
3329 (abfd,
3330 (p->value
3331 + p->section->output_offset
3332 + p->section->output_section->vma))))
b34976b6 3333 return FALSE;
252b5132
RH
3334 }
3335 else
3336 {
3337 if (! (ieee_write_expression
3338 (abfd,
3339 p->value + p->section->output_offset,
3340 p->section->output_section->symbol,
b34976b6
AM
3341 FALSE, 0)))
3342 return FALSE;
252b5132
RH
3343 }
3344 }
3345 else
3346 {
3347 if (! ieee_write_expression (abfd,
3348 p->value,
3349 bfd_abs_section_ptr->symbol,
b34976b6
AM
3350 FALSE, 0))
3351 return FALSE;
252b5132
RH
3352 }
3353 p->value = public_index;
3354 public_index++;
b34976b6 3355 hadone = TRUE;
252b5132
RH
3356 }
3357 else
3358 {
49ae03bf
NC
3359 /* This can happen - when there are gaps in the symbols read
3360 from an input ieee file. */
252b5132
RH
3361 }
3362 }
3363 }
3364 if (hadone)
3365 ieee->w.r.external_part = here;
3366
b34976b6 3367 return TRUE;
252b5132
RH
3368}
3369
3370
47fda0d3 3371static const unsigned char exten[] =
252b5132
RH
3372{
3373 0xf0, 0x20, 0x00,
49ae03bf
NC
3374 0xf1, 0xce, 0x20, 0x00, 37, 3, 3, /* Set version 3 rev 3. */
3375 0xf1, 0xce, 0x20, 0x00, 39, 2, /* Keep symbol in original case. */
1049f94e 3376 0xf1, 0xce, 0x20, 0x00, 38 /* Set object type relocatable to x. */
252b5132
RH
3377};
3378
47fda0d3 3379static const unsigned char envi[] =
252b5132
RH
3380{
3381 0xf0, 0x21, 0x00,
3382
3383/* 0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11,
3384 0x19, 0x2c,
3385*/
c8e7bf0d 3386 0xf1, 0xce, 0x21, 00, 52, 0x00, /* exec ok. */
252b5132 3387
c8e7bf0d 3388 0xf1, 0xce, 0x21, 0, 53, 0x03,/* host unix. */
252b5132
RH
3389/* 0xf1, 0xce, 0x21, 0, 54, 2,1,1 tool & version # */
3390};
3391
b34976b6 3392static bfd_boolean
46e94266 3393ieee_write_me_part (bfd *abfd)
252b5132
RH
3394{
3395 ieee_data_type *ieee = IEEE_DATA (abfd);
3396 ieee->w.r.trailer_part = bfd_tell (abfd);
3397 if (abfd->start_address)
3398 {
3399 if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum)
3400 || ! ieee_write_byte (abfd, ieee_function_either_open_b_enum)
3401 || ! ieee_write_int (abfd, abfd->start_address)
3402 || ! ieee_write_byte (abfd, ieee_function_either_close_b_enum))
b34976b6 3403 return FALSE;
252b5132
RH
3404 }
3405 ieee->w.r.me_record = bfd_tell (abfd);
3406 if (! ieee_write_byte (abfd, ieee_module_end_enum))
b34976b6
AM
3407 return FALSE;
3408 return TRUE;
252b5132
RH
3409}
3410
3411/* Write out the IEEE processor ID. */
3412
b34976b6 3413static bfd_boolean
46e94266 3414ieee_write_processor (bfd *abfd)
252b5132
RH
3415{
3416 const bfd_arch_info_type *arch;
3417
3418 arch = bfd_get_arch_info (abfd);
3419 switch (arch->arch)
3420 {
3421 default:
3422 if (! ieee_write_id (abfd, bfd_printable_name (abfd)))
b34976b6 3423 return FALSE;
252b5132
RH
3424 break;
3425
252b5132
RH
3426 case bfd_arch_h8300:
3427 if (! ieee_write_id (abfd, "H8/300"))
b34976b6 3428 return FALSE;
252b5132
RH
3429 break;
3430
3431 case bfd_arch_h8500:
3432 if (! ieee_write_id (abfd, "H8/500"))
b34976b6 3433 return FALSE;
252b5132
RH
3434 break;
3435
3436 case bfd_arch_i960:
3437 switch (arch->mach)
3438 {
3439 default:
3440 case bfd_mach_i960_core:
3441 case bfd_mach_i960_ka_sa:
3442 if (! ieee_write_id (abfd, "80960KA"))
b34976b6 3443 return FALSE;
252b5132
RH
3444 break;
3445
3446 case bfd_mach_i960_kb_sb:
3447 if (! ieee_write_id (abfd, "80960KB"))
b34976b6 3448 return FALSE;
252b5132
RH
3449 break;
3450
3451 case bfd_mach_i960_ca:
3452 if (! ieee_write_id (abfd, "80960CA"))
b34976b6 3453 return FALSE;
252b5132
RH
3454 break;
3455
3456 case bfd_mach_i960_mc:
3457 case bfd_mach_i960_xa:
3458 if (! ieee_write_id (abfd, "80960MC"))
b34976b6 3459 return FALSE;
252b5132
RH
3460 break;
3461 }
3462 break;
3463
3464 case bfd_arch_m68k:
3465 {
3466 const char *id;
3467
3468 switch (arch->mach)
3469 {
3470 default: id = "68020"; break;
3471 case bfd_mach_m68000: id = "68000"; break;
3472 case bfd_mach_m68008: id = "68008"; break;
3473 case bfd_mach_m68010: id = "68010"; break;
3474 case bfd_mach_m68020: id = "68020"; break;
3475 case bfd_mach_m68030: id = "68030"; break;
3476 case bfd_mach_m68040: id = "68040"; break;
3477 case bfd_mach_m68060: id = "68060"; break;
3478 case bfd_mach_cpu32: id = "cpu32"; break;
0b2e31dc 3479 case bfd_mach_mcf_isa_a_nodiv: id = "isa-a:nodiv"; break;
266abb8f 3480 case bfd_mach_mcf_isa_a: id = "isa-a"; break;
0b2e31dc
NS
3481 case bfd_mach_mcf_isa_a_mac: id = "isa-a:mac"; break;
3482 case bfd_mach_mcf_isa_a_emac: id = "isa-a:emac"; break;
3483 case bfd_mach_mcf_isa_aplus: id = "isa-aplus"; break;
3484 case bfd_mach_mcf_isa_aplus_mac: id = "isa-aplus:mac"; break;
3485 case bfd_mach_mcf_isa_aplus_emac: id = "isa-aplus:mac"; break;
3486 case bfd_mach_mcf_isa_b_nousp: id = "isa-b:nousp"; break;
3487 case bfd_mach_mcf_isa_b_nousp_mac: id = "isa-b:nousp:mac"; break;
3488 case bfd_mach_mcf_isa_b_nousp_emac: id = "isa-b:nousp:emac"; break;
266abb8f
NS
3489 case bfd_mach_mcf_isa_b: id = "isa-b"; break;
3490 case bfd_mach_mcf_isa_b_mac: id = "isa-b:mac"; break;
3491 case bfd_mach_mcf_isa_b_emac: id = "isa-b:emac"; break;
0b2e31dc
NS
3492 case bfd_mach_mcf_isa_b_float: id = "isa-b:float"; break;
3493 case bfd_mach_mcf_isa_b_float_mac: id = "isa-b:float:mac"; break;
3494 case bfd_mach_mcf_isa_b_float_emac: id = "isa-b:float:emac"; break;
8d100c32
KH
3495 case bfd_mach_mcf_isa_c: id = "isa-c"; break;
3496 case bfd_mach_mcf_isa_c_mac: id = "isa-c:mac"; break;
3497 case bfd_mach_mcf_isa_c_emac: id = "isa-c:emac"; break;
3498 case bfd_mach_mcf_isa_c_nodiv: id = "isa-c:nodiv"; break;
3499 case bfd_mach_mcf_isa_c_nodiv_mac: id = "isa-c:nodiv:mac"; break;
3500 case bfd_mach_mcf_isa_c_nodiv_emac: id = "isa-c:nodiv:emac"; break;
252b5132
RH
3501 }
3502
3503 if (! ieee_write_id (abfd, id))
b34976b6 3504 return FALSE;
252b5132
RH
3505 }
3506 break;
3507 }
3508
b34976b6 3509 return TRUE;
252b5132
RH
3510}
3511
b34976b6 3512static bfd_boolean
46e94266 3513ieee_write_object_contents (bfd *abfd)
252b5132
RH
3514{
3515 ieee_data_type *ieee = IEEE_DATA (abfd);
3516 unsigned int i;
3517 file_ptr old;
3518
49ae03bf 3519 /* Fast forward over the header area. */
252b5132 3520 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
b34976b6 3521 return FALSE;
252b5132
RH
3522
3523 if (! ieee_write_byte (abfd, ieee_module_beginning_enum)
3524 || ! ieee_write_processor (abfd)
3525 || ! ieee_write_id (abfd, abfd->filename))
b34976b6 3526 return FALSE;
252b5132 3527
49ae03bf 3528 /* Fast forward over the variable bits. */
252b5132 3529 if (! ieee_write_byte (abfd, ieee_address_descriptor_enum))
b34976b6 3530 return FALSE;
252b5132 3531
49ae03bf 3532 /* Bits per MAU. */
252b5132 3533 if (! ieee_write_byte (abfd, (bfd_byte) (bfd_arch_bits_per_byte (abfd))))
b34976b6 3534 return FALSE;
49ae03bf 3535 /* MAU's per address. */
252b5132
RH
3536 if (! ieee_write_byte (abfd,
3537 (bfd_byte) (bfd_arch_bits_per_address (abfd)
3538 / bfd_arch_bits_per_byte (abfd))))
b34976b6 3539 return FALSE;
252b5132
RH
3540
3541 old = bfd_tell (abfd);
3542 if (bfd_seek (abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR) != 0)
b34976b6 3543 return FALSE;
252b5132
RH
3544
3545 ieee->w.r.extension_record = bfd_tell (abfd);
dc810e39
AM
3546 if (bfd_bwrite ((char *) exten, (bfd_size_type) sizeof (exten), abfd)
3547 != sizeof (exten))
b34976b6 3548 return FALSE;
252b5132
RH
3549 if (abfd->flags & EXEC_P)
3550 {
c8e7bf0d 3551 if (! ieee_write_byte (abfd, 0x1)) /* Absolute. */
b34976b6 3552 return FALSE;
252b5132
RH
3553 }
3554 else
3555 {
c8e7bf0d 3556 if (! ieee_write_byte (abfd, 0x2)) /* Relocateable. */
b34976b6 3557 return FALSE;
252b5132
RH
3558 }
3559
3560 ieee->w.r.environmental_record = bfd_tell (abfd);
dc810e39
AM
3561 if (bfd_bwrite ((char *) envi, (bfd_size_type) sizeof (envi), abfd)
3562 != sizeof (envi))
b34976b6 3563 return FALSE;
252b5132
RH
3564
3565 /* The HP emulator database requires a timestamp in the file. */
3566 {
3567 time_t now;
3568 const struct tm *t;
3569
3570 time (&now);
3571 t = (struct tm *) localtime (&now);
3572 if (! ieee_write_2bytes (abfd, (int) ieee_atn_record_enum)
3573 || ! ieee_write_byte (abfd, 0x21)
3574 || ! ieee_write_byte (abfd, 0)
3575 || ! ieee_write_byte (abfd, 50)
dc810e39
AM
3576 || ! ieee_write_int (abfd, (bfd_vma) (t->tm_year + 1900))
3577 || ! ieee_write_int (abfd, (bfd_vma) (t->tm_mon + 1))
3578 || ! ieee_write_int (abfd, (bfd_vma) t->tm_mday)
3579 || ! ieee_write_int (abfd, (bfd_vma) t->tm_hour)
3580 || ! ieee_write_int (abfd, (bfd_vma) t->tm_min)
3581 || ! ieee_write_int (abfd, (bfd_vma) t->tm_sec))
b34976b6 3582 return FALSE;
252b5132
RH
3583 }
3584
3585 output_bfd = abfd;
3586
3587 flush ();
3588
3589 if (! ieee_write_section_part (abfd))
b34976b6 3590 return FALSE;
252b5132
RH
3591 /* First write the symbols. This changes their values into table
3592 indeces so we cant use it after this point. */
3593 if (! ieee_write_external_part (abfd))
b34976b6 3594 return FALSE;
252b5132 3595
252b5132
RH
3596 /* Write any debugs we have been told about. */
3597 if (! ieee_write_debug_part (abfd))
b34976b6 3598 return FALSE;
252b5132
RH
3599
3600 /* Can only write the data once the symbols have been written, since
3601 the data contains relocation information which points to the
3602 symbols. */
3603 if (! ieee_write_data_part (abfd))
b34976b6 3604 return FALSE;
252b5132
RH
3605
3606 /* At the end we put the end! */
3607 if (! ieee_write_me_part (abfd))
b34976b6 3608 return FALSE;
252b5132 3609
49ae03bf 3610 /* Generate the header. */
252b5132 3611 if (bfd_seek (abfd, old, SEEK_SET) != 0)
b34976b6 3612 return FALSE;
252b5132
RH
3613
3614 for (i = 0; i < N_W_VARIABLES; i++)
3615 {
3616 if (! ieee_write_2bytes (abfd, ieee_assign_value_to_variable_enum)
3617 || ! ieee_write_byte (abfd, (bfd_byte) i)
dc810e39 3618 || ! ieee_write_int5_out (abfd, (bfd_vma) ieee->w.offset[i]))
b34976b6 3619 return FALSE;
252b5132
RH
3620 }
3621
b34976b6 3622 return TRUE;
252b5132
RH
3623}
3624\f
c8e7bf0d 3625/* Native-level interface to symbols. */
252b5132
RH
3626
3627/* We read the symbols into a buffer, which is discarded when this
3628 function exits. We read the strings into a buffer large enough to
49ae03bf 3629 hold them all plus all the cached symbol entries. */
252b5132 3630
47fda0d3 3631static asymbol *
46e94266 3632ieee_make_empty_symbol (bfd *abfd)
252b5132 3633{
dc810e39 3634 bfd_size_type amt = sizeof (ieee_symbol_type);
d3ce72d0 3635 ieee_symbol_type *new_symbol = (ieee_symbol_type *) bfd_zalloc (abfd, amt);
49ae03bf 3636
d3ce72d0 3637 if (!new_symbol)
252b5132 3638 return NULL;
d3ce72d0
NC
3639 new_symbol->symbol.the_bfd = abfd;
3640 return &new_symbol->symbol;
252b5132
RH
3641}
3642
3643static bfd *
46e94266 3644ieee_openr_next_archived_file (bfd *arch, bfd *prev)
252b5132
RH
3645{
3646 ieee_ar_data_type *ar = IEEE_AR_DATA (arch);
49ae03bf
NC
3647
3648 /* Take the next one from the arch state, or reset. */
252b5132 3649 if (prev == (bfd *) NULL)
49ae03bf
NC
3650 /* Reset the index - the first two entries are bogus. */
3651 ar->element_index = 2;
3652
b34976b6 3653 while (TRUE)
252b5132
RH
3654 {
3655 ieee_ar_obstack_type *p = ar->elements + ar->element_index;
49ae03bf 3656
252b5132
RH
3657 ar->element_index++;
3658 if (ar->element_index <= ar->element_count)
3659 {
3660 if (p->file_offset != (file_ptr) 0)
3661 {
3662 if (p->abfd == (bfd *) NULL)
3663 {
3664 p->abfd = _bfd_create_empty_archive_element_shell (arch);
3665 p->abfd->origin = p->file_offset;
3666 }
3667 return p->abfd;
3668 }
3669 }
3670 else
3671 {
3672 bfd_set_error (bfd_error_no_more_archived_files);
46e94266 3673 return NULL;
252b5132 3674 }
252b5132
RH
3675 }
3676}
3677
b34976b6 3678static bfd_boolean
46e94266
NC
3679ieee_find_nearest_line (bfd *abfd ATTRIBUTE_UNUSED,
3680 asection *section ATTRIBUTE_UNUSED,
3681 asymbol **symbols ATTRIBUTE_UNUSED,
3682 bfd_vma offset ATTRIBUTE_UNUSED,
3683 const char **filename_ptr ATTRIBUTE_UNUSED,
3684 const char **functionname_ptr ATTRIBUTE_UNUSED,
3685 unsigned int *line_ptr ATTRIBUTE_UNUSED)
252b5132 3686{
b34976b6 3687 return FALSE;
252b5132
RH
3688}
3689
4ab527b0
FF
3690static bfd_boolean
3691ieee_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
3692 const char **filename_ptr ATTRIBUTE_UNUSED,
3693 const char **functionname_ptr ATTRIBUTE_UNUSED,
3694 unsigned int *line_ptr ATTRIBUTE_UNUSED)
3695{
3696 return FALSE;
3697}
3698
252b5132 3699static int
46e94266 3700ieee_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
252b5132
RH
3701{
3702 ieee_ar_data_type *ar = (ieee_ar_data_type *) NULL;
3703 ieee_data_type *ieee;
3704
3705 if (abfd->my_archive != NULL)
3706 ar = abfd->my_archive->tdata.ieee_ar_data;
3707 if (ar == (ieee_ar_data_type *) NULL)
3708 {
3709 bfd_set_error (bfd_error_invalid_operation);
3710 return -1;
3711 }
3712
3713 if (IEEE_DATA (abfd) == NULL)
3714 {
3715 if (ieee_object_p (abfd) == NULL)
3716 {
3717 bfd_set_error (bfd_error_wrong_format);
3718 return -1;
3719 }
3720 }
3721
3722 ieee = IEEE_DATA (abfd);
3723
3724 buf->st_size = ieee->w.r.me_record + 1;
3725 buf->st_mode = 0644;
3726 return 0;
3727}
3728
3729static int
46e94266 3730ieee_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
a6b96beb 3731 struct bfd_link_info *info ATTRIBUTE_UNUSED)
252b5132
RH
3732{
3733 return 0;
3734}
3735
252b5132
RH
3736#define ieee_close_and_cleanup _bfd_generic_close_and_cleanup
3737#define ieee_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
3738
3739#define ieee_slurp_armap bfd_true
3740#define ieee_slurp_extended_name_table bfd_true
3741#define ieee_construct_extended_name_table \
b34976b6 3742 ((bfd_boolean (*) \
116c20d2 3743 (bfd *, char **, bfd_size_type *, const char **)) \
252b5132
RH
3744 bfd_true)
3745#define ieee_truncate_arname bfd_dont_truncate_arname
3746#define ieee_write_armap \
b34976b6 3747 ((bfd_boolean (*) \
116c20d2 3748 (bfd *, unsigned int, struct orl *, unsigned int, int)) \
252b5132
RH
3749 bfd_true)
3750#define ieee_read_ar_hdr bfd_nullvoidptr
8f95b6e4 3751#define ieee_write_ar_hdr ((bfd_boolean (*) (bfd *, bfd *)) bfd_false)
252b5132
RH
3752#define ieee_update_armap_timestamp bfd_true
3753#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index
3754
3c9458e9
NC
3755#define ieee_bfd_is_target_special_symbol \
3756 ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
252b5132
RH
3757#define ieee_bfd_is_local_label_name bfd_generic_is_local_label_name
3758#define ieee_get_lineno _bfd_nosymbols_get_lineno
3759#define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
3760#define ieee_read_minisymbols _bfd_generic_read_minisymbols
3761#define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
3762
3763#define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
157090f7 3764#define ieee_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
252b5132
RH
3765
3766#define ieee_set_arch_mach _bfd_generic_set_arch_mach
3767
3768#define ieee_get_section_contents_in_window \
3769 _bfd_generic_get_section_contents_in_window
3770#define ieee_bfd_get_relocated_section_contents \
3771 bfd_generic_get_relocated_section_contents
3772#define ieee_bfd_relax_section bfd_generic_relax_section
3773#define ieee_bfd_gc_sections bfd_generic_gc_sections
ae17ab41 3774#define ieee_bfd_lookup_section_flags bfd_generic_lookup_section_flags
8550eb6e 3775#define ieee_bfd_merge_sections bfd_generic_merge_sections
72adc230 3776#define ieee_bfd_is_group_section bfd_generic_is_group_section
e61463e1 3777#define ieee_bfd_discard_group bfd_generic_discard_group
082b7297
L
3778#define ieee_section_already_linked \
3779 _bfd_generic_section_already_linked
3023e3f6 3780#define ieee_bfd_define_common_symbol bfd_generic_define_common_symbol
252b5132
RH
3781#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
3782#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols
2d653fc7 3783#define ieee_bfd_link_just_syms _bfd_generic_link_just_syms
1338dd10
PB
3784#define ieee_bfd_copy_link_hash_symbol_type \
3785 _bfd_generic_copy_link_hash_symbol_type
252b5132
RH
3786#define ieee_bfd_final_link _bfd_generic_final_link
3787#define ieee_bfd_link_split_section _bfd_generic_link_split_section
3788
252b5132
RH
3789const bfd_target ieee_vec =
3790{
116c20d2 3791 "ieee", /* Name. */
252b5132 3792 bfd_target_ieee_flavour,
116c20d2
NC
3793 BFD_ENDIAN_UNKNOWN, /* Target byte order. */
3794 BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */
3795 (HAS_RELOC | EXEC_P | /* Object flags. */
252b5132
RH
3796 HAS_LINENO | HAS_DEBUG |
3797 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
3798 (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
116c20d2
NC
3799 | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */
3800 '_', /* Leading underscore. */
3801 ' ', /* AR_pad_char. */
3802 16, /* AR_max_namelen. */
0aabe54e 3803 0, /* match priority. */
252b5132
RH
3804 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3805 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
116c20d2 3806 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */
252b5132
RH
3807 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3808 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
116c20d2 3809 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */
252b5132
RH
3810
3811 {_bfd_dummy_target,
116c20d2 3812 ieee_object_p, /* bfd_check_format. */
252b5132
RH
3813 ieee_archive_p,
3814 _bfd_dummy_target,
3815 },
3816 {
3817 bfd_false,
3818 ieee_mkobject,
3819 _bfd_generic_mkarchive,
3820 bfd_false
3821 },
3822 {
3823 bfd_false,
3824 ieee_write_object_contents,
3825 _bfd_write_archive_contents,
3826 bfd_false,
3827 },
3828
47fda0d3 3829 /* ieee_close_and_cleanup, ieee_bfd_free_cached_info, ieee_new_section_hook,
c8e7bf0d 3830 ieee_get_section_contents, ieee_get_section_contents_in_window. */
252b5132 3831 BFD_JUMP_TABLE_GENERIC (ieee),
47fda0d3 3832
252b5132
RH
3833 BFD_JUMP_TABLE_COPY (_bfd_generic),
3834 BFD_JUMP_TABLE_CORE (_bfd_nocore),
47fda0d3
AM
3835
3836 /* ieee_slurp_armap, ieee_slurp_extended_name_table,
3837 ieee_construct_extended_name_table, ieee_truncate_arname,
3838 ieee_write_armap, ieee_read_ar_hdr, ieee_openr_next_archived_file,
3839 ieee_get_elt_at_index, ieee_generic_stat_arch_elt,
c8e7bf0d 3840 ieee_update_armap_timestamp. */
252b5132 3841 BFD_JUMP_TABLE_ARCHIVE (ieee),
47fda0d3 3842
6cee3f79
AC
3843 /* ieee_get_symtab_upper_bound, ieee_canonicalize_symtab,
3844 ieee_make_empty_symbol, ieee_print_symbol, ieee_get_symbol_info,
3845 ieee_bfd_is_local_label_name, ieee_get_lineno,
3846 ieee_find_nearest_line, ieee_bfd_make_debug_symbol,
c8e7bf0d 3847 ieee_read_minisymbols, ieee_minisymbol_to_symbol. */
252b5132 3848 BFD_JUMP_TABLE_SYMBOLS (ieee),
47fda0d3
AM
3849
3850 /* ieee_get_reloc_upper_bound, ieee_canonicalize_reloc,
c8e7bf0d 3851 ieee_bfd_reloc_type_lookup. */
252b5132 3852 BFD_JUMP_TABLE_RELOCS (ieee),
47fda0d3 3853
c8e7bf0d 3854 /* ieee_set_arch_mach, ieee_set_section_contents. */
252b5132 3855 BFD_JUMP_TABLE_WRITE (ieee),
47fda0d3
AM
3856
3857 /* ieee_sizeof_headers, ieee_bfd_get_relocated_section_contents,
3858 ieee_bfd_relax_section, ieee_bfd_link_hash_table_create,
3859 ieee_bfd_link_add_symbols, ieee_bfd_final_link,
3860 ieee_bfd_link_split_section, ieee_bfd_gc_sections,
c8e7bf0d 3861 ieee_bfd_merge_sections. */
252b5132 3862 BFD_JUMP_TABLE_LINK (ieee),
47fda0d3 3863
252b5132
RH
3864 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
3865
c3c89269 3866 NULL,
dc810e39 3867
116c20d2 3868 NULL
252b5132 3869};
This page took 1.452137 seconds and 4 git commands to generate.