133965Sjdp/* BFD back-end for ieee-695 objects. 278828Sobrien Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3218822Sdim 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 433965Sjdp Free Software Foundation, Inc. 533965Sjdp 633965Sjdp Written by Steve Chamberlain of Cygnus Support. 733965Sjdp 891041Sobrien This file is part of BFD, the Binary File Descriptor library. 933965Sjdp 1091041Sobrien This program is free software; you can redistribute it and/or modify 1191041Sobrien it under the terms of the GNU General Public License as published by 1291041Sobrien the Free Software Foundation; either version 2 of the License, or 1391041Sobrien (at your option) any later version. 1433965Sjdp 1591041Sobrien This program is distributed in the hope that it will be useful, 1691041Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1791041Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1891041Sobrien GNU General Public License for more details. 1933965Sjdp 2091041Sobrien You should have received a copy of the GNU General Public License 2191041Sobrien along with this program; if not, write to the Free Software 22218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2333965Sjdp 2433965Sjdp#define KEEPMINUSPCININST 0 2533965Sjdp 2633965Sjdp/* IEEE 695 format is a stream of records, which we parse using a simple one- 2733965Sjdp token (which is one byte in this lexicon) lookahead recursive decent 2833965Sjdp parser. */ 2933965Sjdp 30218822Sdim#include "sysdep.h" 3133965Sjdp#include "bfd.h" 3233965Sjdp#include "libbfd.h" 3333965Sjdp#include "ieee.h" 3433965Sjdp#include "libieee.h" 3589857Sobrien#include "safe-ctype.h" 3633965Sjdp 3789857Sobrienstruct output_buffer_struct 3889857Sobrien{ 3989857Sobrien unsigned char *ptrp; 4089857Sobrien int buffer; 4189857Sobrien}; 4260484Sobrien 43218822Sdimstatic unsigned char *output_ptr_start; 44218822Sdimstatic unsigned char *output_ptr; 45218822Sdimstatic unsigned char *output_ptr_end; 46218822Sdimstatic unsigned char *input_ptr_start; 47218822Sdimstatic unsigned char *input_ptr; 48218822Sdimstatic unsigned char *input_ptr_end; 49218822Sdimstatic bfd *input_bfd; 50218822Sdimstatic bfd *output_bfd; 51218822Sdimstatic int output_buffer; 5233965Sjdp 53218822Sdim 54218822Sdimstatic void block (void); 55218822Sdim 5633965Sjdp/* Functions for writing to ieee files in the strange way that the 57218822Sdim standard requires. */ 5833965Sjdp 59130561Sobrienstatic bfd_boolean 60218822Sdimieee_write_byte (bfd *abfd, int barg) 6133965Sjdp{ 6233965Sjdp bfd_byte byte; 6333965Sjdp 6433965Sjdp byte = barg; 65218822Sdim if (bfd_bwrite ((void *) &byte, (bfd_size_type) 1, abfd) != 1) 66130561Sobrien return FALSE; 67130561Sobrien return TRUE; 6833965Sjdp} 6933965Sjdp 70130561Sobrienstatic bfd_boolean 71218822Sdimieee_write_2bytes (bfd *abfd, int bytes) 7233965Sjdp{ 7333965Sjdp bfd_byte buffer[2]; 7433965Sjdp 7533965Sjdp buffer[0] = bytes >> 8; 7633965Sjdp buffer[1] = bytes & 0xff; 77218822Sdim if (bfd_bwrite ((void *) buffer, (bfd_size_type) 2, abfd) != 2) 78130561Sobrien return FALSE; 79130561Sobrien return TRUE; 8033965Sjdp} 8133965Sjdp 82130561Sobrienstatic bfd_boolean 83218822Sdimieee_write_int (bfd *abfd, bfd_vma value) 8433965Sjdp{ 8533965Sjdp if (value <= 127) 8633965Sjdp { 8733965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) value)) 88130561Sobrien return FALSE; 8933965Sjdp } 9033965Sjdp else 9133965Sjdp { 9233965Sjdp unsigned int length; 9333965Sjdp 94130561Sobrien /* How many significant bytes ? */ 95130561Sobrien /* FIXME FOR LONGER INTS. */ 9633965Sjdp if (value & 0xff000000) 9733965Sjdp length = 4; 9833965Sjdp else if (value & 0x00ff0000) 9933965Sjdp length = 3; 10033965Sjdp else if (value & 0x0000ff00) 10133965Sjdp length = 2; 10233965Sjdp else 10333965Sjdp length = 1; 10433965Sjdp 10533965Sjdp if (! ieee_write_byte (abfd, 10633965Sjdp (bfd_byte) ((int) ieee_number_repeat_start_enum 10733965Sjdp + length))) 108130561Sobrien return FALSE; 10933965Sjdp switch (length) 11033965Sjdp { 11133965Sjdp case 4: 11233965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) (value >> 24))) 113130561Sobrien return FALSE; 11433965Sjdp /* Fall through. */ 11533965Sjdp case 3: 11633965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) (value >> 16))) 117130561Sobrien return FALSE; 11833965Sjdp /* Fall through. */ 11933965Sjdp case 2: 12033965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) (value >> 8))) 121130561Sobrien return FALSE; 12233965Sjdp /* Fall through. */ 12333965Sjdp case 1: 12433965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) (value))) 125130561Sobrien return FALSE; 12633965Sjdp } 12733965Sjdp } 12833965Sjdp 129130561Sobrien return TRUE; 13033965Sjdp} 13133965Sjdp 132130561Sobrienstatic bfd_boolean 133218822Sdimieee_write_id (bfd *abfd, const char *id) 13433965Sjdp{ 13533965Sjdp size_t length = strlen (id); 13633965Sjdp 13733965Sjdp if (length <= 127) 13833965Sjdp { 13933965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) length)) 140130561Sobrien return FALSE; 14133965Sjdp } 14233965Sjdp else if (length < 255) 14333965Sjdp { 14433965Sjdp if (! ieee_write_byte (abfd, ieee_extension_length_1_enum) 14533965Sjdp || ! ieee_write_byte (abfd, (bfd_byte) length)) 146130561Sobrien return FALSE; 14733965Sjdp } 14833965Sjdp else if (length < 65535) 14933965Sjdp { 15033965Sjdp if (! ieee_write_byte (abfd, ieee_extension_length_2_enum) 15133965Sjdp || ! ieee_write_2bytes (abfd, (int) length)) 152130561Sobrien return FALSE; 15333965Sjdp } 15433965Sjdp else 15533965Sjdp { 15633965Sjdp (*_bfd_error_handler) 15760484Sobrien (_("%s: string too long (%d chars, max 65535)"), 15833965Sjdp bfd_get_filename (abfd), length); 15933965Sjdp bfd_set_error (bfd_error_invalid_operation); 160130561Sobrien return FALSE; 16133965Sjdp } 16233965Sjdp 163218822Sdim if (bfd_bwrite ((void *) id, (bfd_size_type) length, abfd) != length) 164130561Sobrien return FALSE; 165130561Sobrien return TRUE; 16633965Sjdp} 16733965Sjdp 168130561Sobrien/* Functions for reading from ieee files in the strange way that the 169130561Sobrien standard requires. */ 17033965Sjdp 171218822Sdim#define this_byte(ieee) *((ieee)->input_p) 172218822Sdim#define next_byte(ieee) ((ieee)->input_p++) 17333965Sjdp#define this_byte_and_next(ieee) (*((ieee)->input_p++)) 17433965Sjdp 17533965Sjdpstatic unsigned short 176218822Sdimread_2bytes (common_header_type *ieee) 17733965Sjdp{ 17833965Sjdp unsigned char c1 = this_byte_and_next (ieee); 17933965Sjdp unsigned char c2 = this_byte_and_next (ieee); 180130561Sobrien 18133965Sjdp return (c1 << 8) | c2; 18233965Sjdp} 18333965Sjdp 18433965Sjdpstatic void 185218822Sdimbfd_get_string (common_header_type *ieee, char *string, size_t length) 18633965Sjdp{ 18733965Sjdp size_t i; 188130561Sobrien 18933965Sjdp for (i = 0; i < length; i++) 190130561Sobrien string[i] = this_byte_and_next (ieee); 19133965Sjdp} 19233965Sjdp 19333965Sjdpstatic char * 194218822Sdimread_id (common_header_type *ieee) 19533965Sjdp{ 19633965Sjdp size_t length; 19733965Sjdp char *string; 198130561Sobrien 19933965Sjdp length = this_byte_and_next (ieee); 20033965Sjdp if (length <= 0x7f) 201218822Sdim /* Simple string of length 0 to 127. */ 202218822Sdim ; 203218822Sdim 20433965Sjdp else if (length == 0xde) 205218822Sdim /* Length is next byte, allowing 0..255. */ 206218822Sdim length = this_byte_and_next (ieee); 207218822Sdim 20833965Sjdp else if (length == 0xdf) 20933965Sjdp { 210130561Sobrien /* Length is next two bytes, allowing 0..65535. */ 21133965Sjdp length = this_byte_and_next (ieee); 21233965Sjdp length = (length * 256) + this_byte_and_next (ieee); 21333965Sjdp } 214130561Sobrien 215130561Sobrien /* Buy memory and read string. */ 21689857Sobrien string = bfd_alloc (ieee->abfd, (bfd_size_type) length + 1); 21733965Sjdp if (!string) 21833965Sjdp return NULL; 21933965Sjdp bfd_get_string (ieee, string, length); 22033965Sjdp string[length] = 0; 22133965Sjdp return string; 22233965Sjdp} 22333965Sjdp 224130561Sobrienstatic bfd_boolean 225218822Sdimieee_write_expression (bfd *abfd, 226218822Sdim bfd_vma value, 227218822Sdim asymbol *symbol, 228218822Sdim bfd_boolean pcrel, 229218822Sdim unsigned int index) 23033965Sjdp{ 23133965Sjdp unsigned int term_count = 0; 23233965Sjdp 23333965Sjdp if (value != 0) 23433965Sjdp { 23533965Sjdp if (! ieee_write_int (abfd, value)) 236130561Sobrien return FALSE; 23733965Sjdp term_count++; 23833965Sjdp } 23933965Sjdp 240130561Sobrien /* Badly formatted binaries can have a missing symbol, 241130561Sobrien so test here to prevent a seg fault. */ 242130561Sobrien if (symbol != NULL) 24333965Sjdp { 244130561Sobrien if (bfd_is_com_section (symbol->section) 245130561Sobrien || bfd_is_und_section (symbol->section)) 24633965Sjdp { 247130561Sobrien /* Def of a common symbol. */ 248130561Sobrien if (! ieee_write_byte (abfd, ieee_variable_X_enum) 24933965Sjdp || ! ieee_write_int (abfd, symbol->value)) 250130561Sobrien return FALSE; 251130561Sobrien term_count ++; 25233965Sjdp } 253130561Sobrien else if (! bfd_is_abs_section (symbol->section)) 25433965Sjdp { 255130561Sobrien /* Ref to defined symbol - */ 256130561Sobrien if (symbol->flags & BSF_GLOBAL) 25733965Sjdp { 258130561Sobrien if (! ieee_write_byte (abfd, ieee_variable_I_enum) 259130561Sobrien || ! ieee_write_int (abfd, symbol->value)) 260130561Sobrien return FALSE; 26133965Sjdp term_count++; 26233965Sjdp } 263130561Sobrien else if (symbol->flags & (BSF_LOCAL | BSF_SECTION_SYM)) 264130561Sobrien { 265130561Sobrien /* This is a reference to a defined local symbol. We can 266130561Sobrien easily do a local as a section+offset. */ 267130561Sobrien if (! ieee_write_byte (abfd, ieee_variable_R_enum) 268130561Sobrien || ! ieee_write_byte (abfd, 269130561Sobrien (bfd_byte) (symbol->section->index 270130561Sobrien + IEEE_SECTION_NUMBER_BASE))) 271130561Sobrien return FALSE; 272130561Sobrien 273130561Sobrien term_count++; 274130561Sobrien if (symbol->value != 0) 275130561Sobrien { 276130561Sobrien if (! ieee_write_int (abfd, symbol->value)) 277130561Sobrien return FALSE; 278130561Sobrien term_count++; 279130561Sobrien } 280130561Sobrien } 281130561Sobrien else 282130561Sobrien { 283130561Sobrien (*_bfd_error_handler) 284130561Sobrien (_("%s: unrecognized symbol `%s' flags 0x%x"), 285130561Sobrien bfd_get_filename (abfd), bfd_asymbol_name (symbol), 286130561Sobrien symbol->flags); 287130561Sobrien bfd_set_error (bfd_error_invalid_operation); 288130561Sobrien return FALSE; 289130561Sobrien } 29033965Sjdp } 29133965Sjdp } 29233965Sjdp 29333965Sjdp if (pcrel) 29433965Sjdp { 295130561Sobrien /* Subtract the pc from here by asking for PC of this section. */ 29633965Sjdp if (! ieee_write_byte (abfd, ieee_variable_P_enum) 29733965Sjdp || ! ieee_write_byte (abfd, 29833965Sjdp (bfd_byte) (index + IEEE_SECTION_NUMBER_BASE)) 29933965Sjdp || ! ieee_write_byte (abfd, ieee_function_minus_enum)) 300130561Sobrien return FALSE; 30133965Sjdp } 30233965Sjdp 30333965Sjdp /* Handle the degenerate case of a 0 address. */ 30433965Sjdp if (term_count == 0) 305130561Sobrien if (! ieee_write_int (abfd, (bfd_vma) 0)) 306130561Sobrien return FALSE; 30733965Sjdp 30833965Sjdp while (term_count > 1) 30933965Sjdp { 31033965Sjdp if (! ieee_write_byte (abfd, ieee_function_plus_enum)) 311130561Sobrien return FALSE; 31233965Sjdp term_count--; 31333965Sjdp } 31433965Sjdp 315130561Sobrien return TRUE; 31633965Sjdp} 31733965Sjdp 318130561Sobrien/* Writes any integer into the buffer supplied and always takes 5 bytes. */ 31933965Sjdp 32033965Sjdpstatic void 321218822Sdimieee_write_int5 (bfd_byte *buffer, bfd_vma value) 32233965Sjdp{ 32333965Sjdp buffer[0] = (bfd_byte) ieee_number_repeat_4_enum; 32433965Sjdp buffer[1] = (value >> 24) & 0xff; 32533965Sjdp buffer[2] = (value >> 16) & 0xff; 32633965Sjdp buffer[3] = (value >> 8) & 0xff; 32733965Sjdp buffer[4] = (value >> 0) & 0xff; 32833965Sjdp} 32933965Sjdp 330130561Sobrienstatic bfd_boolean 331218822Sdimieee_write_int5_out (bfd *abfd, bfd_vma value) 33233965Sjdp{ 33333965Sjdp bfd_byte b[5]; 33433965Sjdp 33533965Sjdp ieee_write_int5 (b, value); 336218822Sdim if (bfd_bwrite ((void *) b, (bfd_size_type) 5, abfd) != 5) 337130561Sobrien return FALSE; 338130561Sobrien return TRUE; 33933965Sjdp} 34033965Sjdp 341130561Sobrienstatic bfd_boolean 342218822Sdimparse_int (common_header_type *ieee, bfd_vma *value_ptr) 34333965Sjdp{ 34433965Sjdp int value = this_byte (ieee); 34533965Sjdp int result; 346130561Sobrien 34733965Sjdp if (value >= 0 && value <= 127) 34833965Sjdp { 34933965Sjdp *value_ptr = value; 35033965Sjdp next_byte (ieee); 351130561Sobrien return TRUE; 35233965Sjdp } 35333965Sjdp else if (value >= 0x80 && value <= 0x88) 35433965Sjdp { 35533965Sjdp unsigned int count = value & 0xf; 356130561Sobrien 35733965Sjdp result = 0; 35833965Sjdp next_byte (ieee); 35933965Sjdp while (count) 36033965Sjdp { 36133965Sjdp result = (result << 8) | this_byte_and_next (ieee); 36233965Sjdp count--; 36333965Sjdp } 36433965Sjdp *value_ptr = result; 365130561Sobrien return TRUE; 36633965Sjdp } 367130561Sobrien return FALSE; 36833965Sjdp} 36933965Sjdp 37033965Sjdpstatic int 371218822Sdimparse_i (common_header_type *ieee, bfd_boolean *ok) 37233965Sjdp{ 373218822Sdim bfd_vma x = 0; 37433965Sjdp *ok = parse_int (ieee, &x); 37533965Sjdp return x; 37633965Sjdp} 37733965Sjdp 37833965Sjdpstatic bfd_vma 379218822Sdimmust_parse_int (common_header_type *ieee) 38033965Sjdp{ 381218822Sdim bfd_vma result = 0; 382104834Sobrien BFD_ASSERT (parse_int (ieee, &result)); 38333965Sjdp return result; 38433965Sjdp} 38533965Sjdp 38633965Sjdptypedef struct 38733965Sjdp{ 38833965Sjdp bfd_vma value; 38933965Sjdp asection *section; 39033965Sjdp ieee_symbol_index_type symbol; 39133965Sjdp} ieee_value_type; 39233965Sjdp 39333965Sjdp 39433965Sjdp#if KEEPMINUSPCININST 39533965Sjdp 39633965Sjdp#define SRC_MASK(arg) arg 397130561Sobrien#define PCREL_OFFSET FALSE 39833965Sjdp 39933965Sjdp#else 40033965Sjdp 40133965Sjdp#define SRC_MASK(arg) 0 402130561Sobrien#define PCREL_OFFSET TRUE 40333965Sjdp 40433965Sjdp#endif 40533965Sjdp 40633965Sjdpstatic reloc_howto_type abs32_howto = 40733965Sjdp HOWTO (1, 40833965Sjdp 0, 40933965Sjdp 2, 41033965Sjdp 32, 411130561Sobrien FALSE, 41233965Sjdp 0, 41333965Sjdp complain_overflow_bitfield, 41433965Sjdp 0, 41533965Sjdp "abs32", 416130561Sobrien TRUE, 41733965Sjdp 0xffffffff, 41833965Sjdp 0xffffffff, 419130561Sobrien FALSE); 42033965Sjdp 42133965Sjdpstatic reloc_howto_type abs16_howto = 42233965Sjdp HOWTO (1, 42333965Sjdp 0, 42433965Sjdp 1, 42533965Sjdp 16, 426130561Sobrien FALSE, 42733965Sjdp 0, 42833965Sjdp complain_overflow_bitfield, 42933965Sjdp 0, 43033965Sjdp "abs16", 431130561Sobrien TRUE, 43233965Sjdp 0x0000ffff, 43333965Sjdp 0x0000ffff, 434130561Sobrien FALSE); 43533965Sjdp 43633965Sjdpstatic reloc_howto_type abs8_howto = 43733965Sjdp HOWTO (1, 43833965Sjdp 0, 43933965Sjdp 0, 44033965Sjdp 8, 441130561Sobrien FALSE, 44233965Sjdp 0, 44333965Sjdp complain_overflow_bitfield, 44433965Sjdp 0, 44533965Sjdp "abs8", 446130561Sobrien TRUE, 44733965Sjdp 0x000000ff, 44833965Sjdp 0x000000ff, 449130561Sobrien FALSE); 45033965Sjdp 45133965Sjdpstatic reloc_howto_type rel32_howto = 45233965Sjdp HOWTO (1, 45333965Sjdp 0, 45433965Sjdp 2, 45533965Sjdp 32, 456130561Sobrien TRUE, 45733965Sjdp 0, 45833965Sjdp complain_overflow_signed, 45933965Sjdp 0, 46033965Sjdp "rel32", 461130561Sobrien TRUE, 46233965Sjdp SRC_MASK (0xffffffff), 46333965Sjdp 0xffffffff, 46433965Sjdp PCREL_OFFSET); 46533965Sjdp 46633965Sjdpstatic reloc_howto_type rel16_howto = 46733965Sjdp HOWTO (1, 46833965Sjdp 0, 46933965Sjdp 1, 47033965Sjdp 16, 471130561Sobrien TRUE, 47233965Sjdp 0, 47333965Sjdp complain_overflow_signed, 47433965Sjdp 0, 47533965Sjdp "rel16", 476130561Sobrien TRUE, 47733965Sjdp SRC_MASK (0x0000ffff), 47833965Sjdp 0x0000ffff, 47933965Sjdp PCREL_OFFSET); 48033965Sjdp 48133965Sjdpstatic reloc_howto_type rel8_howto = 48233965Sjdp HOWTO (1, 48333965Sjdp 0, 48433965Sjdp 0, 48533965Sjdp 8, 486130561Sobrien TRUE, 48733965Sjdp 0, 48833965Sjdp complain_overflow_signed, 48933965Sjdp 0, 49033965Sjdp "rel8", 491130561Sobrien TRUE, 49233965Sjdp SRC_MASK (0x000000ff), 49333965Sjdp 0x000000ff, 49433965Sjdp PCREL_OFFSET); 49533965Sjdp 49633965Sjdpstatic ieee_symbol_index_type NOSYMBOL = {0, 0}; 49733965Sjdp 49833965Sjdpstatic void 499218822Sdimparse_expression (ieee_data_type *ieee, 500218822Sdim bfd_vma *value, 501218822Sdim ieee_symbol_index_type *symbol, 502218822Sdim bfd_boolean *pcrel, 503218822Sdim unsigned int *extra, 504218822Sdim asection **section) 50533965Sjdp 50633965Sjdp{ 507218822Sdim bfd_boolean loop = TRUE; 508218822Sdim ieee_value_type stack[10]; 509218822Sdim ieee_value_type *sp = stack; 510218822Sdim asection *dummy; 511218822Sdim 51233965Sjdp#define POS sp[1] 51333965Sjdp#define TOS sp[0] 51433965Sjdp#define NOS sp[-1] 51533965Sjdp#define INC sp++; 51633965Sjdp#define DEC sp--; 51733965Sjdp 518130561Sobrien /* The stack pointer always points to the next unused location. */ 519218822Sdim#define PUSH(x,y,z) TOS.symbol = x; TOS.section = y; TOS.value = z; INC; 520218822Sdim#define POP(x,y,z) DEC; x = TOS.symbol; y = TOS.section; z = TOS.value; 52133965Sjdp 52289857Sobrien while (loop && ieee->h.input_p < ieee->h.last_byte) 52333965Sjdp { 52433965Sjdp switch (this_byte (&(ieee->h))) 52533965Sjdp { 52633965Sjdp case ieee_variable_P_enum: 527130561Sobrien /* P variable, current program counter for section n. */ 52833965Sjdp { 52933965Sjdp int section_n; 530130561Sobrien 53133965Sjdp next_byte (&(ieee->h)); 532130561Sobrien *pcrel = TRUE; 53333965Sjdp section_n = must_parse_int (&(ieee->h)); 53433965Sjdp PUSH (NOSYMBOL, bfd_abs_section_ptr, 0); 53533965Sjdp break; 53633965Sjdp } 53733965Sjdp case ieee_variable_L_enum: 538130561Sobrien /* L variable address of section N. */ 53933965Sjdp next_byte (&(ieee->h)); 54033965Sjdp PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0); 54133965Sjdp break; 54233965Sjdp case ieee_variable_R_enum: 543130561Sobrien /* R variable, logical address of section module. */ 544130561Sobrien /* FIXME, this should be different to L. */ 54533965Sjdp next_byte (&(ieee->h)); 54633965Sjdp PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0); 54733965Sjdp break; 54833965Sjdp case ieee_variable_S_enum: 549130561Sobrien /* S variable, size in MAUS of section module. */ 55033965Sjdp next_byte (&(ieee->h)); 55133965Sjdp PUSH (NOSYMBOL, 55233965Sjdp 0, 553218822Sdim ieee->section_table[must_parse_int (&(ieee->h))]->size); 55433965Sjdp break; 55533965Sjdp case ieee_variable_I_enum: 556130561Sobrien /* Push the address of variable n. */ 55733965Sjdp { 55833965Sjdp ieee_symbol_index_type sy; 559218822Sdim 56033965Sjdp next_byte (&(ieee->h)); 56133965Sjdp sy.index = (int) must_parse_int (&(ieee->h)); 56233965Sjdp sy.letter = 'I'; 56333965Sjdp 56433965Sjdp PUSH (sy, bfd_abs_section_ptr, 0); 56533965Sjdp } 56633965Sjdp break; 56733965Sjdp case ieee_variable_X_enum: 568130561Sobrien /* Push the address of external variable n. */ 56933965Sjdp { 57033965Sjdp ieee_symbol_index_type sy; 571218822Sdim 57233965Sjdp next_byte (&(ieee->h)); 57333965Sjdp sy.index = (int) (must_parse_int (&(ieee->h))); 57433965Sjdp sy.letter = 'X'; 57533965Sjdp 57633965Sjdp PUSH (sy, bfd_und_section_ptr, 0); 57733965Sjdp } 57833965Sjdp break; 57933965Sjdp case ieee_function_minus_enum: 58033965Sjdp { 58133965Sjdp bfd_vma value1, value2; 58233965Sjdp asection *section1, *section_dummy; 58333965Sjdp ieee_symbol_index_type sy; 584218822Sdim 58533965Sjdp next_byte (&(ieee->h)); 58633965Sjdp 58733965Sjdp POP (sy, section1, value1); 58833965Sjdp POP (sy, section_dummy, value2); 58933965Sjdp PUSH (sy, section1 ? section1 : section_dummy, value2 - value1); 59033965Sjdp } 59133965Sjdp break; 59233965Sjdp case ieee_function_plus_enum: 59333965Sjdp { 59433965Sjdp bfd_vma value1, value2; 59533965Sjdp asection *section1; 59633965Sjdp asection *section2; 59733965Sjdp ieee_symbol_index_type sy1; 59833965Sjdp ieee_symbol_index_type sy2; 599218822Sdim 60033965Sjdp next_byte (&(ieee->h)); 60133965Sjdp 60233965Sjdp POP (sy1, section1, value1); 60333965Sjdp POP (sy2, section2, value2); 60433965Sjdp PUSH (sy1.letter ? sy1 : sy2, 60533965Sjdp bfd_is_abs_section (section1) ? section2 : section1, 60633965Sjdp value1 + value2); 60733965Sjdp } 60833965Sjdp break; 60933965Sjdp default: 61033965Sjdp { 61133965Sjdp bfd_vma va; 612218822Sdim 61333965Sjdp BFD_ASSERT (this_byte (&(ieee->h)) < (int) ieee_variable_A_enum 61433965Sjdp || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum); 61533965Sjdp if (parse_int (&(ieee->h), &va)) 61633965Sjdp { 61733965Sjdp PUSH (NOSYMBOL, bfd_abs_section_ptr, va); 61833965Sjdp } 61933965Sjdp else 620218822Sdim /* Thats all that we can understand. */ 621218822Sdim loop = FALSE; 62233965Sjdp } 62333965Sjdp } 62433965Sjdp } 62589857Sobrien 62689857Sobrien /* As far as I can see there is a bug in the Microtec IEEE output 62789857Sobrien which I'm using to scan, whereby the comma operator is omitted 62889857Sobrien sometimes in an expression, giving expressions with too many 62989857Sobrien terms. We can tell if that's the case by ensuring that 63089857Sobrien sp == stack here. If not, then we've pushed something too far, 63189857Sobrien so we keep adding. */ 63289857Sobrien while (sp != stack + 1) 63389857Sobrien { 63489857Sobrien asection *section1; 63589857Sobrien ieee_symbol_index_type sy1; 636218822Sdim 63789857Sobrien POP (sy1, section1, *extra); 63889857Sobrien } 63989857Sobrien 64089857Sobrien POP (*symbol, dummy, *value); 64189857Sobrien if (section) 64289857Sobrien *section = dummy; 64333965Sjdp} 64433965Sjdp 64533965Sjdp 64689857Sobrien#define ieee_seek(ieee, offset) \ 64789857Sobrien do \ 64889857Sobrien { \ 64989857Sobrien ieee->h.input_p = ieee->h.first_byte + offset; \ 65089857Sobrien ieee->h.last_byte = (ieee->h.first_byte \ 65189857Sobrien + ieee_part_after (ieee, offset)); \ 65289857Sobrien } \ 65389857Sobrien while (0) 65433965Sjdp 65589857Sobrien#define ieee_pos(ieee) \ 65689857Sobrien (ieee->h.input_p - ieee->h.first_byte) 65733965Sjdp 65889857Sobrien/* Find the first part of the ieee file after HERE. */ 65989857Sobrien 66089857Sobrienstatic file_ptr 661218822Sdimieee_part_after (ieee_data_type *ieee, file_ptr here) 66289857Sobrien{ 66389857Sobrien int part; 66489857Sobrien file_ptr after = ieee->w.r.me_record; 66589857Sobrien 66689857Sobrien /* File parts can come in any order, except that module end is 66789857Sobrien guaranteed to be last (and the header first). */ 66889857Sobrien for (part = 0; part < N_W_VARIABLES; part++) 66989857Sobrien if (ieee->w.offset[part] > here && after > ieee->w.offset[part]) 67089857Sobrien after = ieee->w.offset[part]; 67189857Sobrien 67289857Sobrien return after; 67389857Sobrien} 67489857Sobrien 67533965Sjdpstatic unsigned int last_index; 676130561Sobrienstatic char last_type; /* Is the index for an X or a D. */ 67733965Sjdp 67833965Sjdpstatic ieee_symbol_type * 679218822Sdimget_symbol (bfd *abfd ATTRIBUTE_UNUSED, 680218822Sdim ieee_data_type *ieee, 681218822Sdim ieee_symbol_type *last_symbol, 682218822Sdim unsigned int *symbol_count, 683218822Sdim ieee_symbol_type ***pptr, 684218822Sdim unsigned int *max_index, 685218822Sdim int this_type) 68633965Sjdp{ 687130561Sobrien /* Need a new symbol. */ 68833965Sjdp unsigned int new_index = must_parse_int (&(ieee->h)); 689130561Sobrien 69033965Sjdp if (new_index != last_index || this_type != last_type) 69133965Sjdp { 69289857Sobrien ieee_symbol_type *new_symbol; 69389857Sobrien bfd_size_type amt = sizeof (ieee_symbol_type); 69489857Sobrien 695218822Sdim new_symbol = bfd_alloc (ieee->h.abfd, amt); 69633965Sjdp if (!new_symbol) 69733965Sjdp return NULL; 69833965Sjdp 69933965Sjdp new_symbol->index = new_index; 70033965Sjdp last_index = new_index; 70133965Sjdp (*symbol_count)++; 70233965Sjdp **pptr = new_symbol; 70333965Sjdp *pptr = &new_symbol->next; 70433965Sjdp if (new_index > *max_index) 705130561Sobrien *max_index = new_index; 706130561Sobrien 70733965Sjdp last_type = this_type; 70833965Sjdp new_symbol->symbol.section = bfd_abs_section_ptr; 70933965Sjdp return new_symbol; 71033965Sjdp } 71133965Sjdp return last_symbol; 71233965Sjdp} 71333965Sjdp 714130561Sobrienstatic bfd_boolean 715218822Sdimieee_slurp_external_symbols (bfd *abfd) 71633965Sjdp{ 71733965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 71833965Sjdp file_ptr offset = ieee->w.r.external_part; 71933965Sjdp 72033965Sjdp ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols; 72133965Sjdp ieee_symbol_type **prev_reference_ptr = &ieee->external_reference; 722218822Sdim ieee_symbol_type *symbol = NULL; 72333965Sjdp unsigned int symbol_count = 0; 724130561Sobrien bfd_boolean loop = TRUE; 725218822Sdim 72633965Sjdp last_index = 0xffffff; 727130561Sobrien ieee->symbol_table_full = TRUE; 72833965Sjdp 72989857Sobrien ieee_seek (ieee, offset); 73033965Sjdp 73133965Sjdp while (loop) 73233965Sjdp { 73333965Sjdp switch (this_byte (&(ieee->h))) 73433965Sjdp { 73533965Sjdp case ieee_nn_record: 73633965Sjdp next_byte (&(ieee->h)); 73733965Sjdp 73833965Sjdp symbol = get_symbol (abfd, ieee, symbol, &symbol_count, 739218822Sdim & prev_symbols_ptr, 740218822Sdim & ieee->external_symbol_max_index, 'I'); 74133965Sjdp if (symbol == NULL) 742130561Sobrien return FALSE; 74333965Sjdp 74433965Sjdp symbol->symbol.the_bfd = abfd; 74533965Sjdp symbol->symbol.name = read_id (&(ieee->h)); 746218822Sdim symbol->symbol.udata.p = NULL; 74733965Sjdp symbol->symbol.flags = BSF_NO_FLAGS; 74833965Sjdp break; 74933965Sjdp case ieee_external_symbol_enum: 75033965Sjdp next_byte (&(ieee->h)); 75133965Sjdp 75233965Sjdp symbol = get_symbol (abfd, ieee, symbol, &symbol_count, 75333965Sjdp &prev_symbols_ptr, 75433965Sjdp &ieee->external_symbol_max_index, 'D'); 75533965Sjdp if (symbol == NULL) 756130561Sobrien return FALSE; 75733965Sjdp 75833965Sjdp BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index); 75933965Sjdp 76033965Sjdp symbol->symbol.the_bfd = abfd; 76133965Sjdp symbol->symbol.name = read_id (&(ieee->h)); 762218822Sdim symbol->symbol.udata.p = NULL; 76333965Sjdp symbol->symbol.flags = BSF_NO_FLAGS; 76433965Sjdp break; 76533965Sjdp case ieee_attribute_record_enum >> 8: 76633965Sjdp { 76733965Sjdp unsigned int symbol_name_index; 76833965Sjdp unsigned int symbol_type_index; 76933965Sjdp unsigned int symbol_attribute_def; 770218822Sdim bfd_vma value = 0; 771218822Sdim 77289857Sobrien switch (read_2bytes (&ieee->h)) 77333965Sjdp { 77433965Sjdp case ieee_attribute_record_enum: 77533965Sjdp symbol_name_index = must_parse_int (&(ieee->h)); 77633965Sjdp symbol_type_index = must_parse_int (&(ieee->h)); 77733965Sjdp symbol_attribute_def = must_parse_int (&(ieee->h)); 77833965Sjdp switch (symbol_attribute_def) 77933965Sjdp { 78033965Sjdp case 8: 78133965Sjdp case 19: 78233965Sjdp parse_int (&ieee->h, &value); 78333965Sjdp break; 78433965Sjdp default: 78533965Sjdp (*_bfd_error_handler) 786218822Sdim (_("%B: unimplemented ATI record %u for symbol %u"), 787218822Sdim abfd, symbol_attribute_def, symbol_name_index); 78833965Sjdp bfd_set_error (bfd_error_bad_value); 789130561Sobrien return FALSE; 79033965Sjdp break; 79133965Sjdp } 79233965Sjdp break; 79333965Sjdp case ieee_external_reference_info_record_enum: 794130561Sobrien /* Skip over ATX record. */ 79533965Sjdp parse_int (&(ieee->h), &value); 79633965Sjdp parse_int (&(ieee->h), &value); 79733965Sjdp parse_int (&(ieee->h), &value); 79833965Sjdp parse_int (&(ieee->h), &value); 79933965Sjdp break; 80060484Sobrien case ieee_atn_record_enum: 80160484Sobrien /* We may get call optimization information here, 80260484Sobrien which we just ignore. The format is 803130561Sobrien {$F1}${CE}{index}{$00}{$3F}{$3F}{#_of_ASNs}. */ 80460484Sobrien parse_int (&ieee->h, &value); 80560484Sobrien parse_int (&ieee->h, &value); 80660484Sobrien parse_int (&ieee->h, &value); 80760484Sobrien if (value != 0x3f) 80860484Sobrien { 80960484Sobrien (*_bfd_error_handler) 810218822Sdim (_("%B: unexpected ATN type %d in external part"), 811218822Sdim abfd, (int) value); 81260484Sobrien bfd_set_error (bfd_error_bad_value); 813130561Sobrien return FALSE; 81460484Sobrien } 81560484Sobrien parse_int (&ieee->h, &value); 81660484Sobrien parse_int (&ieee->h, &value); 81760484Sobrien while (value > 0) 81860484Sobrien { 81960484Sobrien bfd_vma val1; 82060484Sobrien 82160484Sobrien --value; 82260484Sobrien 82389857Sobrien switch (read_2bytes (&ieee->h)) 82460484Sobrien { 82560484Sobrien case ieee_asn_record_enum: 82660484Sobrien parse_int (&ieee->h, &val1); 82760484Sobrien parse_int (&ieee->h, &val1); 82860484Sobrien break; 82960484Sobrien 83060484Sobrien default: 83160484Sobrien (*_bfd_error_handler) 832218822Sdim (_("%B: unexpected type after ATN"), abfd); 83360484Sobrien bfd_set_error (bfd_error_bad_value); 834130561Sobrien return FALSE; 83560484Sobrien } 83660484Sobrien } 83733965Sjdp } 83833965Sjdp } 83933965Sjdp break; 84033965Sjdp case ieee_value_record_enum >> 8: 84133965Sjdp { 84233965Sjdp unsigned int symbol_name_index; 84333965Sjdp ieee_symbol_index_type symbol_ignore; 844130561Sobrien bfd_boolean pcrel_ignore; 84533965Sjdp unsigned int extra; 846218822Sdim 84733965Sjdp next_byte (&(ieee->h)); 84833965Sjdp next_byte (&(ieee->h)); 84933965Sjdp 85033965Sjdp symbol_name_index = must_parse_int (&(ieee->h)); 85133965Sjdp parse_expression (ieee, 85233965Sjdp &symbol->symbol.value, 85333965Sjdp &symbol_ignore, 85433965Sjdp &pcrel_ignore, 85533965Sjdp &extra, 85633965Sjdp &symbol->symbol.section); 85733965Sjdp 85860484Sobrien /* Fully linked IEEE-695 files tend to give every symbol 85960484Sobrien an absolute value. Try to convert that back into a 86060484Sobrien section relative value. FIXME: This won't always to 86160484Sobrien the right thing. */ 86260484Sobrien if (bfd_is_abs_section (symbol->symbol.section) 86360484Sobrien && (abfd->flags & HAS_RELOC) == 0) 86460484Sobrien { 86560484Sobrien bfd_vma val; 86660484Sobrien asection *s; 86760484Sobrien 86860484Sobrien val = symbol->symbol.value; 86960484Sobrien for (s = abfd->sections; s != NULL; s = s->next) 87060484Sobrien { 871218822Sdim if (val >= s->vma && val < s->vma + s->size) 87260484Sobrien { 87360484Sobrien symbol->symbol.section = s; 87460484Sobrien symbol->symbol.value -= s->vma; 87560484Sobrien break; 87660484Sobrien } 87760484Sobrien } 87860484Sobrien } 87960484Sobrien 88033965Sjdp symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT; 88133965Sjdp 88233965Sjdp } 88333965Sjdp break; 88433965Sjdp case ieee_weak_external_reference_enum: 88533965Sjdp { 88633965Sjdp bfd_vma size; 88733965Sjdp bfd_vma value; 888218822Sdim 88933965Sjdp next_byte (&(ieee->h)); 890130561Sobrien /* Throw away the external reference index. */ 89133965Sjdp (void) must_parse_int (&(ieee->h)); 892130561Sobrien /* Fetch the default size if not resolved. */ 89333965Sjdp size = must_parse_int (&(ieee->h)); 894130561Sobrien /* Fetch the default value if available. */ 895104834Sobrien if (! parse_int (&(ieee->h), &value)) 896218822Sdim value = 0; 897130561Sobrien /* This turns into a common. */ 89833965Sjdp symbol->symbol.section = bfd_com_section_ptr; 89933965Sjdp symbol->symbol.value = size; 90033965Sjdp } 90133965Sjdp break; 90233965Sjdp 90333965Sjdp case ieee_external_reference_enum: 90433965Sjdp next_byte (&(ieee->h)); 90533965Sjdp 90633965Sjdp symbol = get_symbol (abfd, ieee, symbol, &symbol_count, 90733965Sjdp &prev_reference_ptr, 90833965Sjdp &ieee->external_reference_max_index, 'X'); 90933965Sjdp if (symbol == NULL) 910130561Sobrien return FALSE; 91133965Sjdp 91233965Sjdp symbol->symbol.the_bfd = abfd; 91333965Sjdp symbol->symbol.name = read_id (&(ieee->h)); 914218822Sdim symbol->symbol.udata.p = NULL; 91533965Sjdp symbol->symbol.section = bfd_und_section_ptr; 91633965Sjdp symbol->symbol.value = (bfd_vma) 0; 91733965Sjdp symbol->symbol.flags = 0; 91833965Sjdp 91933965Sjdp BFD_ASSERT (symbol->index >= ieee->external_reference_min_index); 92033965Sjdp break; 92133965Sjdp 92233965Sjdp default: 923130561Sobrien loop = FALSE; 92433965Sjdp } 92533965Sjdp } 92633965Sjdp 92733965Sjdp if (ieee->external_symbol_max_index != 0) 92833965Sjdp { 92933965Sjdp ieee->external_symbol_count = 93033965Sjdp ieee->external_symbol_max_index - 93133965Sjdp ieee->external_symbol_min_index + 1; 93233965Sjdp } 93333965Sjdp else 934218822Sdim ieee->external_symbol_count = 0; 93533965Sjdp 93633965Sjdp if (ieee->external_reference_max_index != 0) 93733965Sjdp { 93833965Sjdp ieee->external_reference_count = 93933965Sjdp ieee->external_reference_max_index - 94033965Sjdp ieee->external_reference_min_index + 1; 94133965Sjdp } 94233965Sjdp else 943218822Sdim ieee->external_reference_count = 0; 94433965Sjdp 94533965Sjdp abfd->symcount = 94633965Sjdp ieee->external_reference_count + ieee->external_symbol_count; 94733965Sjdp 94833965Sjdp if (symbol_count != abfd->symcount) 949218822Sdim /* There are gaps in the table -- */ 950218822Sdim ieee->symbol_table_full = FALSE; 95133965Sjdp 952218822Sdim *prev_symbols_ptr = NULL; 953218822Sdim *prev_reference_ptr = NULL; 95433965Sjdp 955130561Sobrien return TRUE; 95633965Sjdp} 95733965Sjdp 958130561Sobrienstatic bfd_boolean 959218822Sdimieee_slurp_symbol_table (bfd *abfd) 96033965Sjdp{ 961104834Sobrien if (! IEEE_DATA (abfd)->read_symbols) 96233965Sjdp { 96333965Sjdp if (! ieee_slurp_external_symbols (abfd)) 964130561Sobrien return FALSE; 965130561Sobrien IEEE_DATA (abfd)->read_symbols = TRUE; 96633965Sjdp } 967130561Sobrien return TRUE; 96833965Sjdp} 96933965Sjdp 97089857Sobrienstatic long 971218822Sdimieee_get_symtab_upper_bound (bfd *abfd) 97233965Sjdp{ 97333965Sjdp if (! ieee_slurp_symbol_table (abfd)) 97433965Sjdp return -1; 97533965Sjdp 97633965Sjdp return (abfd->symcount != 0) ? 97733965Sjdp (abfd->symcount + 1) * (sizeof (ieee_symbol_type *)) : 0; 97833965Sjdp} 97933965Sjdp 980130561Sobrien/* Move from our internal lists to the canon table, and insert in 981130561Sobrien symbol index order. */ 98233965Sjdp 98333965Sjdpextern const bfd_target ieee_vec; 98433965Sjdp 98589857Sobrienstatic long 986218822Sdimieee_canonicalize_symtab (bfd *abfd, asymbol **location) 98733965Sjdp{ 98833965Sjdp ieee_symbol_type *symp; 98933965Sjdp static bfd dummy_bfd; 99033965Sjdp static asymbol empty_symbol = 99160484Sobrien { 99260484Sobrien &dummy_bfd, 99360484Sobrien " ieee empty", 99460484Sobrien (symvalue) 0, 99560484Sobrien BSF_DEBUGGING, 99660484Sobrien bfd_abs_section_ptr 99760484Sobrien#ifdef __STDC__ 99860484Sobrien /* K&R compilers can't initialise unions. */ 99960484Sobrien , { 0 } 100060484Sobrien#endif 100160484Sobrien }; 100233965Sjdp 100333965Sjdp if (abfd->symcount) 100433965Sjdp { 100533965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 1006218822Sdim 100733965Sjdp dummy_bfd.xvec = &ieee_vec; 100833965Sjdp if (! ieee_slurp_symbol_table (abfd)) 100933965Sjdp return -1; 101033965Sjdp 1011104834Sobrien if (! ieee->symbol_table_full) 101233965Sjdp { 1013130561Sobrien /* Arrgh - there are gaps in the table, run through and fill them 1014130561Sobrien up with pointers to a null place. */ 101533965Sjdp unsigned int i; 1016130561Sobrien 101733965Sjdp for (i = 0; i < abfd->symcount; i++) 1018130561Sobrien location[i] = &empty_symbol; 101933965Sjdp } 102033965Sjdp 102133965Sjdp ieee->external_symbol_base_offset = -ieee->external_symbol_min_index; 102233965Sjdp for (symp = IEEE_DATA (abfd)->external_symbols; 102333965Sjdp symp != (ieee_symbol_type *) NULL; 102433965Sjdp symp = symp->next) 1025130561Sobrien /* Place into table at correct index locations. */ 1026130561Sobrien location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol; 102733965Sjdp 1028130561Sobrien /* The external refs are indexed in a bit. */ 102933965Sjdp ieee->external_reference_base_offset = 103033965Sjdp -ieee->external_reference_min_index + ieee->external_symbol_count; 103133965Sjdp 103233965Sjdp for (symp = IEEE_DATA (abfd)->external_reference; 103333965Sjdp symp != (ieee_symbol_type *) NULL; 103433965Sjdp symp = symp->next) 1035130561Sobrien location[symp->index + ieee->external_reference_base_offset] = 1036130561Sobrien &symp->symbol; 1037130561Sobrien } 103833965Sjdp 103933965Sjdp if (abfd->symcount) 1040130561Sobrien location[abfd->symcount] = (asymbol *) NULL; 1041130561Sobrien 104233965Sjdp return abfd->symcount; 104333965Sjdp} 104433965Sjdp 104533965Sjdpstatic asection * 1046218822Sdimget_section_entry (bfd *abfd, ieee_data_type *ieee, unsigned int index) 104733965Sjdp{ 104833965Sjdp if (index >= ieee->section_table_size) 104933965Sjdp { 105033965Sjdp unsigned int c, i; 105133965Sjdp asection **n; 105289857Sobrien bfd_size_type amt; 105333965Sjdp 105433965Sjdp c = ieee->section_table_size; 105533965Sjdp if (c == 0) 105633965Sjdp c = 20; 105733965Sjdp while (c <= index) 105833965Sjdp c *= 2; 105933965Sjdp 106089857Sobrien amt = c; 106189857Sobrien amt *= sizeof (asection *); 1062218822Sdim n = bfd_realloc (ieee->section_table, amt); 106333965Sjdp if (n == NULL) 106433965Sjdp return NULL; 106533965Sjdp 106633965Sjdp for (i = ieee->section_table_size; i < c; i++) 106733965Sjdp n[i] = NULL; 106833965Sjdp 106933965Sjdp ieee->section_table = n; 107033965Sjdp ieee->section_table_size = c; 107133965Sjdp } 107233965Sjdp 107333965Sjdp if (ieee->section_table[index] == (asection *) NULL) 107433965Sjdp { 107589857Sobrien char *tmp = bfd_alloc (abfd, (bfd_size_type) 11); 107633965Sjdp asection *section; 107733965Sjdp 107833965Sjdp if (!tmp) 107933965Sjdp return NULL; 108033965Sjdp sprintf (tmp, " fsec%4d", index); 108133965Sjdp section = bfd_make_section (abfd, tmp); 108233965Sjdp ieee->section_table[index] = section; 108333965Sjdp section->target_index = index; 108433965Sjdp ieee->section_table[index] = section; 108533965Sjdp } 108633965Sjdp return ieee->section_table[index]; 108733965Sjdp} 108833965Sjdp 108933965Sjdpstatic void 1090218822Sdimieee_slurp_sections (bfd *abfd) 109133965Sjdp{ 109233965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 109333965Sjdp file_ptr offset = ieee->w.r.section_part; 109433965Sjdp char *name; 109533965Sjdp 109633965Sjdp if (offset != 0) 109733965Sjdp { 109833965Sjdp bfd_byte section_type[3]; 1099218822Sdim 110089857Sobrien ieee_seek (ieee, offset); 1101130561Sobrien while (TRUE) 110233965Sjdp { 110333965Sjdp switch (this_byte (&(ieee->h))) 110433965Sjdp { 110533965Sjdp case ieee_section_type_enum: 110633965Sjdp { 110789857Sobrien asection *section; 110833965Sjdp unsigned int section_index; 1109218822Sdim 111033965Sjdp next_byte (&(ieee->h)); 111133965Sjdp section_index = must_parse_int (&(ieee->h)); 111233965Sjdp 111333965Sjdp section = get_section_entry (abfd, ieee, section_index); 111433965Sjdp 111533965Sjdp section_type[0] = this_byte_and_next (&(ieee->h)); 111633965Sjdp 111733965Sjdp /* Set minimal section attributes. Attributes are 1118130561Sobrien extended later, based on section contents. */ 111933965Sjdp switch (section_type[0]) 112033965Sjdp { 112133965Sjdp case 0xC1: 1122130561Sobrien /* Normal attributes for absolute sections. */ 112333965Sjdp section_type[1] = this_byte (&(ieee->h)); 112433965Sjdp section->flags = SEC_ALLOC; 112533965Sjdp switch (section_type[1]) 112633965Sjdp { 1127218822Sdim /* AS Absolute section attributes. */ 1128218822Sdim case 0xD3: 112933965Sjdp next_byte (&(ieee->h)); 113033965Sjdp section_type[2] = this_byte (&(ieee->h)); 113133965Sjdp switch (section_type[2]) 113233965Sjdp { 113333965Sjdp case 0xD0: 1134130561Sobrien /* Normal code. */ 113533965Sjdp next_byte (&(ieee->h)); 113633965Sjdp section->flags |= SEC_CODE; 113733965Sjdp break; 113833965Sjdp case 0xC4: 1139130561Sobrien /* Normal data. */ 114033965Sjdp next_byte (&(ieee->h)); 114133965Sjdp section->flags |= SEC_DATA; 114233965Sjdp break; 114333965Sjdp case 0xD2: 114433965Sjdp next_byte (&(ieee->h)); 1145130561Sobrien /* Normal rom data. */ 114633965Sjdp section->flags |= SEC_ROM | SEC_DATA; 114733965Sjdp break; 114833965Sjdp default: 114933965Sjdp break; 115033965Sjdp } 115133965Sjdp } 115233965Sjdp break; 1153218822Sdim 1154218822Sdim /* Named relocatable sections (type C). */ 1155218822Sdim case 0xC3: 115633965Sjdp section_type[1] = this_byte (&(ieee->h)); 115733965Sjdp section->flags = SEC_ALLOC; 115833965Sjdp switch (section_type[1]) 115933965Sjdp { 1160130561Sobrien case 0xD0: /* Normal code (CP). */ 116133965Sjdp next_byte (&(ieee->h)); 116233965Sjdp section->flags |= SEC_CODE; 116333965Sjdp break; 1164130561Sobrien case 0xC4: /* Normal data (CD). */ 116533965Sjdp next_byte (&(ieee->h)); 116633965Sjdp section->flags |= SEC_DATA; 116733965Sjdp break; 1168130561Sobrien case 0xD2: /* Normal rom data (CR). */ 116933965Sjdp next_byte (&(ieee->h)); 117033965Sjdp section->flags |= SEC_ROM | SEC_DATA; 117133965Sjdp break; 117233965Sjdp default: 117333965Sjdp break; 117433965Sjdp } 117533965Sjdp } 117633965Sjdp 1177130561Sobrien /* Read section name, use it if non empty. */ 117833965Sjdp name = read_id (&ieee->h); 117933965Sjdp if (name[0]) 118033965Sjdp section->name = name; 118133965Sjdp 1182130561Sobrien /* Skip these fields, which we don't care about. */ 118333965Sjdp { 118433965Sjdp bfd_vma parent, brother, context; 1185218822Sdim 118633965Sjdp parse_int (&(ieee->h), &parent); 118733965Sjdp parse_int (&(ieee->h), &brother); 118833965Sjdp parse_int (&(ieee->h), &context); 118933965Sjdp } 119033965Sjdp } 119133965Sjdp break; 119233965Sjdp case ieee_section_alignment_enum: 119333965Sjdp { 119433965Sjdp unsigned int section_index; 119533965Sjdp bfd_vma value; 119633965Sjdp asection *section; 1197218822Sdim 119833965Sjdp next_byte (&(ieee->h)); 119933965Sjdp section_index = must_parse_int (&ieee->h); 120033965Sjdp section = get_section_entry (abfd, ieee, section_index); 120133965Sjdp if (section_index > ieee->section_count) 1202218822Sdim ieee->section_count = section_index; 1203218822Sdim 120433965Sjdp section->alignment_power = 120533965Sjdp bfd_log2 (must_parse_int (&ieee->h)); 120633965Sjdp (void) parse_int (&(ieee->h), &value); 120733965Sjdp } 120833965Sjdp break; 120933965Sjdp case ieee_e2_first_byte_enum: 121033965Sjdp { 121189857Sobrien asection *section; 121289857Sobrien ieee_record_enum_type t; 121333965Sjdp 121489857Sobrien t = (ieee_record_enum_type) (read_2bytes (&(ieee->h))); 121533965Sjdp switch (t) 121633965Sjdp { 121733965Sjdp case ieee_section_size_enum: 121833965Sjdp section = ieee->section_table[must_parse_int (&(ieee->h))]; 1219218822Sdim section->size = must_parse_int (&(ieee->h)); 122033965Sjdp break; 122133965Sjdp case ieee_physical_region_size_enum: 122233965Sjdp section = ieee->section_table[must_parse_int (&(ieee->h))]; 1223218822Sdim section->size = must_parse_int (&(ieee->h)); 122433965Sjdp break; 122533965Sjdp case ieee_region_base_address_enum: 122633965Sjdp section = ieee->section_table[must_parse_int (&(ieee->h))]; 122733965Sjdp section->vma = must_parse_int (&(ieee->h)); 122833965Sjdp section->lma = section->vma; 122933965Sjdp break; 123033965Sjdp case ieee_mau_size_enum: 123133965Sjdp must_parse_int (&(ieee->h)); 123233965Sjdp must_parse_int (&(ieee->h)); 123333965Sjdp break; 123433965Sjdp case ieee_m_value_enum: 123533965Sjdp must_parse_int (&(ieee->h)); 123633965Sjdp must_parse_int (&(ieee->h)); 123733965Sjdp break; 123833965Sjdp case ieee_section_base_address_enum: 123933965Sjdp section = ieee->section_table[must_parse_int (&(ieee->h))]; 124033965Sjdp section->vma = must_parse_int (&(ieee->h)); 124133965Sjdp section->lma = section->vma; 124233965Sjdp break; 124333965Sjdp case ieee_section_offset_enum: 124433965Sjdp (void) must_parse_int (&(ieee->h)); 124533965Sjdp (void) must_parse_int (&(ieee->h)); 124633965Sjdp break; 124733965Sjdp default: 124833965Sjdp return; 124933965Sjdp } 125033965Sjdp } 125133965Sjdp break; 125233965Sjdp default: 125333965Sjdp return; 125433965Sjdp } 125533965Sjdp } 125633965Sjdp } 125733965Sjdp} 125833965Sjdp 125933965Sjdp/* Make a section for the debugging information, if any. We don't try 126033965Sjdp to interpret the debugging information; we just point the section 126133965Sjdp at the area in the file so that program which understand can dig it 126233965Sjdp out. */ 126333965Sjdp 1264130561Sobrienstatic bfd_boolean 1265218822Sdimieee_slurp_debug (bfd *abfd) 126633965Sjdp{ 126733965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 126833965Sjdp asection *sec; 126960484Sobrien file_ptr debug_end; 1270218822Sdim flagword flags; 127133965Sjdp 127233965Sjdp if (ieee->w.r.debug_information_part == 0) 1273130561Sobrien return TRUE; 127433965Sjdp 1275218822Sdim flags = SEC_DEBUGGING | SEC_HAS_CONTENTS; 1276218822Sdim sec = bfd_make_section_with_flags (abfd, ".debug", flags); 127733965Sjdp if (sec == NULL) 1278130561Sobrien return FALSE; 127933965Sjdp sec->filepos = ieee->w.r.debug_information_part; 128033965Sjdp 128189857Sobrien debug_end = ieee_part_after (ieee, ieee->w.r.debug_information_part); 1282218822Sdim sec->size = debug_end - ieee->w.r.debug_information_part; 128360484Sobrien 1284130561Sobrien return TRUE; 128533965Sjdp} 128633965Sjdp 1287130561Sobrien/* Archive stuff. */ 128833965Sjdp 1289218822Sdimstatic const bfd_target * 1290218822Sdimieee_archive_p (bfd *abfd) 129133965Sjdp{ 129233965Sjdp char *library; 129333965Sjdp unsigned int i; 129433965Sjdp unsigned char buffer[512]; 129533965Sjdp file_ptr buffer_offset = 0; 129633965Sjdp ieee_ar_data_type *save = abfd->tdata.ieee_ar_data; 129733965Sjdp ieee_ar_data_type *ieee; 129889857Sobrien bfd_size_type alc_elts; 129933965Sjdp ieee_ar_obstack_type *elts = NULL; 130089857Sobrien bfd_size_type amt = sizeof (ieee_ar_data_type); 130133965Sjdp 1302218822Sdim abfd->tdata.ieee_ar_data = bfd_alloc (abfd, amt); 130333965Sjdp if (!abfd->tdata.ieee_ar_data) 1304104834Sobrien goto error_ret_restore; 130533965Sjdp ieee = IEEE_AR_DATA (abfd); 130633965Sjdp 130789857Sobrien /* Ignore the return value here. It doesn't matter if we don't read 130889857Sobrien the entire buffer. We might have a very small ieee file. */ 1309218822Sdim bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd); 131033965Sjdp 131133965Sjdp ieee->h.first_byte = buffer; 131233965Sjdp ieee->h.input_p = buffer; 131333965Sjdp 131433965Sjdp ieee->h.abfd = abfd; 131533965Sjdp 131633965Sjdp if (this_byte (&(ieee->h)) != Module_Beginning) 131777298Sobrien goto got_wrong_format_error; 131833965Sjdp 131933965Sjdp next_byte (&(ieee->h)); 132033965Sjdp library = read_id (&(ieee->h)); 132133965Sjdp if (strcmp (library, "LIBRARY") != 0) 132277298Sobrien goto got_wrong_format_error; 132377298Sobrien 132477298Sobrien /* Throw away the filename. */ 132533965Sjdp read_id (&(ieee->h)); 132633965Sjdp 132733965Sjdp ieee->element_count = 0; 132833965Sjdp ieee->element_index = 0; 132933965Sjdp 133077298Sobrien next_byte (&(ieee->h)); /* Drop the ad part. */ 133177298Sobrien must_parse_int (&(ieee->h)); /* And the two dummy numbers. */ 133233965Sjdp must_parse_int (&(ieee->h)); 133333965Sjdp 133433965Sjdp alc_elts = 10; 1335218822Sdim elts = bfd_malloc (alc_elts * sizeof *elts); 133633965Sjdp if (elts == NULL) 133733965Sjdp goto error_return; 133833965Sjdp 133977298Sobrien /* Read the index of the BB table. */ 134033965Sjdp while (1) 134133965Sjdp { 134233965Sjdp int rec; 134333965Sjdp ieee_ar_obstack_type *t; 134433965Sjdp 134533965Sjdp rec = read_2bytes (&(ieee->h)); 134633965Sjdp if (rec != (int) ieee_assign_value_to_variable_enum) 134733965Sjdp break; 134833965Sjdp 134933965Sjdp if (ieee->element_count >= alc_elts) 135033965Sjdp { 135133965Sjdp ieee_ar_obstack_type *n; 135233965Sjdp 135333965Sjdp alc_elts *= 2; 1354218822Sdim n = bfd_realloc (elts, alc_elts * sizeof (* elts)); 135533965Sjdp if (n == NULL) 135633965Sjdp goto error_return; 135733965Sjdp elts = n; 135833965Sjdp } 135933965Sjdp 136033965Sjdp t = &elts[ieee->element_count]; 136133965Sjdp ieee->element_count++; 136233965Sjdp 136333965Sjdp must_parse_int (&(ieee->h)); 136433965Sjdp t->file_offset = must_parse_int (&(ieee->h)); 136533965Sjdp t->abfd = (bfd *) NULL; 136633965Sjdp 136777298Sobrien /* Make sure that we don't go over the end of the buffer. */ 136889857Sobrien if ((size_t) ieee_pos (IEEE_DATA (abfd)) > sizeof (buffer) / 2) 136933965Sjdp { 137077298Sobrien /* Past half way, reseek and reprime. */ 137189857Sobrien buffer_offset += ieee_pos (IEEE_DATA (abfd)); 137233965Sjdp if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0) 137333965Sjdp goto error_return; 137477298Sobrien 137589857Sobrien /* Again ignore return value of bfd_bread. */ 1376218822Sdim bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd); 137733965Sjdp ieee->h.first_byte = buffer; 137833965Sjdp ieee->h.input_p = buffer; 137933965Sjdp } 138033965Sjdp } 138133965Sjdp 138289857Sobrien amt = ieee->element_count; 138389857Sobrien amt *= sizeof *ieee->elements; 1384218822Sdim ieee->elements = bfd_alloc (abfd, amt); 138533965Sjdp if (ieee->elements == NULL) 138633965Sjdp goto error_return; 138777298Sobrien 138889857Sobrien memcpy (ieee->elements, elts, (size_t) amt); 138933965Sjdp free (elts); 139033965Sjdp elts = NULL; 139133965Sjdp 139277298Sobrien /* Now scan the area again, and replace BB offsets with file offsets. */ 139333965Sjdp for (i = 2; i < ieee->element_count; i++) 139433965Sjdp { 139533965Sjdp if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0) 139633965Sjdp goto error_return; 139777298Sobrien 139889857Sobrien /* Again ignore return value of bfd_bread. */ 1399218822Sdim bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd); 140033965Sjdp ieee->h.first_byte = buffer; 140133965Sjdp ieee->h.input_p = buffer; 140233965Sjdp 140377298Sobrien next_byte (&(ieee->h)); /* Drop F8. */ 140477298Sobrien next_byte (&(ieee->h)); /* Drop 14. */ 140577298Sobrien must_parse_int (&(ieee->h)); /* Drop size of block. */ 140689857Sobrien 140733965Sjdp if (must_parse_int (&(ieee->h)) != 0) 140877298Sobrien /* This object has been deleted. */ 140977298Sobrien ieee->elements[i].file_offset = 0; 141033965Sjdp else 141177298Sobrien ieee->elements[i].file_offset = must_parse_int (&(ieee->h)); 141233965Sjdp } 141333965Sjdp 141433965Sjdp /* abfd->has_armap = ;*/ 141533965Sjdp 141633965Sjdp return abfd->xvec; 141733965Sjdp 141860484Sobrien got_wrong_format_error: 141960484Sobrien bfd_set_error (bfd_error_wrong_format); 142033965Sjdp error_return: 142133965Sjdp if (elts != NULL) 142233965Sjdp free (elts); 1423104834Sobrien bfd_release (abfd, ieee); 1424104834Sobrien error_ret_restore: 1425104834Sobrien abfd->tdata.ieee_ar_data = save; 142677298Sobrien 142733965Sjdp return NULL; 142833965Sjdp} 142933965Sjdp 1430218822Sdimstatic bfd_boolean 1431218822Sdimieee_mkobject (bfd *abfd) 143233965Sjdp{ 143389857Sobrien bfd_size_type amt; 143433965Sjdp 1435218822Sdim output_ptr_start = NULL; 1436218822Sdim output_ptr = NULL; 1437218822Sdim output_ptr_end = NULL; 1438218822Sdim input_ptr_start = NULL; 1439218822Sdim input_ptr = NULL; 1440218822Sdim input_ptr_end = NULL; 1441218822Sdim input_bfd = NULL; 1442218822Sdim output_bfd = NULL; 1443218822Sdim output_buffer = 0; 1444218822Sdim amt = sizeof (ieee_data_type); 1445218822Sdim abfd->tdata.ieee_data = bfd_zalloc (abfd, amt); 1446218822Sdim return abfd->tdata.ieee_data != NULL; 144733965Sjdp} 144833965Sjdp 1449130561Sobrienstatic bfd_boolean 1450218822Sdimdo_one (ieee_data_type *ieee, 1451218822Sdim ieee_per_section_type *current_map, 1452218822Sdim unsigned char *location_ptr, 1453218822Sdim asection *s, 1454218822Sdim int iterations) 145533965Sjdp{ 145633965Sjdp switch (this_byte (&(ieee->h))) 145733965Sjdp { 145833965Sjdp case ieee_load_constant_bytes_enum: 145933965Sjdp { 146033965Sjdp unsigned int number_of_maus; 146133965Sjdp unsigned int i; 1462130561Sobrien 146333965Sjdp next_byte (&(ieee->h)); 146433965Sjdp number_of_maus = must_parse_int (&(ieee->h)); 146533965Sjdp 146633965Sjdp for (i = 0; i < number_of_maus; i++) 146733965Sjdp { 146833965Sjdp location_ptr[current_map->pc++] = this_byte (&(ieee->h)); 146933965Sjdp next_byte (&(ieee->h)); 147033965Sjdp } 147133965Sjdp } 147233965Sjdp break; 147333965Sjdp 147433965Sjdp case ieee_load_with_relocation_enum: 147533965Sjdp { 1476130561Sobrien bfd_boolean loop = TRUE; 1477130561Sobrien 147833965Sjdp next_byte (&(ieee->h)); 147933965Sjdp while (loop) 148033965Sjdp { 148133965Sjdp switch (this_byte (&(ieee->h))) 148233965Sjdp { 148333965Sjdp case ieee_variable_R_enum: 148433965Sjdp 148533965Sjdp case ieee_function_signed_open_b_enum: 148633965Sjdp case ieee_function_unsigned_open_b_enum: 148733965Sjdp case ieee_function_either_open_b_enum: 148833965Sjdp { 148933965Sjdp unsigned int extra = 4; 1490130561Sobrien bfd_boolean pcrel = FALSE; 149133965Sjdp asection *section; 149289857Sobrien ieee_reloc_type *r; 149389857Sobrien 1494218822Sdim r = bfd_alloc (ieee->h.abfd, sizeof (* r)); 149533965Sjdp if (!r) 1496130561Sobrien return FALSE; 149733965Sjdp 149833965Sjdp *(current_map->reloc_tail_ptr) = r; 149933965Sjdp current_map->reloc_tail_ptr = &r->next; 150033965Sjdp r->next = (ieee_reloc_type *) NULL; 150133965Sjdp next_byte (&(ieee->h)); 150233965Sjdp/* abort();*/ 150333965Sjdp r->relent.sym_ptr_ptr = 0; 150433965Sjdp parse_expression (ieee, 150533965Sjdp &r->relent.addend, 150633965Sjdp &r->symbol, 150733965Sjdp &pcrel, &extra, §ion); 150833965Sjdp r->relent.address = current_map->pc; 150933965Sjdp s->flags |= SEC_RELOC; 151033965Sjdp s->owner->flags |= HAS_RELOC; 151133965Sjdp s->reloc_count++; 151238889Sjdp if (r->relent.sym_ptr_ptr == NULL && section != NULL) 151338889Sjdp r->relent.sym_ptr_ptr = section->symbol_ptr_ptr; 151433965Sjdp 151533965Sjdp if (this_byte (&(ieee->h)) == (int) ieee_comma) 151633965Sjdp { 151733965Sjdp next_byte (&(ieee->h)); 1518130561Sobrien /* Fetch number of bytes to pad. */ 151933965Sjdp extra = must_parse_int (&(ieee->h)); 152033965Sjdp }; 152133965Sjdp 152233965Sjdp switch (this_byte (&(ieee->h))) 152333965Sjdp { 152433965Sjdp case ieee_function_signed_close_b_enum: 152533965Sjdp next_byte (&(ieee->h)); 152633965Sjdp break; 152733965Sjdp case ieee_function_unsigned_close_b_enum: 152833965Sjdp next_byte (&(ieee->h)); 152933965Sjdp break; 153033965Sjdp case ieee_function_either_close_b_enum: 153133965Sjdp next_byte (&(ieee->h)); 153233965Sjdp break; 153333965Sjdp default: 153433965Sjdp break; 153533965Sjdp } 1536130561Sobrien /* Build a relocation entry for this type. */ 153733965Sjdp /* If pc rel then stick -ve pc into instruction 153833965Sjdp and take out of reloc .. 153933965Sjdp 154033965Sjdp I've changed this. It's all too complicated. I 154133965Sjdp keep 0 in the instruction now. */ 154233965Sjdp 154333965Sjdp switch (extra) 154433965Sjdp { 154533965Sjdp case 0: 154633965Sjdp case 4: 154733965Sjdp 1548104834Sobrien if (pcrel) 154933965Sjdp { 155033965Sjdp#if KEEPMINUSPCININST 155189857Sobrien bfd_put_32 (ieee->h.abfd, -current_map->pc, 155289857Sobrien location_ptr + current_map->pc); 155333965Sjdp r->relent.howto = &rel32_howto; 155489857Sobrien r->relent.addend -= current_map->pc; 155533965Sjdp#else 155689857Sobrien bfd_put_32 (ieee->h.abfd, (bfd_vma) 0, location_ptr + 155733965Sjdp current_map->pc); 155833965Sjdp r->relent.howto = &rel32_howto; 155933965Sjdp#endif 156033965Sjdp } 156133965Sjdp else 156233965Sjdp { 156389857Sobrien bfd_put_32 (ieee->h.abfd, (bfd_vma) 0, 156489857Sobrien location_ptr + current_map->pc); 156533965Sjdp r->relent.howto = &abs32_howto; 156633965Sjdp } 156733965Sjdp current_map->pc += 4; 156833965Sjdp break; 156933965Sjdp case 2: 1570104834Sobrien if (pcrel) 157133965Sjdp { 157233965Sjdp#if KEEPMINUSPCININST 157389857Sobrien bfd_put_16 (ieee->h.abfd, (bfd_vma) -current_map->pc, 157489857Sobrien location_ptr + current_map->pc); 157533965Sjdp r->relent.addend -= current_map->pc; 157633965Sjdp r->relent.howto = &rel16_howto; 157733965Sjdp#else 157833965Sjdp 157989857Sobrien bfd_put_16 (ieee->h.abfd, (bfd_vma) 0, 158089857Sobrien location_ptr + current_map->pc); 158133965Sjdp r->relent.howto = &rel16_howto; 158233965Sjdp#endif 158333965Sjdp } 158433965Sjdp 158533965Sjdp else 158633965Sjdp { 158789857Sobrien bfd_put_16 (ieee->h.abfd, (bfd_vma) 0, 158889857Sobrien location_ptr + current_map->pc); 158933965Sjdp r->relent.howto = &abs16_howto; 159033965Sjdp } 159133965Sjdp current_map->pc += 2; 159233965Sjdp break; 159333965Sjdp case 1: 1594104834Sobrien if (pcrel) 159533965Sjdp { 159633965Sjdp#if KEEPMINUSPCININST 159733965Sjdp bfd_put_8 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc); 159833965Sjdp r->relent.addend -= current_map->pc; 159933965Sjdp r->relent.howto = &rel8_howto; 160033965Sjdp#else 160133965Sjdp bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc); 160233965Sjdp r->relent.howto = &rel8_howto; 160333965Sjdp#endif 160433965Sjdp } 160533965Sjdp else 160633965Sjdp { 160733965Sjdp bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc); 160833965Sjdp r->relent.howto = &abs8_howto; 160933965Sjdp } 161033965Sjdp current_map->pc += 1; 161133965Sjdp break; 161233965Sjdp 161333965Sjdp default: 161433965Sjdp BFD_FAIL (); 1615130561Sobrien return FALSE; 161633965Sjdp } 161733965Sjdp } 161833965Sjdp break; 161933965Sjdp default: 162033965Sjdp { 162133965Sjdp bfd_vma this_size; 1622218822Sdim 1623104834Sobrien if (parse_int (&(ieee->h), &this_size)) 162433965Sjdp { 162533965Sjdp unsigned int i; 1626218822Sdim 162733965Sjdp for (i = 0; i < this_size; i++) 162833965Sjdp { 162933965Sjdp location_ptr[current_map->pc++] = this_byte (&(ieee->h)); 163033965Sjdp next_byte (&(ieee->h)); 163133965Sjdp } 163233965Sjdp } 163333965Sjdp else 1634218822Sdim loop = FALSE; 163533965Sjdp } 163633965Sjdp } 163733965Sjdp 163833965Sjdp /* Prevent more than the first load-item of an LR record 1639218822Sdim from being repeated (MRI convention). */ 164033965Sjdp if (iterations != 1) 1641130561Sobrien loop = FALSE; 164233965Sjdp } 164333965Sjdp } 164433965Sjdp } 1645130561Sobrien return TRUE; 164633965Sjdp} 164733965Sjdp 1648130561Sobrien/* Read in all the section data and relocation stuff too. */ 1649130561Sobrien 1650130561Sobrienstatic bfd_boolean 1651218822Sdimieee_slurp_section_data (bfd *abfd) 165233965Sjdp{ 165333965Sjdp bfd_byte *location_ptr = (bfd_byte *) NULL; 165433965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 165533965Sjdp unsigned int section_number; 1656218822Sdim ieee_per_section_type *current_map = NULL; 165733965Sjdp asection *s; 1658218822Sdim 1659130561Sobrien /* Seek to the start of the data area. */ 1660104834Sobrien if (ieee->read_data) 1661130561Sobrien return TRUE; 1662130561Sobrien ieee->read_data = TRUE; 166389857Sobrien ieee_seek (ieee, ieee->w.r.data_part); 166433965Sjdp 1665130561Sobrien /* Allocate enough space for all the section contents. */ 166633965Sjdp for (s = abfd->sections; s != (asection *) NULL; s = s->next) 166733965Sjdp { 1668130561Sobrien ieee_per_section_type *per = ieee_per_section (s); 1669218822Sdim arelent **relpp; 1670218822Sdim 167133965Sjdp if ((s->flags & SEC_DEBUGGING) != 0) 167233965Sjdp continue; 1673218822Sdim per->data = bfd_alloc (ieee->h.abfd, s->size); 167433965Sjdp if (!per->data) 1675130561Sobrien return FALSE; 1676218822Sdim relpp = &s->relocation; 1677218822Sdim per->reloc_tail_ptr = (ieee_reloc_type **) relpp; 167833965Sjdp } 167933965Sjdp 1680130561Sobrien while (TRUE) 168133965Sjdp { 168233965Sjdp switch (this_byte (&(ieee->h))) 168333965Sjdp { 1684130561Sobrien /* IF we see anything strange then quit. */ 168533965Sjdp default: 1686130561Sobrien return TRUE; 168733965Sjdp 168833965Sjdp case ieee_set_current_section_enum: 168933965Sjdp next_byte (&(ieee->h)); 169033965Sjdp section_number = must_parse_int (&(ieee->h)); 169133965Sjdp s = ieee->section_table[section_number]; 169233965Sjdp s->flags |= SEC_LOAD | SEC_HAS_CONTENTS; 1693130561Sobrien current_map = ieee_per_section (s); 169433965Sjdp location_ptr = current_map->data - s->vma; 1695130561Sobrien /* The document I have says that Microtec's compilers reset 1696130561Sobrien this after a sec section, even though the standard says not 1697130561Sobrien to, SO... */ 169833965Sjdp current_map->pc = s->vma; 169933965Sjdp break; 170033965Sjdp 170133965Sjdp case ieee_e2_first_byte_enum: 170233965Sjdp next_byte (&(ieee->h)); 170333965Sjdp switch (this_byte (&(ieee->h))) 170433965Sjdp { 170533965Sjdp case ieee_set_current_pc_enum & 0xff: 170633965Sjdp { 170733965Sjdp bfd_vma value; 170833965Sjdp ieee_symbol_index_type symbol; 170933965Sjdp unsigned int extra; 1710130561Sobrien bfd_boolean pcrel; 1711130561Sobrien 171233965Sjdp next_byte (&(ieee->h)); 1713130561Sobrien must_parse_int (&(ieee->h)); /* Throw away section #. */ 171433965Sjdp parse_expression (ieee, &value, 171533965Sjdp &symbol, 171633965Sjdp &pcrel, &extra, 171733965Sjdp 0); 171833965Sjdp current_map->pc = value; 1719218822Sdim BFD_ASSERT ((unsigned) (value - s->vma) <= s->size); 172033965Sjdp } 172133965Sjdp break; 172233965Sjdp 172333965Sjdp case ieee_value_starting_address_enum & 0xff: 172433965Sjdp next_byte (&(ieee->h)); 172533965Sjdp if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum) 172633965Sjdp next_byte (&(ieee->h)); 172733965Sjdp abfd->start_address = must_parse_int (&(ieee->h)); 1728130561Sobrien /* We've got to the end of the data now - */ 1729130561Sobrien return TRUE; 173033965Sjdp default: 173133965Sjdp BFD_FAIL (); 1732130561Sobrien return FALSE; 173333965Sjdp } 173433965Sjdp break; 173533965Sjdp case ieee_repeat_data_enum: 173633965Sjdp { 173733965Sjdp /* Repeat the following LD or LR n times - we do this by 1738130561Sobrien remembering the stream pointer before running it and 1739130561Sobrien resetting it and running it n times. We special case 1740130561Sobrien the repetition of a repeat_data/load_constant. */ 174133965Sjdp unsigned int iterations; 174233965Sjdp unsigned char *start; 1743130561Sobrien 174433965Sjdp next_byte (&(ieee->h)); 174533965Sjdp iterations = must_parse_int (&(ieee->h)); 174633965Sjdp start = ieee->h.input_p; 1747130561Sobrien if (start[0] == (int) ieee_load_constant_bytes_enum 1748130561Sobrien && start[1] == 1) 174933965Sjdp { 175033965Sjdp while (iterations != 0) 175133965Sjdp { 175233965Sjdp location_ptr[current_map->pc++] = start[2]; 175333965Sjdp iterations--; 175433965Sjdp } 175533965Sjdp next_byte (&(ieee->h)); 175633965Sjdp next_byte (&(ieee->h)); 175733965Sjdp next_byte (&(ieee->h)); 175833965Sjdp } 175933965Sjdp else 176033965Sjdp { 176133965Sjdp while (iterations != 0) 176233965Sjdp { 176333965Sjdp ieee->h.input_p = start; 176433965Sjdp if (!do_one (ieee, current_map, location_ptr, s, 176589857Sobrien (int) iterations)) 1766130561Sobrien return FALSE; 176733965Sjdp iterations--; 176833965Sjdp } 176933965Sjdp } 177033965Sjdp } 177133965Sjdp break; 177233965Sjdp case ieee_load_constant_bytes_enum: 177333965Sjdp case ieee_load_with_relocation_enum: 1774130561Sobrien if (!do_one (ieee, current_map, location_ptr, s, 1)) 1775130561Sobrien return FALSE; 177633965Sjdp } 177733965Sjdp } 177833965Sjdp} 177933965Sjdp 1780218822Sdimstatic const bfd_target * 1781218822Sdimieee_object_p (bfd *abfd) 1782218822Sdim{ 1783218822Sdim char *processor; 1784218822Sdim unsigned int part; 1785218822Sdim ieee_data_type *ieee; 1786218822Sdim unsigned char buffer[300]; 1787218822Sdim ieee_data_type *save = IEEE_DATA (abfd); 1788218822Sdim bfd_size_type amt; 1789218822Sdim 1790218822Sdim abfd->tdata.ieee_data = 0; 1791218822Sdim ieee_mkobject (abfd); 1792218822Sdim 1793218822Sdim ieee = IEEE_DATA (abfd); 1794218822Sdim if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 1795218822Sdim goto fail; 1796218822Sdim /* Read the first few bytes in to see if it makes sense. Ignore 1797218822Sdim bfd_bread return value; The file might be very small. */ 1798218822Sdim bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd); 1799218822Sdim 1800218822Sdim ieee->h.input_p = buffer; 1801218822Sdim if (this_byte_and_next (&(ieee->h)) != Module_Beginning) 1802218822Sdim goto got_wrong_format; 1803218822Sdim 1804218822Sdim ieee->read_symbols = FALSE; 1805218822Sdim ieee->read_data = FALSE; 1806218822Sdim ieee->section_count = 0; 1807218822Sdim ieee->external_symbol_max_index = 0; 1808218822Sdim ieee->external_symbol_min_index = IEEE_PUBLIC_BASE; 1809218822Sdim ieee->external_reference_min_index = IEEE_REFERENCE_BASE; 1810218822Sdim ieee->external_reference_max_index = 0; 1811218822Sdim ieee->h.abfd = abfd; 1812218822Sdim ieee->section_table = NULL; 1813218822Sdim ieee->section_table_size = 0; 1814218822Sdim 1815218822Sdim processor = ieee->mb.processor = read_id (&(ieee->h)); 1816218822Sdim if (strcmp (processor, "LIBRARY") == 0) 1817218822Sdim goto got_wrong_format; 1818218822Sdim ieee->mb.module_name = read_id (&(ieee->h)); 1819218822Sdim if (abfd->filename == (const char *) NULL) 1820218822Sdim abfd->filename = ieee->mb.module_name; 1821218822Sdim 1822218822Sdim /* Determine the architecture and machine type of the object file. */ 1823218822Sdim { 1824218822Sdim const bfd_arch_info_type *arch; 1825218822Sdim char family[10]; 1826218822Sdim 1827218822Sdim /* IEEE does not specify the format of the processor identification 1828218822Sdim string, so the compiler is free to put in it whatever it wants. 1829218822Sdim We try here to recognize different processors belonging to the 1830218822Sdim m68k family. Code for other processors can be added here. */ 1831218822Sdim if ((processor[0] == '6') && (processor[1] == '8')) 1832218822Sdim { 1833218822Sdim if (processor[2] == '3') /* 683xx integrated processors. */ 1834218822Sdim { 1835218822Sdim switch (processor[3]) 1836218822Sdim { 1837218822Sdim case '0': /* 68302, 68306, 68307 */ 1838218822Sdim case '2': /* 68322, 68328 */ 1839218822Sdim case '5': /* 68356 */ 1840218822Sdim strcpy (family, "68000"); /* MC68000-based controllers. */ 1841218822Sdim break; 1842218822Sdim 1843218822Sdim case '3': /* 68330, 68331, 68332, 68333, 1844218822Sdim 68334, 68335, 68336, 68338 */ 1845218822Sdim case '6': /* 68360 */ 1846218822Sdim case '7': /* 68376 */ 1847218822Sdim strcpy (family, "68332"); /* CPU32 and CPU32+ */ 1848218822Sdim break; 1849218822Sdim 1850218822Sdim case '4': 1851218822Sdim if (processor[4] == '9') /* 68349 */ 1852218822Sdim strcpy (family, "68030"); /* CPU030 */ 1853218822Sdim else /* 68340, 68341 */ 1854218822Sdim strcpy (family, "68332"); /* CPU32 and CPU32+ */ 1855218822Sdim break; 1856218822Sdim 1857218822Sdim default: /* Does not exist yet. */ 1858218822Sdim strcpy (family, "68332"); /* Guess it will be CPU32 */ 1859218822Sdim } 1860218822Sdim } 1861218822Sdim else if (TOUPPER (processor[3]) == 'F') /* 68F333 */ 1862218822Sdim strcpy (family, "68332"); /* CPU32 */ 1863218822Sdim else if ((TOUPPER (processor[3]) == 'C') /* Embedded controllers. */ 1864218822Sdim && ((TOUPPER (processor[2]) == 'E') 1865218822Sdim || (TOUPPER (processor[2]) == 'H') 1866218822Sdim || (TOUPPER (processor[2]) == 'L'))) 1867218822Sdim { 1868218822Sdim strcpy (family, "68"); 1869218822Sdim strncat (family, processor + 4, 7); 1870218822Sdim family[9] = '\0'; 1871218822Sdim } 1872218822Sdim else /* "Regular" processors. */ 1873218822Sdim { 1874218822Sdim strncpy (family, processor, 9); 1875218822Sdim family[9] = '\0'; 1876218822Sdim } 1877218822Sdim } 1878218822Sdim else if ((CONST_STRNEQ (processor, "cpu32")) /* CPU32 and CPU32+ */ 1879218822Sdim || (CONST_STRNEQ (processor, "CPU32"))) 1880218822Sdim strcpy (family, "68332"); 1881218822Sdim else 1882218822Sdim { 1883218822Sdim strncpy (family, processor, 9); 1884218822Sdim family[9] = '\0'; 1885218822Sdim } 1886218822Sdim 1887218822Sdim arch = bfd_scan_arch (family); 1888218822Sdim if (arch == 0) 1889218822Sdim goto got_wrong_format; 1890218822Sdim abfd->arch_info = arch; 1891218822Sdim } 1892218822Sdim 1893218822Sdim if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum) 1894218822Sdim goto fail; 1895218822Sdim 1896218822Sdim next_byte (&(ieee->h)); 1897218822Sdim 1898218822Sdim if (! parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau)) 1899218822Sdim goto fail; 1900218822Sdim 1901218822Sdim if (! parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address)) 1902218822Sdim goto fail; 1903218822Sdim 1904218822Sdim /* If there is a byte order info, take it. */ 1905218822Sdim if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum 1906218822Sdim || this_byte (&(ieee->h)) == (int) ieee_variable_M_enum) 1907218822Sdim next_byte (&(ieee->h)); 1908218822Sdim 1909218822Sdim for (part = 0; part < N_W_VARIABLES; part++) 1910218822Sdim { 1911218822Sdim bfd_boolean ok; 1912218822Sdim 1913218822Sdim if (read_2bytes (&(ieee->h)) != (int) ieee_assign_value_to_variable_enum) 1914218822Sdim goto fail; 1915218822Sdim 1916218822Sdim if (this_byte_and_next (&(ieee->h)) != part) 1917218822Sdim goto fail; 1918218822Sdim 1919218822Sdim ieee->w.offset[part] = parse_i (&(ieee->h), &ok); 1920218822Sdim if (! ok) 1921218822Sdim goto fail; 1922218822Sdim } 1923218822Sdim 1924218822Sdim if (ieee->w.r.external_part != 0) 1925218822Sdim abfd->flags = HAS_SYMS; 1926218822Sdim 1927218822Sdim /* By now we know that this is a real IEEE file, we're going to read 1928218822Sdim the whole thing into memory so that we can run up and down it 1929218822Sdim quickly. We can work out how big the file is from the trailer 1930218822Sdim record. */ 1931218822Sdim 1932218822Sdim amt = ieee->w.r.me_record + 1; 1933218822Sdim IEEE_DATA (abfd)->h.first_byte = bfd_alloc (ieee->h.abfd, amt); 1934218822Sdim if (!IEEE_DATA (abfd)->h.first_byte) 1935218822Sdim goto fail; 1936218822Sdim if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 1937218822Sdim goto fail; 1938218822Sdim /* FIXME: Check return value. I'm not sure whether it needs to read 1939218822Sdim the entire buffer or not. */ 1940218822Sdim bfd_bread ((void *) (IEEE_DATA (abfd)->h.first_byte), 1941218822Sdim (bfd_size_type) ieee->w.r.me_record + 1, abfd); 1942218822Sdim 1943218822Sdim ieee_slurp_sections (abfd); 1944218822Sdim 1945218822Sdim if (! ieee_slurp_debug (abfd)) 1946218822Sdim goto fail; 1947218822Sdim 1948218822Sdim /* Parse section data to activate file and section flags implied by 1949218822Sdim section contents. */ 1950218822Sdim if (! ieee_slurp_section_data (abfd)) 1951218822Sdim goto fail; 1952218822Sdim 1953218822Sdim return abfd->xvec; 1954218822Sdimgot_wrong_format: 1955218822Sdim bfd_set_error (bfd_error_wrong_format); 1956218822Sdimfail: 1957218822Sdim bfd_release (abfd, ieee); 1958218822Sdim abfd->tdata.ieee_data = save; 1959218822Sdim return (const bfd_target *) NULL; 1960218822Sdim} 1961218822Sdim 1962218822Sdimstatic void 1963218822Sdimieee_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED, 1964218822Sdim asymbol *symbol, 1965218822Sdim symbol_info *ret) 1966218822Sdim{ 1967218822Sdim bfd_symbol_info (symbol, ret); 1968218822Sdim if (symbol->name[0] == ' ') 1969218822Sdim ret->name = "* empty table entry "; 1970218822Sdim if (!symbol->section) 1971218822Sdim ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A'; 1972218822Sdim} 1973218822Sdim 1974218822Sdimstatic void 1975218822Sdimieee_print_symbol (bfd *abfd, 1976218822Sdim void * afile, 1977218822Sdim asymbol *symbol, 1978218822Sdim bfd_print_symbol_type how) 1979218822Sdim{ 1980218822Sdim FILE *file = (FILE *) afile; 1981218822Sdim 1982218822Sdim switch (how) 1983218822Sdim { 1984218822Sdim case bfd_print_symbol_name: 1985218822Sdim fprintf (file, "%s", symbol->name); 1986218822Sdim break; 1987218822Sdim case bfd_print_symbol_more: 1988218822Sdim BFD_FAIL (); 1989218822Sdim break; 1990218822Sdim case bfd_print_symbol_all: 1991218822Sdim { 1992218822Sdim const char *section_name = 1993218822Sdim (symbol->section == (asection *) NULL 1994218822Sdim ? "*abs" 1995218822Sdim : symbol->section->name); 1996218822Sdim 1997218822Sdim if (symbol->name[0] == ' ') 1998218822Sdim fprintf (file, "* empty table entry "); 1999218822Sdim else 2000218822Sdim { 2001218822Sdim bfd_print_symbol_vandf (abfd, (void *) file, symbol); 2002218822Sdim 2003218822Sdim fprintf (file, " %-5s %04x %02x %s", 2004218822Sdim section_name, 2005218822Sdim (unsigned) ieee_symbol (symbol)->index, 2006218822Sdim (unsigned) 0, 2007218822Sdim symbol->name); 2008218822Sdim } 2009218822Sdim } 2010218822Sdim break; 2011218822Sdim } 2012218822Sdim} 2013218822Sdim 2014130561Sobrienstatic bfd_boolean 2015218822Sdimieee_new_section_hook (bfd *abfd, asection *newsect) 201633965Sjdp{ 201733965Sjdp if (!newsect->used_by_bfd) 2018218822Sdim { 2019218822Sdim newsect->used_by_bfd = bfd_alloc (abfd, sizeof (ieee_per_section_type)); 2020218822Sdim if (!newsect->used_by_bfd) 2021218822Sdim return FALSE; 2022218822Sdim } 2023218822Sdim ieee_per_section (newsect)->data = NULL; 202433965Sjdp ieee_per_section (newsect)->section = newsect; 2025218822Sdim return _bfd_generic_new_section_hook (abfd, newsect); 202633965Sjdp} 202733965Sjdp 202889857Sobrienstatic long 2029218822Sdimieee_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) 203033965Sjdp{ 203133965Sjdp if ((asect->flags & SEC_DEBUGGING) != 0) 203233965Sjdp return 0; 203333965Sjdp if (! ieee_slurp_section_data (abfd)) 203433965Sjdp return -1; 203533965Sjdp return (asect->reloc_count + 1) * sizeof (arelent *); 203633965Sjdp} 203733965Sjdp 2038130561Sobrienstatic bfd_boolean 2039218822Sdimieee_get_section_contents (bfd *abfd, 2040218822Sdim sec_ptr section, 2041218822Sdim void * location, 2042218822Sdim file_ptr offset, 2043218822Sdim bfd_size_type count) 204433965Sjdp{ 2045130561Sobrien ieee_per_section_type *p = ieee_per_section (section); 204633965Sjdp if ((section->flags & SEC_DEBUGGING) != 0) 204733965Sjdp return _bfd_generic_get_section_contents (abfd, section, location, 204833965Sjdp offset, count); 204933965Sjdp ieee_slurp_section_data (abfd); 2050218822Sdim (void) memcpy ((void *) location, (void *) (p->data + offset), (unsigned) count); 2051130561Sobrien return TRUE; 205233965Sjdp} 205333965Sjdp 205489857Sobrienstatic long 2055218822Sdimieee_canonicalize_reloc (bfd *abfd, 2056218822Sdim sec_ptr section, 2057218822Sdim arelent **relptr, 2058218822Sdim asymbol **symbols) 205933965Sjdp{ 206033965Sjdp ieee_reloc_type *src = (ieee_reloc_type *) (section->relocation); 206133965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 206233965Sjdp 206333965Sjdp if ((section->flags & SEC_DEBUGGING) != 0) 206433965Sjdp return 0; 206533965Sjdp 206633965Sjdp while (src != (ieee_reloc_type *) NULL) 206733965Sjdp { 2068130561Sobrien /* Work out which symbol to attach it this reloc to. */ 206933965Sjdp switch (src->symbol.letter) 207033965Sjdp { 207133965Sjdp case 'I': 207233965Sjdp src->relent.sym_ptr_ptr = 207333965Sjdp symbols + src->symbol.index + ieee->external_symbol_base_offset; 207433965Sjdp break; 207533965Sjdp case 'X': 207633965Sjdp src->relent.sym_ptr_ptr = 207733965Sjdp symbols + src->symbol.index + ieee->external_reference_base_offset; 207833965Sjdp break; 207933965Sjdp case 0: 208038889Sjdp if (src->relent.sym_ptr_ptr != NULL) 208138889Sjdp src->relent.sym_ptr_ptr = 208238889Sjdp src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr; 208333965Sjdp break; 208433965Sjdp default: 208533965Sjdp 208633965Sjdp BFD_FAIL (); 208733965Sjdp } 208833965Sjdp *relptr++ = &src->relent; 208933965Sjdp src = src->next; 209033965Sjdp } 2091218822Sdim *relptr = NULL; 209233965Sjdp return section->reloc_count; 209333965Sjdp} 209433965Sjdp 209533965Sjdpstatic int 2096218822Sdimcomp (const void * ap, const void * bp) 209733965Sjdp{ 209833965Sjdp arelent *a = *((arelent **) ap); 209933965Sjdp arelent *b = *((arelent **) bp); 210033965Sjdp return a->address - b->address; 210133965Sjdp} 210233965Sjdp 210333965Sjdp/* Write the section headers. */ 210433965Sjdp 2105130561Sobrienstatic bfd_boolean 2106218822Sdimieee_write_section_part (bfd *abfd) 210733965Sjdp{ 210833965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 210933965Sjdp asection *s; 2110218822Sdim 211133965Sjdp ieee->w.r.section_part = bfd_tell (abfd); 211233965Sjdp for (s = abfd->sections; s != (asection *) NULL; s = s->next) 211333965Sjdp { 211433965Sjdp if (! bfd_is_abs_section (s) 211533965Sjdp && (s->flags & SEC_DEBUGGING) == 0) 211633965Sjdp { 211733965Sjdp if (! ieee_write_byte (abfd, ieee_section_type_enum) 211833965Sjdp || ! ieee_write_byte (abfd, 211933965Sjdp (bfd_byte) (s->index 212033965Sjdp + IEEE_SECTION_NUMBER_BASE))) 2121130561Sobrien return FALSE; 212233965Sjdp 212333965Sjdp if (abfd->flags & EXEC_P) 212433965Sjdp { 2125130561Sobrien /* This image is executable, so output absolute sections. */ 212633965Sjdp if (! ieee_write_byte (abfd, ieee_variable_A_enum) 212733965Sjdp || ! ieee_write_byte (abfd, ieee_variable_S_enum)) 2128130561Sobrien return FALSE; 212933965Sjdp } 213033965Sjdp else 213133965Sjdp { 213233965Sjdp if (! ieee_write_byte (abfd, ieee_variable_C_enum)) 2133130561Sobrien return FALSE; 213433965Sjdp } 213533965Sjdp 213633965Sjdp switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM)) 213733965Sjdp { 213833965Sjdp case SEC_CODE | SEC_LOAD: 213933965Sjdp case SEC_CODE: 214033965Sjdp if (! ieee_write_byte (abfd, ieee_variable_P_enum)) 2141130561Sobrien return FALSE; 214233965Sjdp break; 214333965Sjdp case SEC_DATA: 214433965Sjdp default: 214533965Sjdp if (! ieee_write_byte (abfd, ieee_variable_D_enum)) 2146130561Sobrien return FALSE; 214733965Sjdp break; 214833965Sjdp case SEC_ROM: 214933965Sjdp case SEC_ROM | SEC_DATA: 215033965Sjdp case SEC_ROM | SEC_LOAD: 215133965Sjdp case SEC_ROM | SEC_DATA | SEC_LOAD: 215233965Sjdp if (! ieee_write_byte (abfd, ieee_variable_R_enum)) 2153130561Sobrien return FALSE; 215433965Sjdp } 215533965Sjdp 215633965Sjdp 215733965Sjdp if (! ieee_write_id (abfd, s->name)) 2158130561Sobrien return FALSE; 2159130561Sobrien /* Alignment. */ 216033965Sjdp if (! ieee_write_byte (abfd, ieee_section_alignment_enum) 216133965Sjdp || ! ieee_write_byte (abfd, 216233965Sjdp (bfd_byte) (s->index 216333965Sjdp + IEEE_SECTION_NUMBER_BASE)) 216489857Sobrien || ! ieee_write_int (abfd, (bfd_vma) 1 << s->alignment_power)) 2165130561Sobrien return FALSE; 216633965Sjdp 2167130561Sobrien /* Size. */ 216833965Sjdp if (! ieee_write_2bytes (abfd, ieee_section_size_enum) 216933965Sjdp || ! ieee_write_byte (abfd, 217033965Sjdp (bfd_byte) (s->index 217133965Sjdp + IEEE_SECTION_NUMBER_BASE)) 2172218822Sdim || ! ieee_write_int (abfd, s->size)) 2173130561Sobrien return FALSE; 217433965Sjdp if (abfd->flags & EXEC_P) 217533965Sjdp { 2176130561Sobrien /* Relocateable sections don't have asl records. */ 2177130561Sobrien /* Vma. */ 217833965Sjdp if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum) 217933965Sjdp || ! ieee_write_byte (abfd, 218033965Sjdp ((bfd_byte) 218133965Sjdp (s->index 218233965Sjdp + IEEE_SECTION_NUMBER_BASE))) 218333965Sjdp || ! ieee_write_int (abfd, s->lma)) 2184130561Sobrien return FALSE; 218533965Sjdp } 218633965Sjdp } 218733965Sjdp } 218833965Sjdp 2189130561Sobrien return TRUE; 219033965Sjdp} 219133965Sjdp 2192130561Sobrienstatic bfd_boolean 2193218822Sdimdo_with_relocs (bfd *abfd, asection *s) 219433965Sjdp{ 219533965Sjdp unsigned int number_of_maus_in_address = 219633965Sjdp bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd); 219733965Sjdp unsigned int relocs_to_go = s->reloc_count; 219833965Sjdp bfd_byte *stream = ieee_per_section (s)->data; 219933965Sjdp arelent **p = s->orelocation; 220033965Sjdp bfd_size_type current_byte_index = 0; 220133965Sjdp 220233965Sjdp qsort (s->orelocation, 220333965Sjdp relocs_to_go, 220433965Sjdp sizeof (arelent **), 220533965Sjdp comp); 220633965Sjdp 2207130561Sobrien /* Output the section preheader. */ 220833965Sjdp if (! ieee_write_byte (abfd, ieee_set_current_section_enum) 220933965Sjdp || ! ieee_write_byte (abfd, 221033965Sjdp (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)) 221133965Sjdp || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum) 221233965Sjdp || ! ieee_write_byte (abfd, 221333965Sjdp (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))) 2214130561Sobrien return FALSE; 221589857Sobrien 221633965Sjdp if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0) 221733965Sjdp { 221833965Sjdp if (! ieee_write_int (abfd, s->lma)) 2219130561Sobrien return FALSE; 222033965Sjdp } 222133965Sjdp else 222233965Sjdp { 222389857Sobrien if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0)) 2224130561Sobrien return FALSE; 222533965Sjdp } 222633965Sjdp 222733965Sjdp if (relocs_to_go == 0) 222833965Sjdp { 222933965Sjdp /* If there aren't any relocations then output the load constant 2230130561Sobrien byte opcode rather than the load with relocation opcode. */ 2231218822Sdim while (current_byte_index < s->size) 223233965Sjdp { 223333965Sjdp bfd_size_type run; 223433965Sjdp unsigned int MAXRUN = 127; 2235130561Sobrien 223633965Sjdp run = MAXRUN; 2237218822Sdim if (run > s->size - current_byte_index) 2238218822Sdim run = s->size - current_byte_index; 223933965Sjdp 224033965Sjdp if (run != 0) 224133965Sjdp { 224233965Sjdp if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)) 2243130561Sobrien return FALSE; 2244130561Sobrien /* Output a stream of bytes. */ 224533965Sjdp if (! ieee_write_int (abfd, run)) 2246130561Sobrien return FALSE; 2247218822Sdim if (bfd_bwrite ((void *) (stream + current_byte_index), run, abfd) 224833965Sjdp != run) 2249130561Sobrien return FALSE; 225033965Sjdp current_byte_index += run; 225133965Sjdp } 225233965Sjdp } 225333965Sjdp } 225433965Sjdp else 225533965Sjdp { 225633965Sjdp if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum)) 2257130561Sobrien return FALSE; 225833965Sjdp 225933965Sjdp /* Output the data stream as the longest sequence of bytes 226033965Sjdp possible, allowing for the a reasonable packet size and 226133965Sjdp relocation stuffs. */ 2262218822Sdim if (stream == NULL) 226333965Sjdp { 2264130561Sobrien /* Outputting a section without data, fill it up. */ 2265218822Sdim stream = bfd_zalloc (abfd, s->size); 226633965Sjdp if (!stream) 2267130561Sobrien return FALSE; 226833965Sjdp } 2269218822Sdim while (current_byte_index < s->size) 227033965Sjdp { 227133965Sjdp bfd_size_type run; 227233965Sjdp unsigned int MAXRUN = 127; 2273130561Sobrien 227433965Sjdp if (relocs_to_go) 227533965Sjdp { 227633965Sjdp run = (*p)->address - current_byte_index; 227733965Sjdp if (run > MAXRUN) 227833965Sjdp run = MAXRUN; 227933965Sjdp } 228033965Sjdp else 2281130561Sobrien run = MAXRUN; 2282130561Sobrien 2283218822Sdim if (run > s->size - current_byte_index) 2284218822Sdim run = s->size - current_byte_index; 228533965Sjdp 228633965Sjdp if (run != 0) 228733965Sjdp { 2288130561Sobrien /* Output a stream of bytes. */ 228933965Sjdp if (! ieee_write_int (abfd, run)) 2290130561Sobrien return FALSE; 2291218822Sdim if (bfd_bwrite ((void *) (stream + current_byte_index), run, abfd) 229233965Sjdp != run) 2293130561Sobrien return FALSE; 229433965Sjdp current_byte_index += run; 229533965Sjdp } 2296130561Sobrien 2297130561Sobrien /* Output any relocations here. */ 229833965Sjdp if (relocs_to_go && (*p) && (*p)->address == current_byte_index) 229933965Sjdp { 230033965Sjdp while (relocs_to_go 230133965Sjdp && (*p) && (*p)->address == current_byte_index) 230233965Sjdp { 230333965Sjdp arelent *r = *p; 230433965Sjdp bfd_signed_vma ov; 230533965Sjdp switch (r->howto->size) 230633965Sjdp { 230733965Sjdp case 2: 230833965Sjdp ov = bfd_get_signed_32 (abfd, 230933965Sjdp stream + current_byte_index); 231033965Sjdp current_byte_index += 4; 231133965Sjdp break; 231233965Sjdp case 1: 231333965Sjdp ov = bfd_get_signed_16 (abfd, 231433965Sjdp stream + current_byte_index); 231533965Sjdp current_byte_index += 2; 231633965Sjdp break; 231733965Sjdp case 0: 231833965Sjdp ov = bfd_get_signed_8 (abfd, 231933965Sjdp stream + current_byte_index); 232033965Sjdp current_byte_index++; 232133965Sjdp break; 232233965Sjdp default: 232333965Sjdp ov = 0; 232433965Sjdp BFD_FAIL (); 2325130561Sobrien return FALSE; 232633965Sjdp } 232733965Sjdp 232833965Sjdp ov &= r->howto->src_mask; 232933965Sjdp 233033965Sjdp if (r->howto->pc_relative 233133965Sjdp && ! r->howto->pcrel_offset) 233233965Sjdp ov += r->address; 233333965Sjdp 233433965Sjdp if (! ieee_write_byte (abfd, 233533965Sjdp ieee_function_either_open_b_enum)) 2336130561Sobrien return FALSE; 233733965Sjdp 233833965Sjdp if (r->sym_ptr_ptr != (asymbol **) NULL) 233933965Sjdp { 234033965Sjdp if (! ieee_write_expression (abfd, r->addend + ov, 234133965Sjdp *(r->sym_ptr_ptr), 234233965Sjdp r->howto->pc_relative, 234389857Sobrien (unsigned) s->index)) 2344130561Sobrien return FALSE; 234533965Sjdp } 234633965Sjdp else 234733965Sjdp { 234833965Sjdp if (! ieee_write_expression (abfd, r->addend + ov, 234933965Sjdp (asymbol *) NULL, 235033965Sjdp r->howto->pc_relative, 235189857Sobrien (unsigned) s->index)) 2352130561Sobrien return FALSE; 235333965Sjdp } 235433965Sjdp 235533965Sjdp if (number_of_maus_in_address 235633965Sjdp != bfd_get_reloc_size (r->howto)) 235733965Sjdp { 235889857Sobrien bfd_vma rsize = bfd_get_reloc_size (r->howto); 235989857Sobrien if (! ieee_write_int (abfd, rsize)) 2360130561Sobrien return FALSE; 236133965Sjdp } 236233965Sjdp if (! ieee_write_byte (abfd, 236333965Sjdp ieee_function_either_close_b_enum)) 2364130561Sobrien return FALSE; 236533965Sjdp 236633965Sjdp relocs_to_go--; 236733965Sjdp p++; 236833965Sjdp } 236933965Sjdp 237033965Sjdp } 237133965Sjdp } 237233965Sjdp } 237333965Sjdp 2374130561Sobrien return TRUE; 237533965Sjdp} 237633965Sjdp 237733965Sjdp/* If there are no relocations in the output section then we can be 237833965Sjdp clever about how we write. We block items up into a max of 127 237933965Sjdp bytes. */ 238033965Sjdp 2381130561Sobrienstatic bfd_boolean 2382218822Sdimdo_as_repeat (bfd *abfd, asection *s) 238333965Sjdp{ 2384218822Sdim if (s->size) 238533965Sjdp { 238633965Sjdp if (! ieee_write_byte (abfd, ieee_set_current_section_enum) 238733965Sjdp || ! ieee_write_byte (abfd, 238833965Sjdp (bfd_byte) (s->index 238933965Sjdp + IEEE_SECTION_NUMBER_BASE)) 239033965Sjdp || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8) 239133965Sjdp || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff) 239233965Sjdp || ! ieee_write_byte (abfd, 239333965Sjdp (bfd_byte) (s->index 239489857Sobrien + IEEE_SECTION_NUMBER_BASE))) 2395130561Sobrien return FALSE; 239689857Sobrien 239789857Sobrien if ((abfd->flags & EXEC_P) != 0) 239889857Sobrien { 239989857Sobrien if (! ieee_write_int (abfd, s->lma)) 2400130561Sobrien return FALSE; 240189857Sobrien } 240289857Sobrien else 240389857Sobrien { 240489857Sobrien if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0)) 2405130561Sobrien return FALSE; 240689857Sobrien } 240789857Sobrien 240889857Sobrien if (! ieee_write_byte (abfd, ieee_repeat_data_enum) 2409218822Sdim || ! ieee_write_int (abfd, s->size) 241033965Sjdp || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum) 241133965Sjdp || ! ieee_write_byte (abfd, 1) 241233965Sjdp || ! ieee_write_byte (abfd, 0)) 2413130561Sobrien return FALSE; 241433965Sjdp } 241533965Sjdp 2416130561Sobrien return TRUE; 241733965Sjdp} 241833965Sjdp 2419130561Sobrienstatic bfd_boolean 2420218822Sdimdo_without_relocs (bfd *abfd, asection *s) 242133965Sjdp{ 242233965Sjdp bfd_byte *stream = ieee_per_section (s)->data; 242333965Sjdp 242433965Sjdp if (stream == 0 || ((s->flags & SEC_LOAD) == 0)) 242533965Sjdp { 242633965Sjdp if (! do_as_repeat (abfd, s)) 2427130561Sobrien return FALSE; 242833965Sjdp } 242933965Sjdp else 243033965Sjdp { 243133965Sjdp unsigned int i; 2432130561Sobrien 2433218822Sdim for (i = 0; i < s->size; i++) 243433965Sjdp { 243533965Sjdp if (stream[i] != 0) 243633965Sjdp { 243733965Sjdp if (! do_with_relocs (abfd, s)) 2438130561Sobrien return FALSE; 2439130561Sobrien return TRUE; 244033965Sjdp } 244133965Sjdp } 244233965Sjdp if (! do_as_repeat (abfd, s)) 2443130561Sobrien return FALSE; 244433965Sjdp } 244533965Sjdp 2446130561Sobrien return TRUE; 244733965Sjdp} 244833965Sjdp 244933965Sjdpstatic void 2450218822Sdimfill (void) 245133965Sjdp{ 245289857Sobrien bfd_size_type amt = input_ptr_end - input_ptr_start; 245333965Sjdp /* FIXME: Check return value. I'm not sure whether it needs to read 245433965Sjdp the entire buffer or not. */ 2455218822Sdim bfd_bread ((void *) input_ptr_start, amt, input_bfd); 245633965Sjdp input_ptr = input_ptr_start; 245733965Sjdp} 245889857Sobrien 245933965Sjdpstatic void 2460218822Sdimflush (void) 246133965Sjdp{ 246289857Sobrien bfd_size_type amt = output_ptr - output_ptr_start; 2463130561Sobrien 2464218822Sdim if (bfd_bwrite ((void *) (output_ptr_start), amt, output_bfd) != amt) 246533965Sjdp abort (); 246633965Sjdp output_ptr = output_ptr_start; 246733965Sjdp output_buffer++; 246833965Sjdp} 246933965Sjdp 247033965Sjdp#define THIS() ( *input_ptr ) 2471218822Sdim#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill (); } 2472218822Sdim#define OUT(x) { *output_ptr++ = (x); if (output_ptr == output_ptr_end) flush (); } 247333965Sjdp 247433965Sjdpstatic void 2475218822Sdimwrite_int (int value) 247633965Sjdp{ 247733965Sjdp if (value >= 0 && value <= 127) 247833965Sjdp { 247933965Sjdp OUT (value); 248033965Sjdp } 248133965Sjdp else 248233965Sjdp { 248333965Sjdp unsigned int length; 2484218822Sdim 2485130561Sobrien /* How many significant bytes ? */ 2486130561Sobrien /* FIXME FOR LONGER INTS. */ 248733965Sjdp if (value & 0xff000000) 2488130561Sobrien length = 4; 248933965Sjdp else if (value & 0x00ff0000) 2490130561Sobrien length = 3; 249133965Sjdp else if (value & 0x0000ff00) 2492130561Sobrien length = 2; 249333965Sjdp else 249433965Sjdp length = 1; 249533965Sjdp 249633965Sjdp OUT ((int) ieee_number_repeat_start_enum + length); 249733965Sjdp switch (length) 249833965Sjdp { 249933965Sjdp case 4: 250033965Sjdp OUT (value >> 24); 250133965Sjdp case 3: 250233965Sjdp OUT (value >> 16); 250333965Sjdp case 2: 250433965Sjdp OUT (value >> 8); 250533965Sjdp case 1: 250633965Sjdp OUT (value); 250733965Sjdp } 250833965Sjdp } 250933965Sjdp} 251033965Sjdp 251133965Sjdpstatic void 2512218822Sdimcopy_id (void) 251333965Sjdp{ 251433965Sjdp int length = THIS (); 251533965Sjdp char ch; 2516130561Sobrien 251733965Sjdp OUT (length); 251833965Sjdp NEXT (); 251933965Sjdp while (length--) 252033965Sjdp { 252133965Sjdp ch = THIS (); 252233965Sjdp OUT (ch); 252333965Sjdp NEXT (); 252433965Sjdp } 252533965Sjdp} 252633965Sjdp 252733965Sjdp#define VAR(x) ((x | 0x80)) 252833965Sjdpstatic void 2529218822Sdimcopy_expression (void) 253033965Sjdp{ 253133965Sjdp int stack[10]; 253233965Sjdp int *tos = stack; 253389857Sobrien int value; 2534130561Sobrien 253533965Sjdp while (1) 253633965Sjdp { 253733965Sjdp switch (THIS ()) 253833965Sjdp { 253933965Sjdp case 0x84: 254033965Sjdp NEXT (); 254133965Sjdp value = THIS (); 254233965Sjdp NEXT (); 254333965Sjdp value = (value << 8) | THIS (); 254433965Sjdp NEXT (); 254533965Sjdp value = (value << 8) | THIS (); 254633965Sjdp NEXT (); 254733965Sjdp value = (value << 8) | THIS (); 254833965Sjdp NEXT (); 254933965Sjdp *tos++ = value; 255033965Sjdp break; 255133965Sjdp case 0x83: 255233965Sjdp NEXT (); 255333965Sjdp value = THIS (); 255433965Sjdp NEXT (); 255533965Sjdp value = (value << 8) | THIS (); 255633965Sjdp NEXT (); 255733965Sjdp value = (value << 8) | THIS (); 255833965Sjdp NEXT (); 255933965Sjdp *tos++ = value; 256033965Sjdp break; 256133965Sjdp case 0x82: 256233965Sjdp NEXT (); 256333965Sjdp value = THIS (); 256433965Sjdp NEXT (); 256533965Sjdp value = (value << 8) | THIS (); 256633965Sjdp NEXT (); 256733965Sjdp *tos++ = value; 256833965Sjdp break; 256933965Sjdp case 0x81: 257033965Sjdp NEXT (); 257133965Sjdp value = THIS (); 257233965Sjdp NEXT (); 257333965Sjdp *tos++ = value; 257433965Sjdp break; 257533965Sjdp case 0x80: 257633965Sjdp NEXT (); 257733965Sjdp *tos++ = 0; 257833965Sjdp break; 257933965Sjdp default: 258033965Sjdp if (THIS () > 0x84) 258133965Sjdp { 2582130561Sobrien /* Not a number, just bug out with the answer. */ 258333965Sjdp write_int (*(--tos)); 258433965Sjdp return; 258533965Sjdp } 258633965Sjdp *tos++ = THIS (); 258733965Sjdp NEXT (); 258833965Sjdp break; 258933965Sjdp case 0xa5: 2590130561Sobrien /* PLUS anything. */ 259189857Sobrien value = *(--tos); 259289857Sobrien value += *(--tos); 259389857Sobrien *tos++ = value; 259489857Sobrien NEXT (); 259533965Sjdp break; 259633965Sjdp case VAR ('R'): 259733965Sjdp { 259833965Sjdp int section_number; 259933965Sjdp ieee_data_type *ieee; 260033965Sjdp asection *s; 2601130561Sobrien 260233965Sjdp NEXT (); 260333965Sjdp section_number = THIS (); 260433965Sjdp 260533965Sjdp NEXT (); 260633965Sjdp ieee = IEEE_DATA (input_bfd); 260733965Sjdp s = ieee->section_table[section_number]; 260889857Sobrien value = 0; 260933965Sjdp if (s->output_section) 261089857Sobrien value = s->output_section->lma; 261133965Sjdp value += s->output_offset; 261233965Sjdp *tos++ = value; 261333965Sjdp } 261433965Sjdp break; 261533965Sjdp case 0x90: 261633965Sjdp { 261733965Sjdp NEXT (); 261833965Sjdp write_int (*(--tos)); 261933965Sjdp OUT (0x90); 262033965Sjdp return; 262133965Sjdp } 262233965Sjdp } 262333965Sjdp } 262433965Sjdp} 262533965Sjdp 262633965Sjdp/* Drop the int in the buffer, and copy a null into the gap, which we 2627218822Sdim will overwrite later. */ 262833965Sjdp 262933965Sjdpstatic void 2630218822Sdimfill_int (struct output_buffer_struct *buf) 263133965Sjdp{ 263233965Sjdp if (buf->buffer == output_buffer) 263333965Sjdp { 2634130561Sobrien /* Still a chance to output the size. */ 263533965Sjdp int value = output_ptr - buf->ptrp + 3; 263633965Sjdp buf->ptrp[0] = value >> 24; 263733965Sjdp buf->ptrp[1] = value >> 16; 263833965Sjdp buf->ptrp[2] = value >> 8; 263933965Sjdp buf->ptrp[3] = value >> 0; 264033965Sjdp } 264133965Sjdp} 264233965Sjdp 264333965Sjdpstatic void 2644218822Sdimdrop_int (struct output_buffer_struct *buf) 264533965Sjdp{ 264633965Sjdp int type = THIS (); 264733965Sjdp int ch; 2648130561Sobrien 264933965Sjdp if (type <= 0x84) 265033965Sjdp { 265133965Sjdp NEXT (); 265233965Sjdp switch (type) 265333965Sjdp { 265433965Sjdp case 0x84: 265533965Sjdp ch = THIS (); 265633965Sjdp NEXT (); 265733965Sjdp case 0x83: 265833965Sjdp ch = THIS (); 265933965Sjdp NEXT (); 266033965Sjdp case 0x82: 266133965Sjdp ch = THIS (); 266233965Sjdp NEXT (); 266333965Sjdp case 0x81: 266433965Sjdp ch = THIS (); 266533965Sjdp NEXT (); 266633965Sjdp case 0x80: 266733965Sjdp break; 266833965Sjdp } 266933965Sjdp } 267033965Sjdp OUT (0x84); 267133965Sjdp buf->ptrp = output_ptr; 267233965Sjdp buf->buffer = output_buffer; 267333965Sjdp OUT (0); 267433965Sjdp OUT (0); 267533965Sjdp OUT (0); 267633965Sjdp OUT (0); 267733965Sjdp} 267833965Sjdp 267933965Sjdpstatic void 2680218822Sdimcopy_int (void) 268133965Sjdp{ 268233965Sjdp int type = THIS (); 268333965Sjdp int ch; 268433965Sjdp if (type <= 0x84) 268533965Sjdp { 268633965Sjdp OUT (type); 268733965Sjdp NEXT (); 268833965Sjdp switch (type) 268933965Sjdp { 269033965Sjdp case 0x84: 269133965Sjdp ch = THIS (); 269233965Sjdp NEXT (); 269333965Sjdp OUT (ch); 269433965Sjdp case 0x83: 269533965Sjdp ch = THIS (); 269633965Sjdp NEXT (); 269733965Sjdp OUT (ch); 269833965Sjdp case 0x82: 269933965Sjdp ch = THIS (); 270033965Sjdp NEXT (); 270133965Sjdp OUT (ch); 270233965Sjdp case 0x81: 270333965Sjdp ch = THIS (); 270433965Sjdp NEXT (); 270533965Sjdp OUT (ch); 270633965Sjdp case 0x80: 270733965Sjdp break; 270833965Sjdp } 270933965Sjdp } 271033965Sjdp} 271133965Sjdp 2712218822Sdim#define ID copy_id () 2713218822Sdim#define INT copy_int () 2714218822Sdim#define EXP copy_expression () 2715218822Sdim#define INTn(q) copy_int () 2716218822Sdim#define EXPn(q) copy_expression () 271733965Sjdp 271833965Sjdpstatic void 2719218822Sdimcopy_till_end (void) 272033965Sjdp{ 2721218822Sdim int ch = THIS (); 2722218822Sdim 2723218822Sdim while (1) 2724218822Sdim { 2725218822Sdim while (ch <= 0x80) 2726218822Sdim { 2727218822Sdim OUT (ch); 2728218822Sdim NEXT (); 2729218822Sdim ch = THIS (); 2730218822Sdim } 2731218822Sdim switch (ch) 2732218822Sdim { 2733218822Sdim case 0x84: 2734218822Sdim OUT (THIS ()); 2735218822Sdim NEXT (); 2736218822Sdim case 0x83: 2737218822Sdim OUT (THIS ()); 2738218822Sdim NEXT (); 2739218822Sdim case 0x82: 2740218822Sdim OUT (THIS ()); 2741218822Sdim NEXT (); 2742218822Sdim case 0x81: 2743218822Sdim OUT (THIS ()); 2744218822Sdim NEXT (); 2745218822Sdim OUT (THIS ()); 2746218822Sdim NEXT (); 2747218822Sdim 2748218822Sdim ch = THIS (); 2749218822Sdim break; 2750218822Sdim default: 2751218822Sdim return; 2752218822Sdim } 2753218822Sdim } 2754218822Sdim 2755218822Sdim} 2756218822Sdim 2757218822Sdimstatic void 2758218822Sdimf1_record (void) 2759218822Sdim{ 276033965Sjdp int ch; 2761130561Sobrien 2762130561Sobrien /* ATN record. */ 276333965Sjdp NEXT (); 276433965Sjdp ch = THIS (); 276533965Sjdp switch (ch) 276633965Sjdp { 276733965Sjdp default: 276833965Sjdp OUT (0xf1); 276933965Sjdp OUT (ch); 277033965Sjdp break; 277133965Sjdp case 0xc9: 277233965Sjdp NEXT (); 277333965Sjdp OUT (0xf1); 277433965Sjdp OUT (0xc9); 277533965Sjdp INT; 277633965Sjdp INT; 277733965Sjdp ch = THIS (); 277833965Sjdp switch (ch) 277933965Sjdp { 278033965Sjdp case 0x16: 278133965Sjdp NEXT (); 278233965Sjdp break; 278333965Sjdp case 0x01: 278433965Sjdp NEXT (); 278533965Sjdp break; 278633965Sjdp case 0x00: 278733965Sjdp NEXT (); 278833965Sjdp INT; 278933965Sjdp break; 279033965Sjdp case 0x03: 279133965Sjdp NEXT (); 279233965Sjdp INT; 279333965Sjdp break; 279433965Sjdp case 0x13: 279533965Sjdp EXPn (instruction address); 279633965Sjdp break; 279733965Sjdp default: 279833965Sjdp break; 279933965Sjdp } 280033965Sjdp break; 280133965Sjdp case 0xd8: 2802130561Sobrien /* EXternal ref. */ 280333965Sjdp NEXT (); 280433965Sjdp OUT (0xf1); 280533965Sjdp OUT (0xd8); 280633965Sjdp EXP; 280733965Sjdp EXP; 280833965Sjdp EXP; 280933965Sjdp EXP; 281033965Sjdp break; 281133965Sjdp case 0xce: 281233965Sjdp NEXT (); 281333965Sjdp OUT (0xf1); 281433965Sjdp OUT (0xce); 281533965Sjdp INT; 281633965Sjdp INT; 281733965Sjdp ch = THIS (); 281833965Sjdp INT; 281933965Sjdp switch (ch) 282033965Sjdp { 282133965Sjdp case 0x01: 282233965Sjdp INT; 282333965Sjdp INT; 282433965Sjdp break; 282533965Sjdp case 0x02: 282633965Sjdp INT; 282733965Sjdp break; 282833965Sjdp case 0x04: 282933965Sjdp EXPn (external function); 283033965Sjdp break; 283133965Sjdp case 0x05: 283233965Sjdp break; 283333965Sjdp case 0x07: 283433965Sjdp INTn (line number); 283533965Sjdp INT; 283633965Sjdp case 0x08: 283733965Sjdp break; 283833965Sjdp case 0x0a: 283933965Sjdp INTn (locked register); 284033965Sjdp INT; 284133965Sjdp break; 284233965Sjdp case 0x3f: 284333965Sjdp copy_till_end (); 284433965Sjdp break; 284533965Sjdp case 0x3e: 284633965Sjdp copy_till_end (); 284733965Sjdp break; 284833965Sjdp case 0x40: 284933965Sjdp copy_till_end (); 285033965Sjdp break; 285133965Sjdp case 0x41: 285233965Sjdp ID; 285333965Sjdp break; 285433965Sjdp } 285533965Sjdp } 285633965Sjdp} 285733965Sjdp 285833965Sjdpstatic void 2859218822Sdimf0_record (void) 286033965Sjdp{ 2861130561Sobrien /* Attribute record. */ 286233965Sjdp NEXT (); 286333965Sjdp OUT (0xf0); 286433965Sjdp INTn (Symbol name); 286533965Sjdp ID; 286633965Sjdp} 286733965Sjdp 286833965Sjdpstatic void 2869218822Sdimf2_record (void) 287033965Sjdp{ 287133965Sjdp NEXT (); 287233965Sjdp OUT (0xf2); 287333965Sjdp INT; 287433965Sjdp NEXT (); 287533965Sjdp OUT (0xce); 287633965Sjdp INT; 287733965Sjdp copy_till_end (); 287833965Sjdp} 287933965Sjdp 288033965Sjdpstatic void 2881218822Sdimf8_record (void) 288233965Sjdp{ 288333965Sjdp int ch; 288433965Sjdp NEXT (); 288533965Sjdp ch = THIS (); 288633965Sjdp switch (ch) 288733965Sjdp { 288833965Sjdp case 0x01: 288933965Sjdp case 0x02: 289033965Sjdp case 0x03: 2891130561Sobrien /* Unique typedefs for module. */ 2892130561Sobrien /* GLobal typedefs. */ 2893130561Sobrien /* High level module scope beginning. */ 289433965Sjdp { 289533965Sjdp struct output_buffer_struct ob; 2896130561Sobrien 289733965Sjdp NEXT (); 289833965Sjdp OUT (0xf8); 289933965Sjdp OUT (ch); 290033965Sjdp drop_int (&ob); 290133965Sjdp ID; 290233965Sjdp 290333965Sjdp block (); 290433965Sjdp 290533965Sjdp NEXT (); 290633965Sjdp fill_int (&ob); 290733965Sjdp OUT (0xf9); 290833965Sjdp } 290933965Sjdp break; 291033965Sjdp case 0x04: 2911130561Sobrien /* Global function. */ 291233965Sjdp { 291333965Sjdp struct output_buffer_struct ob; 2914130561Sobrien 291533965Sjdp NEXT (); 291633965Sjdp OUT (0xf8); 291733965Sjdp OUT (0x04); 291833965Sjdp drop_int (&ob); 291933965Sjdp ID; 292033965Sjdp INTn (stack size); 292133965Sjdp INTn (ret val); 292233965Sjdp EXPn (offset); 292333965Sjdp 292433965Sjdp block (); 292533965Sjdp 292633965Sjdp NEXT (); 292733965Sjdp OUT (0xf9); 292833965Sjdp EXPn (size of block); 292933965Sjdp fill_int (&ob); 293033965Sjdp } 293133965Sjdp break; 293233965Sjdp 293333965Sjdp case 0x05: 2934130561Sobrien /* File name for source line numbers. */ 293533965Sjdp { 293633965Sjdp struct output_buffer_struct ob; 2937130561Sobrien 293833965Sjdp NEXT (); 293933965Sjdp OUT (0xf8); 294033965Sjdp OUT (0x05); 294133965Sjdp drop_int (&ob); 294233965Sjdp ID; 294333965Sjdp INTn (year); 294433965Sjdp INTn (month); 294533965Sjdp INTn (day); 294633965Sjdp INTn (hour); 294733965Sjdp INTn (monute); 294833965Sjdp INTn (second); 294933965Sjdp block (); 295033965Sjdp NEXT (); 295133965Sjdp OUT (0xf9); 295233965Sjdp fill_int (&ob); 295333965Sjdp } 295433965Sjdp break; 295533965Sjdp 295633965Sjdp case 0x06: 2957130561Sobrien /* Local function. */ 295833965Sjdp { 295933965Sjdp struct output_buffer_struct ob; 2960130561Sobrien 296133965Sjdp NEXT (); 296233965Sjdp OUT (0xf8); 296333965Sjdp OUT (0x06); 296433965Sjdp drop_int (&ob); 296533965Sjdp ID; 296633965Sjdp INTn (stack size); 296733965Sjdp INTn (type return); 296833965Sjdp EXPn (offset); 296933965Sjdp block (); 297033965Sjdp NEXT (); 297133965Sjdp OUT (0xf9); 297233965Sjdp EXPn (size); 297333965Sjdp fill_int (&ob); 297433965Sjdp } 297533965Sjdp break; 297633965Sjdp 297733965Sjdp case 0x0a: 2978130561Sobrien /* Assembler module scope beginning - */ 297933965Sjdp { 298033965Sjdp struct output_buffer_struct ob; 298133965Sjdp 298233965Sjdp NEXT (); 298333965Sjdp OUT (0xf8); 298433965Sjdp OUT (0x0a); 298533965Sjdp drop_int (&ob); 298633965Sjdp ID; 298733965Sjdp ID; 298833965Sjdp INT; 298933965Sjdp ID; 299033965Sjdp INT; 299133965Sjdp INT; 299233965Sjdp INT; 299333965Sjdp INT; 299433965Sjdp INT; 299533965Sjdp INT; 299633965Sjdp 299733965Sjdp block (); 299833965Sjdp 299933965Sjdp NEXT (); 300033965Sjdp OUT (0xf9); 300133965Sjdp fill_int (&ob); 300233965Sjdp } 300333965Sjdp break; 300433965Sjdp case 0x0b: 300533965Sjdp { 300633965Sjdp struct output_buffer_struct ob; 3007130561Sobrien 300833965Sjdp NEXT (); 300933965Sjdp OUT (0xf8); 301033965Sjdp OUT (0x0b); 301133965Sjdp drop_int (&ob); 301233965Sjdp ID; 301333965Sjdp INT; 301433965Sjdp INTn (section index); 301533965Sjdp EXPn (offset); 301633965Sjdp INTn (stuff); 301733965Sjdp 301833965Sjdp block (); 301933965Sjdp 302033965Sjdp OUT (0xf9); 302133965Sjdp NEXT (); 302233965Sjdp EXPn (Size in Maus); 302333965Sjdp fill_int (&ob); 302433965Sjdp } 302533965Sjdp break; 302633965Sjdp } 302733965Sjdp} 302833965Sjdp 302933965Sjdpstatic void 3030218822Sdime2_record (void) 303133965Sjdp{ 303233965Sjdp OUT (0xe2); 303333965Sjdp NEXT (); 303433965Sjdp OUT (0xce); 303533965Sjdp NEXT (); 303633965Sjdp INT; 303733965Sjdp EXP; 303833965Sjdp} 303933965Sjdp 304033965Sjdpstatic void 3041218822Sdimblock (void) 304233965Sjdp{ 304333965Sjdp int ch; 3044130561Sobrien 304533965Sjdp while (1) 304633965Sjdp { 304733965Sjdp ch = THIS (); 304833965Sjdp switch (ch) 304933965Sjdp { 305033965Sjdp case 0xe1: 305133965Sjdp case 0xe5: 305233965Sjdp return; 305333965Sjdp case 0xf9: 305433965Sjdp return; 305533965Sjdp case 0xf0: 305633965Sjdp f0_record (); 305733965Sjdp break; 305833965Sjdp case 0xf1: 305933965Sjdp f1_record (); 306033965Sjdp break; 306133965Sjdp case 0xf2: 306233965Sjdp f2_record (); 306333965Sjdp break; 306433965Sjdp case 0xf8: 306533965Sjdp f8_record (); 306633965Sjdp break; 306733965Sjdp case 0xe2: 306833965Sjdp e2_record (); 306933965Sjdp break; 307033965Sjdp 307133965Sjdp } 307233965Sjdp } 307333965Sjdp} 307433965Sjdp 3075130561Sobrien/* Moves all the debug information from the source bfd to the output 3076130561Sobrien bfd, and relocates any expressions it finds. */ 307733965Sjdp 307833965Sjdpstatic void 3079218822Sdimrelocate_debug (bfd *output ATTRIBUTE_UNUSED, 3080218822Sdim bfd *input) 308133965Sjdp{ 308233965Sjdp#define IBS 400 308333965Sjdp#define OBS 400 308433965Sjdp unsigned char input_buffer[IBS]; 308533965Sjdp 308633965Sjdp input_ptr_start = input_ptr = input_buffer; 308733965Sjdp input_ptr_end = input_buffer + IBS; 308833965Sjdp input_bfd = input; 308933965Sjdp /* FIXME: Check return value. I'm not sure whether it needs to read 309033965Sjdp the entire buffer or not. */ 3091218822Sdim bfd_bread ((void *) input_ptr_start, (bfd_size_type) IBS, input); 309233965Sjdp block (); 309333965Sjdp} 309433965Sjdp 309577298Sobrien/* Gather together all the debug information from each input BFD into 309677298Sobrien one place, relocating it and emitting it as we go. */ 309733965Sjdp 3098130561Sobrienstatic bfd_boolean 3099218822Sdimieee_write_debug_part (bfd *abfd) 310033965Sjdp{ 310133965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 310233965Sjdp bfd_chain_type *chain = ieee->chain_root; 310389857Sobrien unsigned char obuff[OBS]; 3104130561Sobrien bfd_boolean some_debug = FALSE; 310533965Sjdp file_ptr here = bfd_tell (abfd); 310633965Sjdp 310789857Sobrien output_ptr_start = output_ptr = obuff; 310889857Sobrien output_ptr_end = obuff + OBS; 310989857Sobrien output_ptr = obuff; 311033965Sjdp output_bfd = abfd; 311133965Sjdp 311233965Sjdp if (chain == (bfd_chain_type *) NULL) 311333965Sjdp { 311433965Sjdp asection *s; 311533965Sjdp 311633965Sjdp for (s = abfd->sections; s != NULL; s = s->next) 311733965Sjdp if ((s->flags & SEC_DEBUGGING) != 0) 311833965Sjdp break; 311933965Sjdp if (s == NULL) 312033965Sjdp { 312133965Sjdp ieee->w.r.debug_information_part = 0; 3122130561Sobrien return TRUE; 312333965Sjdp } 312433965Sjdp 312533965Sjdp ieee->w.r.debug_information_part = here; 3126218822Sdim if (bfd_bwrite (s->contents, s->size, abfd) != s->size) 3127130561Sobrien return FALSE; 312833965Sjdp } 312933965Sjdp else 313033965Sjdp { 313133965Sjdp while (chain != (bfd_chain_type *) NULL) 313233965Sjdp { 313333965Sjdp bfd *entry = chain->this; 313433965Sjdp ieee_data_type *entry_ieee = IEEE_DATA (entry); 3135130561Sobrien 313633965Sjdp if (entry_ieee->w.r.debug_information_part) 313733965Sjdp { 313833965Sjdp if (bfd_seek (entry, entry_ieee->w.r.debug_information_part, 313989857Sobrien SEEK_SET) != 0) 3140130561Sobrien return FALSE; 314133965Sjdp relocate_debug (abfd, entry); 314233965Sjdp } 314333965Sjdp 314433965Sjdp chain = chain->next; 314533965Sjdp } 3146130561Sobrien 314733965Sjdp if (some_debug) 3148130561Sobrien ieee->w.r.debug_information_part = here; 314933965Sjdp else 3150130561Sobrien ieee->w.r.debug_information_part = 0; 315133965Sjdp 315233965Sjdp flush (); 315333965Sjdp } 315433965Sjdp 3155130561Sobrien return TRUE; 315633965Sjdp} 315733965Sjdp 315833965Sjdp/* Write the data in an ieee way. */ 315933965Sjdp 3160130561Sobrienstatic bfd_boolean 3161218822Sdimieee_write_data_part (bfd *abfd) 316233965Sjdp{ 316333965Sjdp asection *s; 3164130561Sobrien 316533965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 316633965Sjdp ieee->w.r.data_part = bfd_tell (abfd); 3167130561Sobrien 316833965Sjdp for (s = abfd->sections; s != (asection *) NULL; s = s->next) 316933965Sjdp { 317033965Sjdp /* Skip sections that have no loadable contents (.bss, 317133965Sjdp debugging, etc.) */ 317233965Sjdp if ((s->flags & SEC_LOAD) == 0) 317333965Sjdp continue; 317433965Sjdp 317533965Sjdp /* Sort the reloc records so we can insert them in the correct 3176218822Sdim places. */ 317733965Sjdp if (s->reloc_count != 0) 317833965Sjdp { 317933965Sjdp if (! do_with_relocs (abfd, s)) 3180130561Sobrien return FALSE; 318133965Sjdp } 318233965Sjdp else 318333965Sjdp { 318433965Sjdp if (! do_without_relocs (abfd, s)) 3185130561Sobrien return FALSE; 318633965Sjdp } 318733965Sjdp } 318833965Sjdp 3189130561Sobrien return TRUE; 319033965Sjdp} 319133965Sjdp 3192130561Sobrienstatic bfd_boolean 3193218822Sdiminit_for_output (bfd *abfd) 319433965Sjdp{ 319533965Sjdp asection *s; 3196130561Sobrien 319733965Sjdp for (s = abfd->sections; s != (asection *) NULL; s = s->next) 319833965Sjdp { 319933965Sjdp if ((s->flags & SEC_DEBUGGING) != 0) 320033965Sjdp continue; 3201218822Sdim if (s->size != 0) 320233965Sjdp { 3203218822Sdim bfd_size_type size = s->size; 3204218822Sdim ieee_per_section (s)->data = bfd_alloc (abfd, size); 320533965Sjdp if (!ieee_per_section (s)->data) 3206130561Sobrien return FALSE; 320733965Sjdp } 320833965Sjdp } 3209130561Sobrien return TRUE; 321033965Sjdp} 321133965Sjdp 3212130561Sobrien/* Exec and core file sections. */ 321333965Sjdp 3214130561Sobrien/* Set section contents is complicated with IEEE since the format is 3215130561Sobrien not a byte image, but a record stream. */ 3216130561Sobrien 3217130561Sobrienstatic bfd_boolean 3218218822Sdimieee_set_section_contents (bfd *abfd, 3219218822Sdim sec_ptr section, 3220218822Sdim const void * location, 3221218822Sdim file_ptr offset, 3222218822Sdim bfd_size_type count) 322333965Sjdp{ 322433965Sjdp if ((section->flags & SEC_DEBUGGING) != 0) 322533965Sjdp { 322633965Sjdp if (section->contents == NULL) 322733965Sjdp { 3228218822Sdim bfd_size_type size = section->size; 3229218822Sdim section->contents = bfd_alloc (abfd, size); 323033965Sjdp if (section->contents == NULL) 3231130561Sobrien return FALSE; 323233965Sjdp } 323333965Sjdp /* bfd_set_section_contents has already checked that everything 323433965Sjdp is within range. */ 323589857Sobrien memcpy (section->contents + offset, location, (size_t) count); 3236130561Sobrien return TRUE; 323733965Sjdp } 323833965Sjdp 323933965Sjdp if (ieee_per_section (section)->data == (bfd_byte *) NULL) 324033965Sjdp { 324133965Sjdp if (!init_for_output (abfd)) 3242130561Sobrien return FALSE; 324333965Sjdp } 3244218822Sdim memcpy ((void *) (ieee_per_section (section)->data + offset), 3245218822Sdim (void *) location, 324633965Sjdp (unsigned int) count); 3247130561Sobrien return TRUE; 324833965Sjdp} 324933965Sjdp 325033965Sjdp/* Write the external symbols of a file. IEEE considers two sorts of 325133965Sjdp external symbols, public, and referenced. It uses to internal 325233965Sjdp forms to index them as well. When we write them out we turn their 325333965Sjdp symbol values into indexes from the right base. */ 325433965Sjdp 3255130561Sobrienstatic bfd_boolean 3256218822Sdimieee_write_external_part (bfd *abfd) 325733965Sjdp{ 325833965Sjdp asymbol **q; 325933965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 326033965Sjdp unsigned int reference_index = IEEE_REFERENCE_BASE; 326133965Sjdp unsigned int public_index = IEEE_PUBLIC_BASE + 2; 326233965Sjdp file_ptr here = bfd_tell (abfd); 3263130561Sobrien bfd_boolean hadone = FALSE; 3264130561Sobrien 326533965Sjdp if (abfd->outsymbols != (asymbol **) NULL) 326633965Sjdp { 326733965Sjdp 326833965Sjdp for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++) 326933965Sjdp { 327033965Sjdp asymbol *p = *q; 3271130561Sobrien 327233965Sjdp if (bfd_is_und_section (p->section)) 327333965Sjdp { 3274130561Sobrien /* This must be a symbol reference. */ 327533965Sjdp if (! ieee_write_byte (abfd, ieee_external_reference_enum) 327689857Sobrien || ! ieee_write_int (abfd, (bfd_vma) reference_index) 327733965Sjdp || ! ieee_write_id (abfd, p->name)) 3278130561Sobrien return FALSE; 327933965Sjdp p->value = reference_index; 328033965Sjdp reference_index++; 3281130561Sobrien hadone = TRUE; 328233965Sjdp } 328333965Sjdp else if (bfd_is_com_section (p->section)) 328433965Sjdp { 3285130561Sobrien /* This is a weak reference. */ 328633965Sjdp if (! ieee_write_byte (abfd, ieee_external_reference_enum) 328789857Sobrien || ! ieee_write_int (abfd, (bfd_vma) reference_index) 328833965Sjdp || ! ieee_write_id (abfd, p->name) 328933965Sjdp || ! ieee_write_byte (abfd, 329033965Sjdp ieee_weak_external_reference_enum) 329189857Sobrien || ! ieee_write_int (abfd, (bfd_vma) reference_index) 329233965Sjdp || ! ieee_write_int (abfd, p->value)) 3293130561Sobrien return FALSE; 329433965Sjdp p->value = reference_index; 329533965Sjdp reference_index++; 3296130561Sobrien hadone = TRUE; 329733965Sjdp } 329833965Sjdp else if (p->flags & BSF_GLOBAL) 329933965Sjdp { 3300130561Sobrien /* This must be a symbol definition. */ 330133965Sjdp if (! ieee_write_byte (abfd, ieee_external_symbol_enum) 330289857Sobrien || ! ieee_write_int (abfd, (bfd_vma) public_index) 330333965Sjdp || ! ieee_write_id (abfd, p->name) 330433965Sjdp || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum) 330589857Sobrien || ! ieee_write_int (abfd, (bfd_vma) public_index) 3306218822Sdim || ! ieee_write_byte (abfd, 15) /* Instruction address. */ 3307218822Sdim || ! ieee_write_byte (abfd, 19) /* Static symbol. */ 3308218822Sdim || ! ieee_write_byte (abfd, 1)) /* One of them. */ 3309130561Sobrien return FALSE; 331033965Sjdp 3311130561Sobrien /* Write out the value. */ 331233965Sjdp if (! ieee_write_2bytes (abfd, ieee_value_record_enum) 331389857Sobrien || ! ieee_write_int (abfd, (bfd_vma) public_index)) 3314130561Sobrien return FALSE; 331533965Sjdp if (! bfd_is_abs_section (p->section)) 331633965Sjdp { 331733965Sjdp if (abfd->flags & EXEC_P) 331833965Sjdp { 331933965Sjdp /* If fully linked, then output all symbols 3320130561Sobrien relocated. */ 332133965Sjdp if (! (ieee_write_int 332233965Sjdp (abfd, 332333965Sjdp (p->value 332433965Sjdp + p->section->output_offset 332533965Sjdp + p->section->output_section->vma)))) 3326130561Sobrien return FALSE; 332733965Sjdp } 332833965Sjdp else 332933965Sjdp { 333033965Sjdp if (! (ieee_write_expression 333133965Sjdp (abfd, 333233965Sjdp p->value + p->section->output_offset, 333333965Sjdp p->section->output_section->symbol, 3334130561Sobrien FALSE, 0))) 3335130561Sobrien return FALSE; 333633965Sjdp } 333733965Sjdp } 333833965Sjdp else 333933965Sjdp { 334033965Sjdp if (! ieee_write_expression (abfd, 334133965Sjdp p->value, 334233965Sjdp bfd_abs_section_ptr->symbol, 3343130561Sobrien FALSE, 0)) 3344130561Sobrien return FALSE; 334533965Sjdp } 334633965Sjdp p->value = public_index; 334733965Sjdp public_index++; 3348130561Sobrien hadone = TRUE; 334933965Sjdp } 335033965Sjdp else 335133965Sjdp { 3352130561Sobrien /* This can happen - when there are gaps in the symbols read 3353130561Sobrien from an input ieee file. */ 335433965Sjdp } 335533965Sjdp } 335633965Sjdp } 335733965Sjdp if (hadone) 335833965Sjdp ieee->w.r.external_part = here; 335933965Sjdp 3360130561Sobrien return TRUE; 336133965Sjdp} 336233965Sjdp 336333965Sjdp 336489857Sobrienstatic const unsigned char exten[] = 336533965Sjdp{ 336633965Sjdp 0xf0, 0x20, 0x00, 3367130561Sobrien 0xf1, 0xce, 0x20, 0x00, 37, 3, 3, /* Set version 3 rev 3. */ 3368130561Sobrien 0xf1, 0xce, 0x20, 0x00, 39, 2, /* Keep symbol in original case. */ 3369130561Sobrien 0xf1, 0xce, 0x20, 0x00, 38 /* Set object type relocatable to x. */ 337033965Sjdp}; 337133965Sjdp 337289857Sobrienstatic const unsigned char envi[] = 337333965Sjdp{ 337433965Sjdp 0xf0, 0x21, 0x00, 337533965Sjdp 337633965Sjdp/* 0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11, 337733965Sjdp 0x19, 0x2c, 337833965Sjdp*/ 3379218822Sdim 0xf1, 0xce, 0x21, 00, 52, 0x00, /* exec ok. */ 338033965Sjdp 3381218822Sdim 0xf1, 0xce, 0x21, 0, 53, 0x03,/* host unix. */ 338233965Sjdp/* 0xf1, 0xce, 0x21, 0, 54, 2,1,1 tool & version # */ 338333965Sjdp}; 338433965Sjdp 3385130561Sobrienstatic bfd_boolean 3386218822Sdimieee_write_me_part (bfd *abfd) 338733965Sjdp{ 338833965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 338933965Sjdp ieee->w.r.trailer_part = bfd_tell (abfd); 339033965Sjdp if (abfd->start_address) 339133965Sjdp { 339233965Sjdp if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum) 339333965Sjdp || ! ieee_write_byte (abfd, ieee_function_either_open_b_enum) 339433965Sjdp || ! ieee_write_int (abfd, abfd->start_address) 339533965Sjdp || ! ieee_write_byte (abfd, ieee_function_either_close_b_enum)) 3396130561Sobrien return FALSE; 339733965Sjdp } 339833965Sjdp ieee->w.r.me_record = bfd_tell (abfd); 339933965Sjdp if (! ieee_write_byte (abfd, ieee_module_end_enum)) 3400130561Sobrien return FALSE; 3401130561Sobrien return TRUE; 340233965Sjdp} 340333965Sjdp 340433965Sjdp/* Write out the IEEE processor ID. */ 340533965Sjdp 3406130561Sobrienstatic bfd_boolean 3407218822Sdimieee_write_processor (bfd *abfd) 340833965Sjdp{ 340933965Sjdp const bfd_arch_info_type *arch; 341033965Sjdp 341133965Sjdp arch = bfd_get_arch_info (abfd); 341233965Sjdp switch (arch->arch) 341333965Sjdp { 341433965Sjdp default: 341533965Sjdp if (! ieee_write_id (abfd, bfd_printable_name (abfd))) 3416130561Sobrien return FALSE; 341733965Sjdp break; 341833965Sjdp 341933965Sjdp case bfd_arch_h8300: 342033965Sjdp if (! ieee_write_id (abfd, "H8/300")) 3421130561Sobrien return FALSE; 342233965Sjdp break; 342333965Sjdp 342433965Sjdp case bfd_arch_h8500: 342533965Sjdp if (! ieee_write_id (abfd, "H8/500")) 3426130561Sobrien return FALSE; 342733965Sjdp break; 342833965Sjdp 342933965Sjdp case bfd_arch_i960: 343033965Sjdp switch (arch->mach) 343133965Sjdp { 343233965Sjdp default: 343333965Sjdp case bfd_mach_i960_core: 343433965Sjdp case bfd_mach_i960_ka_sa: 343533965Sjdp if (! ieee_write_id (abfd, "80960KA")) 3436130561Sobrien return FALSE; 343733965Sjdp break; 343833965Sjdp 343933965Sjdp case bfd_mach_i960_kb_sb: 344033965Sjdp if (! ieee_write_id (abfd, "80960KB")) 3441130561Sobrien return FALSE; 344233965Sjdp break; 344333965Sjdp 344433965Sjdp case bfd_mach_i960_ca: 344533965Sjdp if (! ieee_write_id (abfd, "80960CA")) 3446130561Sobrien return FALSE; 344733965Sjdp break; 344833965Sjdp 344933965Sjdp case bfd_mach_i960_mc: 345033965Sjdp case bfd_mach_i960_xa: 345133965Sjdp if (! ieee_write_id (abfd, "80960MC")) 3452130561Sobrien return FALSE; 345333965Sjdp break; 345433965Sjdp } 345533965Sjdp break; 345633965Sjdp 345733965Sjdp case bfd_arch_m68k: 345833965Sjdp { 345960484Sobrien const char *id; 346033965Sjdp 346160484Sobrien switch (arch->mach) 346260484Sobrien { 346360484Sobrien default: id = "68020"; break; 346460484Sobrien case bfd_mach_m68000: id = "68000"; break; 346560484Sobrien case bfd_mach_m68008: id = "68008"; break; 346660484Sobrien case bfd_mach_m68010: id = "68010"; break; 346760484Sobrien case bfd_mach_m68020: id = "68020"; break; 346860484Sobrien case bfd_mach_m68030: id = "68030"; break; 346960484Sobrien case bfd_mach_m68040: id = "68040"; break; 347060484Sobrien case bfd_mach_m68060: id = "68060"; break; 347160484Sobrien case bfd_mach_cpu32: id = "cpu32"; break; 3472218822Sdim case bfd_mach_mcf_isa_a_nodiv: id = "isa-a:nodiv"; break; 3473218822Sdim case bfd_mach_mcf_isa_a: id = "isa-a"; break; 3474218822Sdim case bfd_mach_mcf_isa_a_mac: id = "isa-a:mac"; break; 3475218822Sdim case bfd_mach_mcf_isa_a_emac: id = "isa-a:emac"; break; 3476218822Sdim case bfd_mach_mcf_isa_aplus: id = "isa-aplus"; break; 3477218822Sdim case bfd_mach_mcf_isa_aplus_mac: id = "isa-aplus:mac"; break; 3478218822Sdim case bfd_mach_mcf_isa_aplus_emac: id = "isa-aplus:mac"; break; 3479218822Sdim case bfd_mach_mcf_isa_b_nousp: id = "isa-b:nousp"; break; 3480218822Sdim case bfd_mach_mcf_isa_b_nousp_mac: id = "isa-b:nousp:mac"; break; 3481218822Sdim case bfd_mach_mcf_isa_b_nousp_emac: id = "isa-b:nousp:emac"; break; 3482218822Sdim case bfd_mach_mcf_isa_b: id = "isa-b"; break; 3483218822Sdim case bfd_mach_mcf_isa_b_mac: id = "isa-b:mac"; break; 3484218822Sdim case bfd_mach_mcf_isa_b_emac: id = "isa-b:emac"; break; 3485218822Sdim case bfd_mach_mcf_isa_b_float: id = "isa-b:float"; break; 3486218822Sdim case bfd_mach_mcf_isa_b_float_mac: id = "isa-b:float:mac"; break; 3487218822Sdim case bfd_mach_mcf_isa_b_float_emac: id = "isa-b:float:emac"; break; 348860484Sobrien } 348960484Sobrien 349060484Sobrien if (! ieee_write_id (abfd, id)) 3491130561Sobrien return FALSE; 349233965Sjdp } 349333965Sjdp break; 349433965Sjdp } 349533965Sjdp 3496130561Sobrien return TRUE; 349733965Sjdp} 349833965Sjdp 3499130561Sobrienstatic bfd_boolean 3500218822Sdimieee_write_object_contents (bfd *abfd) 350133965Sjdp{ 350233965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 350333965Sjdp unsigned int i; 350433965Sjdp file_ptr old; 350533965Sjdp 3506130561Sobrien /* Fast forward over the header area. */ 350733965Sjdp if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 3508130561Sobrien return FALSE; 350933965Sjdp 351033965Sjdp if (! ieee_write_byte (abfd, ieee_module_beginning_enum) 351133965Sjdp || ! ieee_write_processor (abfd) 351233965Sjdp || ! ieee_write_id (abfd, abfd->filename)) 3513130561Sobrien return FALSE; 351433965Sjdp 3515130561Sobrien /* Fast forward over the variable bits. */ 351633965Sjdp if (! ieee_write_byte (abfd, ieee_address_descriptor_enum)) 3517130561Sobrien return FALSE; 351833965Sjdp 3519130561Sobrien /* Bits per MAU. */ 352033965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) (bfd_arch_bits_per_byte (abfd)))) 3521130561Sobrien return FALSE; 3522130561Sobrien /* MAU's per address. */ 352333965Sjdp if (! ieee_write_byte (abfd, 352433965Sjdp (bfd_byte) (bfd_arch_bits_per_address (abfd) 352533965Sjdp / bfd_arch_bits_per_byte (abfd)))) 3526130561Sobrien return FALSE; 352733965Sjdp 352833965Sjdp old = bfd_tell (abfd); 352933965Sjdp if (bfd_seek (abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR) != 0) 3530130561Sobrien return FALSE; 353133965Sjdp 353233965Sjdp ieee->w.r.extension_record = bfd_tell (abfd); 353389857Sobrien if (bfd_bwrite ((char *) exten, (bfd_size_type) sizeof (exten), abfd) 353489857Sobrien != sizeof (exten)) 3535130561Sobrien return FALSE; 353633965Sjdp if (abfd->flags & EXEC_P) 353733965Sjdp { 3538218822Sdim if (! ieee_write_byte (abfd, 0x1)) /* Absolute. */ 3539130561Sobrien return FALSE; 354033965Sjdp } 354133965Sjdp else 354233965Sjdp { 3543218822Sdim if (! ieee_write_byte (abfd, 0x2)) /* Relocateable. */ 3544130561Sobrien return FALSE; 354533965Sjdp } 354633965Sjdp 354733965Sjdp ieee->w.r.environmental_record = bfd_tell (abfd); 354889857Sobrien if (bfd_bwrite ((char *) envi, (bfd_size_type) sizeof (envi), abfd) 354989857Sobrien != sizeof (envi)) 3550130561Sobrien return FALSE; 355133965Sjdp 355233965Sjdp /* The HP emulator database requires a timestamp in the file. */ 355333965Sjdp { 355433965Sjdp time_t now; 355533965Sjdp const struct tm *t; 355633965Sjdp 355733965Sjdp time (&now); 355833965Sjdp t = (struct tm *) localtime (&now); 355933965Sjdp if (! ieee_write_2bytes (abfd, (int) ieee_atn_record_enum) 356033965Sjdp || ! ieee_write_byte (abfd, 0x21) 356133965Sjdp || ! ieee_write_byte (abfd, 0) 356233965Sjdp || ! ieee_write_byte (abfd, 50) 356389857Sobrien || ! ieee_write_int (abfd, (bfd_vma) (t->tm_year + 1900)) 356489857Sobrien || ! ieee_write_int (abfd, (bfd_vma) (t->tm_mon + 1)) 356589857Sobrien || ! ieee_write_int (abfd, (bfd_vma) t->tm_mday) 356689857Sobrien || ! ieee_write_int (abfd, (bfd_vma) t->tm_hour) 356789857Sobrien || ! ieee_write_int (abfd, (bfd_vma) t->tm_min) 356889857Sobrien || ! ieee_write_int (abfd, (bfd_vma) t->tm_sec)) 3569130561Sobrien return FALSE; 357033965Sjdp } 357133965Sjdp 357233965Sjdp output_bfd = abfd; 357333965Sjdp 357433965Sjdp flush (); 357533965Sjdp 357633965Sjdp if (! ieee_write_section_part (abfd)) 3577130561Sobrien return FALSE; 357833965Sjdp /* First write the symbols. This changes their values into table 357933965Sjdp indeces so we cant use it after this point. */ 358033965Sjdp if (! ieee_write_external_part (abfd)) 3581130561Sobrien return FALSE; 358233965Sjdp 358333965Sjdp /* Write any debugs we have been told about. */ 358433965Sjdp if (! ieee_write_debug_part (abfd)) 3585130561Sobrien return FALSE; 358633965Sjdp 358733965Sjdp /* Can only write the data once the symbols have been written, since 358833965Sjdp the data contains relocation information which points to the 358933965Sjdp symbols. */ 359033965Sjdp if (! ieee_write_data_part (abfd)) 3591130561Sobrien return FALSE; 359233965Sjdp 359333965Sjdp /* At the end we put the end! */ 359433965Sjdp if (! ieee_write_me_part (abfd)) 3595130561Sobrien return FALSE; 359633965Sjdp 3597130561Sobrien /* Generate the header. */ 359833965Sjdp if (bfd_seek (abfd, old, SEEK_SET) != 0) 3599130561Sobrien return FALSE; 360033965Sjdp 360133965Sjdp for (i = 0; i < N_W_VARIABLES; i++) 360233965Sjdp { 360333965Sjdp if (! ieee_write_2bytes (abfd, ieee_assign_value_to_variable_enum) 360433965Sjdp || ! ieee_write_byte (abfd, (bfd_byte) i) 360589857Sobrien || ! ieee_write_int5_out (abfd, (bfd_vma) ieee->w.offset[i])) 3606130561Sobrien return FALSE; 360733965Sjdp } 360833965Sjdp 3609130561Sobrien return TRUE; 361033965Sjdp} 361133965Sjdp 3612218822Sdim/* Native-level interface to symbols. */ 361333965Sjdp 361433965Sjdp/* We read the symbols into a buffer, which is discarded when this 361533965Sjdp function exits. We read the strings into a buffer large enough to 3616130561Sobrien hold them all plus all the cached symbol entries. */ 361733965Sjdp 361889857Sobrienstatic asymbol * 3619218822Sdimieee_make_empty_symbol (bfd *abfd) 362033965Sjdp{ 362189857Sobrien bfd_size_type amt = sizeof (ieee_symbol_type); 3622218822Sdim ieee_symbol_type *new = bfd_zalloc (abfd, amt); 3623130561Sobrien 362433965Sjdp if (!new) 362533965Sjdp return NULL; 362633965Sjdp new->symbol.the_bfd = abfd; 362733965Sjdp return &new->symbol; 362833965Sjdp} 362933965Sjdp 363033965Sjdpstatic bfd * 3631218822Sdimieee_openr_next_archived_file (bfd *arch, bfd *prev) 363233965Sjdp{ 363333965Sjdp ieee_ar_data_type *ar = IEEE_AR_DATA (arch); 3634130561Sobrien 3635130561Sobrien /* Take the next one from the arch state, or reset. */ 363633965Sjdp if (prev == (bfd *) NULL) 3637130561Sobrien /* Reset the index - the first two entries are bogus. */ 3638130561Sobrien ar->element_index = 2; 3639130561Sobrien 3640130561Sobrien while (TRUE) 364133965Sjdp { 364233965Sjdp ieee_ar_obstack_type *p = ar->elements + ar->element_index; 3643130561Sobrien 364433965Sjdp ar->element_index++; 364533965Sjdp if (ar->element_index <= ar->element_count) 364633965Sjdp { 364733965Sjdp if (p->file_offset != (file_ptr) 0) 364833965Sjdp { 364933965Sjdp if (p->abfd == (bfd *) NULL) 365033965Sjdp { 365133965Sjdp p->abfd = _bfd_create_empty_archive_element_shell (arch); 365233965Sjdp p->abfd->origin = p->file_offset; 365333965Sjdp } 365433965Sjdp return p->abfd; 365533965Sjdp } 365633965Sjdp } 365733965Sjdp else 365833965Sjdp { 365933965Sjdp bfd_set_error (bfd_error_no_more_archived_files); 3660218822Sdim return NULL; 366133965Sjdp } 366233965Sjdp } 366333965Sjdp} 366433965Sjdp 3665130561Sobrienstatic bfd_boolean 3666218822Sdimieee_find_nearest_line (bfd *abfd ATTRIBUTE_UNUSED, 3667218822Sdim asection *section ATTRIBUTE_UNUSED, 3668218822Sdim asymbol **symbols ATTRIBUTE_UNUSED, 3669218822Sdim bfd_vma offset ATTRIBUTE_UNUSED, 3670218822Sdim const char **filename_ptr ATTRIBUTE_UNUSED, 3671218822Sdim const char **functionname_ptr ATTRIBUTE_UNUSED, 3672218822Sdim unsigned int *line_ptr ATTRIBUTE_UNUSED) 367333965Sjdp{ 3674130561Sobrien return FALSE; 367533965Sjdp} 367633965Sjdp 3677218822Sdimstatic bfd_boolean 3678218822Sdimieee_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED, 3679218822Sdim const char **filename_ptr ATTRIBUTE_UNUSED, 3680218822Sdim const char **functionname_ptr ATTRIBUTE_UNUSED, 3681218822Sdim unsigned int *line_ptr ATTRIBUTE_UNUSED) 3682218822Sdim{ 3683218822Sdim return FALSE; 3684218822Sdim} 3685218822Sdim 368633965Sjdpstatic int 3687218822Sdimieee_generic_stat_arch_elt (bfd *abfd, struct stat *buf) 368833965Sjdp{ 368938889Sjdp ieee_ar_data_type *ar = (ieee_ar_data_type *) NULL; 369033965Sjdp ieee_data_type *ieee; 369133965Sjdp 369238889Sjdp if (abfd->my_archive != NULL) 369338889Sjdp ar = abfd->my_archive->tdata.ieee_ar_data; 369433965Sjdp if (ar == (ieee_ar_data_type *) NULL) 369533965Sjdp { 369633965Sjdp bfd_set_error (bfd_error_invalid_operation); 369733965Sjdp return -1; 369833965Sjdp } 369933965Sjdp 370033965Sjdp if (IEEE_DATA (abfd) == NULL) 370133965Sjdp { 370233965Sjdp if (ieee_object_p (abfd) == NULL) 370333965Sjdp { 370433965Sjdp bfd_set_error (bfd_error_wrong_format); 370533965Sjdp return -1; 370633965Sjdp } 370733965Sjdp } 370833965Sjdp 370933965Sjdp ieee = IEEE_DATA (abfd); 371033965Sjdp 371133965Sjdp buf->st_size = ieee->w.r.me_record + 1; 371233965Sjdp buf->st_mode = 0644; 371333965Sjdp return 0; 371433965Sjdp} 371533965Sjdp 371633965Sjdpstatic int 3717218822Sdimieee_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, 3718218822Sdim struct bfd_link_info *info ATTRIBUTE_UNUSED) 371933965Sjdp{ 372033965Sjdp return 0; 372133965Sjdp} 372233965Sjdp 372333965Sjdp#define ieee_close_and_cleanup _bfd_generic_close_and_cleanup 372433965Sjdp#define ieee_bfd_free_cached_info _bfd_generic_bfd_free_cached_info 372533965Sjdp 372633965Sjdp#define ieee_slurp_armap bfd_true 372733965Sjdp#define ieee_slurp_extended_name_table bfd_true 372833965Sjdp#define ieee_construct_extended_name_table \ 3729130561Sobrien ((bfd_boolean (*) \ 3730218822Sdim (bfd *, char **, bfd_size_type *, const char **)) \ 373133965Sjdp bfd_true) 373233965Sjdp#define ieee_truncate_arname bfd_dont_truncate_arname 373333965Sjdp#define ieee_write_armap \ 3734130561Sobrien ((bfd_boolean (*) \ 3735218822Sdim (bfd *, unsigned int, struct orl *, unsigned int, int)) \ 373633965Sjdp bfd_true) 373733965Sjdp#define ieee_read_ar_hdr bfd_nullvoidptr 373833965Sjdp#define ieee_update_armap_timestamp bfd_true 373933965Sjdp#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index 374033965Sjdp 3741218822Sdim#define ieee_bfd_is_target_special_symbol \ 3742218822Sdim ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) 374333965Sjdp#define ieee_bfd_is_local_label_name bfd_generic_is_local_label_name 374433965Sjdp#define ieee_get_lineno _bfd_nosymbols_get_lineno 374533965Sjdp#define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol 374633965Sjdp#define ieee_read_minisymbols _bfd_generic_read_minisymbols 374733965Sjdp#define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol 374833965Sjdp 374933965Sjdp#define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup 3750218822Sdim#define ieee_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup 375133965Sjdp 375233965Sjdp#define ieee_set_arch_mach _bfd_generic_set_arch_mach 375333965Sjdp 375433965Sjdp#define ieee_get_section_contents_in_window \ 375533965Sjdp _bfd_generic_get_section_contents_in_window 375633965Sjdp#define ieee_bfd_get_relocated_section_contents \ 375733965Sjdp bfd_generic_get_relocated_section_contents 375833965Sjdp#define ieee_bfd_relax_section bfd_generic_relax_section 375960484Sobrien#define ieee_bfd_gc_sections bfd_generic_gc_sections 376089857Sobrien#define ieee_bfd_merge_sections bfd_generic_merge_sections 3761218822Sdim#define ieee_bfd_is_group_section bfd_generic_is_group_section 3762104834Sobrien#define ieee_bfd_discard_group bfd_generic_discard_group 3763218822Sdim#define ieee_section_already_linked \ 3764218822Sdim _bfd_generic_section_already_linked 376533965Sjdp#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create 3766104834Sobrien#define ieee_bfd_link_hash_table_free _bfd_generic_link_hash_table_free 376733965Sjdp#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols 3768104834Sobrien#define ieee_bfd_link_just_syms _bfd_generic_link_just_syms 376933965Sjdp#define ieee_bfd_final_link _bfd_generic_final_link 377033965Sjdp#define ieee_bfd_link_split_section _bfd_generic_link_split_section 377133965Sjdp 377233965Sjdpconst bfd_target ieee_vec = 377333965Sjdp{ 3774218822Sdim "ieee", /* Name. */ 377533965Sjdp bfd_target_ieee_flavour, 3776218822Sdim BFD_ENDIAN_UNKNOWN, /* Target byte order. */ 3777218822Sdim BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */ 3778218822Sdim (HAS_RELOC | EXEC_P | /* Object flags. */ 377933965Sjdp HAS_LINENO | HAS_DEBUG | 378033965Sjdp HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 378133965Sjdp (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS 3782218822Sdim | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ 3783218822Sdim '_', /* Leading underscore. */ 3784218822Sdim ' ', /* AR_pad_char. */ 3785218822Sdim 16, /* AR_max_namelen. */ 378633965Sjdp bfd_getb64, bfd_getb_signed_64, bfd_putb64, 378733965Sjdp bfd_getb32, bfd_getb_signed_32, bfd_putb32, 3788218822Sdim bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ 378933965Sjdp bfd_getb64, bfd_getb_signed_64, bfd_putb64, 379033965Sjdp bfd_getb32, bfd_getb_signed_32, bfd_putb32, 3791218822Sdim bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */ 379233965Sjdp 379333965Sjdp {_bfd_dummy_target, 3794218822Sdim ieee_object_p, /* bfd_check_format. */ 379533965Sjdp ieee_archive_p, 379633965Sjdp _bfd_dummy_target, 379733965Sjdp }, 379833965Sjdp { 379933965Sjdp bfd_false, 380033965Sjdp ieee_mkobject, 380133965Sjdp _bfd_generic_mkarchive, 380233965Sjdp bfd_false 380333965Sjdp }, 380433965Sjdp { 380533965Sjdp bfd_false, 380633965Sjdp ieee_write_object_contents, 380733965Sjdp _bfd_write_archive_contents, 380833965Sjdp bfd_false, 380933965Sjdp }, 381033965Sjdp 381189857Sobrien /* ieee_close_and_cleanup, ieee_bfd_free_cached_info, ieee_new_section_hook, 3812218822Sdim ieee_get_section_contents, ieee_get_section_contents_in_window. */ 381333965Sjdp BFD_JUMP_TABLE_GENERIC (ieee), 381489857Sobrien 381533965Sjdp BFD_JUMP_TABLE_COPY (_bfd_generic), 381633965Sjdp BFD_JUMP_TABLE_CORE (_bfd_nocore), 381789857Sobrien 381889857Sobrien /* ieee_slurp_armap, ieee_slurp_extended_name_table, 381989857Sobrien ieee_construct_extended_name_table, ieee_truncate_arname, 382089857Sobrien ieee_write_armap, ieee_read_ar_hdr, ieee_openr_next_archived_file, 382189857Sobrien ieee_get_elt_at_index, ieee_generic_stat_arch_elt, 3822218822Sdim ieee_update_armap_timestamp. */ 382333965Sjdp BFD_JUMP_TABLE_ARCHIVE (ieee), 382489857Sobrien 3825130561Sobrien /* ieee_get_symtab_upper_bound, ieee_canonicalize_symtab, 3826130561Sobrien ieee_make_empty_symbol, ieee_print_symbol, ieee_get_symbol_info, 3827130561Sobrien ieee_bfd_is_local_label_name, ieee_get_lineno, 3828130561Sobrien ieee_find_nearest_line, ieee_bfd_make_debug_symbol, 3829218822Sdim ieee_read_minisymbols, ieee_minisymbol_to_symbol. */ 383033965Sjdp BFD_JUMP_TABLE_SYMBOLS (ieee), 383189857Sobrien 383289857Sobrien /* ieee_get_reloc_upper_bound, ieee_canonicalize_reloc, 3833218822Sdim ieee_bfd_reloc_type_lookup. */ 383433965Sjdp BFD_JUMP_TABLE_RELOCS (ieee), 383589857Sobrien 3836218822Sdim /* ieee_set_arch_mach, ieee_set_section_contents. */ 383733965Sjdp BFD_JUMP_TABLE_WRITE (ieee), 383889857Sobrien 383989857Sobrien /* ieee_sizeof_headers, ieee_bfd_get_relocated_section_contents, 384089857Sobrien ieee_bfd_relax_section, ieee_bfd_link_hash_table_create, 3841104834Sobrien _bfd_generic_link_hash_table_free, 384289857Sobrien ieee_bfd_link_add_symbols, ieee_bfd_final_link, 384389857Sobrien ieee_bfd_link_split_section, ieee_bfd_gc_sections, 3844218822Sdim ieee_bfd_merge_sections. */ 384533965Sjdp BFD_JUMP_TABLE_LINK (ieee), 384689857Sobrien 384733965Sjdp BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 384833965Sjdp 384960484Sobrien NULL, 385089857Sobrien 3851218822Sdim NULL 385233965Sjdp}; 3853