Tue Jan 19 09:06:14 1993 Ian Lance Taylor (ian@cygnus.com)
[deliverable/binutils-gdb.git] / bfd / ieee.c
CommitLineData
aff6e0b4
SC
1/* BFD back-end for ieee-695 objects.
2 Copyright 1990, 1991, 1992 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) {
87f86b4e
DHW
81 ieee_write_byte(abfd, value);
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
ce3f6d51 98 ieee_write_byte(abfd, (int)ieee_number_repeat_start_enum + length);
87f86b4e
DHW
99 switch (length) {
100 case 4:
101 ieee_write_byte(abfd, value >> 24);
102 case 3:
103 ieee_write_byte(abfd, value >> 16);
104 case 2:
105 ieee_write_byte(abfd, value >> 8);
106 case 1:
107 ieee_write_byte(abfd, value);
108 }
109 }
110}
111
112static void
301dfc71
SC
113DEFUN(ieee_write_id,(abfd, id),
114 bfd *abfd AND
115 CONST char *id)
87f86b4e
DHW
116{
117 size_t length = strlen(id);
118 if (length >= 0 && length <= 127) {
119 ieee_write_byte(abfd, length);
120 }
121 else if (length < 255) {
122 ieee_write_byte(abfd, ieee_extension_length_1_enum);
123 ieee_write_byte(abfd, length);
124 }
125 else if (length < 65535) {
126 ieee_write_byte(abfd, ieee_extension_length_2_enum);
127 ieee_write_byte(abfd, length >> 8);
128 ieee_write_byte(abfd, length & 0xff);
129 }
130 else {
131 BFD_FAIL();
132 }
d0ec7a8e 133 bfd_write((PTR)id, 1, length, abfd);
87f86b4e
DHW
134}
135/***************************************************************************
136Functions for reading from ieee files in the strange way that the
137standard requires:
138*/
87f86b4e 139
d0ec7a8e 140
6f715d66
SC
141#define this_byte(ieee) *((ieee)->input_p)
142#define next_byte(ieee) ((ieee)->input_p++)
143#define this_byte_and_next(ieee) (*((ieee)->input_p++))
87f86b4e
DHW
144
145
301dfc71 146static unsigned short
d0ec7a8e 147DEFUN(read_2bytes,(ieee),
6f715d66 148 common_header_type *ieee)
87f86b4e 149{
d0ec7a8e
SC
150 unsigned char c1 = this_byte_and_next(ieee);
151 unsigned char c2 = this_byte_and_next(ieee);
87f86b4e
DHW
152 return (c1<<8 ) | c2;
153
154}
155
156static void
d0ec7a8e 157DEFUN(bfd_get_string,(ieee, string, length),
6f715d66 158 common_header_type *ieee AND
301dfc71
SC
159 char *string AND
160 size_t length)
87f86b4e
DHW
161{
162 size_t i;
163 for (i= 0; i < length; i++) {
d0ec7a8e 164 string[i] = this_byte_and_next(ieee);
87f86b4e
DHW
165 }
166}
167
301dfc71 168static char *
d0ec7a8e 169DEFUN(read_id,(ieee),
6f715d66 170 common_header_type *ieee)
87f86b4e
DHW
171{
172 size_t length;
173 char *string;
d0ec7a8e 174 length = this_byte_and_next(ieee);
87f86b4e
DHW
175 if (length >= 0x00 && length <= 0x7f) {
176 /* Simple string of length 0 to 127 */
177 }
178 else if (length == 0xde) {
179 /* Length is next byte, allowing 0..255 */
d0ec7a8e 180 length = this_byte_and_next(ieee);
87f86b4e
DHW
181 }
182 else if (length == 0xdf) {
183 /* Length is next two bytes, allowing 0..65535 */
d0ec7a8e
SC
184 length = this_byte_and_next(ieee) ;
185 length = (length * 256) + this_byte_and_next(ieee);
87f86b4e
DHW
186 }
187 /* Buy memory and read string */
d0ec7a8e
SC
188 string = bfd_alloc(ieee->abfd, length+1);
189 bfd_get_string(ieee, string, length);
87f86b4e
DHW
190 string[length] = 0;
191 return string;
192}
193
194static void
69e0d34d 195DEFUN(ieee_write_expression,(abfd, value, symbol, pcrel, index),
301dfc71
SC
196 bfd*abfd AND
197 bfd_vma value AND
d0ec7a8e
SC
198 asymbol *symbol AND
199 boolean pcrel AND
b2c91bd9 200 unsigned int index)
87f86b4e 201{
69e0d34d 202 unsigned int term_count = 0;
b2c91bd9 203
69e0d34d
SC
204 if (value != 0)
205 {
206 ieee_write_int(abfd, value);
207 term_count++;
87f86b4e 208 }
69e0d34d
SC
209
210
87f86b4e 211
69e0d34d
SC
212 if (symbol->section == &bfd_com_section
213 || symbol->section == &bfd_und_section)
214 {
215 /* Def of a common symbol */
216 ieee_write_byte(abfd, ieee_variable_X_enum);
217 ieee_write_int(abfd, symbol->value);
218 term_count++;
219 }
220 else if (symbol->section != &bfd_abs_section)
221 {
222 /* Ref to defined symbol - */
223
224 ieee_write_byte(abfd, ieee_variable_R_enum);
225 ieee_write_byte(abfd, symbol->section->index + IEEE_SECTION_NUMBER_BASE);
226 term_count++;
227 if (symbol->flags & BSF_GLOBAL)
228 {
87f86b4e
DHW
229 ieee_write_byte(abfd, ieee_variable_I_enum);
230 ieee_write_int(abfd, symbol->value);
69e0d34d 231 term_count++;
87f86b4e 232 }
69e0d34d
SC
233 else if (symbol->flags & ( BSF_LOCAL | BSF_SECTION_SYM))
234 {
301dfc71
SC
235 /* This is a reference to a defined local symbol,
236 We can easily do a local as a section+offset */
69e0d34d
SC
237 ieee_write_byte(abfd, ieee_variable_R_enum); /* or L */
238 ieee_write_byte(abfd, symbol->section->index +
239 IEEE_SECTION_NUMBER_BASE);
301dfc71 240 ieee_write_int(abfd, symbol->value);
69e0d34d 241 term_count++;
301dfc71 242
87f86b4e 243 }
69e0d34d
SC
244 else {
245 BFD_FAIL();
246 }
247
87f86b4e
DHW
248 }
249
69e0d34d
SC
250
251
d0ec7a8e 252 if(pcrel) {
69e0d34d
SC
253 /* subtract the pc from here by asking for PC of this section*/
254 ieee_write_byte(abfd, ieee_variable_P_enum);
255 ieee_write_byte(abfd, index +IEEE_SECTION_NUMBER_BASE);
256 ieee_write_byte(abfd, ieee_function_minus_enum);
257 }
258
259 if (term_count == 1)
260 {
261 ieee_write_byte(abfd,0);
d0ec7a8e 262 }
69e0d34d
SC
263 else {
264 while (term_count > 1) {
265 ieee_write_byte(abfd, ieee_function_plus_enum);
266 term_count--;
267 }
d0ec7a8e 268
b2c91bd9 269 }
87f86b4e
DHW
270
271}
272
273
274
275
276
277
278
279
87f86b4e
DHW
280/*****************************************************************************/
281
282/*
283writes any integer into the buffer supplied and always takes 5 bytes
284*/
285static void
301dfc71
SC
286DEFUN(ieee_write_int5,(buffer, value),
287 bfd_byte*buffer AND
288 bfd_vma value )
87f86b4e 289{
b2c91bd9 290 buffer[0] = (bfd_byte)ieee_number_repeat_4_enum;
87f86b4e
DHW
291 buffer[1] = (value >> 24 ) & 0xff;
292 buffer[2] = (value >> 16 ) & 0xff;
293 buffer[3] = (value >> 8 ) & 0xff;
301dfc71
SC
294 buffer[4] = (value >> 0 ) & 0xff;
295}
296static void
297DEFUN(ieee_write_int5_out, (abfd, value),
298 bfd *abfd AND
299 bfd_vma value)
300{
d0ec7a8e 301 bfd_byte b[5];
301dfc71 302 ieee_write_int5(b, value);
d0ec7a8e 303 bfd_write((PTR)b,1,5,abfd);
87f86b4e 304}
87f86b4e
DHW
305
306
307static boolean
d0ec7a8e 308DEFUN(parse_int,(ieee, value_ptr),
6f715d66 309 common_header_type *ieee AND
301dfc71 310 bfd_vma *value_ptr)
87f86b4e 311{
d0ec7a8e 312 int value = this_byte(ieee);
87f86b4e
DHW
313 int result;
314 if (value >= 0 && value <= 127) {
315 *value_ptr = value;
d0ec7a8e 316 next_byte(ieee);
87f86b4e
DHW
317 return true;
318 }
319 else if (value >= 0x80 && value <= 0x88) {
320 unsigned int count = value & 0xf;
321 result = 0;
d0ec7a8e 322 next_byte(ieee);
87f86b4e 323 while (count) {
d0ec7a8e 324 result =(result << 8) | this_byte_and_next(ieee);
87f86b4e
DHW
325 count--;
326 }
327 *value_ptr = result;
328 return true;
329 }
330 return false;
331}
301dfc71 332static int
d0ec7a8e 333DEFUN(parse_i,(ieee, ok),
6f715d66 334 common_header_type *ieee AND
301dfc71 335 boolean *ok)
87f86b4e
DHW
336{
337 bfd_vma x;
d0ec7a8e 338 *ok = parse_int(ieee, &x);
87f86b4e
DHW
339 return x;
340}
341
301dfc71 342static bfd_vma
d0ec7a8e 343DEFUN(must_parse_int,(ieee),
6f715d66 344 common_header_type *ieee)
87f86b4e
DHW
345{
346 bfd_vma result;
d0ec7a8e 347 BFD_ASSERT(parse_int(ieee, &result) == true);
87f86b4e
DHW
348 return result;
349}
350
351typedef struct
352{
353 bfd_vma value;
354 asection *section;
355 ieee_symbol_index_type symbol;
356} ieee_value_type;
357
358
359static
360reloc_howto_type abs32_howto
b2c91bd9 361 = HOWTO(1,0,2,32,false,0,false,true,0,"abs32",true,0xffffffff, 0xffffffff,false);
87f86b4e
DHW
362static
363reloc_howto_type abs16_howto
b2c91bd9
SC
364 = HOWTO(1,0,1,16,false,0,false,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false);
365
366static
367reloc_howto_type abs8_howto
368 = HOWTO(1,0,0,8,false,0,false,true,0,"abs8",true,0x000000ff, 0x000000ff,false);
d0ec7a8e
SC
369
370static
371reloc_howto_type rel32_howto
9465d03e
SC
372 = HOWTO(1,0,2,32,true,0,false,true,0,"rel32",true,0xffffffff,
373 0xffffffff,false);
374
d0ec7a8e
SC
375static
376reloc_howto_type rel16_howto
9465d03e 377 = HOWTO(1,0,1,16,true,0,false,true,0,"rel16",true,0x0000ffff, 0x0000ffff,false);
b2c91bd9
SC
378
379static
380reloc_howto_type rel8_howto
9465d03e 381 = HOWTO(1,0,0,8,true,0,false,true,0,"rel8",true,0x000000ff, 0x000000ff,false);
b2c91bd9 382
87f86b4e
DHW
383
384static ieee_symbol_index_type NOSYMBOL = { 0, 0};
385
386
301dfc71 387static void
9465d03e 388DEFUN(parse_expression,(ieee, value, symbol, pcrel, extra, section),
d0ec7a8e 389 ieee_data_type *ieee AND
301dfc71 390 bfd_vma *value AND
301dfc71
SC
391 ieee_symbol_index_type *symbol AND
392 boolean *pcrel AND
9465d03e
SC
393 unsigned int *extra AND
394 asection **section)
d0ec7a8e 395
87f86b4e
DHW
396{
397#define POS sp[1]
398#define TOS sp[0]
399#define NOS sp[-1]
400#define INC sp++;
401#define DEC sp--;
69e0d34d 402
e98e6ec1 403
87f86b4e
DHW
404 boolean loop = true;
405 ieee_value_type stack[10];
406
407 /* The stack pointer always points to the next unused location */
408#define PUSH(x,y,z) TOS.symbol=x;TOS.section=y;TOS.value=z;INC;
409#define POP(x,y,z) DEC;x=TOS.symbol;y=TOS.section;z=TOS.value;
410 ieee_value_type *sp = stack;
411
412 while (loop) {
6f715d66 413 switch (this_byte(&(ieee->h)))
87f86b4e 414 {
d0ec7a8e
SC
415 case ieee_variable_P_enum:
416 /* P variable, current program counter for section n */
417 {
418 int section_n ;
6f715d66 419 next_byte(&(ieee->h));
d0ec7a8e 420 *pcrel = true;
6f715d66 421 section_n = must_parse_int(&(ieee->h));
69e0d34d 422 PUSH(NOSYMBOL, &bfd_abs_section,
d0ec7a8e
SC
423 TOS.value = ieee->section_table[section_n]->vma +
424 ieee_per_section(ieee->section_table[section_n])->pc);
425 break;
426 }
427 case ieee_variable_L_enum:
428 /* L variable address of section N */
6f715d66
SC
429 next_byte(&(ieee->h));
430 PUSH(NOSYMBOL,ieee->section_table[must_parse_int(&(ieee->h))],0);
d0ec7a8e
SC
431 break;
432 case ieee_variable_R_enum:
433 /* R variable, logical address of section module */
434 /* FIXME, this should be different to L */
6f715d66
SC
435 next_byte(&(ieee->h));
436 PUSH(NOSYMBOL,ieee->section_table[must_parse_int(&(ieee->h))],0);
d0ec7a8e
SC
437 break;
438 case ieee_variable_S_enum:
439 /* S variable, size in MAUS of section module */
6f715d66 440 next_byte(&(ieee->h));
d0ec7a8e
SC
441 PUSH(NOSYMBOL,
442 0,
69e0d34d 443 ieee->section_table[must_parse_int(&(ieee->h))]->_raw_size);
87f86b4e 444 break;
b2c91bd9 445 case ieee_variable_I_enum:
d0ec7a8e
SC
446 case ieee_variable_X_enum:
447 /* Push the address of external variable n */
448 {
449 ieee_symbol_index_type sy;
6f715d66
SC
450 next_byte(&(ieee->h));
451 sy.index = (int)(must_parse_int(&(ieee->h))) ;
d0ec7a8e 452 sy.letter = 'X';
87f86b4e 453
69e0d34d 454 PUSH(sy, &bfd_und_section, 0);
d0ec7a8e
SC
455 }
456 break;
457 case ieee_function_minus_enum:
87f86b4e 458 {
d0ec7a8e
SC
459 bfd_vma value1, value2;
460 asection *section1, *section_dummy;
461 ieee_symbol_index_type sy;
6f715d66 462 next_byte(&(ieee->h));
d0ec7a8e
SC
463
464 POP(sy, section1, value1);
465 POP(sy, section_dummy, value2);
b2c91bd9 466 PUSH(sy, section1 ? section1 : section_dummy, value1-value2);
87f86b4e 467 }
d0ec7a8e
SC
468 break;
469 case ieee_function_plus_enum:
470 {
471 bfd_vma value1, value2;
472 asection *section1;
473 asection *section2;
474 ieee_symbol_index_type sy1;
475 ieee_symbol_index_type sy2;
6f715d66 476 next_byte(&(ieee->h));
d0ec7a8e
SC
477
478 POP(sy1, section1, value1);
479 POP(sy2, section2, value2);
9465d03e 480 PUSH(sy1.letter ? sy1 : sy2, section1!=&bfd_abs_section ? section1: section2, value1+value2);
87f86b4e 481 }
d0ec7a8e
SC
482 break;
483 default:
484 {
485 bfd_vma va;
6f715d66
SC
486 BFD_ASSERT(this_byte(&(ieee->h)) < (int)ieee_variable_A_enum
487 || this_byte(&(ieee->h)) > (int)ieee_variable_Z_enum);
488 if (parse_int(&(ieee->h), &va))
d0ec7a8e 489 {
69e0d34d 490 PUSH(NOSYMBOL, &bfd_abs_section, va);
d0ec7a8e
SC
491 }
492 else {
493 /*
494 Thats all that we can understand. As far as I can see
495 there is a bug in the Microtec IEEE output which I'm
496 using to scan, whereby the comma operator is ommited
497 sometimes in an expression, giving expressions with too
498 many terms. We can tell if that's the case by ensuring
499 that sp == stack here. If not, then we've pushed
500 something too far, so we keep adding
501 */
502
503 while (sp != stack+1) {
504 asection *section1;
505 ieee_symbol_index_type sy1;
506 POP(sy1, section1, *extra);
507 }
69e0d34d
SC
508 {
509 asection *dummy;
9465d03e 510
69e0d34d 511 POP(*symbol, dummy, *value);
9465d03e 512 if (section) *section = dummy;
69e0d34d
SC
513 }
514
d0ec7a8e
SC
515 loop = false;
516 }
87f86b4e 517 }
87f86b4e 518
d0ec7a8e 519 }
87f86b4e
DHW
520 }
521}
522
301dfc71
SC
523
524
525#define ieee_seek(abfd, offset) \
e98e6ec1 526 IEEE_DATA(abfd)->h.input_p = IEEE_DATA(abfd)->h.first_byte + offset
6f715d66 527
e98e6ec1 528#define ieee_pos(abfd) IEEE_DATA(abfd)->h.input_p -IEEE_DATA(abfd)->h.first_byte
87f86b4e 529
b2c91bd9 530static unsigned int last_index;
aff6e0b4 531static char last_type; /* is the index for an X or a D */
b2c91bd9
SC
532static ieee_symbol_type *
533DEFUN(get_symbol,(abfd,
534 ieee,
535 last_symbol,
536 symbol_count,
aff6e0b4
SC
537 pptr,
538 max_index,
539 this_type
b2c91bd9
SC
540 ),
541 bfd *abfd AND
542 ieee_data_type *ieee AND
543 ieee_symbol_type *last_symbol AND
544 unsigned int *symbol_count AND
545 ieee_symbol_type *** pptr AND
aff6e0b4
SC
546 unsigned int *max_index AND
547 char this_type
b2c91bd9
SC
548 )
549{
550 /* Need a new symbol */
551 unsigned int new_index = must_parse_int(&(ieee->h));
aff6e0b4 552 if (new_index != last_index || this_type != last_type) {
b2c91bd9
SC
553 ieee_symbol_type * new_symbol = (ieee_symbol_type *)bfd_alloc(ieee->h.abfd,
554 sizeof(ieee_symbol_type));
555
556 new_symbol->index = new_index;
557 last_index = new_index;
558 ( *symbol_count)++;
559 ** pptr= new_symbol;
560 *pptr = &new_symbol->next;
561 if (new_index > *max_index) {
562 *max_index = new_index;
563 }
aff6e0b4 564 last_type = this_type;
b2c91bd9
SC
565 return new_symbol;
566 }
567 return last_symbol;
568}
87f86b4e 569static void
301dfc71
SC
570DEFUN(ieee_slurp_external_symbols,(abfd),
571 bfd *abfd)
87f86b4e 572{
e98e6ec1 573 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e
DHW
574 file_ptr offset = ieee->w.r.external_part;
575
b2c91bd9 576
87f86b4e
DHW
577 ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols;
578 ieee_symbol_type **prev_reference_ptr = &ieee->external_reference;
b2c91bd9 579 ieee_symbol_type *symbol = (ieee_symbol_type *)NULL;
87f86b4e
DHW
580 unsigned int symbol_count = 0;
581 boolean loop = true;
b2c91bd9 582 last_index = 0xffffff;
87f86b4e
DHW
583 ieee->symbol_table_full = true;
584
301dfc71 585 ieee_seek(abfd, offset );
87f86b4e
DHW
586
587 while (loop) {
6f715d66 588 switch (this_byte(&(ieee->h))) {
b2c91bd9
SC
589 case ieee_nn_record:
590 next_byte(&(ieee->h));
aff6e0b4 591
b2c91bd9
SC
592 symbol = get_symbol(abfd, ieee, symbol, &symbol_count,
593 &prev_symbols_ptr,
aff6e0b4
SC
594 &ieee->external_symbol_max_index,'D');
595
b2c91bd9
SC
596
597 symbol->symbol.the_bfd = abfd;
598 symbol->symbol.name = read_id(&(ieee->h));
599 symbol->symbol.udata = (PTR)NULL;
600 symbol->symbol.flags = BSF_NO_FLAGS;
601
602
603 break;
87f86b4e 604 case ieee_external_symbol_enum:
6f715d66 605 next_byte(&(ieee->h));
b2c91bd9
SC
606
607 symbol = get_symbol(abfd, ieee, symbol, &symbol_count,
608 &prev_symbols_ptr,
aff6e0b4 609 &ieee->external_symbol_max_index,'D');
b2c91bd9 610
87f86b4e 611
87f86b4e 612 BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index);
b2c91bd9 613
87f86b4e 614 symbol->symbol.the_bfd = abfd;
6f715d66 615 symbol->symbol.name = read_id(&(ieee->h));
d0ec7a8e 616 symbol->symbol.udata = (PTR)NULL;
87f86b4e
DHW
617 symbol->symbol.flags = BSF_NO_FLAGS;
618 break;
619 case ieee_attribute_record_enum >> 8:
b2c91bd9
SC
620 {
621 unsigned int symbol_name_index;
622 unsigned int symbol_type_index;
623 unsigned int symbol_attribute_def;
624 bfd_vma value;
625 next_byte(&(ieee->h)); /* Skip prefix */
626 next_byte(&(ieee->h));
627 symbol_name_index = must_parse_int(&(ieee->h));
628 symbol_type_index = must_parse_int(&(ieee->h));
629 symbol_attribute_def = must_parse_int(&(ieee->h));
630 switch (symbol_attribute_def) {
631 case 63:
632 /* Module misc; followed by two fields which describe the
633 current module block. The first fired is the type id
634 number, the second is the number of asn records
635 associated with the directive */
636 parse_int(&(ieee->h),&value);
637 parse_int(&(ieee->h),&value);
638 break;
87f86b4e 639
b2c91bd9
SC
640 default:
641 parse_int(&(ieee->h),&value);
642 break;
643 }
644 }
87f86b4e
DHW
645 break;
646 case ieee_value_record_enum >> 8:
b2c91bd9
SC
647 {
648 unsigned int symbol_name_index;
649 ieee_symbol_index_type symbol_ignore;
650 boolean pcrel_ignore;
651 unsigned int extra;
652 next_byte(&(ieee->h));
653 next_byte(&(ieee->h));
654
655 symbol_name_index = must_parse_int(&(ieee->h));
656 parse_expression(ieee,
657 &symbol->symbol.value,
b2c91bd9
SC
658 &symbol_ignore,
659 &pcrel_ignore,
9465d03e
SC
660 &extra,
661 &symbol->symbol.section);
e98e6ec1 662
b2c91bd9 663 symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
e98e6ec1 664
87f86b4e 665 }
87f86b4e
DHW
666 break;
667 case ieee_weak_external_reference_enum:
b2c91bd9
SC
668 { bfd_vma size;
669 bfd_vma value ;
670 next_byte(&(ieee->h));
671 /* Throw away the external reference index */
672 (void)must_parse_int(&(ieee->h));
673 /* Fetch the default size if not resolved */
674 size = must_parse_int(&(ieee->h));
675 /* Fetch the defautlt value if available */
676 if ( parse_int(&(ieee->h), &value) == false) {
677 value = 0;
678 }
679 /* This turns into a common */
e98e6ec1 680 symbol->symbol.section = &bfd_com_section;
b2c91bd9 681 symbol->symbol.value = size;
87f86b4e 682 }
87f86b4e
DHW
683 break;
684
685 case ieee_external_reference_enum:
6f715d66 686 next_byte(&(ieee->h));
b2c91bd9
SC
687
688 symbol = get_symbol(abfd, ieee, symbol, &symbol_count,
689 &prev_reference_ptr,
aff6e0b4 690 &ieee->external_reference_max_index,'X');
b2c91bd9
SC
691
692
87f86b4e 693 symbol->symbol.the_bfd = abfd;
6f715d66 694 symbol->symbol.name = read_id(&(ieee->h));
d0ec7a8e 695 symbol->symbol.udata = (PTR)NULL;
e98e6ec1 696 symbol->symbol.section = &bfd_und_section;
87f86b4e 697 symbol->symbol.value = (bfd_vma)0;
e98e6ec1 698 symbol->symbol.flags = 0;
b2c91bd9 699
87f86b4e
DHW
700 BFD_ASSERT (symbol->index >= ieee->external_reference_min_index);
701 break;
702
703 default:
704 loop = false;
705 }
706 }
707
708 if (ieee->external_symbol_max_index != 0) {
709 ieee->external_symbol_count =
710 ieee->external_symbol_max_index -
711 ieee->external_symbol_min_index + 1 ;
712 }
713 else {
714 ieee->external_symbol_count = 0;
715 }
716
717
718 if(ieee->external_reference_max_index != 0) {
719 ieee->external_reference_count =
720 ieee->external_reference_max_index -
721 ieee->external_reference_min_index + 1;
722 }
723 else {
724 ieee->external_reference_count = 0;
725 }
726
727 abfd->symcount =
728 ieee->external_reference_count + ieee->external_symbol_count;
729
730 if (symbol_count != abfd->symcount) {
731 /* There are gaps in the table -- */
732 ieee->symbol_table_full = false;
733 }
b2c91bd9
SC
734
735
87f86b4e
DHW
736 *prev_symbols_ptr = (ieee_symbol_type *)NULL;
737 *prev_reference_ptr = (ieee_symbol_type *)NULL;
738}
739
740static void
301dfc71
SC
741DEFUN(ieee_slurp_symbol_table,(abfd),
742 bfd *abfd)
87f86b4e 743{
e98e6ec1 744 if (IEEE_DATA(abfd)->read_symbols == false) {
87f86b4e 745 ieee_slurp_external_symbols(abfd);
e98e6ec1 746 IEEE_DATA(abfd)->read_symbols= true;
87f86b4e
DHW
747 }
748}
749
d0ec7a8e 750unsigned int
301dfc71
SC
751DEFUN(ieee_get_symtab_upper_bound,(abfd),
752 bfd *abfd)
87f86b4e
DHW
753{
754 ieee_slurp_symbol_table (abfd);
755
756 return (abfd->symcount != 0) ?
757 (abfd->symcount+1) * (sizeof (ieee_symbol_type *)) : 0;
758}
759
760/*
761Move from our internal lists to the canon table, and insert in
762symbol index order
763*/
764
765extern bfd_target ieee_vec;
766unsigned int
301dfc71
SC
767DEFUN(ieee_get_symtab,(abfd, location),
768 bfd *abfd AND
769 asymbol **location)
87f86b4e
DHW
770{
771 ieee_symbol_type *symp;
772 static bfd dummy_bfd;
773 static asymbol empty_symbol =
294eaca4 774 { &dummy_bfd," ieee empty",(symvalue)0,BSF_DEBUGGING , &bfd_abs_section};
d0ec7a8e 775
294eaca4
SC
776 if (abfd->symcount)
777{
778 ieee_data_type *ieee = IEEE_DATA(abfd);
779 dummy_bfd.xvec= &ieee_vec;
780 ieee_slurp_symbol_table(abfd);
b2c91bd9 781
294eaca4
SC
782 if (ieee->symbol_table_full == false) {
783 /* Arrgh - there are gaps in the table, run through and fill them */
784 /* up with pointers to a null place */
785 unsigned int i;
786 for (i= 0; i < abfd->symcount; i++) {
787 location[i] = &empty_symbol;
788 }
789 }
b2c91bd9
SC
790
791
294eaca4
SC
792 ieee->external_symbol_base_offset= - ieee->external_symbol_min_index;
793 for (symp = IEEE_DATA(abfd)->external_symbols;
794 symp != (ieee_symbol_type *)NULL;
795 symp = symp->next) {
796 /* Place into table at correct index locations */
797 location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol;
87f86b4e 798
87f86b4e 799 }
87f86b4e 800
294eaca4
SC
801 /* The external refs are indexed in a bit */
802 ieee->external_reference_base_offset =
803 - ieee->external_reference_min_index +ieee->external_symbol_count ;
87f86b4e 804
294eaca4
SC
805 for (symp = IEEE_DATA(abfd)->external_reference;
806 symp != (ieee_symbol_type *)NULL;
807 symp = symp->next) {
808 location[symp->index + ieee->external_reference_base_offset] =
809 &symp->symbol;
87f86b4e 810
294eaca4 811 }
87f86b4e 812
87f86b4e
DHW
813
814
815
294eaca4 816 }
aff6e0b4
SC
817 if (abfd->symcount) {
818 location[abfd->symcount] = (asymbol *)NULL;
819 }
87f86b4e
DHW
820 return abfd->symcount;
821}
b2c91bd9
SC
822static asection *
823DEFUN(get_section_entry,(abfd, ieee,index),
824 bfd *abfd AND
825 ieee_data_type *ieee AND
826 unsigned int index)
827{
828 if (ieee->section_table[index] == (asection *)NULL) {
aff6e0b4
SC
829 char *tmp = bfd_alloc(abfd,11);
830 asection *section;
831 sprintf(tmp," fsec%4d", index);
832 section = bfd_make_section(abfd, tmp);
b2c91bd9
SC
833 ieee->section_table[index] = section;
834 section->flags = SEC_NO_FLAGS;
835 section->target_index = index;
836 ieee->section_table[index] = section;
837 }
838 return ieee->section_table[index];
839}
87f86b4e
DHW
840
841static void
301dfc71
SC
842DEFUN(ieee_slurp_sections,(abfd),
843 bfd *abfd)
87f86b4e 844{
e98e6ec1 845 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e
DHW
846 file_ptr offset = ieee->w.r.section_part;
847
848 asection *section = (asection *)NULL;
849
850 if (offset != 0) {
851 bfd_byte section_type[3];
301dfc71 852 ieee_seek(abfd, offset);
87f86b4e 853 while (true) {
6f715d66 854 switch (this_byte(&(ieee->h))) {
87f86b4e 855 case ieee_section_type_enum:
b2c91bd9
SC
856 {
857 unsigned int section_index ;
858 next_byte(&(ieee->h));
859 section_index = must_parse_int(&(ieee->h));
860 /* Fixme to be nice about a silly number of sections */
861 BFD_ASSERT(section_index < NSECTIONS);
862
863 section =get_section_entry(abfd, ieee, section_index);
864
865 section_type[0] = this_byte_and_next(&(ieee->h));
866 switch (section_type[0]) {
867 case 0xC1:
868 /* Normal attributes for absolute sections */
869 section_type[1] = this_byte(&(ieee->h));
870 section->flags = SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
871 switch(section_type[1]) {
872 case 0xD3:
873 next_byte(&(ieee->h));
874 section_type[2] = this_byte(&(ieee->h));
875 switch (section_type[2])
876 {
877 case 0xD0:
878 /* Normal code */
879 next_byte(&(ieee->h));
880 section->flags |= SEC_LOAD | SEC_CODE;
881 break;
882 case 0xC4:
883 next_byte(&(ieee->h));
884 section->flags |= SEC_LOAD | SEC_DATA;
885 /* Normal data */
886 break;
887 case 0xD2:
888 next_byte(&(ieee->h));
889 /* Normal rom data */
890 section->flags |= SEC_LOAD | SEC_ROM | SEC_DATA;
891 break;
892 default:
893 break;
894 }
895 }
87f86b4e 896 break;
b2c91bd9
SC
897 case 0xC3:
898 section_type[1] = this_byte(&(ieee->h));
899 section->flags = SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
900 switch (section_type[1]) {
901 case 0xD0:
902 /* Normal code */
903 next_byte(&(ieee->h));
904 section->flags |= SEC_LOAD | SEC_CODE;
905 break;
906 case 0xC4:
907 next_byte(&(ieee->h));
908 section->flags |= SEC_LOAD | SEC_DATA;
909 /* Normal data */
910 break;
911 case 0xD2:
912 next_byte(&(ieee->h));
913 /* Normal rom data */
914 section->flags |= SEC_LOAD | SEC_ROM | SEC_DATA;
915 break;
916 default:
917 break;
918 }
87f86b4e 919 }
aff6e0b4
SC
920 memcpy(section->name, read_id(&(ieee->h)),8);
921 /* Truncate sections to 8 chars */
922 if (strlen(section->name) > 8)
923 {
924 section->name[8] = 0;
925 }
b2c91bd9
SC
926 { bfd_vma parent, brother, context;
927 parse_int(&(ieee->h), &parent);
928 parse_int(&(ieee->h), &brother);
929 parse_int(&(ieee->h), &context);
930 }
87f86b4e
DHW
931
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
SC
1493 bfd_vma value;
1494 asection *dsection;
1495 ieee_symbol_index_type symbol;
1496 unsigned int extra;
1497 boolean pcrel;
6f715d66
SC
1498 next_byte(&(ieee->h));
1499 must_parse_int(&(ieee->h)); /* Thow away section #*/
e98e6ec1 1500 parse_expression(ieee, &value,
69e0d34d 1501 &symbol,
9465d03e
SC
1502 &pcrel, &extra,
1503 0);
7564d3d7 1504 current_map->pc = value;
e98e6ec1 1505 BFD_ASSERT((unsigned)(value - s->vma) <= s->_raw_size);
87f86b4e 1506 }
7564d3d7
SC
1507 break;
1508
1509 case ieee_value_starting_address_enum & 0xff:
1510 /* We've got to the end of the data now - */
1511 return true;
1512 default:
1513 BFD_FAIL();
1514 return true;
1515 }
1516 break;
1517 case ieee_repeat_data_enum:
1518 {
1519 /* Repeat the following LD or LR n times - we do this by
1520 remembering the stream pointer before running it and
6f715d66
SC
1521 resetting it and running it n times. We special case
1522 the repetition of a repeat_data/load_constant
7564d3d7
SC
1523 */
1524
1525 unsigned int iterations ;
1526 uint8e_type *start ;
6f715d66
SC
1527 next_byte(&(ieee->h));
1528 iterations = must_parse_int(&(ieee->h));
1529 start = ieee->h.input_p;
b2c91bd9 1530 if (start[0] == (int)ieee_load_constant_bytes_enum &&
6f715d66
SC
1531 start[1] == 1) {
1532 while (iterations != 0) {
1533 location_ptr[current_map->pc++] = start[2];
1534 iterations--;
1535 }
1536 next_byte(&(ieee->h));
1537 next_byte(&(ieee->h));
1538 next_byte(&(ieee->h));
1539 }
1540 else {
1541 while (iterations != 0) {
1542 ieee->h.input_p = start;
1543 do_one(ieee, current_map, location_ptr,s);
1544 iterations --;
1545 }
7564d3d7
SC
1546 }
1547 }
1548 break;
1549 case ieee_load_constant_bytes_enum:
1550 case ieee_load_with_relocation_enum:
1551 {
1552 do_one(ieee, current_map, location_ptr,s);
87f86b4e
DHW
1553 }
1554 }
87f86b4e
DHW
1555 }
1556}
1557
1558
1559
7564d3d7
SC
1560
1561
87f86b4e 1562boolean
301dfc71
SC
1563DEFUN(ieee_new_section_hook,(abfd, newsect),
1564 bfd *abfd AND
1565 asection *newsect)
87f86b4e 1566{
a6dab071 1567 newsect->used_by_bfd = (PTR)
d0ec7a8e 1568 bfd_alloc(abfd, sizeof(ieee_per_section_type));
87f86b4e
DHW
1569 ieee_per_section( newsect)->data = (bfd_byte *)NULL;
1570 ieee_per_section(newsect)->section = newsect;
1571 return true;
1572}
1573
1574
1575unsigned int
301dfc71
SC
1576DEFUN(ieee_get_reloc_upper_bound,(abfd, asect),
1577 bfd *abfd AND
1578 sec_ptr asect)
87f86b4e
DHW
1579{
1580 ieee_slurp_section_data(abfd);
1581 return (asect->reloc_count+1) * sizeof(arelent *);
1582}
1583
1584static boolean
301dfc71
SC
1585DEFUN(ieee_get_section_contents,(abfd, section, location, offset, count),
1586 bfd *abfd AND
1587 sec_ptr section AND
d0ec7a8e 1588 PTR location AND
301dfc71 1589 file_ptr offset AND
7ed4093a 1590 bfd_size_type count)
87f86b4e 1591{
a6dab071 1592 ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;
87f86b4e 1593 ieee_slurp_section_data(abfd);
b2c91bd9 1594 (void) memcpy((PTR)location, (PTR)(p->data + offset), (unsigned)count);
87f86b4e
DHW
1595 return true;
1596}
1597
1598
1599unsigned int
301dfc71
SC
1600DEFUN(ieee_canonicalize_reloc,(abfd, section, relptr, symbols),
1601 bfd *abfd AND
1602 sec_ptr section AND
1603 arelent **relptr AND
1604 asymbol **symbols)
87f86b4e 1605{
d0ec7a8e 1606/* ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;*/
87f86b4e 1607 ieee_reloc_type *src = (ieee_reloc_type *)(section->relocation);
e98e6ec1 1608 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e
DHW
1609
1610 while (src != (ieee_reloc_type *)NULL) {
b2c91bd9 1611 /* Work out which symbol to attach it this reloc to */
87f86b4e
DHW
1612 switch (src->symbol.letter) {
1613 case 'X':
1614 src->relent.sym_ptr_ptr =
1615 symbols + src->symbol.index + ieee->external_reference_base_offset;
1616 break;
1617 case 0:
aff6e0b4
SC
1618 src->relent.sym_ptr_ptr =
1619 src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr;
87f86b4e
DHW
1620 break;
1621 default:
1622
1623 BFD_FAIL();
1624 }
1625 *relptr++ = &src->relent;
1626 src = src->next;
1627 }
1628 *relptr = (arelent *)NULL;
1629 return section->reloc_count;
1630}
1631
87f86b4e 1632
87f86b4e 1633
301dfc71
SC
1634static int
1635DEFUN(comp,(ap, bp),
39a2ce33
SC
1636 CONST PTR ap AND
1637 CONST PTR bp)
87f86b4e 1638{
9872a49c
SC
1639 arelent *a = *((arelent **)ap);
1640 arelent *b = *((arelent **)bp);
87f86b4e
DHW
1641 return a->address - b->address;
1642}
9872a49c 1643
87f86b4e
DHW
1644/*
1645Write the section headers
1646*/
1647
1648static void
301dfc71
SC
1649DEFUN(ieee_write_section_part,(abfd),
1650 bfd *abfd)
87f86b4e 1651{
e98e6ec1 1652 ieee_data_type *ieee = IEEE_DATA(abfd);
87f86b4e
DHW
1653 asection *s;
1654 ieee->w.r.section_part = bfd_tell(abfd);
1655 for (s = abfd->sections; s != (asection *)NULL; s=s->next) {
e98e6ec1
SC
1656 if (s != &bfd_abs_section)
1657 {
1658
1659 ieee_write_byte(abfd, ieee_section_type_enum);
1660 ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
87f86b4e 1661
e98e6ec1 1662 if (abfd->flags & EXEC_P)
6f715d66
SC
1663 {
1664 /* This image is executable, so output absolute sections */
1665 ieee_write_byte(abfd, ieee_variable_A_enum);
1666 ieee_write_byte(abfd, ieee_variable_S_enum);
1667 }
e98e6ec1 1668 else
6f715d66
SC
1669 {
1670 ieee_write_byte(abfd, ieee_variable_C_enum);
1671 }
1672
e98e6ec1 1673 switch (s->flags &(SEC_CODE | SEC_DATA | SEC_ROM))
6f715d66
SC
1674 {
1675 case SEC_CODE | SEC_LOAD:
1676 case SEC_CODE:
1677 ieee_write_byte(abfd, ieee_variable_P_enum);
1678 break;
1679 case SEC_DATA:
1680 default:
1681 ieee_write_byte(abfd, ieee_variable_D_enum);
1682 break;
1683 case SEC_ROM:
1684 case SEC_ROM | SEC_DATA:
1685 case SEC_ROM | SEC_LOAD:
1686 case SEC_ROM | SEC_DATA | SEC_LOAD:
1687
1688 ieee_write_byte(abfd, ieee_variable_R_enum);
1689 }
1690
87f86b4e 1691
e98e6ec1 1692 ieee_write_id(abfd, s->name);
6f715d66 1693#if 0
e98e6ec1
SC
1694 ieee_write_int(abfd, 0); /* Parent */
1695 ieee_write_int(abfd, 0); /* Brother */
1696 ieee_write_int(abfd, 0); /* Context */
6f715d66 1697#endif
e98e6ec1
SC
1698 /* Alignment */
1699 ieee_write_byte(abfd, ieee_section_alignment_enum);
1700 ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
1701 ieee_write_int(abfd, 1 << s->alignment_power);
1702
1703 /* Size */
1704 ieee_write_2bytes(abfd, ieee_section_size_enum);
1705 ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
69e0d34d 1706 ieee_write_int(abfd, s->_raw_size);
e98e6ec1
SC
1707 if (abfd->flags & EXEC_P) {
1708 /* Relocateable sections don't have asl records */
1709 /* Vma */
1710 ieee_write_2bytes(abfd, ieee_section_base_address_enum);
1711 ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
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);
1741 ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
6f715d66 1742
b2c91bd9
SC
1743 ieee_write_twobyte(abfd, ieee_set_current_pc_enum);
1744 ieee_write_byte(abfd, 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);
1883 ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
1884 ieee_write_byte(abfd, ieee_set_current_pc_enum >> 8);
1885 ieee_write_byte(abfd, ieee_set_current_pc_enum & 0xff);
1886 ieee_write_byte(abfd, s->index + IEEE_SECTION_NUMBER_BASE);
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 }
e98e6ec1 2609 else if(p->section == &bfd_com_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
69e0d34d 2678CONST static 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
69e0d34d 2686CONST static 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 */
2737 ieee_write_byte(abfd, bfd_arch_bits_per_byte(abfd));
2738 /* MAU's per address */
2739 ieee_write_byte(abfd, bfd_arch_bits_per_address(abfd) /
2740 bfd_arch_bits_per_byte(abfd));
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);
2793 ieee_write_byte(abfd, 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
87f86b4e
DHW
2970/*SUPPRESS 460 */
2971bfd_target ieee_vec =
2972{
2973 "ieee", /* name */
01dd1b2b 2974 bfd_target_ieee_flavour,
87f86b4e
DHW
2975 true, /* target byte order */
2976 true, /* target headers byte order */
2977 (HAS_RELOC | EXEC_P | /* object flags */
2978 HAS_LINENO | HAS_DEBUG |
2979 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
e98e6ec1 2980 ( SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
87f86b4e 2981 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
294eaca4 2982 0, /* leading underscore */
87f86b4e
DHW
2983 ' ', /* ar_pad_char */
2984 16, /* ar_max_namelen */
6f715d66 2985 1, /* minimum alignment */
7ed4093a
SC
2986_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
2987_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
87f86b4e 2988
d0ec7a8e 2989 { _bfd_dummy_target,
87f86b4e
DHW
2990 ieee_object_p, /* bfd_check_format */
2991 ieee_archive_p,
d0ec7a8e 2992 _bfd_dummy_target,
87f86b4e
DHW
2993 },
2994 {
2995 bfd_false,
2996 ieee_mkobject,
2997 _bfd_generic_mkarchive,
2998 bfd_false
2999 },
2b1d8a50
JG
3000 {
3001 bfd_false,
3002 ieee_write_object_contents,
3003 _bfd_write_archive_contents,
3004 bfd_false,
3005 },
3006 JUMP_TABLE(ieee)
87f86b4e 3007};
aff6e0b4 3008
This page took 0.205925 seconds and 4 git commands to generate.