* gdbint.texinfo (Target Conditionals): Remove NO_TYPEDEFS,
[deliverable/binutils-gdb.git] / bfd / ieee.c
CommitLineData
aff6e0b4 1/* BFD back-end for ieee-695 objects.
8feff717 2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
b2c91bd9 3 Written by Steve Chamberlain of Cygnus Support.
d0ec7a8e 4
b2c91bd9 5This file is part of BFD, the Binary File Descriptor library.
87f86b4e 6
b2c91bd9 7This program is free software; you can redistribute it and/or modify
9b4641a6 8it under the terms of the GNU General Public License as published by
b2c91bd9
SC
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
87f86b4e 11
b2c91bd9 12This program is distributed in the hope that it will be useful,
9b4641a6
JG
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
87f86b4e 16
9b4641a6 17You should have received a copy of the GNU General Public License
b2c91bd9
SC
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
87f86b4e 20
aff6e0b4 21#define KEEPMINUSPCININST 0
9465d03e 22
b2c91bd9
SC
23/* IEEE 695 format is a stream of records, which we parse using a simple one-
24 token (which is one byte in this lexicon) lookahead recursive decent
25 parser. */
d0ec7a8e 26
87f86b4e 27#include "bfd.h"
01dd1b2b 28#include "sysdep.h"
87f86b4e 29#include "libbfd.h"
87f86b4e
DHW
30#include "ieee.h"
31#include "libieee.h"
32
9465d03e
SC
33
34#include "obstack.h"
35#define obstack_chunk_alloc bfd_xmalloc
36#define obstack_chunk_free free
37
ce3f6d51
JG
38/* Functions for writing to ieee files in the strange way that the
39 standard requires. */
87f86b4e
DHW
40
41static void
301dfc71
SC
42DEFUN(ieee_write_byte,(abfd, byte),
43 bfd *abfd AND
44 bfd_byte byte)
87f86b4e 45{
d0ec7a8e 46 bfd_write((PTR)&byte, 1, 1, abfd);
87f86b4e
DHW
47}
48
49
b2c91bd9
SC
50static void
51DEFUN(ieee_write_twobyte,(abfd, twobyte),
52 bfd *abfd AND
53 int twobyte)
54{
55 bfd_byte b[2];
56 b[1] = twobyte & 0xff;
57 b[0] = twobyte >> 8;
58 bfd_write((PTR)&b[0], 1, 2, abfd);
59}
60
61
62
87f86b4e 63static void
301dfc71
SC
64DEFUN(ieee_write_2bytes,(abfd, bytes),
65 bfd *abfd AND
66 int bytes)
87f86b4e
DHW
67{
68 bfd_byte buffer[2];
69 buffer[0] = bytes >> 8;
70 buffer[1] = bytes & 0xff;
71
d0ec7a8e 72 bfd_write((PTR)buffer, 1, 2, abfd);
87f86b4e
DHW
73}
74
75static void
301dfc71
SC
76DEFUN(ieee_write_int,(abfd, value),
77 bfd *abfd AND
78 bfd_vma value)
87f86b4e 79{
b2c91bd9 80 if (((unsigned)value) <= 127) {
71858486 81 ieee_write_byte(abfd, (bfd_byte)value);
87f86b4e
DHW
82 }
83 else {
84 unsigned int length;
85 /* How many significant bytes ? */
86 /* FIXME FOR LONGER INTS */
87 if (value & 0xff000000) {
88 length = 4;
89 }
90 else if (value & 0x00ff0000) {
91 length = 3;
92 }
93 else if (value & 0x0000ff00) {
94 length = 2;
95 }
96 else length = 1;
97
71858486
JG
98 ieee_write_byte(abfd,
99 (bfd_byte)((int)ieee_number_repeat_start_enum + length));
87f86b4e
DHW
100 switch (length) {
101 case 4:
71858486 102 ieee_write_byte(abfd, (bfd_byte)(value >> 24));
87f86b4e 103 case 3:
71858486 104 ieee_write_byte(abfd, (bfd_byte)(value >> 16));
87f86b4e 105 case 2:
71858486 106 ieee_write_byte(abfd, (bfd_byte)(value >> 8));
87f86b4e 107 case 1:
71858486 108 ieee_write_byte(abfd, (bfd_byte)(value));
87f86b4e
DHW
109 }
110 }
111}
112
113static void
301dfc71
SC
114DEFUN(ieee_write_id,(abfd, id),
115 bfd *abfd AND
116 CONST char *id)
87f86b4e
DHW
117{
118 size_t length = strlen(id);
119 if (length >= 0 && length <= 127) {
71858486 120 ieee_write_byte(abfd, (bfd_byte)length);
87f86b4e
DHW
121 }
122 else if (length < 255) {
123 ieee_write_byte(abfd, ieee_extension_length_1_enum);
71858486 124 ieee_write_byte(abfd, (bfd_byte)length);
87f86b4e
DHW
125 }
126 else if (length < 65535) {
127 ieee_write_byte(abfd, ieee_extension_length_2_enum);
71858486
JG
128 ieee_write_byte(abfd, (bfd_byte)(length >> 8));
129 ieee_write_byte(abfd, (bfd_byte)(length & 0xff));
87f86b4e
DHW
130 }
131 else {
132 BFD_FAIL();
133 }
d0ec7a8e 134 bfd_write((PTR)id, 1, length, abfd);
87f86b4e
DHW
135}
136/***************************************************************************
137Functions for reading from ieee files in the strange way that the
138standard requires:
139*/
87f86b4e 140
d0ec7a8e 141
6f715d66
SC
142#define this_byte(ieee) *((ieee)->input_p)
143#define next_byte(ieee) ((ieee)->input_p++)
144#define this_byte_and_next(ieee) (*((ieee)->input_p++))
87f86b4e
DHW
145
146
301dfc71 147static unsigned short
d0ec7a8e 148DEFUN(read_2bytes,(ieee),
6f715d66 149 common_header_type *ieee)
87f86b4e 150{
d0ec7a8e
SC
151 unsigned char c1 = this_byte_and_next(ieee);
152 unsigned char c2 = this_byte_and_next(ieee);
87f86b4e
DHW
153 return (c1<<8 ) | c2;
154
155}
156
157static void
d0ec7a8e 158DEFUN(bfd_get_string,(ieee, string, length),
6f715d66 159 common_header_type *ieee AND
301dfc71
SC
160 char *string AND
161 size_t length)
87f86b4e
DHW
162{
163 size_t i;
164 for (i= 0; i < length; i++) {
d0ec7a8e 165 string[i] = this_byte_and_next(ieee);
87f86b4e
DHW
166 }
167}
168
301dfc71 169static char *
d0ec7a8e 170DEFUN(read_id,(ieee),
6f715d66 171 common_header_type *ieee)
87f86b4e
DHW
172{
173 size_t length;
174 char *string;
d0ec7a8e 175 length = this_byte_and_next(ieee);
87f86b4e
DHW
176 if (length >= 0x00 && length <= 0x7f) {
177 /* Simple string of length 0 to 127 */
178 }
179 else if (length == 0xde) {
180 /* Length is next byte, allowing 0..255 */
d0ec7a8e 181 length = this_byte_and_next(ieee);
87f86b4e
DHW
182 }
183 else if (length == 0xdf) {
184 /* Length is next two bytes, allowing 0..65535 */
d0ec7a8e
SC
185 length = this_byte_and_next(ieee) ;
186 length = (length * 256) + this_byte_and_next(ieee);
87f86b4e
DHW
187 }
188 /* Buy memory and read string */
d0ec7a8e
SC
189 string = bfd_alloc(ieee->abfd, length+1);
190 bfd_get_string(ieee, string, length);
87f86b4e
DHW
191 string[length] = 0;
192 return string;
193}
194
195static void
69e0d34d 196DEFUN(ieee_write_expression,(abfd, value, symbol, pcrel, index),
301dfc71
SC
197 bfd*abfd AND
198 bfd_vma value AND
d0ec7a8e
SC
199 asymbol *symbol AND
200 boolean pcrel AND
b2c91bd9 201 unsigned int index)
87f86b4e 202{
69e0d34d 203 unsigned int term_count = 0;
b2c91bd9 204
69e0d34d
SC
205 if (value != 0)
206 {
207 ieee_write_int(abfd, value);
208 term_count++;
87f86b4e 209 }
69e0d34d
SC
210
211
87f86b4e 212
8feff717 213 if (bfd_is_com_section (symbol->section)
69e0d34d
SC
214 || symbol->section == &bfd_und_section)
215 {
216 /* Def of a common symbol */
217 ieee_write_byte(abfd, ieee_variable_X_enum);
218 ieee_write_int(abfd, symbol->value);
219 term_count++;
220 }
221 else if (symbol->section != &bfd_abs_section)
222 {
223 /* Ref to defined symbol - */
224
225 ieee_write_byte(abfd, ieee_variable_R_enum);
71858486
JG
226 ieee_write_byte(abfd,
227 (bfd_byte) (symbol->section->index + IEEE_SECTION_NUMBER_BASE));
69e0d34d
SC
228 term_count++;
229 if (symbol->flags & BSF_GLOBAL)
230 {
87f86b4e
DHW
231 ieee_write_byte(abfd, ieee_variable_I_enum);
232 ieee_write_int(abfd, symbol->value);
69e0d34d 233 term_count++;
87f86b4e 234 }
69e0d34d
SC
235 else if (symbol->flags & ( BSF_LOCAL | BSF_SECTION_SYM))
236 {
301dfc71
SC
237 /* This is a reference to a defined local symbol,
238 We can easily do a local as a section+offset */
69e0d34d 239 ieee_write_byte(abfd, ieee_variable_R_enum); /* or L */
71858486
JG
240 ieee_write_byte(abfd,
241 (bfd_byte)(symbol->section->index + IEEE_SECTION_NUMBER_BASE));
301dfc71 242 ieee_write_int(abfd, symbol->value);
69e0d34d 243 term_count++;
301dfc71 244
87f86b4e 245 }
69e0d34d
SC
246 else {
247 BFD_FAIL();
248 }
249
87f86b4e
DHW
250 }
251
69e0d34d
SC
252
253
d0ec7a8e 254 if(pcrel) {
69e0d34d
SC
255 /* subtract the pc from here by asking for PC of this section*/
256 ieee_write_byte(abfd, ieee_variable_P_enum);
71858486 257 ieee_write_byte(abfd, (bfd_byte)(index+IEEE_SECTION_NUMBER_BASE));
69e0d34d
SC
258 ieee_write_byte(abfd, ieee_function_minus_enum);
259 }
260
261 if (term_count == 1)
262 {
263 ieee_write_byte(abfd,0);
d0ec7a8e 264 }
69e0d34d
SC
265 else {
266 while (term_count > 1) {
267 ieee_write_byte(abfd, ieee_function_plus_enum);
268 term_count--;
269 }
d0ec7a8e 270
b2c91bd9 271 }
87f86b4e
DHW
272
273}
274
275
276
277
278
279
280
281
87f86b4e
DHW
282/*****************************************************************************/
283
284/*
285writes any integer into the buffer supplied and always takes 5 bytes
286*/
287static void
301dfc71
SC
288DEFUN(ieee_write_int5,(buffer, value),
289 bfd_byte*buffer AND
290 bfd_vma value )
87f86b4e 291{
b2c91bd9 292 buffer[0] = (bfd_byte)ieee_number_repeat_4_enum;
87f86b4e
DHW
293 buffer[1] = (value >> 24 ) & 0xff;
294 buffer[2] = (value >> 16 ) & 0xff;
295 buffer[3] = (value >> 8 ) & 0xff;
301dfc71
SC
296 buffer[4] = (value >> 0 ) & 0xff;
297}
298static void
299DEFUN(ieee_write_int5_out, (abfd, value),
300 bfd *abfd AND
301 bfd_vma value)
302{
d0ec7a8e 303 bfd_byte b[5];
301dfc71 304 ieee_write_int5(b, value);
d0ec7a8e 305 bfd_write((PTR)b,1,5,abfd);
87f86b4e 306}
87f86b4e
DHW
307
308
309static boolean
d0ec7a8e 310DEFUN(parse_int,(ieee, value_ptr),
6f715d66 311 common_header_type *ieee AND
301dfc71 312 bfd_vma *value_ptr)
87f86b4e 313{
d0ec7a8e 314 int value = this_byte(ieee);
87f86b4e
DHW
315 int result;
316 if (value >= 0 && value <= 127) {
317 *value_ptr = value;
d0ec7a8e 318 next_byte(ieee);
87f86b4e
DHW
319 return true;
320 }
321 else if (value >= 0x80 && value <= 0x88) {
322 unsigned int count = value & 0xf;
323 result = 0;
d0ec7a8e 324 next_byte(ieee);
87f86b4e 325 while (count) {
d0ec7a8e 326 result =(result << 8) | this_byte_and_next(ieee);
87f86b4e
DHW
327 count--;
328 }
329 *value_ptr = result;
330 return true;
331 }
332 return false;
333}
301dfc71 334static int
d0ec7a8e 335DEFUN(parse_i,(ieee, ok),
6f715d66 336 common_header_type *ieee AND
301dfc71 337 boolean *ok)
87f86b4e
DHW
338{
339 bfd_vma x;
d0ec7a8e 340 *ok = parse_int(ieee, &x);
87f86b4e
DHW
341 return x;
342}
343
301dfc71 344static bfd_vma
d0ec7a8e 345DEFUN(must_parse_int,(ieee),
6f715d66 346 common_header_type *ieee)
87f86b4e
DHW
347{
348 bfd_vma result;
d0ec7a8e 349 BFD_ASSERT(parse_int(ieee, &result) == true);
87f86b4e
DHW
350 return result;
351}
352
353typedef struct
354{
355 bfd_vma value;
356 asection *section;
357 ieee_symbol_index_type symbol;
358} ieee_value_type;
359
360
361static
362reloc_howto_type abs32_howto
b2c91bd9 363 = HOWTO(1,0,2,32,false,0,false,true,0,"abs32",true,0xffffffff, 0xffffffff,false);
87f86b4e
DHW
364static
365reloc_howto_type abs16_howto
b2c91bd9
SC
366 = HOWTO(1,0,1,16,false,0,false,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false);
367
368static
369reloc_howto_type abs8_howto
370 = HOWTO(1,0,0,8,false,0,false,true,0,"abs8",true,0x000000ff, 0x000000ff,false);
d0ec7a8e
SC
371
372static
373reloc_howto_type rel32_howto
9465d03e
SC
374 = HOWTO(1,0,2,32,true,0,false,true,0,"rel32",true,0xffffffff,
375 0xffffffff,false);
376
d0ec7a8e
SC
377static
378reloc_howto_type rel16_howto
9465d03e 379 = HOWTO(1,0,1,16,true,0,false,true,0,"rel16",true,0x0000ffff, 0x0000ffff,false);
b2c91bd9
SC
380
381static
382reloc_howto_type rel8_howto
9465d03e 383 = HOWTO(1,0,0,8,true,0,false,true,0,"rel8",true,0x000000ff, 0x000000ff,false);
b2c91bd9 384
87f86b4e
DHW
385
386static ieee_symbol_index_type NOSYMBOL = { 0, 0};
387
388
301dfc71 389static void
9465d03e 390DEFUN(parse_expression,(ieee, value, symbol, pcrel, extra, section),
d0ec7a8e 391 ieee_data_type *ieee AND
301dfc71 392 bfd_vma *value AND
301dfc71
SC
393 ieee_symbol_index_type *symbol AND
394 boolean *pcrel AND
9465d03e
SC
395 unsigned int *extra AND
396 asection **section)
d0ec7a8e 397
87f86b4e
DHW
398{
399#define POS sp[1]
400#define TOS sp[0]
401#define NOS sp[-1]
402#define INC sp++;
403#define DEC sp--;
69e0d34d 404
e98e6ec1 405
87f86b4e
DHW
406 boolean loop = true;
407 ieee_value_type stack[10];
408
409 /* The stack pointer always points to the next unused location */
410#define PUSH(x,y,z) TOS.symbol=x;TOS.section=y;TOS.value=z;INC;
411#define POP(x,y,z) DEC;x=TOS.symbol;y=TOS.section;z=TOS.value;
412 ieee_value_type *sp = stack;
413
414 while (loop) {
6f715d66 415 switch (this_byte(&(ieee->h)))
87f86b4e 416 {
d0ec7a8e
SC
417 case ieee_variable_P_enum:
418 /* P variable, current program counter for section n */
419 {
420 int section_n ;
6f715d66 421 next_byte(&(ieee->h));
d0ec7a8e 422 *pcrel = true;
6f715d66 423 section_n = must_parse_int(&(ieee->h));
69e0d34d 424 PUSH(NOSYMBOL, &bfd_abs_section,
d0ec7a8e
SC
425 TOS.value = ieee->section_table[section_n]->vma +
426 ieee_per_section(ieee->section_table[section_n])->pc);
427 break;
428 }
429 case ieee_variable_L_enum:
430 /* L variable address of section N */
6f715d66
SC
431 next_byte(&(ieee->h));
432 PUSH(NOSYMBOL,ieee->section_table[must_parse_int(&(ieee->h))],0);
d0ec7a8e
SC
433 break;
434 case ieee_variable_R_enum:
435 /* R variable, logical address of section module */
436 /* FIXME, this should be different to L */
6f715d66
SC
437 next_byte(&(ieee->h));
438 PUSH(NOSYMBOL,ieee->section_table[must_parse_int(&(ieee->h))],0);
d0ec7a8e
SC
439 break;
440 case ieee_variable_S_enum:
441 /* S variable, size in MAUS of section module */
6f715d66 442 next_byte(&(ieee->h));
d0ec7a8e
SC
443 PUSH(NOSYMBOL,
444 0,
69e0d34d 445 ieee->section_table[must_parse_int(&(ieee->h))]->_raw_size);
87f86b4e 446 break;
b2c91bd9 447 case ieee_variable_I_enum:
d0ec7a8e
SC
448 case ieee_variable_X_enum:
449 /* Push the address of external variable n */
450 {
451 ieee_symbol_index_type sy;
6f715d66
SC
452 next_byte(&(ieee->h));
453 sy.index = (int)(must_parse_int(&(ieee->h))) ;
d0ec7a8e 454 sy.letter = 'X';
87f86b4e 455
69e0d34d 456 PUSH(sy, &bfd_und_section, 0);
d0ec7a8e
SC
457 }
458 break;
459 case ieee_function_minus_enum:
87f86b4e 460 {
d0ec7a8e
SC
461 bfd_vma value1, value2;
462 asection *section1, *section_dummy;
463 ieee_symbol_index_type sy;
6f715d66 464 next_byte(&(ieee->h));
d0ec7a8e
SC
465
466 POP(sy, section1, value1);
467 POP(sy, section_dummy, value2);
b2c91bd9 468 PUSH(sy, section1 ? section1 : section_dummy, value1-value2);
87f86b4e 469 }
d0ec7a8e
SC
470 break;
471 case ieee_function_plus_enum:
472 {
473 bfd_vma value1, value2;
474 asection *section1;
475 asection *section2;
476 ieee_symbol_index_type sy1;
477 ieee_symbol_index_type sy2;
6f715d66 478 next_byte(&(ieee->h));
d0ec7a8e
SC
479
480 POP(sy1, section1, value1);
481 POP(sy2, section2, value2);
9465d03e 482 PUSH(sy1.letter ? sy1 : sy2, section1!=&bfd_abs_section ? section1: section2, value1+value2);
87f86b4e 483 }
d0ec7a8e
SC
484 break;
485 default:
486 {
487 bfd_vma va;
6f715d66
SC
488 BFD_ASSERT(this_byte(&(ieee->h)) < (int)ieee_variable_A_enum
489 || this_byte(&(ieee->h)) > (int)ieee_variable_Z_enum);
490 if (parse_int(&(ieee->h), &va))
d0ec7a8e 491 {
69e0d34d 492 PUSH(NOSYMBOL, &bfd_abs_section, va);
d0ec7a8e
SC
493 }
494 else {
495 /*
496 Thats all that we can understand. As far as I can see
497 there is a bug in the Microtec IEEE output which I'm
498 using to scan, whereby the comma operator is ommited
499 sometimes in an expression, giving expressions with too
500 many terms. We can tell if that's the case by ensuring
501 that sp == stack here. If not, then we've pushed
502 something too far, so we keep adding
503 */
504
505 while (sp != stack+1) {
506 asection *section1;
507 ieee_symbol_index_type sy1;
508 POP(sy1, section1, *extra);
509 }
69e0d34d
SC
510 {
511 asection *dummy;
9465d03e 512
69e0d34d 513 POP(*symbol, dummy, *value);
9465d03e 514 if (section) *section = dummy;
69e0d34d
SC
515 }
516
d0ec7a8e
SC
517 loop = false;
518 }
87f86b4e 519 }
87f86b4e 520
d0ec7a8e 521 }
87f86b4e
DHW
522 }
523}
524
301dfc71
SC
525
526
527#define ieee_seek(abfd, offset) \
e98e6ec1 528 IEEE_DATA(abfd)->h.input_p = IEEE_DATA(abfd)->h.first_byte + offset
6f715d66 529
e98e6ec1 530#define ieee_pos(abfd) IEEE_DATA(abfd)->h.input_p -IEEE_DATA(abfd)->h.first_byte
87f86b4e 531
b2c91bd9 532static unsigned int last_index;
aff6e0b4 533static char last_type; /* is the index for an X or a D */
b2c91bd9
SC
534static ieee_symbol_type *
535DEFUN(get_symbol,(abfd,
536 ieee,
537 last_symbol,
538 symbol_count,
aff6e0b4
SC
539 pptr,
540 max_index,
541 this_type
b2c91bd9
SC
542 ),
543 bfd *abfd AND
544 ieee_data_type *ieee AND
545 ieee_symbol_type *last_symbol AND
546 unsigned int *symbol_count AND
547 ieee_symbol_type *** pptr AND
aff6e0b4
SC
548 unsigned int *max_index AND
549 char this_type
b2c91bd9
SC
550 )
551{
552 /* Need a new symbol */
553 unsigned int new_index = must_parse_int(&(ieee->h));
aff6e0b4 554 if (new_index != last_index || this_type != last_type) {
b2c91bd9
SC
555 ieee_symbol_type * new_symbol = (ieee_symbol_type *)bfd_alloc(ieee->h.abfd,
556 sizeof(ieee_symbol_type));
557
558 new_symbol->index = new_index;
559 last_index = new_index;
560 ( *symbol_count)++;
561 ** pptr= new_symbol;
562 *pptr = &new_symbol->next;
563 if (new_index > *max_index) {
564 *max_index = new_index;
565 }
aff6e0b4 566 last_type = this_type;
b2c91bd9
SC
567 return new_symbol;
568 }
569 return last_symbol;
570}
87f86b4e 571static void
301dfc71
SC
572DEFUN(ieee_slurp_external_symbols,(abfd),
573 bfd *abfd)
87f86b4e 574{
e98e6ec1 575 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e
DHW
576 file_ptr offset = ieee->w.r.external_part;
577
b2c91bd9 578
87f86b4e
DHW
579 ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols;
580 ieee_symbol_type **prev_reference_ptr = &ieee->external_reference;
b2c91bd9 581 ieee_symbol_type *symbol = (ieee_symbol_type *)NULL;
87f86b4e
DHW
582 unsigned int symbol_count = 0;
583 boolean loop = true;
b2c91bd9 584 last_index = 0xffffff;
87f86b4e
DHW
585 ieee->symbol_table_full = true;
586
301dfc71 587 ieee_seek(abfd, offset );
87f86b4e
DHW
588
589 while (loop) {
6f715d66 590 switch (this_byte(&(ieee->h))) {
b2c91bd9
SC
591 case ieee_nn_record:
592 next_byte(&(ieee->h));
aff6e0b4 593
b2c91bd9
SC
594 symbol = get_symbol(abfd, ieee, symbol, &symbol_count,
595 &prev_symbols_ptr,
aff6e0b4
SC
596 &ieee->external_symbol_max_index,'D');
597
b2c91bd9
SC
598
599 symbol->symbol.the_bfd = abfd;
600 symbol->symbol.name = read_id(&(ieee->h));
601 symbol->symbol.udata = (PTR)NULL;
602 symbol->symbol.flags = BSF_NO_FLAGS;
603
604
605 break;
87f86b4e 606 case ieee_external_symbol_enum:
6f715d66 607 next_byte(&(ieee->h));
b2c91bd9
SC
608
609 symbol = get_symbol(abfd, ieee, symbol, &symbol_count,
610 &prev_symbols_ptr,
aff6e0b4 611 &ieee->external_symbol_max_index,'D');
b2c91bd9 612
87f86b4e 613
87f86b4e 614 BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index);
b2c91bd9 615
87f86b4e 616 symbol->symbol.the_bfd = abfd;
6f715d66 617 symbol->symbol.name = read_id(&(ieee->h));
d0ec7a8e 618 symbol->symbol.udata = (PTR)NULL;
87f86b4e
DHW
619 symbol->symbol.flags = BSF_NO_FLAGS;
620 break;
621 case ieee_attribute_record_enum >> 8:
b2c91bd9
SC
622 {
623 unsigned int symbol_name_index;
624 unsigned int symbol_type_index;
625 unsigned int symbol_attribute_def;
626 bfd_vma value;
627 next_byte(&(ieee->h)); /* Skip prefix */
628 next_byte(&(ieee->h));
629 symbol_name_index = must_parse_int(&(ieee->h));
630 symbol_type_index = must_parse_int(&(ieee->h));
631 symbol_attribute_def = must_parse_int(&(ieee->h));
632 switch (symbol_attribute_def) {
633 case 63:
634 /* Module misc; followed by two fields which describe the
635 current module block. The first fired is the type id
636 number, the second is the number of asn records
637 associated with the directive */
638 parse_int(&(ieee->h),&value);
639 parse_int(&(ieee->h),&value);
640 break;
87f86b4e 641
b2c91bd9
SC
642 default:
643 parse_int(&(ieee->h),&value);
644 break;
645 }
646 }
87f86b4e
DHW
647 break;
648 case ieee_value_record_enum >> 8:
b2c91bd9
SC
649 {
650 unsigned int symbol_name_index;
651 ieee_symbol_index_type symbol_ignore;
652 boolean pcrel_ignore;
653 unsigned int extra;
654 next_byte(&(ieee->h));
655 next_byte(&(ieee->h));
656
657 symbol_name_index = must_parse_int(&(ieee->h));
658 parse_expression(ieee,
659 &symbol->symbol.value,
b2c91bd9
SC
660 &symbol_ignore,
661 &pcrel_ignore,
9465d03e
SC
662 &extra,
663 &symbol->symbol.section);
e98e6ec1 664
b2c91bd9 665 symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
e98e6ec1 666
87f86b4e 667 }
87f86b4e
DHW
668 break;
669 case ieee_weak_external_reference_enum:
b2c91bd9
SC
670 { bfd_vma size;
671 bfd_vma value ;
672 next_byte(&(ieee->h));
673 /* Throw away the external reference index */
674 (void)must_parse_int(&(ieee->h));
675 /* Fetch the default size if not resolved */
676 size = must_parse_int(&(ieee->h));
677 /* Fetch the defautlt value if available */
678 if ( parse_int(&(ieee->h), &value) == false) {
679 value = 0;
680 }
681 /* This turns into a common */
e98e6ec1 682 symbol->symbol.section = &bfd_com_section;
b2c91bd9 683 symbol->symbol.value = size;
87f86b4e 684 }
87f86b4e
DHW
685 break;
686
687 case ieee_external_reference_enum:
6f715d66 688 next_byte(&(ieee->h));
b2c91bd9
SC
689
690 symbol = get_symbol(abfd, ieee, symbol, &symbol_count,
691 &prev_reference_ptr,
aff6e0b4 692 &ieee->external_reference_max_index,'X');
b2c91bd9
SC
693
694
87f86b4e 695 symbol->symbol.the_bfd = abfd;
6f715d66 696 symbol->symbol.name = read_id(&(ieee->h));
d0ec7a8e 697 symbol->symbol.udata = (PTR)NULL;
e98e6ec1 698 symbol->symbol.section = &bfd_und_section;
87f86b4e 699 symbol->symbol.value = (bfd_vma)0;
e98e6ec1 700 symbol->symbol.flags = 0;
b2c91bd9 701
87f86b4e
DHW
702 BFD_ASSERT (symbol->index >= ieee->external_reference_min_index);
703 break;
704
705 default:
706 loop = false;
707 }
708 }
709
710 if (ieee->external_symbol_max_index != 0) {
711 ieee->external_symbol_count =
712 ieee->external_symbol_max_index -
713 ieee->external_symbol_min_index + 1 ;
714 }
715 else {
716 ieee->external_symbol_count = 0;
717 }
718
719
720 if(ieee->external_reference_max_index != 0) {
721 ieee->external_reference_count =
722 ieee->external_reference_max_index -
723 ieee->external_reference_min_index + 1;
724 }
725 else {
726 ieee->external_reference_count = 0;
727 }
728
729 abfd->symcount =
730 ieee->external_reference_count + ieee->external_symbol_count;
731
732 if (symbol_count != abfd->symcount) {
733 /* There are gaps in the table -- */
734 ieee->symbol_table_full = false;
735 }
b2c91bd9
SC
736
737
87f86b4e
DHW
738 *prev_symbols_ptr = (ieee_symbol_type *)NULL;
739 *prev_reference_ptr = (ieee_symbol_type *)NULL;
740}
741
742static void
301dfc71
SC
743DEFUN(ieee_slurp_symbol_table,(abfd),
744 bfd *abfd)
87f86b4e 745{
e98e6ec1 746 if (IEEE_DATA(abfd)->read_symbols == false) {
87f86b4e 747 ieee_slurp_external_symbols(abfd);
e98e6ec1 748 IEEE_DATA(abfd)->read_symbols= true;
87f86b4e
DHW
749 }
750}
751
d0ec7a8e 752unsigned int
301dfc71
SC
753DEFUN(ieee_get_symtab_upper_bound,(abfd),
754 bfd *abfd)
87f86b4e
DHW
755{
756 ieee_slurp_symbol_table (abfd);
757
758 return (abfd->symcount != 0) ?
759 (abfd->symcount+1) * (sizeof (ieee_symbol_type *)) : 0;
760}
761
762/*
763Move from our internal lists to the canon table, and insert in
764symbol index order
765*/
766
767extern bfd_target ieee_vec;
768unsigned int
301dfc71
SC
769DEFUN(ieee_get_symtab,(abfd, location),
770 bfd *abfd AND
771 asymbol **location)
87f86b4e
DHW
772{
773 ieee_symbol_type *symp;
774 static bfd dummy_bfd;
775 static asymbol empty_symbol =
8feff717
ILT
776 /* the_bfd, name, value, attr, section */
777 { &dummy_bfd, " ieee empty", (symvalue)0, BSF_DEBUGGING, &bfd_abs_section};
d0ec7a8e 778
294eaca4
SC
779 if (abfd->symcount)
780{
781 ieee_data_type *ieee = IEEE_DATA(abfd);
782 dummy_bfd.xvec= &ieee_vec;
783 ieee_slurp_symbol_table(abfd);
b2c91bd9 784
294eaca4
SC
785 if (ieee->symbol_table_full == false) {
786 /* Arrgh - there are gaps in the table, run through and fill them */
787 /* up with pointers to a null place */
788 unsigned int i;
789 for (i= 0; i < abfd->symcount; i++) {
790 location[i] = &empty_symbol;
791 }
792 }
b2c91bd9
SC
793
794
294eaca4
SC
795 ieee->external_symbol_base_offset= - ieee->external_symbol_min_index;
796 for (symp = IEEE_DATA(abfd)->external_symbols;
797 symp != (ieee_symbol_type *)NULL;
798 symp = symp->next) {
799 /* Place into table at correct index locations */
800 location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol;
87f86b4e 801
87f86b4e 802 }
87f86b4e 803
294eaca4
SC
804 /* The external refs are indexed in a bit */
805 ieee->external_reference_base_offset =
806 - ieee->external_reference_min_index +ieee->external_symbol_count ;
87f86b4e 807
294eaca4
SC
808 for (symp = IEEE_DATA(abfd)->external_reference;
809 symp != (ieee_symbol_type *)NULL;
810 symp = symp->next) {
811 location[symp->index + ieee->external_reference_base_offset] =
812 &symp->symbol;
87f86b4e 813
294eaca4 814 }
87f86b4e 815
87f86b4e
DHW
816
817
818
294eaca4 819 }
aff6e0b4
SC
820 if (abfd->symcount) {
821 location[abfd->symcount] = (asymbol *)NULL;
822 }
87f86b4e
DHW
823 return abfd->symcount;
824}
b2c91bd9
SC
825static asection *
826DEFUN(get_section_entry,(abfd, ieee,index),
827 bfd *abfd AND
828 ieee_data_type *ieee AND
829 unsigned int index)
830{
831 if (ieee->section_table[index] == (asection *)NULL) {
aff6e0b4
SC
832 char *tmp = bfd_alloc(abfd,11);
833 asection *section;
834 sprintf(tmp," fsec%4d", index);
835 section = bfd_make_section(abfd, tmp);
b2c91bd9
SC
836 ieee->section_table[index] = section;
837 section->flags = SEC_NO_FLAGS;
838 section->target_index = index;
839 ieee->section_table[index] = section;
840 }
841 return ieee->section_table[index];
842}
87f86b4e
DHW
843
844static void
301dfc71
SC
845DEFUN(ieee_slurp_sections,(abfd),
846 bfd *abfd)
87f86b4e 847{
e98e6ec1 848 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e 849 file_ptr offset = ieee->w.r.section_part;
87f86b4e 850 asection *section = (asection *)NULL;
b07d03ba 851 char *name;
87f86b4e
DHW
852
853 if (offset != 0) {
854 bfd_byte section_type[3];
301dfc71 855 ieee_seek(abfd, offset);
87f86b4e 856 while (true) {
6f715d66 857 switch (this_byte(&(ieee->h))) {
87f86b4e 858 case ieee_section_type_enum:
b2c91bd9
SC
859 {
860 unsigned int section_index ;
861 next_byte(&(ieee->h));
862 section_index = must_parse_int(&(ieee->h));
863 /* Fixme to be nice about a silly number of sections */
864 BFD_ASSERT(section_index < NSECTIONS);
865
866 section =get_section_entry(abfd, ieee, section_index);
867
868 section_type[0] = this_byte_and_next(&(ieee->h));
869 switch (section_type[0]) {
870 case 0xC1:
871 /* Normal attributes for absolute sections */
872 section_type[1] = this_byte(&(ieee->h));
873 section->flags = SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
874 switch(section_type[1]) {
71858486 875 case 0xD3: /* AS Absolute section attributes */
b2c91bd9
SC
876 next_byte(&(ieee->h));
877 section_type[2] = this_byte(&(ieee->h));
878 switch (section_type[2])
879 {
880 case 0xD0:
881 /* Normal code */
882 next_byte(&(ieee->h));
883 section->flags |= SEC_LOAD | SEC_CODE;
884 break;
885 case 0xC4:
886 next_byte(&(ieee->h));
887 section->flags |= SEC_LOAD | SEC_DATA;
888 /* Normal data */
889 break;
890 case 0xD2:
891 next_byte(&(ieee->h));
892 /* Normal rom data */
893 section->flags |= SEC_LOAD | SEC_ROM | SEC_DATA;
894 break;
895 default:
896 break;
897 }
898 }
87f86b4e 899 break;
71858486 900 case 0xC3: /* Named relocatable sections (type C) */
b2c91bd9
SC
901 section_type[1] = this_byte(&(ieee->h));
902 section->flags = SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
903 switch (section_type[1]) {
71858486 904 case 0xD0: /* Normal code (CP) */
b2c91bd9
SC
905 next_byte(&(ieee->h));
906 section->flags |= SEC_LOAD | SEC_CODE;
907 break;
71858486 908 case 0xC4: /* Normal data (CD) */
b2c91bd9
SC
909 next_byte(&(ieee->h));
910 section->flags |= SEC_LOAD | SEC_DATA;
b2c91bd9 911 break;
71858486 912 case 0xD2: /* Normal rom data (CR) */
b2c91bd9 913 next_byte(&(ieee->h));
b2c91bd9
SC
914 section->flags |= SEC_LOAD | SEC_ROM | SEC_DATA;
915 break;
916 default:
917 break;
918 }
87f86b4e 919 }
71858486
JG
920
921 /* Read section name, use it if non empty. */
922 name = read_id (&ieee->h);
923 if (name[0])
924 section->name = name;
8feff717 925
71858486
JG
926 /* Skip these fields, which we don't care about */
927 {
928 bfd_vma parent, brother, context;
b2c91bd9
SC
929 parse_int(&(ieee->h), &parent);
930 parse_int(&(ieee->h), &brother);
931 parse_int(&(ieee->h), &context);
71858486 932 }
b2c91bd9 933 }
87f86b4e
DHW
934 break;
935 case ieee_section_alignment_enum:
b2c91bd9
SC
936 {
937 unsigned int section_index;
938 bfd_vma value;
939 asection *section;
940 next_byte(&(ieee->h));
941 section_index = must_parse_int(&ieee->h);
942 section = get_section_entry(abfd, ieee, section_index);
943 if (section_index > ieee->section_count) {
944 ieee->section_count = section_index;
945 }
946 section->alignment_power =
947 bfd_log2(must_parse_int(&ieee->h));
948 (void)parse_int(&(ieee->h), & value);
87f86b4e 949 }
87f86b4e
DHW
950 break;
951 case ieee_e2_first_byte_enum:
b2c91bd9
SC
952 {
953 ieee_record_enum_type t = (ieee_record_enum_type)(read_2bytes(&(ieee->h)));
954
955 switch (t) {
956 case ieee_section_size_enum:
957 section = ieee->section_table[must_parse_int(&(ieee->h))];
e98e6ec1 958 section->_raw_size = must_parse_int(&(ieee->h));
b2c91bd9
SC
959 break;
960 case ieee_physical_region_size_enum:
961 section = ieee->section_table[must_parse_int(&(ieee->h))];
e98e6ec1 962 section->_raw_size = must_parse_int(&(ieee->h));
b2c91bd9
SC
963 break;
964 case ieee_region_base_address_enum:
965 section = ieee->section_table[must_parse_int(&(ieee->h))];
966 section->vma = must_parse_int(&(ieee->h));
967 break;
968 case ieee_mau_size_enum:
969 must_parse_int(&(ieee->h));
970 must_parse_int(&(ieee->h));
971 break;
972 case ieee_m_value_enum:
973 must_parse_int(&(ieee->h));
974 must_parse_int(&(ieee->h));
975 break;
976 case ieee_section_base_address_enum:
977 section = ieee->section_table[must_parse_int(&(ieee->h))];
978 section->vma = must_parse_int(&(ieee->h));
979 break;
980 case ieee_section_offset_enum:
981 (void) must_parse_int(&(ieee->h));
982 (void) must_parse_int(&(ieee->h));
983 break;
984 default:
985 return;
986 }
87f86b4e 987 }
87f86b4e
DHW
988 break;
989 default:
990 return;
991 }
992 }
993 }
994}
995
996/***********************************************************************
997* archive stuff
998*/
999bfd_target *
301dfc71
SC
1000DEFUN(ieee_archive_p,(abfd),
1001 bfd *abfd)
87f86b4e
DHW
1002{
1003 char *library;
1004 boolean loop;
6f715d66 1005
87f86b4e 1006 unsigned int i;
6f715d66 1007uint8e_type buffer[512];
9465d03e 1008 struct obstack ob;
f8e01940 1009 file_ptr buffer_offset = 0;
69e0d34d 1010 ieee_ar_data_type *save = abfd->tdata.ieee_ar_data;
6f715d66 1011 ieee_ar_data_type *ieee ;
e98e6ec1
SC
1012 abfd->tdata.ieee_ar_data = (ieee_ar_data_type *)bfd_alloc(abfd, sizeof(ieee_ar_data_type));
1013 ieee= IEEE_AR_DATA(abfd);
6f715d66
SC
1014
1015
9465d03e 1016
6f715d66 1017 bfd_read((PTR)buffer, 1, sizeof(buffer), abfd);
d0ec7a8e 1018
6f715d66
SC
1019 ieee->h.first_byte = buffer;
1020 ieee->h.input_p = buffer;
d0ec7a8e 1021
6f715d66
SC
1022 ieee->h.abfd = abfd;
1023
69e0d34d
SC
1024 if (this_byte(&(ieee->h)) != Module_Beginning) {
1025 abfd->tdata.ieee_ar_data = save;
1026 return (bfd_target*)NULL;
1027 }
1028
6f715d66
SC
1029
1030 next_byte(&(ieee->h));
1031 library= read_id(&(ieee->h));
87f86b4e 1032 if (strcmp(library , "LIBRARY") != 0) {
295cce3c 1033 bfd_release(abfd, ieee);
e98e6ec1 1034 abfd->tdata.ieee_ar_data = save;
87f86b4e
DHW
1035 return (bfd_target *)NULL;
1036 }
1037 /* Throw away the filename */
aff6e0b4 1038 read_id(&(ieee->h));
87f86b4e
DHW
1039 /* This must be an IEEE archive, so we'll buy some space to do
1040 things */
9465d03e
SC
1041
1042 obstack_begin(&ob, 128);
1043
1044
6f715d66
SC
1045 ieee->element_count = 0;
1046 ieee->element_index = 0;
87f86b4e 1047
6f715d66
SC
1048 next_byte(&(ieee->h)); /* Drop the ad part */
1049 must_parse_int(&(ieee->h)); /* And the two dummy numbers */
1050 must_parse_int(&(ieee->h));
87f86b4e
DHW
1051
1052 loop = true;
1053 /* Read the index of the BB table */
1054 while (loop) {
1055 ieee_ar_obstack_type t;
6f715d66 1056 int rec =read_2bytes(&(ieee->h));
b2c91bd9 1057 if (rec ==(int)ieee_assign_value_to_variable_enum) {
6f715d66
SC
1058 int record_number = must_parse_int(&(ieee->h));
1059 t.file_offset = must_parse_int(&(ieee->h));
87f86b4e 1060 t.abfd = (bfd *)NULL;
6f715d66 1061 ieee->element_count++;
9465d03e
SC
1062
1063 obstack_grow(&ob, (PTR)&t, sizeof(t));
6f715d66
SC
1064
1065 /* Make sure that we don't go over the end of the buffer */
1066
1067 if (ieee_pos(abfd) > sizeof(buffer)/2) {
1068 /* Past half way, reseek and reprime */
1069 buffer_offset += ieee_pos(abfd);
1070 bfd_seek(abfd, buffer_offset, SEEK_SET);
b2c91bd9 1071 bfd_read((PTR)buffer, 1, sizeof(buffer), abfd);
6f715d66
SC
1072 ieee->h.first_byte = buffer;
1073 ieee->h.input_p = buffer;
1074 }
87f86b4e
DHW
1075 }
1076 else loop = false;
1077 }
6f715d66 1078
294eaca4 1079 ieee->elements = (ieee_ar_obstack_type *)obstack_finish(&ob);
87f86b4e
DHW
1080
1081 /* Now scan the area again, and replace BB offsets with file */
1082 /* offsets */
1083
1084
6f715d66
SC
1085 for (i = 2; i < ieee->element_count; i++) {
1086 bfd_seek(abfd, ieee->elements[i].file_offset, SEEK_SET);
b2c91bd9 1087 bfd_read((PTR)buffer, 1, sizeof(buffer), abfd);
6f715d66
SC
1088 ieee->h.first_byte = buffer;
1089 ieee->h.input_p = buffer;
1090
1091 next_byte(&(ieee->h)); /* Drop F8 */
1092 next_byte(&(ieee->h)); /* Drop 14 */
1093 must_parse_int(&(ieee->h)); /* Drop size of block */
1094 if (must_parse_int(&(ieee->h)) != 0) {
87f86b4e 1095 /* This object has been deleted */
6f715d66 1096 ieee->elements[i].file_offset = 0;
87f86b4e
DHW
1097 }
1098 else {
6f715d66 1099 ieee->elements[i].file_offset = must_parse_int(&(ieee->h));
87f86b4e
DHW
1100 }
1101 }
1102
aff6e0b4 1103/* abfd->has_armap = ;*/
87f86b4e 1104 return abfd->xvec;
6f715d66 1105
87f86b4e
DHW
1106}
1107
301dfc71
SC
1108static boolean
1109DEFUN(ieee_mkobject,(abfd),
1110 bfd *abfd)
6f715d66 1111{
e98e6ec1 1112abfd->tdata.ieee_data = (ieee_data_type *)bfd_zalloc(abfd,sizeof(ieee_data_type));
6f715d66
SC
1113
1114
301dfc71
SC
1115 return true;
1116}
1117
87f86b4e 1118bfd_target *
301dfc71
SC
1119DEFUN(ieee_object_p,(abfd),
1120 bfd *abfd)
87f86b4e
DHW
1121{
1122 char *processor;
1123 unsigned int part;
301dfc71 1124 ieee_data_type *ieee;
d0ec7a8e 1125 uint8e_type buffer[300];
e98e6ec1
SC
1126 ieee_data_type *save = IEEE_DATA(abfd);
1127 abfd->tdata.ieee_data = 0;
301dfc71 1128 ieee_mkobject(abfd);
301dfc71 1129
9465d03e 1130 ieee = IEEE_DATA(abfd);
f8e01940 1131 bfd_seek(abfd, (file_ptr) 0, SEEK_SET);
301dfc71 1132 /* Read the first few bytes in to see if it makes sense */
d0ec7a8e 1133 bfd_read((PTR)buffer, 1, sizeof(buffer), abfd);
301dfc71 1134
6f715d66
SC
1135 ieee->h.input_p = buffer;
1136 if (this_byte_and_next(&(ieee->h)) != Module_Beginning) goto fail;
301dfc71
SC
1137
1138 ieee->read_symbols= false;
1139 ieee->read_data= false;
1140 ieee->section_count = 0;
1141 ieee->external_symbol_max_index = 0;
1142 ieee->external_symbol_min_index = IEEE_PUBLIC_BASE;
1143 ieee->external_reference_min_index =IEEE_REFERENCE_BASE;
1144 ieee->external_reference_max_index = 0;
6f715d66 1145 ieee->h.abfd = abfd;
301dfc71
SC
1146 memset((PTR)ieee->section_table, 0, sizeof(ieee->section_table));
1147
6f715d66 1148 processor = ieee->mb.processor = read_id(&(ieee->h));
301dfc71 1149 if (strcmp(processor,"LIBRARY") == 0) goto fail;
6f715d66 1150 ieee->mb.module_name = read_id(&(ieee->h));
b645b632 1151 if (abfd->filename == (CONST char *)NULL) {
301dfc71 1152 abfd->filename = ieee->mb.module_name;
87f86b4e 1153 }
b2c91bd9
SC
1154 /* Determine the architecture and machine type of the object file.
1155 */
1156 {
01dd1b2b 1157 bfd_arch_info_type *arch = bfd_scan_arch(processor);
b2c91bd9
SC
1158 if (arch == 0) goto fail;
1159 abfd->arch_info = arch;
1160 }
87f86b4e 1161
b2c91bd9 1162 if (this_byte(&(ieee->h)) != (int)ieee_address_descriptor_enum) {
301dfc71 1163 goto fail;
87f86b4e 1164 }
6f715d66 1165 next_byte(&(ieee->h));
87f86b4e 1166
6f715d66 1167 if (parse_int(&(ieee->h), &ieee->ad.number_of_bits_mau) == false) {
301dfc71 1168 goto fail;
87f86b4e 1169 }
6f715d66 1170 if(parse_int(&(ieee->h), &ieee->ad.number_of_maus_in_address) == false) {
301dfc71 1171 goto fail;
87f86b4e
DHW
1172 }
1173
1174 /* If there is a byte order info, take it */
b2c91bd9
SC
1175 if (this_byte(&(ieee->h)) == (int)ieee_variable_L_enum ||
1176 this_byte(&(ieee->h)) == (int)ieee_variable_M_enum)
6f715d66 1177 next_byte(&(ieee->h));
87f86b4e
DHW
1178
1179
1180 for (part = 0; part < N_W_VARIABLES; part++) {
1181 boolean ok;
b2c91bd9 1182 if (read_2bytes(&(ieee->h)) != (int) ieee_assign_value_to_variable_enum) {
301dfc71 1183 goto fail;
87f86b4e 1184 }
6f715d66 1185 if (this_byte_and_next(&(ieee->h)) != part) {
301dfc71 1186 goto fail;
87f86b4e
DHW
1187 }
1188
6f715d66 1189 ieee->w.offset[part] = parse_i(&(ieee->h), &ok);
87f86b4e 1190 if (ok==false) {
301dfc71 1191 goto fail;
87f86b4e
DHW
1192 }
1193
1194 }
1195 abfd->flags = HAS_SYMS;
301dfc71
SC
1196/* By now we know that this is a real IEEE file, we're going to read
1197 the whole thing into memory so that we can run up and down it
1198 quickly. We can work out how big the file is from the trailer
1199 record */
1200
e98e6ec1 1201 IEEE_DATA(abfd)->h.first_byte = (uint8e_type *) bfd_alloc(ieee->h.abfd, ieee->w.r.me_record
301dfc71 1202 + 50);
f8e01940 1203 bfd_seek(abfd, (file_ptr) 0, SEEK_SET);
e98e6ec1 1204 bfd_read((PTR)(IEEE_DATA(abfd)->h.first_byte), 1, ieee->w.r.me_record+50, abfd);
301dfc71 1205
87f86b4e
DHW
1206 ieee_slurp_sections(abfd);
1207 return abfd->xvec;
301dfc71 1208 fail:
d0ec7a8e 1209 (void) bfd_release(abfd, ieee);
e98e6ec1 1210abfd->tdata.ieee_data = save;
301dfc71 1211 return (bfd_target *)NULL;
87f86b4e
DHW
1212}
1213
1214
1215void
2b1d8a50 1216DEFUN(ieee_print_symbol,(ignore_abfd, afile, symbol, how),
301dfc71 1217 bfd *ignore_abfd AND
2b1d8a50 1218 PTR afile AND
301dfc71 1219 asymbol *symbol AND
01dd1b2b 1220 bfd_print_symbol_type how)
87f86b4e 1221{
2b1d8a50
JG
1222 FILE *file = (FILE *)afile;
1223
87f86b4e 1224 switch (how) {
01dd1b2b 1225 case bfd_print_symbol_name:
87f86b4e
DHW
1226 fprintf(file,"%s", symbol->name);
1227 break;
01dd1b2b 1228 case bfd_print_symbol_more:
87f86b4e
DHW
1229#if 0
1230 fprintf(file,"%4x %2x",aout_symbol(symbol)->desc & 0xffff,
1231 aout_symbol(symbol)->other & 0xff);
1232#endif
1233 BFD_FAIL();
1234 break;
b645b632 1235 case bfd_print_symbol_nm:
01dd1b2b 1236 case bfd_print_symbol_all:
301dfc71
SC
1237 {
1238 CONST char *section_name = symbol->section == (asection *)NULL ?
b645b632 1239 (CONST char *)"*abs" : symbol->section->name;
d0ec7a8e
SC
1240 if (symbol->name[0] == ' ') {
1241 fprintf(file,"* empty table entry ");
1242 }
1243 else {
1244 bfd_print_symbol_vandf((PTR)file,symbol);
301dfc71 1245
d0ec7a8e
SC
1246 fprintf(file," %-5s %04x %02x %s",
1247 section_name,
1248 (unsigned) ieee_symbol(symbol)->index,
1249 (unsigned) 0, /*
301dfc71
SC
1250 aout_symbol(symbol)->desc & 0xffff,
1251 aout_symbol(symbol)->other & 0xff,*/
d0ec7a8e
SC
1252 symbol->name);
1253 }
301dfc71 1254 }
87f86b4e
DHW
1255 break;
1256 }
1257}
1258
1259
7ed4093a 1260static void
7564d3d7
SC
1261DEFUN(do_one,(ieee, current_map, location_ptr,s),
1262 ieee_data_type *ieee AND
1263 ieee_per_section_type *current_map AND
1264 uint8e_type *location_ptr AND
1265 asection *s)
1266{
6f715d66 1267 switch (this_byte(&(ieee->h)))
7564d3d7
SC
1268 {
1269 case ieee_load_constant_bytes_enum:
1270 {
1271 unsigned int number_of_maus;
1272 unsigned int i;
6f715d66
SC
1273 next_byte(&(ieee->h));
1274 number_of_maus = must_parse_int(&(ieee->h));
7564d3d7
SC
1275
1276 for (i = 0; i < number_of_maus; i++) {
6f715d66
SC
1277 location_ptr[current_map->pc++]= this_byte(&(ieee->h));
1278 next_byte(&(ieee->h));
7564d3d7
SC
1279 }
1280 }
1281 break;
1282
1283 case ieee_load_with_relocation_enum:
1284 {
1285 boolean loop = true;
6f715d66 1286 next_byte(&(ieee->h));
7564d3d7
SC
1287 while (loop)
1288 {
6f715d66 1289 switch (this_byte(&(ieee->h)))
7564d3d7
SC
1290 {
1291 case ieee_variable_R_enum:
1292
1293 case ieee_function_signed_open_b_enum:
1294 case ieee_function_unsigned_open_b_enum:
1295 case ieee_function_either_open_b_enum:
1296 {
1297 unsigned int extra = 4;
1298 boolean pcrel = false;
69e0d34d 1299asection *section;
7564d3d7 1300 ieee_reloc_type *r =
6f715d66 1301 (ieee_reloc_type *) bfd_alloc(ieee->h.abfd,
7564d3d7
SC
1302 sizeof(ieee_reloc_type));
1303
1304 *(current_map->reloc_tail_ptr) = r;
1305 current_map->reloc_tail_ptr= &r->next;
1306 r->next = (ieee_reloc_type *)NULL;
6f715d66 1307 next_byte(&(ieee->h));
69e0d34d 1308/* abort();*/
aff6e0b4 1309 r->relent.sym_ptr_ptr = 0;
7564d3d7
SC
1310 parse_expression(ieee,
1311 &r->relent.addend,
7564d3d7 1312 &r->symbol,
9465d03e 1313 &pcrel, &extra, &section);
7564d3d7
SC
1314 r->relent.address = current_map->pc;
1315 s->reloc_count++;
69e0d34d
SC
1316if (r->relent.sym_ptr_ptr == 0) {
1317 r->relent.sym_ptr_ptr = section->symbol_ptr_ptr;
1318}
b2c91bd9
SC
1319
1320 if (this_byte(&(ieee->h)) == (int)ieee_comma) {
1321 next_byte(&(ieee->h));
1322 /* Fetch number of bytes to pad */
1323 extra = must_parse_int(&(ieee->h));
1324 };
1325
6f715d66 1326 switch (this_byte(&(ieee->h))) {
7564d3d7 1327 case ieee_function_signed_close_b_enum:
6f715d66 1328 next_byte(&(ieee->h));
7564d3d7
SC
1329 break;
1330 case ieee_function_unsigned_close_b_enum:
6f715d66 1331 next_byte(&(ieee->h));
7564d3d7
SC
1332 break;
1333 case ieee_function_either_close_b_enum:
6f715d66 1334 next_byte(&(ieee->h));
7564d3d7
SC
1335 break;
1336 default:
1337 break;
1338 }
1339 /* Build a relocation entry for this type */
7564d3d7 1340 /* If pc rel then stick -ve pc into instruction
b2c91bd9
SC
1341 and take out of reloc ..
1342
1343 I've changed this. It's all too
1344 complicated. I keep 0 in the
1345 instruction now.
1346 */
7564d3d7
SC
1347
1348 switch (extra)
1349 {
1350 case 0:
1351 case 4:
b2c91bd9 1352
7564d3d7
SC
1353 if (pcrel == true)
1354 {
b2c91bd9 1355#if KEEPMINUSPCININST
6f715d66 1356 bfd_put_32(ieee->h.abfd, -current_map->pc, location_ptr +
7564d3d7
SC
1357 current_map->pc);
1358 r->relent.howto = &rel32_howto;
b2c91bd9
SC
1359 r->relent.addend -=
1360 current_map->pc;
1361#else
1362 bfd_put_32(ieee->h.abfd,0, location_ptr +
1363 current_map->pc);
1364 r->relent.howto = &rel32_howto;
1365#endif
7564d3d7
SC
1366 }
1367 else
1368 {
6f715d66 1369 bfd_put_32(ieee->h.abfd, 0, location_ptr +
7564d3d7
SC
1370 current_map->pc);
1371 r->relent.howto = &abs32_howto;
1372 }
1373 current_map->pc +=4;
1374 break;
1375 case 2:
1376 if (pcrel == true) {
b2c91bd9 1377#if KEEPMINUSPCININST
6f715d66 1378 bfd_put_16(ieee->h.abfd, (int)(-current_map->pc), location_ptr +current_map->pc);
7564d3d7
SC
1379 r->relent.addend -= current_map->pc;
1380 r->relent.howto = &rel16_howto;
b2c91bd9
SC
1381#else
1382
1383 bfd_put_16(ieee->h.abfd, 0, location_ptr +current_map->pc);
1384 r->relent.howto = &rel16_howto;
1385#endif
7564d3d7 1386 }
b2c91bd9 1387
7564d3d7 1388 else {
6f715d66 1389 bfd_put_16(ieee->h.abfd, 0, location_ptr +current_map->pc);
7564d3d7
SC
1390 r->relent.howto = &abs16_howto;
1391 }
1392 current_map->pc +=2;
1393 break;
b2c91bd9
SC
1394 case 1:
1395 if (pcrel == true) {
1396#if KEEPMINUSPCININST
1397 bfd_put_8(ieee->h.abfd, (int)(-current_map->pc), location_ptr +current_map->pc);
1398 r->relent.addend -= current_map->pc;
1399 r->relent.howto = &rel8_howto;
1400#else
1401 bfd_put_8(ieee->h.abfd,0, location_ptr +current_map->pc);
1402 r->relent.howto = &rel8_howto;
1403#endif
1404 }
1405 else {
1406 bfd_put_8(ieee->h.abfd, 0, location_ptr +current_map->pc);
1407 r->relent.howto = &abs8_howto;
1408 }
1409 current_map->pc +=1;
1410 break;
7564d3d7
SC
1411
1412 default:
1413 BFD_FAIL();
1414 break;
1415 }
1416 }
1417 break;
1418 default:
1419 {
1420 bfd_vma this_size ;
6f715d66 1421 if (parse_int(&(ieee->h), &this_size) == true) {
7564d3d7
SC
1422 unsigned int i;
1423 for (i = 0; i < this_size; i++) {
6f715d66
SC
1424 location_ptr[current_map->pc ++] = this_byte(&(ieee->h));
1425 next_byte(&(ieee->h));
7564d3d7
SC
1426 }
1427 }
1428 else {
1429 loop = false;
1430 }
1431 }
1432 }
1433 }
1434 }
1435 }
1436}
87f86b4e 1437
6f715d66 1438/* Read in all the section data and relocation stuff too */
301dfc71
SC
1439static boolean
1440DEFUN(ieee_slurp_section_data,(abfd),
1441 bfd *abfd)
87f86b4e 1442{
b2c91bd9 1443 bfd_byte *location_ptr = (bfd_byte *)NULL;
e98e6ec1 1444 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e
DHW
1445 unsigned int section_number ;
1446
b2c91bd9 1447 ieee_per_section_type *current_map = (ieee_per_section_type *)NULL;
87f86b4e
DHW
1448 asection *s;
1449 /* Seek to the start of the data area */
1450 if (ieee->read_data== true) return true;
1451 ieee->read_data = true;
301dfc71 1452 ieee_seek(abfd, ieee->w.r.data_part);
87f86b4e
DHW
1453
1454 /* Allocate enough space for all the section contents */
1455
1456
1457 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
a6dab071 1458 ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd;
e98e6ec1 1459 per->data = (bfd_byte *) bfd_alloc(ieee->h.abfd, s->_raw_size);
87f86b4e 1460 /*SUPPRESS 68*/
87f86b4e
DHW
1461 per->reloc_tail_ptr =
1462 (ieee_reloc_type **)&(s->relocation);
1463 }
1464
1465
1466
1467 while (true) {
6f715d66 1468 switch (this_byte(&(ieee->h)))
87f86b4e 1469 {
7564d3d7
SC
1470 /* IF we see anything strange then quit */
1471 default:
1472 return true;
87f86b4e 1473
7564d3d7 1474 case ieee_set_current_section_enum:
6f715d66
SC
1475 next_byte(&(ieee->h));
1476 section_number = must_parse_int(&(ieee->h));
7564d3d7
SC
1477 s = ieee->section_table[section_number];
1478 current_map = (ieee_per_section_type *) s->used_by_bfd;
1479 location_ptr = current_map->data - s->vma;
1480 /* The document I have says that Microtec's compilers reset */
1481 /* this after a sec section, even though the standard says not */
1482 /* to. SO .. */
1483 current_map->pc =s->vma;
1484 break;
87f86b4e 1485
87f86b4e 1486
7564d3d7 1487 case ieee_e2_first_byte_enum:
6f715d66
SC
1488 next_byte(&(ieee->h));
1489 switch (this_byte(&(ieee->h)))
7564d3d7
SC
1490 {
1491 case ieee_set_current_pc_enum & 0xff:
87f86b4e 1492 {
7564d3d7 1493 bfd_vma value;
7564d3d7
SC
1494 ieee_symbol_index_type symbol;
1495 unsigned int extra;
1496 boolean pcrel;
6f715d66
SC
1497 next_byte(&(ieee->h));
1498 must_parse_int(&(ieee->h)); /* Thow away section #*/
e98e6ec1 1499 parse_expression(ieee, &value,
69e0d34d 1500 &symbol,
9465d03e
SC
1501 &pcrel, &extra,
1502 0);
7564d3d7 1503 current_map->pc = value;
e98e6ec1 1504 BFD_ASSERT((unsigned)(value - s->vma) <= s->_raw_size);
87f86b4e 1505 }
7564d3d7
SC
1506 break;
1507
1508 case ieee_value_starting_address_enum & 0xff:
1509 /* We've got to the end of the data now - */
1510 return true;
1511 default:
1512 BFD_FAIL();
1513 return true;
1514 }
1515 break;
1516 case ieee_repeat_data_enum:
1517 {
1518 /* Repeat the following LD or LR n times - we do this by
1519 remembering the stream pointer before running it and
6f715d66
SC
1520 resetting it and running it n times. We special case
1521 the repetition of a repeat_data/load_constant
7564d3d7
SC
1522 */
1523
1524 unsigned int iterations ;
1525 uint8e_type *start ;
6f715d66
SC
1526 next_byte(&(ieee->h));
1527 iterations = must_parse_int(&(ieee->h));
1528 start = ieee->h.input_p;
b2c91bd9 1529 if (start[0] == (int)ieee_load_constant_bytes_enum &&
6f715d66
SC
1530 start[1] == 1) {
1531 while (iterations != 0) {
1532 location_ptr[current_map->pc++] = start[2];
1533 iterations--;
1534 }
1535 next_byte(&(ieee->h));
1536 next_byte(&(ieee->h));
1537 next_byte(&(ieee->h));
1538 }
1539 else {
1540 while (iterations != 0) {
1541 ieee->h.input_p = start;
1542 do_one(ieee, current_map, location_ptr,s);
1543 iterations --;
1544 }
7564d3d7
SC
1545 }
1546 }
1547 break;
1548 case ieee_load_constant_bytes_enum:
1549 case ieee_load_with_relocation_enum:
1550 {
1551 do_one(ieee, current_map, location_ptr,s);
87f86b4e
DHW
1552 }
1553 }
87f86b4e
DHW
1554 }
1555}
1556
1557
1558
7564d3d7
SC
1559
1560
87f86b4e 1561boolean
301dfc71
SC
1562DEFUN(ieee_new_section_hook,(abfd, newsect),
1563 bfd *abfd AND
1564 asection *newsect)
87f86b4e 1565{
a6dab071 1566 newsect->used_by_bfd = (PTR)
d0ec7a8e 1567 bfd_alloc(abfd, sizeof(ieee_per_section_type));
87f86b4e
DHW
1568 ieee_per_section( newsect)->data = (bfd_byte *)NULL;
1569 ieee_per_section(newsect)->section = newsect;
1570 return true;
1571}
1572
1573
1574unsigned int
301dfc71
SC
1575DEFUN(ieee_get_reloc_upper_bound,(abfd, asect),
1576 bfd *abfd AND
1577 sec_ptr asect)
87f86b4e
DHW
1578{
1579 ieee_slurp_section_data(abfd);
1580 return (asect->reloc_count+1) * sizeof(arelent *);
1581}
1582
1583static boolean
301dfc71
SC
1584DEFUN(ieee_get_section_contents,(abfd, section, location, offset, count),
1585 bfd *abfd AND
1586 sec_ptr section AND
d0ec7a8e 1587 PTR location AND
301dfc71 1588 file_ptr offset AND
7ed4093a 1589 bfd_size_type count)
87f86b4e 1590{
a6dab071 1591 ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;
87f86b4e 1592 ieee_slurp_section_data(abfd);
b2c91bd9 1593 (void) memcpy((PTR)location, (PTR)(p->data + offset), (unsigned)count);
87f86b4e
DHW
1594 return true;
1595}
1596
1597
1598unsigned int
301dfc71
SC
1599DEFUN(ieee_canonicalize_reloc,(abfd, section, relptr, symbols),
1600 bfd *abfd AND
1601 sec_ptr section AND
1602 arelent **relptr AND
1603 asymbol **symbols)
87f86b4e 1604{
d0ec7a8e 1605/* ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;*/
87f86b4e 1606 ieee_reloc_type *src = (ieee_reloc_type *)(section->relocation);
e98e6ec1 1607 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e
DHW
1608
1609 while (src != (ieee_reloc_type *)NULL) {
b2c91bd9 1610 /* Work out which symbol to attach it this reloc to */
87f86b4e
DHW
1611 switch (src->symbol.letter) {
1612 case 'X':
1613 src->relent.sym_ptr_ptr =
1614 symbols + src->symbol.index + ieee->external_reference_base_offset;
1615 break;
1616 case 0:
aff6e0b4
SC
1617 src->relent.sym_ptr_ptr =
1618 src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr;
87f86b4e
DHW
1619 break;
1620 default:
1621
1622 BFD_FAIL();
1623 }
1624 *relptr++ = &src->relent;
1625 src = src->next;
1626 }
1627 *relptr = (arelent *)NULL;
1628 return section->reloc_count;
1629}
1630
87f86b4e 1631
87f86b4e 1632
301dfc71
SC
1633static int
1634DEFUN(comp,(ap, bp),
39a2ce33
SC
1635 CONST PTR ap AND
1636 CONST PTR bp)
87f86b4e 1637{
9872a49c
SC
1638 arelent *a = *((arelent **)ap);
1639 arelent *b = *((arelent **)bp);
87f86b4e
DHW
1640 return a->address - b->address;
1641}
9872a49c 1642
87f86b4e
DHW
1643/*
1644Write the section headers
1645*/
1646
1647static void
301dfc71
SC
1648DEFUN(ieee_write_section_part,(abfd),
1649 bfd *abfd)
87f86b4e 1650{
e98e6ec1 1651 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e
DHW
1652 asection *s;
1653 ieee->w.r.section_part = bfd_tell(abfd);
1654 for (s = abfd->sections; s != (asection *)NULL; s=s->next) {
e98e6ec1
SC
1655 if (s != &bfd_abs_section)
1656 {
1657
1658 ieee_write_byte(abfd, ieee_section_type_enum);
71858486 1659 ieee_write_byte(abfd, (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE));
87f86b4e 1660
e98e6ec1 1661 if (abfd->flags & EXEC_P)
6f715d66
SC
1662 {
1663 /* This image is executable, so output absolute sections */
1664 ieee_write_byte(abfd, ieee_variable_A_enum);
1665 ieee_write_byte(abfd, ieee_variable_S_enum);
1666 }
e98e6ec1 1667 else
6f715d66
SC
1668 {
1669 ieee_write_byte(abfd, ieee_variable_C_enum);
1670 }
1671
e98e6ec1 1672 switch (s->flags &(SEC_CODE | SEC_DATA | SEC_ROM))
6f715d66
SC
1673 {
1674 case SEC_CODE | SEC_LOAD:
1675 case SEC_CODE:
1676 ieee_write_byte(abfd, ieee_variable_P_enum);
1677 break;
1678 case SEC_DATA:
1679 default:
1680 ieee_write_byte(abfd, ieee_variable_D_enum);
1681 break;
1682 case SEC_ROM:
1683 case SEC_ROM | SEC_DATA:
1684 case SEC_ROM | SEC_LOAD:
1685 case SEC_ROM | SEC_DATA | SEC_LOAD:
1686
1687 ieee_write_byte(abfd, ieee_variable_R_enum);
1688 }
1689
87f86b4e 1690
e98e6ec1 1691 ieee_write_id(abfd, s->name);
6f715d66 1692#if 0
e98e6ec1
SC
1693 ieee_write_int(abfd, 0); /* Parent */
1694 ieee_write_int(abfd, 0); /* Brother */
1695 ieee_write_int(abfd, 0); /* Context */
6f715d66 1696#endif
e98e6ec1
SC
1697 /* Alignment */
1698 ieee_write_byte(abfd, ieee_section_alignment_enum);
71858486 1699 ieee_write_byte(abfd, (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE));
e98e6ec1
SC
1700 ieee_write_int(abfd, 1 << s->alignment_power);
1701
1702 /* Size */
1703 ieee_write_2bytes(abfd, ieee_section_size_enum);
71858486 1704 ieee_write_byte(abfd, (bfd_byte)(s->index + IEEE_SECTION_NUMBER_BASE));
69e0d34d 1705 ieee_write_int(abfd, s->_raw_size);
e98e6ec1
SC
1706 if (abfd->flags & EXEC_P) {
1707 /* Relocateable sections don't have asl records */
1708 /* Vma */
1709 ieee_write_2bytes(abfd, ieee_section_base_address_enum);
71858486
JG
1710 ieee_write_byte(abfd,
1711 (bfd_byte)(s->index + IEEE_SECTION_NUMBER_BASE));
e98e6ec1
SC
1712 ieee_write_int(abfd, s->vma);
1713 }
1714 }
1715
b2c91bd9 1716 }
87f86b4e
DHW
1717}
1718
1719
1720
6f715d66
SC
1721static void
1722DEFUN(do_with_relocs,(abfd, s),
1723 bfd *abfd AND
1724 asection *s)
87f86b4e 1725{
6f715d66 1726 unsigned int relocs_to_go = s->reloc_count;
b2c91bd9 1727
6f715d66
SC
1728
1729 bfd_byte *stream = ieee_per_section(s)->data;
1730 arelent **p = s->orelocation;
1731
1732 bfd_size_type current_byte_index = 0;
1733
1734 qsort(s->orelocation,
1735 relocs_to_go,
1736 sizeof(arelent **),
1737 comp);
1738
b2c91bd9
SC
1739 /* Output the section preheader */
1740 ieee_write_byte(abfd, ieee_set_current_section_enum);
71858486 1741 ieee_write_byte(abfd, (bfd_byte)(s->index + IEEE_SECTION_NUMBER_BASE));
6f715d66 1742
b2c91bd9 1743 ieee_write_twobyte(abfd, ieee_set_current_pc_enum);
71858486 1744 ieee_write_byte(abfd, (bfd_byte)(s->index + IEEE_SECTION_NUMBER_BASE));
69e0d34d 1745 ieee_write_expression(abfd, 0, s->symbol, 0, 0);
6f715d66 1746
b2c91bd9
SC
1747 if (relocs_to_go == 0)
1748 {
1749 /* If there arn't any relocations then output the load constant byte
1750 opcode rather than the load with relocation opcode */
1751
69e0d34d 1752 while (current_byte_index < s->_raw_size) {
b2c91bd9
SC
1753 bfd_size_type run;
1754 unsigned int MAXRUN = 32;
1755 run = MAXRUN;
69e0d34d
SC
1756 if (run > s->_raw_size - current_byte_index) {
1757 run = s->_raw_size - current_byte_index;
b2c91bd9 1758 }
6f715d66 1759
b2c91bd9
SC
1760 if (run != 0) {
1761 ieee_write_byte(abfd, ieee_load_constant_bytes_enum);
1762 /* Output a stream of bytes */
1763 ieee_write_int(abfd, run);
1764 bfd_write((PTR)(stream + current_byte_index),
1765 1,
1766 run,
1767 abfd);
1768 current_byte_index += run;
1769 }
6f715d66 1770 }
b2c91bd9
SC
1771 }
1772 else
1773 {
1774 ieee_write_byte(abfd, ieee_load_with_relocation_enum);
6f715d66 1775
6f715d66 1776
b2c91bd9
SC
1777 /* Output the data stream as the longest sequence of bytes
1778 possible, allowing for the a reasonable packet size and
1779 relocation stuffs */
6f715d66 1780
b2c91bd9
SC
1781 if ((PTR)stream == (PTR)NULL) {
1782 /* Outputting a section without data, fill it up */
69e0d34d
SC
1783 stream = (uint8e_type *)(bfd_alloc(abfd, s->_raw_size));
1784 memset((PTR)stream, 0, s->_raw_size);
6f715d66 1785 }
69e0d34d 1786 while (current_byte_index < s->_raw_size) {
b2c91bd9
SC
1787 bfd_size_type run;
1788 unsigned int MAXRUN = 32;
1789 if (relocs_to_go) {
1790 run = (*p)->address - current_byte_index;
1791 }
1792 else {
1793 run = MAXRUN;
1794 }
69e0d34d
SC
1795 if (run > s->_raw_size - current_byte_index) {
1796 run = s->_raw_size - current_byte_index;
b2c91bd9 1797 }
6f715d66 1798
b2c91bd9
SC
1799 if (run != 0) {
1800 /* Output a stream of bytes */
1801 ieee_write_int(abfd, run);
1802 bfd_write((PTR)(stream + current_byte_index),
1803 1,
1804 run,
1805 abfd);
1806 current_byte_index += run;
1807 }
1808 /* Output any relocations here */
1809 if (relocs_to_go && (*p) && (*p)->address == current_byte_index) {
1810 while (relocs_to_go && (*p) && (*p)->address == current_byte_index) {
6f715d66 1811
b2c91bd9
SC
1812 arelent *r = *p;
1813 bfd_vma ov;
1814
1815#if 0
1816 if (r->howto->pc_relative) {
1817 r->addend += current_byte_index ;
1818 }
1819#endif
1820
1821 switch (r->howto->size) {
1822 case 2:
1823
1824 ov = bfd_get_32(abfd,
1825 stream+current_byte_index);
1826 current_byte_index +=4;
1827 break;
1828 case 1:
1829 ov = bfd_get_16(abfd,
1830 stream+current_byte_index);
1831 current_byte_index +=2;
1832 break;
1833 case 0:
1834 ov = bfd_get_8(abfd,
1835 stream+current_byte_index);
1836 current_byte_index ++;
1837 break;
1838 default:
1839 ov = 0;
1840 BFD_FAIL();
1841 }
1842 ieee_write_byte(abfd, ieee_function_either_open_b_enum);
aff6e0b4 1843/* abort();*/
e98e6ec1 1844
b2c91bd9
SC
1845 if (r->sym_ptr_ptr != (asymbol **)NULL) {
1846 ieee_write_expression(abfd, r->addend + ov,
b2c91bd9
SC
1847 *(r->sym_ptr_ptr),
1848 r->howto->pc_relative, s->index);
1849 }
1850 else {
1851 ieee_write_expression(abfd, r->addend + ov,
b2c91bd9
SC
1852 (asymbol *)NULL,
1853 r->howto->pc_relative, s->index);
1854 }
1855
1856 if (1 || r->howto->size != 2) {
1857 ieee_write_byte(abfd, ieee_comma);
1858 ieee_write_int(abfd, 1<< r->howto->size);
1859 }
1860 ieee_write_byte(abfd,
1861 ieee_function_either_close_b_enum);
1862
1863 relocs_to_go --;
1864 p++;
1865 }
1866
1867 }
1868 }
1869 }
6f715d66
SC
1870}
1871
1872/* If there are no relocations in the output section then we can
1873be clever about how we write. We block items up into a max of 127
1874bytes */
1875
1876static void
1877DEFUN(do_as_repeat, (abfd, s),
1878 bfd *abfd AND
1879 asection *s)
1880{
aff6e0b4
SC
1881 if (s->_raw_size) {
1882 ieee_write_byte(abfd, ieee_set_current_section_enum);
71858486 1883 ieee_write_byte(abfd, (bfd_byte)(s->index + IEEE_SECTION_NUMBER_BASE));
aff6e0b4
SC
1884 ieee_write_byte(abfd, ieee_set_current_pc_enum >> 8);
1885 ieee_write_byte(abfd, ieee_set_current_pc_enum & 0xff);
71858486 1886 ieee_write_byte(abfd, (bfd_byte)(s->index + IEEE_SECTION_NUMBER_BASE));
aff6e0b4
SC
1887 ieee_write_int(abfd, s->vma );
1888
1889 ieee_write_byte(abfd,ieee_repeat_data_enum);
1890 ieee_write_int(abfd, s->_raw_size);
1891 ieee_write_byte(abfd, ieee_load_constant_bytes_enum);
1892 ieee_write_byte(abfd, 1);
1893 ieee_write_byte(abfd, 0);
1894 }
6f715d66
SC
1895}
1896
1897static void
1898DEFUN(do_without_relocs, (abfd, s),
1899 bfd *abfd AND
1900 asection *s)
1901{
1902 bfd_byte *stream = ieee_per_section(s)->data;
1903
1904 if (stream == 0 || ((s->flags & SEC_LOAD) == 0))
301dfc71 1905 {
6f715d66
SC
1906 do_as_repeat(abfd, s);
1907 }
1908 else
1909 {
1910 unsigned int i;
69e0d34d 1911 for (i = 0; i < s->_raw_size; i++) {
6f715d66
SC
1912 if (stream[i] != 0) {
1913 do_with_relocs(abfd, s);
1914 return;
1915 }
1916 }
1917 do_as_repeat(abfd, s);
1918 }
1919
1920}
301dfc71 1921
6f715d66
SC
1922
1923static unsigned char *output_ptr_start;
1924static unsigned char *output_ptr;
1925static unsigned char *output_ptr_end;
1926static unsigned char *input_ptr_start;
1927static unsigned char *input_ptr;
1928static unsigned char *input_ptr_end;
1929static bfd *input_bfd;
1930static bfd *output_bfd;
1931static int output_buffer;
1932
1933static void fill()
1934{
b2c91bd9 1935 bfd_read((PTR)input_ptr_start, 1, input_ptr_end - input_ptr_start, input_bfd);
6f715d66
SC
1936 input_ptr = input_ptr_start;
1937}
1938static void flush()
1939{
b2c91bd9 1940 bfd_write((PTR)(output_ptr_start),1,output_ptr - output_ptr_start, output_bfd);
6f715d66
SC
1941 output_ptr = output_ptr_start;
1942 output_buffer++;
1943}
1944
1945#define THIS() ( *input_ptr )
1946#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); }
1947#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end) flush(); }
1948
1949static void write_int(value)
1950int value;
1951{
1952 if (value >= 0 && value <= 127) {
1953 OUT(value);
1954 }
1955 else {
1956 unsigned int length;
1957 /* How many significant bytes ? */
1958 /* FIXME FOR LONGER INTS */
1959 if (value & 0xff000000) {
1960 length = 4;
1961 }
1962 else if (value & 0x00ff0000) {
1963 length = 3;
1964 }
1965 else if (value & 0x0000ff00) {
1966 length = 2;
1967 }
1968 else length = 1;
1969
1970 OUT((int)ieee_number_repeat_start_enum + length);
1971 switch (length) {
1972 case 4:
1973 OUT( value >> 24);
1974 case 3:
1975 OUT( value >> 16);
1976 case 2:
1977 OUT( value >> 8);
1978 case 1:
1979 OUT( value);
1980 }
1981
1982 }
1983}
1984static void copy_id()
1985{
1986 int length = THIS();
1987 char ch;
1988 OUT(length);
1989 NEXT();
1990 while (length--) {
1991 ch = THIS();
1992 OUT(ch);
1993 NEXT();
1994 }
1995}
1996#define VAR(x) ((x | 0x80))
1997static void copy_expression()
1998{
1999 int stack[10];
2000 int *tos = stack;
2001 int value = 0;
2002 while (1) {
2003 switch (THIS()) {
2004 case 0x84:
2005 NEXT();
2006 value = THIS(); NEXT();
2007 value = (value << 8) | THIS(); NEXT();
2008 value = (value << 8) | THIS(); NEXT();
2009 value = (value << 8) | THIS(); NEXT();
2010 *tos ++ = value;
2011 break;
2012 case 0x83:
2013 NEXT();
2014 value = THIS(); NEXT();
2015 value = (value << 8) | THIS(); NEXT();
2016 value = (value << 8) | THIS(); NEXT();
2017 *tos ++ = value;
2018 break;
2019 case 0x82:
2020 NEXT();
2021 value = THIS(); NEXT();
2022 value = (value << 8) | THIS(); NEXT();
2023 *tos ++ = value;
2024 break;
2025 case 0x81:
2026 NEXT();
2027 value = THIS(); NEXT();
2028 *tos ++ = value;
2029 break;
2030 case 0x80:
2031 NEXT();
2032 *tos ++ = 0;
2033 break;
2034 default:
2035 if (THIS() >0x84) {
2036 /* Not a number, just bug out with the answer */
2037 write_int(*(--tos));
2038 return;
2039 }
2040 *tos++ = THIS();
2041NEXT();
2042 value = 0;
2043 break;
2044 case 0xa5:
2045 /* PLUS anything */
2046 {
2047 int value = *(--tos);
2048 value += *(--tos);
2049 *tos++ = value;
2050 NEXT();
301dfc71 2051 }
6f715d66
SC
2052 break;
2053 case VAR('R') :
2054 {
2055 int section_number ;
2056 ieee_data_type *ieee;
2057 asection *s;
2058 NEXT();
2059 section_number = THIS();
2060
2061 NEXT();
e98e6ec1 2062 ieee= IEEE_DATA(input_bfd);
6f715d66
SC
2063 s = ieee->section_table[section_number];
2064 if (s->output_section) {
2065 value = s->output_section->vma ;
2066 } else { value = 0; }
2067 value += s->output_offset;
2068 *tos++ = value;
2069 value = 0;
2070 }
2071 break;
2072 case 0x90:
2073 {
2074 NEXT();
2075 write_int(*(--tos));
2076 OUT(0x90);
2077 return;
87f86b4e 2078
6f715d66
SC
2079 }
2080 }
2081 }
2082
2083}
87f86b4e 2084
6f715d66
SC
2085/* Drop the int in the buffer, and copy a null into the gap, which we
2086 will overwrite later */
87f86b4e 2087
6f715d66
SC
2088struct output_buffer_struct {
2089unsigned char *ptrp;
2090 int buffer;
2091} ;
87f86b4e 2092
6f715d66
SC
2093static void
2094DEFUN(fill_int,(buf),
2095 struct output_buffer_struct *buf)
2096{
2097 if (buf->buffer == output_buffer) {
2098 /* Still a chance to output the size */
2099 int value = output_ptr - buf->ptrp + 3;
2100 buf->ptrp[0] = value >> 24;
2101 buf->ptrp[1] = value >> 16;
2102 buf->ptrp[2] = value >> 8;
2103 buf->ptrp[3] = value >> 0;
2104 }
87f86b4e 2105
6f715d66
SC
2106}
2107static void
2108DEFUN(drop_int,(buf),
2109 struct output_buffer_struct *buf)
2110{
2111 int type = THIS();
2112 int ch;
2113 if (type <= 0x84) {
2114 NEXT();
2115 switch(type) {
2116 case 0x84: ch = THIS(); NEXT();
2117 case 0x83: ch = THIS(); NEXT();
2118 case 0x82: ch = THIS(); NEXT();
2119 case 0x81: ch = THIS(); NEXT();
2120 case 0x80: break;
2121 }
2122 }
2123 OUT(0x84);
2124 buf->ptrp = output_ptr;
2125 buf->buffer = output_buffer;
2126 OUT(0);OUT(0);OUT(0);OUT(0);
2127}
2128
2129static void copy_int()
2130{
2131 int type = THIS();
2132 int ch;
2133 if (type <= 0x84) {
2134 OUT(type);
2135 NEXT();
2136 switch(type) {
2137 case 0x84: ch = THIS(); NEXT(); OUT(ch);
2138 case 0x83: ch = THIS(); NEXT(); OUT(ch);
2139 case 0x82: ch = THIS(); NEXT(); OUT(ch);
2140 case 0x81: ch = THIS(); NEXT(); OUT(ch);
2141 case 0x80: break;
2142 }
2143 }
2144}
2145
2146#define ID copy_id()
2147#define INT copy_int()
2148#define EXP copy_expression()
2149static void copy_till_end();
2150#define INTn(q) copy_int()
2151#define EXPn(q) copy_expression()
2152static void f1_record()
2153{
2154 int ch;
2155 /* ATN record */
2156 NEXT();
2157 ch = THIS();
2158 switch (ch)
2159 {
2160 default:
2161 OUT(0xf1); OUT(ch);
2162 break;
2163 case 0xc9:
2164 NEXT();
2165 OUT(0xf1); OUT(0xc9);
2166 INT; INT; ch = THIS();
2167 switch (ch)
2168 {
2169 case 0x16: NEXT();break;
2170 case 0x01: NEXT();break;
2171 case 0x00: NEXT(); INT; break;
2172 case 0x03: NEXT(); INT; break;
2173 case 0x13: EXPn(instruction address); break;
2174 default:
2175 break;
2176 }
2177 break;
2178 case 0xd8:
2179 /* EXternal ref */
2180 NEXT();
2181 OUT(0xf1); OUT(0xd8);
2182 EXP ; EXP; EXP; EXP;
2183 break;
2184 case 0xce:
2185 NEXT();
2186 OUT(0xf1);OUT(0xce); INT; INT; ch = THIS(); INT;
2187 switch (ch) {
2188 case 0x01:
2189 INT; INT; break;
2190 case 0x02:
2191 INT; break;
2192 case 0x04:
2193 EXPn(external function); break;
2194 case 0x05:
2195 break;
2196 case 0x07: INTn(line number); INT;
2197 case 0x08: break;
2198 case 0x0a: INTn(locked register); INT; break;
2199 case 0x3f: copy_till_end(); break;
2200 case 0x3e: copy_till_end(); break;
2201 case 0x40: copy_till_end(); break;
2202 case 0x41: ID; break;
87f86b4e 2203 }
6f715d66
SC
2204 }
2205
2206}
2207static void f0_record()
2208{
2209 /* Attribute record */
2210 NEXT();
2211 OUT(0xf0);
2212 INTn(Symbol name );
2213 ID;
2214}
2215static void copy_till_end()
2216{
2217 int ch = THIS();
2218 while (1) {
2219 while (ch <= 0x80)
2220 {
2221 OUT(ch);
2222 NEXT();
2223 ch = THIS();
2224 }
2225 switch (ch) {
2226 case 0x84:
2227 OUT(THIS());
2228 NEXT();
2229 case 0x83:
2230 OUT(THIS());
2231 NEXT();
2232 case 0x82:
2233 OUT(THIS());
2234 NEXT();
2235 case 0x81:
2236 OUT(THIS());
2237 NEXT();
2238 OUT(THIS());
2239 NEXT();
2240
2241 ch = THIS();
2242 break;
2243 default:
2244 return;
2245 }
2246 }
2247
2248}
2249
2250static void f2_record()
2251{
6f715d66
SC
2252 NEXT();
2253 OUT(0xf2);
2254 INT ;
2255 NEXT();
2256 OUT(0xce);
2257 INT ;
b2c91bd9 2258 copy_till_end();
6f715d66
SC
2259}
2260
2261
2262static void block();
2263static void f8_record()
2264{
2265 int ch;
2266 NEXT();
2267 ch = THIS();
2268 switch (ch)
2269 {
2270 case 0x01:
2271 case 0x02:
2272 case 0x03:
2273 /* Unique typedefs for module */
2274 /* GLobal typedefs */
2275 /* High level module scope beginning */
2276 {
2277 struct output_buffer_struct ob;
2278 NEXT();
2279 OUT(0xf8); OUT(ch);
2280 drop_int(&ob); ID ;
2281
2282 block();
2283
2284 NEXT();
2285 fill_int(&ob);
2286 OUT(0xf9);
301dfc71 2287 }
6f715d66
SC
2288 break;
2289 case 0x04:
2290 /* Global function */
2291 {
2292 struct output_buffer_struct ob;
2293 NEXT();
2294 OUT(0xf8); OUT(0x04);
2295 drop_int(&ob); ID ; INTn(stack size); INTn(ret val);
2296 EXPn(offset);
2297
2298 block();
2299
2300 NEXT();
2301 OUT(0xf9);
2302 EXPn(size of block);
2303 fill_int(&ob);
301dfc71 2304 }
6f715d66 2305 break;
301dfc71 2306
6f715d66
SC
2307 case 0x05:
2308 /* File name for source line numbers */
2309 {
2310 struct output_buffer_struct ob;
2311 NEXT();
2312 OUT(0xf8); OUT(0x05);
2313 drop_int(&ob);
2314 ID; INTn(year); INTn(month); INTn(day);
2315 INTn(hour); INTn(monute); INTn(second);
2316 block();
2317 NEXT();
2318 OUT(0xf9);
2319 fill_int(&ob);
301dfc71 2320 }
6f715d66
SC
2321 break;
2322
2323 case 0x06:
2324 /* Local function */
2325 { struct output_buffer_struct ob;
2326 NEXT(); OUT(0xf8); OUT(0x06);
2327 drop_int(&ob);
2328 ID; INTn(stack size); INTn(type return);
2329 EXPn(offset);
2330 block();
2331 NEXT();
2332 OUT(0xf9);
2333 EXPn(size);
2334 fill_int(&ob);
2335 }
2336 break;
2337
2338 case 0x0a:
2339 /* Assembler module scope beginning -*/
2340 { struct output_buffer_struct ob;
d0ec7a8e 2341
6f715d66
SC
2342 NEXT();
2343 OUT(0xf8); OUT(0x0a);
2344 drop_int(&ob);
2345 ID; ID; INT; ID; INT; INT; INT; INT; INT; INT;
d0ec7a8e 2346
6f715d66 2347 block();
d0ec7a8e 2348
6f715d66
SC
2349 NEXT();
2350 OUT(0xf9);
2351 fill_int(&ob);
2352 }
2353 break;
2354 case 0x0b:
2355 {
2356 struct output_buffer_struct ob;
2357 NEXT();
2358 OUT(0xf8); OUT(0x0b);
2359 drop_int(&ob); ID ; INT; INTn(section index); EXPn(offset); INTn(stuff);
d0ec7a8e 2360
6f715d66 2361 block();
d0ec7a8e 2362
6f715d66
SC
2363 OUT(0xf9);
2364 NEXT();
2365 EXPn(Size in Maus);
2366 fill_int(&ob);
87f86b4e 2367 }
6f715d66 2368 break;
87f86b4e 2369 }
6f715d66 2370}
87f86b4e 2371
6f715d66
SC
2372static void e2_record()
2373{
2374 OUT(0xe2);
2375 NEXT();
2376 OUT(0xce);
2377 NEXT();
2378 INT;
2379 EXP;
2380}
2381
2382static void DEFUN_VOID(block)
2383{
2384 int ch ;
2385 while (1) {
2386 ch = THIS();
2387 switch (ch) {
2388 case 0xe1:
2389 case 0xe5:
2390 return;
2391 case 0xf9:
2392 return;
2393 case 0xf0:
2394 f0_record();
2395 break;
2396 case 0xf1:
2397 f1_record();
2398 break;
2399 case 0xf2:
2400 f2_record();
2401 break;
2402 case 0xf8:
2403 f8_record();
2404 break;
2405 case 0xe2:
2406 e2_record();
2407 break;
2408
2409 }
2410 }
2411}
2412
2413
2414
2415/* relocate_debug,
2416 moves all the debug information from the source bfd to the output
2417 bfd, and relocates any expressions it finds
2418*/
2419
2420static void
2421DEFUN(relocate_debug,(output, input),
2422 bfd *output AND
2423 bfd *input)
2424{
2425#define IBS 400
2426#define OBS 400
2427 unsigned char input_buffer[IBS];
2428
2429 input_ptr_start = input_ptr = input_buffer;
2430 input_ptr_end = input_buffer + IBS;
2431 input_bfd = input;
b2c91bd9 2432 bfd_read((PTR)input_ptr_start, 1, IBS, input);
6f715d66
SC
2433 block();
2434}
2435/*
2436 During linking, we we told about the bfds which made up our
2437 contents, we have a list of them. They will still be open, so go to
2438 the debug info in each, and copy it out, relocating it as we go.
2439*/
2440
2441static void
2442DEFUN(ieee_write_debug_part, (abfd),
2443 bfd *abfd)
2444{
e98e6ec1 2445 ieee_data_type *ieee = IEEE_DATA(abfd);
6f715d66
SC
2446 bfd_chain_type *chain = ieee->chain_root;
2447 unsigned char output_buffer[OBS];
b2c91bd9
SC
2448 boolean some_debug = false;
2449 file_ptr here = bfd_tell(abfd);
2450
6f715d66
SC
2451 output_ptr_start = output_ptr = output_buffer ;
2452 output_ptr_end = output_buffer + OBS;
2453 output_ptr = output_buffer;
2454 output_bfd = abfd;
6f715d66 2455
b2c91bd9 2456 if (chain == (bfd_chain_type *)NULL) {
b645b632 2457#if 0
e98e6ec1
SC
2458 /* There is no debug info, so we'll fake some up */
2459 CONST static char fake[] = {
2460 0xf8, 0xa, 0, 5, 't', 't', 't', 't', 't', 0, 2, 3,
2461 '1','.','1',0x82, 1991>>8, 1991 & 0xff, 9, 20, 11, 07,50 };
2462 ieee->w.r.debug_information_part = 0;
b2c91bd9 2463
b645b632 2464
e98e6ec1 2465 here;
b2c91bd9
SC
2466
2467
e98e6ec1
SC
2468 /* bfd_write(fake, 1, sizeof(fake), abfd);*/
2469 /* Now write a header for each section */
2470 {
2471 int i = 0;
2472 asection *s = abfd->sections;
2473 while (s) {
2474 if (s != abfd->abs_section)
2475 {
2476
2477 ieee_write_byte(abfd, 0xf8);
2478 ieee_write_byte(abfd, 0x0b);
2479 ieee_write_byte(abfd, 0);
2480 ieee_write_byte(abfd, 0);
2481 ieee_write_byte(abfd, 1);
2482 ieee_write_byte(abfd, i + IEEE_SECTION_NUMBER_BASE);
69e0d34d 2483 ieee_write_expression(abfd, 0, s->symbol, 0, 0, 0);
e98e6ec1
SC
2484 ieee_write_byte(abfd,0);
2485 ieee_write_byte(abfd, 0xf9);
69e0d34d
SC
2486 ieee_write_expression(abfd, s->size,
2487 bfd_abs_section.symbol, 0, 0, 0);
e98e6ec1
SC
2488 i++;
2489 }
2490
b2c91bd9 2491 s = s->next;
e98e6ec1 2492
b2c91bd9 2493 }
e98e6ec1
SC
2494 /* Close the scope */
2495 ieee_write_byte(abfd, 0xf9);
2496 }
b2c91bd9 2497#endif
e98e6ec1 2498 }
b2c91bd9 2499 else{
e98e6ec1
SC
2500 while (chain != (bfd_chain_type *)NULL) {
2501 bfd *entry = chain->this;
2502 ieee_data_type *entry_ieee = IEEE_DATA(entry);
2503 if (entry_ieee->w.r.debug_information_part) {
2504 bfd_seek(entry, entry_ieee->w.r.debug_information_part, SEEK_SET);
2505 relocate_debug(abfd, entry);
2506 }
6f715d66 2507
e98e6ec1
SC
2508 chain = chain->next;
2509 }
2510 if (some_debug) {
2511 ieee->w.r.debug_information_part = here;
2512 }
2513 else {
2514 ieee->w.r.debug_information_part = 0;
2515 }
b2c91bd9 2516 }
6f715d66
SC
2517 flush();
2518
2519}
2520/* write the data in an ieee way */
2521static void
2522DEFUN(ieee_write_data_part,(abfd),
2523 bfd *abfd)
2524{
2525 asection *s;
e98e6ec1 2526 ieee_data_type *ieee = IEEE_DATA(abfd);
6f715d66
SC
2527 ieee->w.r.data_part = bfd_tell(abfd);
2528 for (s = abfd->sections; s != (asection *)NULL; s = s->next)
2529 {
2530 /* Sort the reloc records so we can insert them in the correct
2531 places */
2532 if (s->reloc_count != 0)
2533 {
b2c91bd9 2534 do_with_relocs(abfd, s);
6f715d66
SC
2535 }
2536 else
2537 {
2538 do_without_relocs(abfd, s);
2539 }
2540 }
301dfc71 2541}
87f86b4e
DHW
2542
2543
2544
2545static void
301dfc71
SC
2546DEFUN(init_for_output,(abfd),
2547 bfd *abfd)
87f86b4e
DHW
2548{
2549 asection *s;
2550 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
69e0d34d
SC
2551 if (s->_raw_size != 0) {
2552 ieee_per_section(s)->data = (bfd_byte *)(bfd_alloc(abfd, s->_raw_size));
87f86b4e
DHW
2553 }
2554 }
2555}
2556
2557/** exec and core file sections */
2558
2559/* set section contents is complicated with IEEE since the format is
2560* not a byte image, but a record stream.
2561*/
2562boolean
301dfc71
SC
2563DEFUN(ieee_set_section_contents,(abfd, section, location, offset, count),
2564 bfd *abfd AND
2565 sec_ptr section AND
d0ec7a8e 2566 PTR location AND
301dfc71 2567 file_ptr offset AND
7ed4093a 2568 bfd_size_type count)
87f86b4e
DHW
2569{
2570 if (ieee_per_section(section)->data == (bfd_byte *)NULL) {
2571 init_for_output(abfd);
2572 }
b2c91bd9
SC
2573 (void) memcpy((PTR)(ieee_per_section(section)->data + offset),
2574 (PTR)location,
7ed4093a 2575 (unsigned int)count);
87f86b4e
DHW
2576 return true;
2577}
2578
2579/*
2580write the external symbols of a file, IEEE considers two sorts of
2581external symbols, public, and referenced. It uses to internal forms
2582to index them as well. When we write them out we turn their symbol
2583values into indexes from the right base.
2584*/
2585static void
301dfc71
SC
2586DEFUN(ieee_write_external_part,(abfd),
2587 bfd *abfd)
87f86b4e
DHW
2588{
2589 asymbol **q;
e98e6ec1 2590 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e
DHW
2591
2592 unsigned int reference_index = IEEE_REFERENCE_BASE;
b2c91bd9
SC
2593 unsigned int public_index = IEEE_PUBLIC_BASE+2;
2594 file_ptr here = bfd_tell(abfd);
2595 boolean hadone = false;
87f86b4e 2596 if (abfd->outsymbols != (asymbol **)NULL) {
b2c91bd9 2597
87f86b4e
DHW
2598 for (q = abfd->outsymbols; *q != (asymbol *)NULL; q++) {
2599 asymbol *p = *q;
b2c91bd9 2600 hadone = true;
e98e6ec1 2601 if (p->section == &bfd_und_section) {
87f86b4e
DHW
2602 /* This must be a symbol reference .. */
2603 ieee_write_byte(abfd, ieee_external_reference_enum);
2604 ieee_write_int(abfd, reference_index);
2605 ieee_write_id(abfd, p->name);
2606 p->value = reference_index;
2607 reference_index++;
2608 }
8feff717 2609 else if (bfd_is_com_section (p->section)) {
87f86b4e
DHW
2610 /* This is a weak reference */
2611 ieee_write_byte(abfd, ieee_external_reference_enum);
2612 ieee_write_int(abfd, reference_index);
2613 ieee_write_id(abfd, p->name);
2614 ieee_write_byte(abfd, ieee_weak_external_reference_enum);
2615 ieee_write_int(abfd, reference_index);
2616 ieee_write_int(abfd, p->value);
2617 ieee_write_int(abfd, BFD_FORT_COMM_DEFAULT_VALUE);
2618 p->value = reference_index;
2619 reference_index++;
2620 }
2621 else if(p->flags & BSF_GLOBAL) {
2622 /* This must be a symbol definition */
2623
b2c91bd9 2624
87f86b4e
DHW
2625 ieee_write_byte(abfd, ieee_external_symbol_enum);
2626 ieee_write_int(abfd, public_index );
2627 ieee_write_id(abfd, p->name);
2628
b2c91bd9
SC
2629 ieee_write_twobyte(abfd, ieee_attribute_record_enum);
2630 ieee_write_int(abfd, public_index );
2631 ieee_write_byte(abfd, 15); /* instruction address */
2632 ieee_write_byte(abfd, 19); /* static symbol */
2633 ieee_write_byte(abfd, 1); /* one of them */
2634
2635
87f86b4e
DHW
2636 /* Write out the value */
2637 ieee_write_2bytes(abfd, ieee_value_record_enum);
2638 ieee_write_int(abfd, public_index);
e98e6ec1 2639 if (p->section != &bfd_abs_section)
b2c91bd9
SC
2640 {
2641 if (abfd->flags & EXEC_P)
e98e6ec1
SC
2642 {
2643 /* If fully linked, then output all symbols
2644 relocated */
2645 ieee_write_int(abfd,
2646 p->value + p->section->output_offset+ p->section->output_section->vma);
6f715d66 2647
b2c91bd9 2648 }
e98e6ec1
SC
2649 else {
2650 ieee_write_expression(abfd,
2651 p->value + p->section->output_offset,
69e0d34d
SC
2652 p->section->output_section->symbol
2653 , false, 0);
e98e6ec1 2654 }
b2c91bd9
SC
2655 }
2656 else
2657 {
6f715d66 2658 ieee_write_expression(abfd,
b2c91bd9 2659 p->value,
69e0d34d
SC
2660 bfd_abs_section.symbol,
2661 false, 0);
6f715d66 2662 }
87f86b4e
DHW
2663 p->value = public_index;
2664 public_index++;
2665 }
2666 else {
2667 /* This can happen - when there are gaps in the symbols read */
2668 /* from an input ieee file */
2669 }
2670 }
2671 }
b2c91bd9
SC
2672 if (hadone)
2673 ieee->w.r.external_part = here;
87f86b4e
DHW
2674
2675}
2676
b2c91bd9 2677
71858486 2678static CONST unsigned char exten[] =
b2c91bd9
SC
2679 {
2680 0xf0, 0x20, 0x00,
2681 0xf1, 0xce, 0x20, 0x00, 37, 3, 3, /* Set version 3 rev 3 */
2682 0xf1, 0xce, 0x20, 0x00, 39, 2, /* keep symbol in original case */
2683 0xf1, 0xce, 0x20, 0x00, 38 /* set object type relocateable to x */
2684 };
2685
71858486 2686static CONST unsigned char envi[] =
b2c91bd9
SC
2687 {
2688 0xf0, 0x21, 0x00,
2689
2690/* 0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11,
2691 0x19, 0x2c,
2692*/
2693 0xf1, 0xce, 0x21, 00, 52, 0x00, /* exec ok */
2694
2695 0xf1, 0xce, 0x21, 0, 53, 0x03, /* host unix */
2696/* 0xf1, 0xce, 0x21, 0, 54, 2,1,1 tool & version # */
2697 };
2698
87f86b4e 2699static
301dfc71
SC
2700void
2701DEFUN(ieee_write_me_part,(abfd),
2702 bfd *abfd)
87f86b4e 2703{
e98e6ec1 2704 ieee_data_type *ieee= IEEE_DATA(abfd);
b2c91bd9
SC
2705 ieee->w.r.trailer_part = bfd_tell(abfd);
2706 if (abfd->start_address) {
2707 ieee->w.r.me_record = bfd_tell(abfd);
2708 ieee_write_2bytes(abfd, ieee_value_starting_address_enum);
2709 ieee_write_byte(abfd, ieee_function_either_open_b_enum);
2710 ieee_write_int(abfd, abfd->start_address);
2711 ieee_write_byte(abfd, ieee_function_either_close_b_enum);
2712 }
2713 else {
2714 ieee->w.r.me_record = bfd_tell(abfd);
2715 }
87f86b4e
DHW
2716 ieee_write_byte(abfd, ieee_module_end_enum);
2717
2718}
2719boolean
301dfc71
SC
2720DEFUN(ieee_write_object_contents,(abfd),
2721 bfd *abfd)
87f86b4e 2722{
e98e6ec1 2723 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e 2724 unsigned int i;
301dfc71
SC
2725 file_ptr old;
2726 /* Fast forward over the header area */
f8e01940 2727 bfd_seek(abfd, (file_ptr) 0, SEEK_SET);
301dfc71
SC
2728 ieee_write_byte(abfd, ieee_module_beginning_enum);
2729
b2c91bd9 2730 ieee_write_id(abfd, bfd_printable_name(abfd));
301dfc71 2731 ieee_write_id(abfd, abfd->filename);
6f715d66 2732
6f715d66 2733 /* Fast forward over the variable bits */
301dfc71 2734 ieee_write_byte(abfd, ieee_address_descriptor_enum);
b2c91bd9
SC
2735
2736 /* Bits per MAU */
71858486 2737 ieee_write_byte(abfd, (bfd_byte) (bfd_arch_bits_per_byte(abfd)));
b2c91bd9 2738 /* MAU's per address */
71858486
JG
2739 ieee_write_byte(abfd,
2740 (bfd_byte) (bfd_arch_bits_per_address(abfd) / bfd_arch_bits_per_byte(abfd)));
b2c91bd9 2741
301dfc71 2742 old = bfd_tell(abfd);
f8e01940 2743 bfd_seek(abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR);
6f715d66
SC
2744
2745 ieee->w.r.extension_record = bfd_tell(abfd);
69e0d34d 2746 bfd_write((char *)exten, 1, sizeof(exten), abfd);
b2c91bd9
SC
2747 if (abfd->flags & EXEC_P)
2748 ieee_write_byte(abfd, 0x1); /* Absolute */
2749 else
2750 ieee_write_byte(abfd, 0x2); /* Relocateable */
2751
e98e6ec1 2752 ieee->w.r.environmental_record = bfd_tell(abfd);
69e0d34d 2753 bfd_write((char *)envi, 1, sizeof(envi), abfd);
b2c91bd9
SC
2754 output_bfd = abfd;
2755 flush();
6f715d66 2756
b2c91bd9 2757 ieee_write_section_part(abfd);
87f86b4e 2758 /*
301dfc71
SC
2759 First write the symbols, this changes their values into table
2760 indeces so we cant use it after this point
2761 */
87f86b4e 2762 ieee_write_external_part(abfd);
b2c91bd9 2763 /* ieee_write_byte(abfd, ieee_record_seperator_enum);*/
87f86b4e 2764
b2c91bd9
SC
2765
2766 /* ieee_write_byte(abfd, ieee_record_seperator_enum);*/
6f715d66
SC
2767
2768
2769 /*
2770 Write any debugs we have been told about
2771 */
b2c91bd9 2772 ieee_write_debug_part(abfd);
6f715d66 2773
87f86b4e 2774 /*
301dfc71
SC
2775 Can only write the data once the symbols have been written since
2776 the data contains relocation information which points to the
2777 symbols
2778 */
87f86b4e 2779 ieee_write_data_part(abfd);
b2c91bd9 2780
87f86b4e
DHW
2781
2782 /*
301dfc71
SC
2783 At the end we put the end !
2784 */
87f86b4e 2785 ieee_write_me_part(abfd);
87f86b4e 2786
87f86b4e 2787
301dfc71 2788 /* Generate the header */
f8e01940 2789 bfd_seek(abfd, old, SEEK_SET);
87f86b4e
DHW
2790
2791 for (i= 0; i < N_W_VARIABLES; i++) {
2792 ieee_write_2bytes(abfd,ieee_assign_value_to_variable_enum);
71858486 2793 ieee_write_byte(abfd, (bfd_byte) i);
301dfc71 2794 ieee_write_int5_out(abfd, ieee->w.offset[i]);
87f86b4e
DHW
2795 }
2796 return true;
2797}
2798
2799
2800
2801\f
2802/* Native-level interface to symbols. */
2803
2804/* We read the symbols into a buffer, which is discarded when this
2805function exits. We read the strings into a buffer large enough to
2806hold them all plus all the cached symbol entries. */
2807
2808asymbol *
301dfc71
SC
2809DEFUN(ieee_make_empty_symbol,(abfd),
2810 bfd *abfd)
87f86b4e
DHW
2811{
2812
2813 ieee_symbol_type *new =
2814 (ieee_symbol_type *)zalloc (sizeof (ieee_symbol_type));
2815 new->symbol.the_bfd = abfd;
2816 return &new->symbol;
2817
2818}
2819
87f86b4e 2820static bfd *
6f715d66
SC
2821DEFUN(ieee_openr_next_archived_file,(arch, prev),
2822 bfd *arch AND
2823 bfd *prev)
87f86b4e 2824{
e98e6ec1 2825 ieee_ar_data_type *ar = IEEE_AR_DATA(arch);
87f86b4e
DHW
2826 /* take the next one from the arch state, or reset */
2827 if (prev == (bfd *)NULL) {
2828 /* Reset the index - the first two entries are bogus*/
2829 ar->element_index = 2;
2830 }
2831 while (true) {
2832 ieee_ar_obstack_type *p = ar->elements + ar->element_index;
2833 ar->element_index++;
2834 if (ar->element_index <= ar->element_count) {
2835 if (p->file_offset != (file_ptr)0) {
2836 if (p->abfd == (bfd *)NULL) {
2837 p->abfd = _bfd_create_empty_archive_element_shell(arch);
2838 p->abfd->origin = p->file_offset;
2839 }
2840 return p->abfd;
2841 }
2842 }
2843 else {
6f715d66 2844 bfd_error = no_more_archived_files;
87f86b4e
DHW
2845 return (bfd *)NULL;
2846 }
2847
2848 }
2849}
2850
2851static boolean
2852ieee_find_nearest_line(abfd,
2853 section,
2854 symbols,
2855 offset,
2856 filename_ptr,
2857 functionname_ptr,
2858 line_ptr)
2859bfd *abfd;
2860asection *section;
2861asymbol **symbols;
2862bfd_vma offset;
2863char **filename_ptr;
2864char **functionname_ptr;
d0ec7a8e 2865int *line_ptr;
87f86b4e
DHW
2866{
2867 return false;
87f86b4e 2868}
301dfc71
SC
2869
2870
2871static int
9872a49c 2872ieee_generic_stat_arch_elt(abfd, buf)
301dfc71
SC
2873bfd *abfd;
2874struct stat *buf;
2875{
9465d03e 2876 ieee_ar_data_type *ar = abfd->my_archive->tdata.ieee_ar_data;
301dfc71
SC
2877 if (ar == (ieee_ar_data_type *)NULL) {
2878 bfd_error = invalid_operation;
2879 return -1;
2880 }
2881 else {
2882 buf->st_size = 0x1;
2883 buf->st_mode = 0666;
9465d03e 2884 return ! ieee_object_p(abfd);
301dfc71
SC
2885 }
2886}
39a2ce33 2887static int
d0ec7a8e
SC
2888DEFUN(ieee_sizeof_headers,(abfd, x),
2889 bfd *abfd AND
2890 boolean x)
39a2ce33 2891{
d0ec7a8e 2892 return 0;
39a2ce33
SC
2893}
2894
6f715d66
SC
2895
2896
2897static void
2898DEFUN(ieee_bfd_debug_info_start,(abfd),
2899 bfd *abfd)
2900 {
2901
2902 }
2903
2904static void
2905DEFUN(ieee_bfd_debug_info_end,(abfd),
2906 bfd *abfd)
2907 {
2908
2909 }
2910
2911
2912/* Add this section to the list of sections we have debug info for, to
2913 be ready to output it at close time
2914 */
2915static void
2916DEFUN(ieee_bfd_debug_info_accumulate,(abfd, section),
2917 bfd *abfd AND
2918 asection *section)
2919{
e98e6ec1
SC
2920 ieee_data_type *ieee = IEEE_DATA(section->owner);
2921 ieee_data_type *output_ieee = IEEE_DATA(abfd);
6f715d66
SC
2922 /* can only accumulate data from other ieee bfds */
2923 if (section->owner->xvec != abfd->xvec)
2924 return;
2925 /* Only bother once per bfd */
2926 if (ieee->done_debug == true)
2927 return;
2928 ieee->done_debug = true;
2929
2930 /* Don't bother if there is no debug info */
2931 if (ieee->w.r.debug_information_part == 0)
2932 return;
2933
2934
2935 /* Add to chain */
2936 {
2937 bfd_chain_type *n = (bfd_chain_type *) bfd_alloc(abfd, sizeof(bfd_chain_type));
2938 n->this = section->owner;
2939 n->next = (bfd_chain_type *)NULL;
2940
2941 if (output_ieee->chain_head) {
2942 output_ieee->chain_head->next = n;
2943 }
2944 else {
2945 output_ieee->chain_root = n;
2946
2947 }
2948 output_ieee->chain_head = n;
2949 }
2950}
2951
2952
2953
2954
2955
2956
2957#define FOO PROTO
d0ec7a8e
SC
2958#define ieee_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
2959#define ieee_core_file_failing_signal (int (*)())bfd_0
6f715d66 2960#define ieee_core_file_matches_executable_p ( FOO(boolean, (*),(bfd *, bfd *)))bfd_false
9872a49c
SC
2961#define ieee_slurp_armap bfd_true
2962#define ieee_slurp_extended_name_table bfd_true
d0ec7a8e 2963#define ieee_truncate_arname (void (*)())bfd_nullvoidptr
01dd1b2b 2964#define ieee_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, unsigned int, int))) bfd_nullvoidptr
d0ec7a8e 2965#define ieee_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
2b1d8a50 2966#define ieee_close_and_cleanup bfd_generic_close_and_cleanup
b2c91bd9 2967#define ieee_set_arch_mach bfd_default_set_arch_mach
e98e6ec1 2968#define ieee_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
69e0d34d 2969#define ieee_bfd_relax_section bfd_generic_relax_section
8feff717
ILT
2970#define ieee_bfd_seclet_link bfd_generic_seclet_link
2971#define ieee_bfd_reloc_type_lookup \
2972 ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
2973#define ieee_bfd_make_debug_symbol \
2974 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
2975
87f86b4e
DHW
2976/*SUPPRESS 460 */
2977bfd_target ieee_vec =
2978{
2979 "ieee", /* name */
01dd1b2b 2980 bfd_target_ieee_flavour,
87f86b4e
DHW
2981 true, /* target byte order */
2982 true, /* target headers byte order */
2983 (HAS_RELOC | EXEC_P | /* object flags */
2984 HAS_LINENO | HAS_DEBUG |
2985 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
e98e6ec1 2986 ( SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
87f86b4e 2987 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
294eaca4 2988 0, /* leading underscore */
87f86b4e
DHW
2989 ' ', /* ar_pad_char */
2990 16, /* ar_max_namelen */
6f715d66 2991 1, /* minimum alignment */
7ed4093a
SC
2992_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
2993_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
87f86b4e 2994
d0ec7a8e 2995 { _bfd_dummy_target,
87f86b4e
DHW
2996 ieee_object_p, /* bfd_check_format */
2997 ieee_archive_p,
d0ec7a8e 2998 _bfd_dummy_target,
87f86b4e
DHW
2999 },
3000 {
3001 bfd_false,
3002 ieee_mkobject,
3003 _bfd_generic_mkarchive,
3004 bfd_false
3005 },
2b1d8a50
JG
3006 {
3007 bfd_false,
3008 ieee_write_object_contents,
3009 _bfd_write_archive_contents,
3010 bfd_false,
3011 },
8feff717
ILT
3012 JUMP_TABLE(ieee),
3013 (PTR) 0
87f86b4e 3014};
aff6e0b4 3015
This page took 0.228524 seconds and 4 git commands to generate.