ieee.c revision 104834
133965Sjdp/* BFD back-end for ieee-695 objects. 278828Sobrien Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 391041Sobrien 2000, 2001, 2002 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 2291041Sobrien Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 3033965Sjdp#include "bfd.h" 3133965Sjdp#include "sysdep.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 4333965Sjdpstatic boolean ieee_write_byte PARAMS ((bfd *, int)); 4433965Sjdpstatic boolean ieee_write_2bytes PARAMS ((bfd *, int)); 4533965Sjdpstatic boolean ieee_write_int PARAMS ((bfd *, bfd_vma)); 4633965Sjdpstatic boolean ieee_write_id PARAMS ((bfd *, const char *)); 4789857Sobrienstatic unsigned short read_2bytes PARAMS ((common_header_type *)); 4889857Sobrienstatic void bfd_get_string PARAMS ((common_header_type *, char *, size_t)); 4989857Sobrienstatic char *read_id PARAMS ((common_header_type *)); 5033965Sjdpstatic boolean ieee_write_expression 5133965Sjdp PARAMS ((bfd *, bfd_vma, asymbol *, boolean, unsigned int)); 5233965Sjdpstatic void ieee_write_int5 PARAMS ((bfd_byte *, bfd_vma)); 5333965Sjdpstatic boolean ieee_write_int5_out PARAMS ((bfd *, bfd_vma)); 5489857Sobrienstatic boolean parse_int PARAMS ((common_header_type *, bfd_vma *)); 5589857Sobrienstatic int parse_i PARAMS ((common_header_type *, boolean *)); 5689857Sobrienstatic bfd_vma must_parse_int PARAMS ((common_header_type *)); 5789857Sobrienstatic void parse_expression 5889857Sobrien PARAMS ((ieee_data_type *, bfd_vma *, ieee_symbol_index_type *, 5989857Sobrien boolean *, unsigned int *, asection **)); 6089857Sobrienstatic file_ptr ieee_part_after PARAMS ((ieee_data_type *, file_ptr)); 6189857Sobrienstatic ieee_symbol_type *get_symbol 6289857Sobrien PARAMS ((bfd *, ieee_data_type *, ieee_symbol_type *, unsigned int *, 6389857Sobrien ieee_symbol_type ***, unsigned int *, int)); 6489857Sobrienstatic boolean ieee_slurp_external_symbols PARAMS ((bfd *)); 6589857Sobrienstatic boolean ieee_slurp_symbol_table PARAMS ((bfd *)); 6689857Sobrienstatic long ieee_get_symtab_upper_bound PARAMS ((bfd *)); 6789857Sobrienstatic long ieee_get_symtab PARAMS ((bfd *, asymbol **)); 6889857Sobrienstatic asection *get_section_entry 6989857Sobrien PARAMS ((bfd *, ieee_data_type *i, unsigned int)); 7089857Sobrienstatic void ieee_slurp_sections PARAMS ((bfd *)); 7189857Sobrienstatic boolean ieee_slurp_debug PARAMS ((bfd *)); 7289857Sobrienconst bfd_target *ieee_archive_p PARAMS ((bfd *)); 7389857Sobrienconst bfd_target *ieee_object_p PARAMS ((bfd *)); 7489857Sobrienstatic void ieee_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); 7589857Sobrienstatic void ieee_print_symbol 7689857Sobrien PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type)); 7789857Sobrienstatic boolean do_one 7889857Sobrien PARAMS ((ieee_data_type *, ieee_per_section_type *, unsigned char *, 7989857Sobrien asection *, int)); 8089857Sobrienstatic boolean ieee_slurp_section_data PARAMS ((bfd *)); 8189857Sobrienstatic boolean ieee_new_section_hook PARAMS ((bfd *, asection *)); 8289857Sobrienstatic long ieee_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); 8389857Sobrienstatic boolean ieee_get_section_contents 8489857Sobrien PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); 8589857Sobrienstatic long ieee_canonicalize_reloc 8689857Sobrien PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); 8789857Sobrienstatic int comp PARAMS ((const PTR, const PTR)); 8833965Sjdpstatic boolean ieee_write_section_part PARAMS ((bfd *)); 8933965Sjdpstatic boolean do_with_relocs PARAMS ((bfd *, asection *)); 9033965Sjdpstatic boolean do_as_repeat PARAMS ((bfd *, asection *)); 9133965Sjdpstatic boolean do_without_relocs PARAMS ((bfd *, asection *)); 9289857Sobrienstatic boolean ieee_mkobject PARAMS ((bfd *)); 9389857Sobrienstatic void fill PARAMS ((void)); 9489857Sobrienstatic void flush PARAMS ((void)); 9589857Sobrienstatic void write_int PARAMS ((int)); 9689857Sobrienstatic void copy_id PARAMS ((void)); 9789857Sobrienstatic void copy_expression PARAMS ((void)); 9889857Sobrienstatic void fill_int PARAMS ((struct output_buffer_struct *)); 9989857Sobrienstatic void drop_int PARAMS ((struct output_buffer_struct *)); 10089857Sobrienstatic void copy_int PARAMS ((void)); 10189857Sobrienstatic void f1_record PARAMS ((void)); 10289857Sobrienstatic void f0_record PARAMS ((void)); 10389857Sobrienstatic void copy_till_end PARAMS ((void)); 10489857Sobrienstatic void f2_record PARAMS ((void)); 10589857Sobrienstatic void f8_record PARAMS ((void)); 10689857Sobrienstatic void e2_record PARAMS ((void)); 10789857Sobrienstatic void block PARAMS ((void)); 10889857Sobrienstatic void relocate_debug PARAMS ((bfd *, bfd *)); 10989857Sobrienstatic boolean ieee_write_debug_part PARAMS ((bfd *)); 11089857Sobrienstatic boolean ieee_write_data_part PARAMS ((bfd *)); 11189857Sobrienstatic boolean init_for_output PARAMS ((bfd *)); 11289857Sobrienstatic boolean ieee_set_section_contents 11389857Sobrien PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); 11433965Sjdpstatic boolean ieee_write_external_part PARAMS ((bfd *)); 11533965Sjdpstatic boolean ieee_write_me_part PARAMS ((bfd *)); 11633965Sjdpstatic boolean ieee_write_processor PARAMS ((bfd *)); 11789857Sobrienstatic boolean ieee_write_object_contents PARAMS ((bfd *)); 11889857Sobrienstatic asymbol *ieee_make_empty_symbol PARAMS ((bfd *)); 11989857Sobrienstatic bfd *ieee_openr_next_archived_file PARAMS ((bfd *, bfd *)); 12089857Sobrienstatic boolean ieee_find_nearest_line 12189857Sobrien PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, 12289857Sobrien const char **, unsigned int *)); 12389857Sobrienstatic int ieee_generic_stat_arch_elt PARAMS ((bfd *, struct stat *)); 12489857Sobrienstatic int ieee_sizeof_headers PARAMS ((bfd *, boolean)); 12533965Sjdp 12633965Sjdp/* Functions for writing to ieee files in the strange way that the 12733965Sjdp standard requires. */ 12833965Sjdp 12933965Sjdpstatic boolean 13033965Sjdpieee_write_byte (abfd, barg) 13133965Sjdp bfd *abfd; 13233965Sjdp int barg; 13333965Sjdp{ 13433965Sjdp bfd_byte byte; 13533965Sjdp 13633965Sjdp byte = barg; 13789857Sobrien if (bfd_bwrite ((PTR) &byte, (bfd_size_type) 1, abfd) != 1) 13833965Sjdp return false; 13933965Sjdp return true; 14033965Sjdp} 14133965Sjdp 14233965Sjdpstatic boolean 14333965Sjdpieee_write_2bytes (abfd, bytes) 14433965Sjdp bfd *abfd; 14533965Sjdp int bytes; 14633965Sjdp{ 14733965Sjdp bfd_byte buffer[2]; 14833965Sjdp 14933965Sjdp buffer[0] = bytes >> 8; 15033965Sjdp buffer[1] = bytes & 0xff; 15189857Sobrien if (bfd_bwrite ((PTR) buffer, (bfd_size_type) 2, abfd) != 2) 15233965Sjdp return false; 15333965Sjdp return true; 15433965Sjdp} 15533965Sjdp 15633965Sjdpstatic boolean 15733965Sjdpieee_write_int (abfd, value) 15833965Sjdp bfd *abfd; 15933965Sjdp bfd_vma value; 16033965Sjdp{ 16133965Sjdp if (value <= 127) 16233965Sjdp { 16333965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) value)) 16433965Sjdp return false; 16533965Sjdp } 16633965Sjdp else 16733965Sjdp { 16833965Sjdp unsigned int length; 16933965Sjdp 17033965Sjdp /* How many significant bytes ? */ 17133965Sjdp /* FIXME FOR LONGER INTS */ 17233965Sjdp if (value & 0xff000000) 17333965Sjdp length = 4; 17433965Sjdp else if (value & 0x00ff0000) 17533965Sjdp length = 3; 17633965Sjdp else if (value & 0x0000ff00) 17733965Sjdp length = 2; 17833965Sjdp else 17933965Sjdp length = 1; 18033965Sjdp 18133965Sjdp if (! ieee_write_byte (abfd, 18233965Sjdp (bfd_byte) ((int) ieee_number_repeat_start_enum 18333965Sjdp + length))) 18433965Sjdp return false; 18533965Sjdp switch (length) 18633965Sjdp { 18733965Sjdp case 4: 18833965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) (value >> 24))) 18933965Sjdp return false; 19033965Sjdp /* Fall through. */ 19133965Sjdp case 3: 19233965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) (value >> 16))) 19333965Sjdp return false; 19433965Sjdp /* Fall through. */ 19533965Sjdp case 2: 19633965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) (value >> 8))) 19733965Sjdp return false; 19833965Sjdp /* Fall through. */ 19933965Sjdp case 1: 20033965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) (value))) 20133965Sjdp return false; 20233965Sjdp } 20333965Sjdp } 20433965Sjdp 20533965Sjdp return true; 20633965Sjdp} 20733965Sjdp 20833965Sjdpstatic boolean 20933965Sjdpieee_write_id (abfd, id) 21033965Sjdp bfd *abfd; 21133965Sjdp const char *id; 21233965Sjdp{ 21333965Sjdp size_t length = strlen (id); 21433965Sjdp 21533965Sjdp if (length <= 127) 21633965Sjdp { 21733965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) length)) 21833965Sjdp return false; 21933965Sjdp } 22033965Sjdp else if (length < 255) 22133965Sjdp { 22233965Sjdp if (! ieee_write_byte (abfd, ieee_extension_length_1_enum) 22333965Sjdp || ! ieee_write_byte (abfd, (bfd_byte) length)) 22433965Sjdp return false; 22533965Sjdp } 22633965Sjdp else if (length < 65535) 22733965Sjdp { 22833965Sjdp if (! ieee_write_byte (abfd, ieee_extension_length_2_enum) 22933965Sjdp || ! ieee_write_2bytes (abfd, (int) length)) 23033965Sjdp return false; 23133965Sjdp } 23233965Sjdp else 23333965Sjdp { 23433965Sjdp (*_bfd_error_handler) 23560484Sobrien (_("%s: string too long (%d chars, max 65535)"), 23633965Sjdp bfd_get_filename (abfd), length); 23733965Sjdp bfd_set_error (bfd_error_invalid_operation); 23833965Sjdp return false; 23933965Sjdp } 24033965Sjdp 24189857Sobrien if (bfd_bwrite ((PTR) id, (bfd_size_type) length, abfd) != length) 24233965Sjdp return false; 24333965Sjdp return true; 24433965Sjdp} 24533965Sjdp 24633965Sjdp/*************************************************************************** 24733965SjdpFunctions for reading from ieee files in the strange way that the 24833965Sjdpstandard requires: 24933965Sjdp*/ 25033965Sjdp 25133965Sjdp#define this_byte(ieee) *((ieee)->input_p) 25233965Sjdp#define next_byte(ieee) ((ieee)->input_p++) 25333965Sjdp#define this_byte_and_next(ieee) (*((ieee)->input_p++)) 25433965Sjdp 25533965Sjdpstatic unsigned short 25633965Sjdpread_2bytes (ieee) 25733965Sjdp common_header_type *ieee; 25833965Sjdp{ 25933965Sjdp unsigned char c1 = this_byte_and_next (ieee); 26033965Sjdp unsigned char c2 = this_byte_and_next (ieee); 26133965Sjdp return (c1 << 8) | c2; 26233965Sjdp} 26333965Sjdp 26433965Sjdpstatic void 26533965Sjdpbfd_get_string (ieee, string, length) 26633965Sjdp common_header_type *ieee; 26733965Sjdp char *string; 26833965Sjdp size_t length; 26933965Sjdp{ 27033965Sjdp size_t i; 27133965Sjdp for (i = 0; i < length; i++) 27233965Sjdp { 27333965Sjdp string[i] = this_byte_and_next (ieee); 27433965Sjdp } 27533965Sjdp} 27633965Sjdp 27733965Sjdpstatic char * 27833965Sjdpread_id (ieee) 27933965Sjdp common_header_type *ieee; 28033965Sjdp{ 28133965Sjdp size_t length; 28233965Sjdp char *string; 28333965Sjdp length = this_byte_and_next (ieee); 28433965Sjdp if (length <= 0x7f) 28533965Sjdp { 28633965Sjdp /* Simple string of length 0 to 127 */ 28733965Sjdp } 28833965Sjdp else if (length == 0xde) 28933965Sjdp { 29033965Sjdp /* Length is next byte, allowing 0..255 */ 29133965Sjdp length = this_byte_and_next (ieee); 29233965Sjdp } 29333965Sjdp else if (length == 0xdf) 29433965Sjdp { 29533965Sjdp /* Length is next two bytes, allowing 0..65535 */ 29633965Sjdp length = this_byte_and_next (ieee); 29733965Sjdp length = (length * 256) + this_byte_and_next (ieee); 29833965Sjdp } 29933965Sjdp /* Buy memory and read string */ 30089857Sobrien string = bfd_alloc (ieee->abfd, (bfd_size_type) length + 1); 30133965Sjdp if (!string) 30233965Sjdp return NULL; 30333965Sjdp bfd_get_string (ieee, string, length); 30433965Sjdp string[length] = 0; 30533965Sjdp return string; 30633965Sjdp} 30733965Sjdp 30833965Sjdpstatic boolean 30933965Sjdpieee_write_expression (abfd, value, symbol, pcrel, index) 31033965Sjdp bfd *abfd; 31133965Sjdp bfd_vma value; 31233965Sjdp asymbol *symbol; 31333965Sjdp boolean pcrel; 31433965Sjdp unsigned int index; 31533965Sjdp{ 31633965Sjdp unsigned int term_count = 0; 31733965Sjdp 31833965Sjdp if (value != 0) 31933965Sjdp { 32033965Sjdp if (! ieee_write_int (abfd, value)) 32133965Sjdp return false; 32233965Sjdp term_count++; 32333965Sjdp } 32433965Sjdp 32533965Sjdp if (bfd_is_com_section (symbol->section) 32633965Sjdp || bfd_is_und_section (symbol->section)) 32733965Sjdp { 32833965Sjdp /* Def of a common symbol */ 32933965Sjdp if (! ieee_write_byte (abfd, ieee_variable_X_enum) 33033965Sjdp || ! ieee_write_int (abfd, symbol->value)) 33133965Sjdp return false; 33233965Sjdp term_count++; 33333965Sjdp } 33433965Sjdp else if (! bfd_is_abs_section (symbol->section)) 33533965Sjdp { 33633965Sjdp /* Ref to defined symbol - */ 33733965Sjdp 33833965Sjdp if (symbol->flags & BSF_GLOBAL) 33933965Sjdp { 34033965Sjdp if (! ieee_write_byte (abfd, ieee_variable_I_enum) 34133965Sjdp || ! ieee_write_int (abfd, symbol->value)) 34233965Sjdp return false; 34333965Sjdp term_count++; 34433965Sjdp } 34533965Sjdp else if (symbol->flags & (BSF_LOCAL | BSF_SECTION_SYM)) 34633965Sjdp { 34733965Sjdp /* This is a reference to a defined local symbol. We can 34833965Sjdp easily do a local as a section+offset. */ 34933965Sjdp if (! ieee_write_byte (abfd, ieee_variable_R_enum) 35033965Sjdp || ! ieee_write_byte (abfd, 35133965Sjdp (bfd_byte) (symbol->section->index 35233965Sjdp + IEEE_SECTION_NUMBER_BASE))) 35333965Sjdp return false; 35433965Sjdp term_count++; 35533965Sjdp if (symbol->value != 0) 35633965Sjdp { 35733965Sjdp if (! ieee_write_int (abfd, symbol->value)) 35833965Sjdp return false; 35933965Sjdp term_count++; 36033965Sjdp } 36133965Sjdp } 36233965Sjdp else 36333965Sjdp { 36433965Sjdp (*_bfd_error_handler) 36560484Sobrien (_("%s: unrecognized symbol `%s' flags 0x%x"), 36633965Sjdp bfd_get_filename (abfd), bfd_asymbol_name (symbol), 36733965Sjdp symbol->flags); 36833965Sjdp bfd_set_error (bfd_error_invalid_operation); 36933965Sjdp return false; 37033965Sjdp } 37133965Sjdp } 37233965Sjdp 37333965Sjdp if (pcrel) 37433965Sjdp { 37533965Sjdp /* subtract the pc from here by asking for PC of this section*/ 37633965Sjdp if (! ieee_write_byte (abfd, ieee_variable_P_enum) 37733965Sjdp || ! ieee_write_byte (abfd, 37833965Sjdp (bfd_byte) (index + IEEE_SECTION_NUMBER_BASE)) 37933965Sjdp || ! ieee_write_byte (abfd, ieee_function_minus_enum)) 38033965Sjdp return false; 38133965Sjdp } 38233965Sjdp 38333965Sjdp /* Handle the degenerate case of a 0 address. */ 38433965Sjdp if (term_count == 0) 38533965Sjdp { 38689857Sobrien if (! ieee_write_int (abfd, (bfd_vma) 0)) 38733965Sjdp return false; 38833965Sjdp } 38933965Sjdp 39033965Sjdp while (term_count > 1) 39133965Sjdp { 39233965Sjdp if (! ieee_write_byte (abfd, ieee_function_plus_enum)) 39333965Sjdp return false; 39433965Sjdp term_count--; 39533965Sjdp } 39633965Sjdp 39733965Sjdp return true; 39833965Sjdp} 39933965Sjdp 40033965Sjdp/*****************************************************************************/ 40133965Sjdp 40233965Sjdp/* 40333965Sjdpwrites any integer into the buffer supplied and always takes 5 bytes 40433965Sjdp*/ 40533965Sjdpstatic void 40633965Sjdpieee_write_int5 (buffer, value) 40733965Sjdp bfd_byte *buffer; 40833965Sjdp bfd_vma value; 40933965Sjdp{ 41033965Sjdp buffer[0] = (bfd_byte) ieee_number_repeat_4_enum; 41133965Sjdp buffer[1] = (value >> 24) & 0xff; 41233965Sjdp buffer[2] = (value >> 16) & 0xff; 41333965Sjdp buffer[3] = (value >> 8) & 0xff; 41433965Sjdp buffer[4] = (value >> 0) & 0xff; 41533965Sjdp} 41633965Sjdp 41733965Sjdpstatic boolean 41833965Sjdpieee_write_int5_out (abfd, value) 41933965Sjdp bfd *abfd; 42033965Sjdp bfd_vma value; 42133965Sjdp{ 42233965Sjdp bfd_byte b[5]; 42333965Sjdp 42433965Sjdp ieee_write_int5 (b, value); 42589857Sobrien if (bfd_bwrite ((PTR) b, (bfd_size_type) 5, abfd) != 5) 42633965Sjdp return false; 42733965Sjdp return true; 42833965Sjdp} 42933965Sjdp 43033965Sjdpstatic boolean 43133965Sjdpparse_int (ieee, value_ptr) 43233965Sjdp common_header_type *ieee; 43333965Sjdp bfd_vma *value_ptr; 43433965Sjdp{ 43533965Sjdp int value = this_byte (ieee); 43633965Sjdp int result; 43733965Sjdp if (value >= 0 && value <= 127) 43833965Sjdp { 43933965Sjdp *value_ptr = value; 44033965Sjdp next_byte (ieee); 44133965Sjdp return true; 44233965Sjdp } 44333965Sjdp else if (value >= 0x80 && value <= 0x88) 44433965Sjdp { 44533965Sjdp unsigned int count = value & 0xf; 44633965Sjdp result = 0; 44733965Sjdp next_byte (ieee); 44833965Sjdp while (count) 44933965Sjdp { 45033965Sjdp result = (result << 8) | this_byte_and_next (ieee); 45133965Sjdp count--; 45233965Sjdp } 45333965Sjdp *value_ptr = result; 45433965Sjdp return true; 45533965Sjdp } 45633965Sjdp return false; 45733965Sjdp} 45833965Sjdp 45933965Sjdpstatic int 46033965Sjdpparse_i (ieee, ok) 46133965Sjdp common_header_type *ieee; 46233965Sjdp boolean *ok; 46333965Sjdp{ 46433965Sjdp bfd_vma x; 46533965Sjdp *ok = parse_int (ieee, &x); 46633965Sjdp return x; 46733965Sjdp} 46833965Sjdp 46933965Sjdpstatic bfd_vma 47033965Sjdpmust_parse_int (ieee) 47133965Sjdp common_header_type *ieee; 47233965Sjdp{ 47333965Sjdp bfd_vma result; 474104834Sobrien BFD_ASSERT (parse_int (ieee, &result)); 47533965Sjdp return result; 47633965Sjdp} 47733965Sjdp 47833965Sjdptypedef struct 47933965Sjdp{ 48033965Sjdp bfd_vma value; 48133965Sjdp asection *section; 48233965Sjdp ieee_symbol_index_type symbol; 48333965Sjdp} ieee_value_type; 48433965Sjdp 48533965Sjdp 48633965Sjdp#if KEEPMINUSPCININST 48733965Sjdp 48833965Sjdp#define SRC_MASK(arg) arg 48933965Sjdp#define PCREL_OFFSET false 49033965Sjdp 49133965Sjdp#else 49233965Sjdp 49333965Sjdp#define SRC_MASK(arg) 0 49433965Sjdp#define PCREL_OFFSET true 49533965Sjdp 49633965Sjdp#endif 49733965Sjdp 49833965Sjdpstatic reloc_howto_type abs32_howto = 49933965Sjdp HOWTO (1, 50033965Sjdp 0, 50133965Sjdp 2, 50233965Sjdp 32, 50333965Sjdp false, 50433965Sjdp 0, 50533965Sjdp complain_overflow_bitfield, 50633965Sjdp 0, 50733965Sjdp "abs32", 50833965Sjdp true, 50933965Sjdp 0xffffffff, 51033965Sjdp 0xffffffff, 51133965Sjdp false); 51233965Sjdp 51333965Sjdpstatic reloc_howto_type abs16_howto = 51433965Sjdp HOWTO (1, 51533965Sjdp 0, 51633965Sjdp 1, 51733965Sjdp 16, 51833965Sjdp false, 51933965Sjdp 0, 52033965Sjdp complain_overflow_bitfield, 52133965Sjdp 0, 52233965Sjdp "abs16", 52333965Sjdp true, 52433965Sjdp 0x0000ffff, 52533965Sjdp 0x0000ffff, 52633965Sjdp false); 52733965Sjdp 52833965Sjdpstatic reloc_howto_type abs8_howto = 52933965Sjdp HOWTO (1, 53033965Sjdp 0, 53133965Sjdp 0, 53233965Sjdp 8, 53333965Sjdp false, 53433965Sjdp 0, 53533965Sjdp complain_overflow_bitfield, 53633965Sjdp 0, 53733965Sjdp "abs8", 53833965Sjdp true, 53933965Sjdp 0x000000ff, 54033965Sjdp 0x000000ff, 54133965Sjdp false); 54233965Sjdp 54333965Sjdpstatic reloc_howto_type rel32_howto = 54433965Sjdp HOWTO (1, 54533965Sjdp 0, 54633965Sjdp 2, 54733965Sjdp 32, 54833965Sjdp true, 54933965Sjdp 0, 55033965Sjdp complain_overflow_signed, 55133965Sjdp 0, 55233965Sjdp "rel32", 55333965Sjdp true, 55433965Sjdp SRC_MASK (0xffffffff), 55533965Sjdp 0xffffffff, 55633965Sjdp PCREL_OFFSET); 55733965Sjdp 55833965Sjdpstatic reloc_howto_type rel16_howto = 55933965Sjdp HOWTO (1, 56033965Sjdp 0, 56133965Sjdp 1, 56233965Sjdp 16, 56333965Sjdp true, 56433965Sjdp 0, 56533965Sjdp complain_overflow_signed, 56633965Sjdp 0, 56733965Sjdp "rel16", 56833965Sjdp true, 56933965Sjdp SRC_MASK (0x0000ffff), 57033965Sjdp 0x0000ffff, 57133965Sjdp PCREL_OFFSET); 57233965Sjdp 57333965Sjdpstatic reloc_howto_type rel8_howto = 57433965Sjdp HOWTO (1, 57533965Sjdp 0, 57633965Sjdp 0, 57733965Sjdp 8, 57833965Sjdp true, 57933965Sjdp 0, 58033965Sjdp complain_overflow_signed, 58133965Sjdp 0, 58233965Sjdp "rel8", 58333965Sjdp true, 58433965Sjdp SRC_MASK (0x000000ff), 58533965Sjdp 0x000000ff, 58633965Sjdp PCREL_OFFSET); 58733965Sjdp 58833965Sjdpstatic ieee_symbol_index_type NOSYMBOL = {0, 0}; 58933965Sjdp 59033965Sjdpstatic void 59133965Sjdpparse_expression (ieee, value, symbol, pcrel, extra, section) 59233965Sjdp ieee_data_type *ieee; 59333965Sjdp bfd_vma *value; 59433965Sjdp ieee_symbol_index_type *symbol; 59533965Sjdp boolean *pcrel; 59633965Sjdp unsigned int *extra; 59733965Sjdp asection **section; 59833965Sjdp 59933965Sjdp{ 60033965Sjdp#define POS sp[1] 60133965Sjdp#define TOS sp[0] 60233965Sjdp#define NOS sp[-1] 60333965Sjdp#define INC sp++; 60433965Sjdp#define DEC sp--; 60533965Sjdp 60633965Sjdp boolean loop = true; 60733965Sjdp ieee_value_type stack[10]; 60833965Sjdp 60933965Sjdp /* The stack pointer always points to the next unused location */ 61033965Sjdp#define PUSH(x,y,z) TOS.symbol=x;TOS.section=y;TOS.value=z;INC; 61133965Sjdp#define POP(x,y,z) DEC;x=TOS.symbol;y=TOS.section;z=TOS.value; 61233965Sjdp ieee_value_type *sp = stack; 61389857Sobrien asection *dummy; 61433965Sjdp 61589857Sobrien while (loop && ieee->h.input_p < ieee->h.last_byte) 61633965Sjdp { 61733965Sjdp switch (this_byte (&(ieee->h))) 61833965Sjdp { 61933965Sjdp case ieee_variable_P_enum: 62033965Sjdp /* P variable, current program counter for section n */ 62133965Sjdp { 62233965Sjdp int section_n; 62333965Sjdp next_byte (&(ieee->h)); 62433965Sjdp *pcrel = true; 62533965Sjdp section_n = must_parse_int (&(ieee->h)); 62633965Sjdp PUSH (NOSYMBOL, bfd_abs_section_ptr, 0); 62733965Sjdp break; 62833965Sjdp } 62933965Sjdp case ieee_variable_L_enum: 63033965Sjdp /* L variable address of section N */ 63133965Sjdp next_byte (&(ieee->h)); 63233965Sjdp PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0); 63333965Sjdp break; 63433965Sjdp case ieee_variable_R_enum: 63533965Sjdp /* R variable, logical address of section module */ 63633965Sjdp /* FIXME, this should be different to L */ 63733965Sjdp next_byte (&(ieee->h)); 63833965Sjdp PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0); 63933965Sjdp break; 64033965Sjdp case ieee_variable_S_enum: 64133965Sjdp /* S variable, size in MAUS of section module */ 64233965Sjdp next_byte (&(ieee->h)); 64333965Sjdp PUSH (NOSYMBOL, 64433965Sjdp 0, 64533965Sjdp ieee->section_table[must_parse_int (&(ieee->h))]->_raw_size); 64633965Sjdp break; 64733965Sjdp case ieee_variable_I_enum: 64833965Sjdp /* Push the address of variable n */ 64933965Sjdp { 65033965Sjdp ieee_symbol_index_type sy; 65133965Sjdp next_byte (&(ieee->h)); 65233965Sjdp sy.index = (int) must_parse_int (&(ieee->h)); 65333965Sjdp sy.letter = 'I'; 65433965Sjdp 65533965Sjdp PUSH (sy, bfd_abs_section_ptr, 0); 65633965Sjdp } 65733965Sjdp break; 65833965Sjdp case ieee_variable_X_enum: 65933965Sjdp /* Push the address of external variable n */ 66033965Sjdp { 66133965Sjdp ieee_symbol_index_type sy; 66233965Sjdp next_byte (&(ieee->h)); 66333965Sjdp sy.index = (int) (must_parse_int (&(ieee->h))); 66433965Sjdp sy.letter = 'X'; 66533965Sjdp 66633965Sjdp PUSH (sy, bfd_und_section_ptr, 0); 66733965Sjdp } 66833965Sjdp break; 66933965Sjdp case ieee_function_minus_enum: 67033965Sjdp { 67133965Sjdp bfd_vma value1, value2; 67233965Sjdp asection *section1, *section_dummy; 67333965Sjdp ieee_symbol_index_type sy; 67433965Sjdp next_byte (&(ieee->h)); 67533965Sjdp 67633965Sjdp POP (sy, section1, value1); 67733965Sjdp POP (sy, section_dummy, value2); 67833965Sjdp PUSH (sy, section1 ? section1 : section_dummy, value2 - value1); 67933965Sjdp } 68033965Sjdp break; 68133965Sjdp case ieee_function_plus_enum: 68233965Sjdp { 68333965Sjdp bfd_vma value1, value2; 68433965Sjdp asection *section1; 68533965Sjdp asection *section2; 68633965Sjdp ieee_symbol_index_type sy1; 68733965Sjdp ieee_symbol_index_type sy2; 68833965Sjdp next_byte (&(ieee->h)); 68933965Sjdp 69033965Sjdp POP (sy1, section1, value1); 69133965Sjdp POP (sy2, section2, value2); 69233965Sjdp PUSH (sy1.letter ? sy1 : sy2, 69333965Sjdp bfd_is_abs_section (section1) ? section2 : section1, 69433965Sjdp value1 + value2); 69533965Sjdp } 69633965Sjdp break; 69733965Sjdp default: 69833965Sjdp { 69933965Sjdp bfd_vma va; 70033965Sjdp BFD_ASSERT (this_byte (&(ieee->h)) < (int) ieee_variable_A_enum 70133965Sjdp || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum); 70233965Sjdp if (parse_int (&(ieee->h), &va)) 70333965Sjdp { 70433965Sjdp PUSH (NOSYMBOL, bfd_abs_section_ptr, va); 70533965Sjdp } 70633965Sjdp else 70733965Sjdp { 70889857Sobrien /* Thats all that we can understand. */ 70933965Sjdp loop = false; 71033965Sjdp } 71133965Sjdp } 71233965Sjdp } 71333965Sjdp } 71489857Sobrien 71589857Sobrien /* As far as I can see there is a bug in the Microtec IEEE output 71689857Sobrien which I'm using to scan, whereby the comma operator is omitted 71789857Sobrien sometimes in an expression, giving expressions with too many 71889857Sobrien terms. We can tell if that's the case by ensuring that 71989857Sobrien sp == stack here. If not, then we've pushed something too far, 72089857Sobrien so we keep adding. */ 72189857Sobrien 72289857Sobrien while (sp != stack + 1) 72389857Sobrien { 72489857Sobrien asection *section1; 72589857Sobrien ieee_symbol_index_type sy1; 72689857Sobrien POP (sy1, section1, *extra); 72789857Sobrien } 72889857Sobrien 72989857Sobrien POP (*symbol, dummy, *value); 73089857Sobrien if (section) 73189857Sobrien *section = dummy; 73233965Sjdp} 73333965Sjdp 73433965Sjdp 73589857Sobrien#define ieee_seek(ieee, offset) \ 73689857Sobrien do \ 73789857Sobrien { \ 73889857Sobrien ieee->h.input_p = ieee->h.first_byte + offset; \ 73989857Sobrien ieee->h.last_byte = (ieee->h.first_byte \ 74089857Sobrien + ieee_part_after (ieee, offset)); \ 74189857Sobrien } \ 74289857Sobrien while (0) 74333965Sjdp 74489857Sobrien#define ieee_pos(ieee) \ 74589857Sobrien (ieee->h.input_p - ieee->h.first_byte) 74633965Sjdp 74789857Sobrien/* Find the first part of the ieee file after HERE. */ 74889857Sobrien 74989857Sobrienstatic file_ptr 75089857Sobrienieee_part_after (ieee, here) 75189857Sobrien ieee_data_type *ieee; 75289857Sobrien file_ptr here; 75389857Sobrien{ 75489857Sobrien int part; 75589857Sobrien file_ptr after = ieee->w.r.me_record; 75689857Sobrien 75789857Sobrien /* File parts can come in any order, except that module end is 75889857Sobrien guaranteed to be last (and the header first). */ 75989857Sobrien for (part = 0; part < N_W_VARIABLES; part++) 76089857Sobrien if (ieee->w.offset[part] > here && after > ieee->w.offset[part]) 76189857Sobrien after = ieee->w.offset[part]; 76289857Sobrien 76389857Sobrien return after; 76489857Sobrien} 76589857Sobrien 76633965Sjdpstatic unsigned int last_index; 76733965Sjdpstatic char last_type; /* is the index for an X or a D */ 76833965Sjdp 76933965Sjdpstatic ieee_symbol_type * 77089857Sobrienget_symbol (abfd, ieee, last_symbol, symbol_count, pptr, max_index, this_type) 77160484Sobrien bfd *abfd ATTRIBUTE_UNUSED; 77233965Sjdp ieee_data_type *ieee; 77333965Sjdp ieee_symbol_type *last_symbol; 77433965Sjdp unsigned int *symbol_count; 77533965Sjdp ieee_symbol_type ***pptr; 77633965Sjdp unsigned int *max_index; 77789857Sobrien int this_type; 77833965Sjdp{ 77933965Sjdp /* Need a new symbol */ 78033965Sjdp unsigned int new_index = must_parse_int (&(ieee->h)); 78133965Sjdp if (new_index != last_index || this_type != last_type) 78233965Sjdp { 78389857Sobrien ieee_symbol_type *new_symbol; 78489857Sobrien bfd_size_type amt = sizeof (ieee_symbol_type); 78589857Sobrien 78689857Sobrien new_symbol = (ieee_symbol_type *) bfd_alloc (ieee->h.abfd, amt); 78733965Sjdp if (!new_symbol) 78833965Sjdp return NULL; 78933965Sjdp 79033965Sjdp new_symbol->index = new_index; 79133965Sjdp last_index = new_index; 79233965Sjdp (*symbol_count)++; 79333965Sjdp **pptr = new_symbol; 79433965Sjdp *pptr = &new_symbol->next; 79533965Sjdp if (new_index > *max_index) 79633965Sjdp { 79733965Sjdp *max_index = new_index; 79833965Sjdp } 79933965Sjdp last_type = this_type; 80033965Sjdp new_symbol->symbol.section = bfd_abs_section_ptr; 80133965Sjdp return new_symbol; 80233965Sjdp } 80333965Sjdp return last_symbol; 80433965Sjdp} 80533965Sjdp 80633965Sjdpstatic boolean 80733965Sjdpieee_slurp_external_symbols (abfd) 80833965Sjdp bfd *abfd; 80933965Sjdp{ 81033965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 81133965Sjdp file_ptr offset = ieee->w.r.external_part; 81233965Sjdp 81333965Sjdp ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols; 81433965Sjdp ieee_symbol_type **prev_reference_ptr = &ieee->external_reference; 81533965Sjdp ieee_symbol_type *symbol = (ieee_symbol_type *) NULL; 81633965Sjdp unsigned int symbol_count = 0; 81733965Sjdp boolean loop = true; 81833965Sjdp last_index = 0xffffff; 81933965Sjdp ieee->symbol_table_full = true; 82033965Sjdp 82189857Sobrien ieee_seek (ieee, offset); 82233965Sjdp 82333965Sjdp while (loop) 82433965Sjdp { 82533965Sjdp switch (this_byte (&(ieee->h))) 82633965Sjdp { 82733965Sjdp case ieee_nn_record: 82833965Sjdp next_byte (&(ieee->h)); 82933965Sjdp 83033965Sjdp symbol = get_symbol (abfd, ieee, symbol, &symbol_count, 83133965Sjdp &prev_symbols_ptr, 83233965Sjdp &ieee->external_symbol_max_index, 'I'); 83333965Sjdp if (symbol == NULL) 83433965Sjdp return false; 83533965Sjdp 83633965Sjdp symbol->symbol.the_bfd = abfd; 83733965Sjdp symbol->symbol.name = read_id (&(ieee->h)); 83833965Sjdp symbol->symbol.udata.p = (PTR) NULL; 83933965Sjdp symbol->symbol.flags = BSF_NO_FLAGS; 84033965Sjdp break; 84133965Sjdp case ieee_external_symbol_enum: 84233965Sjdp next_byte (&(ieee->h)); 84333965Sjdp 84433965Sjdp symbol = get_symbol (abfd, ieee, symbol, &symbol_count, 84533965Sjdp &prev_symbols_ptr, 84633965Sjdp &ieee->external_symbol_max_index, 'D'); 84733965Sjdp if (symbol == NULL) 84833965Sjdp return false; 84933965Sjdp 85033965Sjdp BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index); 85133965Sjdp 85233965Sjdp symbol->symbol.the_bfd = abfd; 85333965Sjdp symbol->symbol.name = read_id (&(ieee->h)); 85433965Sjdp symbol->symbol.udata.p = (PTR) NULL; 85533965Sjdp symbol->symbol.flags = BSF_NO_FLAGS; 85633965Sjdp break; 85733965Sjdp case ieee_attribute_record_enum >> 8: 85833965Sjdp { 85933965Sjdp unsigned int symbol_name_index; 86033965Sjdp unsigned int symbol_type_index; 86133965Sjdp unsigned int symbol_attribute_def; 86233965Sjdp bfd_vma value; 86389857Sobrien switch (read_2bytes (&ieee->h)) 86433965Sjdp { 86533965Sjdp case ieee_attribute_record_enum: 86633965Sjdp symbol_name_index = must_parse_int (&(ieee->h)); 86733965Sjdp symbol_type_index = must_parse_int (&(ieee->h)); 86833965Sjdp symbol_attribute_def = must_parse_int (&(ieee->h)); 86933965Sjdp switch (symbol_attribute_def) 87033965Sjdp { 87133965Sjdp case 8: 87233965Sjdp case 19: 87333965Sjdp parse_int (&ieee->h, &value); 87433965Sjdp break; 87533965Sjdp default: 87633965Sjdp (*_bfd_error_handler) 87791041Sobrien (_("%s: unimplemented ATI record %u for symbol %u"), 87889857Sobrien bfd_archive_filename (abfd), symbol_attribute_def, 87933965Sjdp symbol_name_index); 88033965Sjdp bfd_set_error (bfd_error_bad_value); 88133965Sjdp return false; 88233965Sjdp break; 88333965Sjdp } 88433965Sjdp break; 88533965Sjdp case ieee_external_reference_info_record_enum: 88633965Sjdp /* Skip over ATX record. */ 88733965Sjdp parse_int (&(ieee->h), &value); 88833965Sjdp parse_int (&(ieee->h), &value); 88933965Sjdp parse_int (&(ieee->h), &value); 89033965Sjdp parse_int (&(ieee->h), &value); 89133965Sjdp break; 89260484Sobrien case ieee_atn_record_enum: 89360484Sobrien /* We may get call optimization information here, 89460484Sobrien which we just ignore. The format is 89560484Sobrien {$F1}${CE}{index}{$00}{$3F}{$3F}{#_of_ASNs} */ 89660484Sobrien parse_int (&ieee->h, &value); 89760484Sobrien parse_int (&ieee->h, &value); 89860484Sobrien parse_int (&ieee->h, &value); 89960484Sobrien if (value != 0x3f) 90060484Sobrien { 90160484Sobrien (*_bfd_error_handler) 90260484Sobrien (_("%s: unexpected ATN type %d in external part"), 90389857Sobrien bfd_archive_filename (abfd), (int) value); 90460484Sobrien bfd_set_error (bfd_error_bad_value); 90560484Sobrien return false; 90660484Sobrien } 90760484Sobrien parse_int (&ieee->h, &value); 90860484Sobrien parse_int (&ieee->h, &value); 90960484Sobrien while (value > 0) 91060484Sobrien { 91160484Sobrien bfd_vma val1; 91260484Sobrien 91360484Sobrien --value; 91460484Sobrien 91589857Sobrien switch (read_2bytes (&ieee->h)) 91660484Sobrien { 91760484Sobrien case ieee_asn_record_enum: 91860484Sobrien parse_int (&ieee->h, &val1); 91960484Sobrien parse_int (&ieee->h, &val1); 92060484Sobrien break; 92160484Sobrien 92260484Sobrien default: 92360484Sobrien (*_bfd_error_handler) 92460484Sobrien (_("%s: unexpected type after ATN"), 92589857Sobrien bfd_archive_filename (abfd)); 92660484Sobrien bfd_set_error (bfd_error_bad_value); 92760484Sobrien return false; 92860484Sobrien } 92960484Sobrien } 93033965Sjdp } 93133965Sjdp } 93233965Sjdp break; 93333965Sjdp case ieee_value_record_enum >> 8: 93433965Sjdp { 93533965Sjdp unsigned int symbol_name_index; 93633965Sjdp ieee_symbol_index_type symbol_ignore; 93733965Sjdp boolean pcrel_ignore; 93833965Sjdp unsigned int extra; 93933965Sjdp next_byte (&(ieee->h)); 94033965Sjdp next_byte (&(ieee->h)); 94133965Sjdp 94233965Sjdp symbol_name_index = must_parse_int (&(ieee->h)); 94333965Sjdp parse_expression (ieee, 94433965Sjdp &symbol->symbol.value, 94533965Sjdp &symbol_ignore, 94633965Sjdp &pcrel_ignore, 94733965Sjdp &extra, 94833965Sjdp &symbol->symbol.section); 94933965Sjdp 95060484Sobrien /* Fully linked IEEE-695 files tend to give every symbol 95160484Sobrien an absolute value. Try to convert that back into a 95260484Sobrien section relative value. FIXME: This won't always to 95360484Sobrien the right thing. */ 95460484Sobrien if (bfd_is_abs_section (symbol->symbol.section) 95560484Sobrien && (abfd->flags & HAS_RELOC) == 0) 95660484Sobrien { 95760484Sobrien bfd_vma val; 95860484Sobrien asection *s; 95960484Sobrien 96060484Sobrien val = symbol->symbol.value; 96160484Sobrien for (s = abfd->sections; s != NULL; s = s->next) 96260484Sobrien { 96360484Sobrien if (val >= s->vma && val < s->vma + s->_raw_size) 96460484Sobrien { 96560484Sobrien symbol->symbol.section = s; 96660484Sobrien symbol->symbol.value -= s->vma; 96760484Sobrien break; 96860484Sobrien } 96960484Sobrien } 97060484Sobrien } 97160484Sobrien 97233965Sjdp symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT; 97333965Sjdp 97433965Sjdp } 97533965Sjdp break; 97633965Sjdp case ieee_weak_external_reference_enum: 97733965Sjdp { 97833965Sjdp bfd_vma size; 97933965Sjdp bfd_vma value; 98033965Sjdp next_byte (&(ieee->h)); 98133965Sjdp /* Throw away the external reference index */ 98233965Sjdp (void) must_parse_int (&(ieee->h)); 98333965Sjdp /* Fetch the default size if not resolved */ 98433965Sjdp size = must_parse_int (&(ieee->h)); 98533965Sjdp /* Fetch the defautlt value if available */ 986104834Sobrien if (! parse_int (&(ieee->h), &value)) 98733965Sjdp { 98833965Sjdp value = 0; 98933965Sjdp } 99033965Sjdp /* This turns into a common */ 99133965Sjdp symbol->symbol.section = bfd_com_section_ptr; 99233965Sjdp symbol->symbol.value = size; 99333965Sjdp } 99433965Sjdp break; 99533965Sjdp 99633965Sjdp case ieee_external_reference_enum: 99733965Sjdp next_byte (&(ieee->h)); 99833965Sjdp 99933965Sjdp symbol = get_symbol (abfd, ieee, symbol, &symbol_count, 100033965Sjdp &prev_reference_ptr, 100133965Sjdp &ieee->external_reference_max_index, 'X'); 100233965Sjdp if (symbol == NULL) 100333965Sjdp return false; 100433965Sjdp 100533965Sjdp symbol->symbol.the_bfd = abfd; 100633965Sjdp symbol->symbol.name = read_id (&(ieee->h)); 100733965Sjdp symbol->symbol.udata.p = (PTR) NULL; 100833965Sjdp symbol->symbol.section = bfd_und_section_ptr; 100933965Sjdp symbol->symbol.value = (bfd_vma) 0; 101033965Sjdp symbol->symbol.flags = 0; 101133965Sjdp 101233965Sjdp BFD_ASSERT (symbol->index >= ieee->external_reference_min_index); 101333965Sjdp break; 101433965Sjdp 101533965Sjdp default: 101633965Sjdp loop = false; 101733965Sjdp } 101833965Sjdp } 101933965Sjdp 102033965Sjdp if (ieee->external_symbol_max_index != 0) 102133965Sjdp { 102233965Sjdp ieee->external_symbol_count = 102333965Sjdp ieee->external_symbol_max_index - 102433965Sjdp ieee->external_symbol_min_index + 1; 102533965Sjdp } 102633965Sjdp else 102733965Sjdp { 102833965Sjdp ieee->external_symbol_count = 0; 102933965Sjdp } 103033965Sjdp 103133965Sjdp if (ieee->external_reference_max_index != 0) 103233965Sjdp { 103333965Sjdp ieee->external_reference_count = 103433965Sjdp ieee->external_reference_max_index - 103533965Sjdp ieee->external_reference_min_index + 1; 103633965Sjdp } 103733965Sjdp else 103833965Sjdp { 103933965Sjdp ieee->external_reference_count = 0; 104033965Sjdp } 104133965Sjdp 104233965Sjdp abfd->symcount = 104333965Sjdp ieee->external_reference_count + ieee->external_symbol_count; 104433965Sjdp 104533965Sjdp if (symbol_count != abfd->symcount) 104633965Sjdp { 104733965Sjdp /* There are gaps in the table -- */ 104833965Sjdp ieee->symbol_table_full = false; 104933965Sjdp } 105033965Sjdp 105133965Sjdp *prev_symbols_ptr = (ieee_symbol_type *) NULL; 105233965Sjdp *prev_reference_ptr = (ieee_symbol_type *) NULL; 105333965Sjdp 105433965Sjdp return true; 105533965Sjdp} 105633965Sjdp 105733965Sjdpstatic boolean 105833965Sjdpieee_slurp_symbol_table (abfd) 105933965Sjdp bfd *abfd; 106033965Sjdp{ 1061104834Sobrien if (! IEEE_DATA (abfd)->read_symbols) 106233965Sjdp { 106333965Sjdp if (! ieee_slurp_external_symbols (abfd)) 106433965Sjdp return false; 106533965Sjdp IEEE_DATA (abfd)->read_symbols = true; 106633965Sjdp } 106733965Sjdp return true; 106833965Sjdp} 106933965Sjdp 107089857Sobrienstatic long 107133965Sjdpieee_get_symtab_upper_bound (abfd) 107233965Sjdp bfd *abfd; 107333965Sjdp{ 107433965Sjdp if (! ieee_slurp_symbol_table (abfd)) 107533965Sjdp return -1; 107633965Sjdp 107733965Sjdp return (abfd->symcount != 0) ? 107833965Sjdp (abfd->symcount + 1) * (sizeof (ieee_symbol_type *)) : 0; 107933965Sjdp} 108033965Sjdp 108133965Sjdp/* 108233965SjdpMove from our internal lists to the canon table, and insert in 108333965Sjdpsymbol index order 108433965Sjdp*/ 108533965Sjdp 108633965Sjdpextern const bfd_target ieee_vec; 108733965Sjdp 108889857Sobrienstatic long 108933965Sjdpieee_get_symtab (abfd, location) 109033965Sjdp bfd *abfd; 109133965Sjdp asymbol **location; 109233965Sjdp{ 109333965Sjdp ieee_symbol_type *symp; 109433965Sjdp static bfd dummy_bfd; 109533965Sjdp static asymbol empty_symbol = 109660484Sobrien { 109760484Sobrien &dummy_bfd, 109860484Sobrien " ieee empty", 109960484Sobrien (symvalue) 0, 110060484Sobrien BSF_DEBUGGING, 110160484Sobrien bfd_abs_section_ptr 110260484Sobrien#ifdef __STDC__ 110360484Sobrien /* K&R compilers can't initialise unions. */ 110460484Sobrien , { 0 } 110560484Sobrien#endif 110660484Sobrien }; 110733965Sjdp 110833965Sjdp if (abfd->symcount) 110933965Sjdp { 111033965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 111133965Sjdp dummy_bfd.xvec = &ieee_vec; 111233965Sjdp if (! ieee_slurp_symbol_table (abfd)) 111333965Sjdp return -1; 111433965Sjdp 1115104834Sobrien if (! ieee->symbol_table_full) 111633965Sjdp { 111733965Sjdp /* Arrgh - there are gaps in the table, run through and fill them */ 111833965Sjdp /* up with pointers to a null place */ 111933965Sjdp unsigned int i; 112033965Sjdp for (i = 0; i < abfd->symcount; i++) 112133965Sjdp { 112233965Sjdp location[i] = &empty_symbol; 112333965Sjdp } 112433965Sjdp } 112533965Sjdp 112633965Sjdp ieee->external_symbol_base_offset = -ieee->external_symbol_min_index; 112733965Sjdp for (symp = IEEE_DATA (abfd)->external_symbols; 112833965Sjdp symp != (ieee_symbol_type *) NULL; 112933965Sjdp symp = symp->next) 113033965Sjdp { 113133965Sjdp /* Place into table at correct index locations */ 113233965Sjdp location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol; 113333965Sjdp } 113433965Sjdp 113533965Sjdp /* The external refs are indexed in a bit */ 113633965Sjdp ieee->external_reference_base_offset = 113733965Sjdp -ieee->external_reference_min_index + ieee->external_symbol_count; 113833965Sjdp 113933965Sjdp for (symp = IEEE_DATA (abfd)->external_reference; 114033965Sjdp symp != (ieee_symbol_type *) NULL; 114133965Sjdp symp = symp->next) 114233965Sjdp { 114333965Sjdp location[symp->index + ieee->external_reference_base_offset] = 114433965Sjdp &symp->symbol; 114533965Sjdp 114633965Sjdp } 114733965Sjdp } 114833965Sjdp if (abfd->symcount) 114933965Sjdp { 115033965Sjdp location[abfd->symcount] = (asymbol *) NULL; 115133965Sjdp } 115233965Sjdp return abfd->symcount; 115333965Sjdp} 115433965Sjdp 115533965Sjdpstatic asection * 115633965Sjdpget_section_entry (abfd, ieee, index) 115733965Sjdp bfd *abfd; 115833965Sjdp ieee_data_type *ieee; 115933965Sjdp unsigned int index; 116033965Sjdp{ 116133965Sjdp if (index >= ieee->section_table_size) 116233965Sjdp { 116333965Sjdp unsigned int c, i; 116433965Sjdp asection **n; 116589857Sobrien bfd_size_type amt; 116633965Sjdp 116733965Sjdp c = ieee->section_table_size; 116833965Sjdp if (c == 0) 116933965Sjdp c = 20; 117033965Sjdp while (c <= index) 117133965Sjdp c *= 2; 117233965Sjdp 117389857Sobrien amt = c; 117489857Sobrien amt *= sizeof (asection *); 117589857Sobrien n = (asection **) bfd_realloc (ieee->section_table, amt); 117633965Sjdp if (n == NULL) 117733965Sjdp return NULL; 117833965Sjdp 117933965Sjdp for (i = ieee->section_table_size; i < c; i++) 118033965Sjdp n[i] = NULL; 118133965Sjdp 118233965Sjdp ieee->section_table = n; 118333965Sjdp ieee->section_table_size = c; 118433965Sjdp } 118533965Sjdp 118633965Sjdp if (ieee->section_table[index] == (asection *) NULL) 118733965Sjdp { 118889857Sobrien char *tmp = bfd_alloc (abfd, (bfd_size_type) 11); 118933965Sjdp asection *section; 119033965Sjdp 119133965Sjdp if (!tmp) 119233965Sjdp return NULL; 119333965Sjdp sprintf (tmp, " fsec%4d", index); 119433965Sjdp section = bfd_make_section (abfd, tmp); 119533965Sjdp ieee->section_table[index] = section; 119633965Sjdp section->flags = SEC_NO_FLAGS; 119733965Sjdp section->target_index = index; 119833965Sjdp ieee->section_table[index] = section; 119933965Sjdp } 120033965Sjdp return ieee->section_table[index]; 120133965Sjdp} 120233965Sjdp 120333965Sjdpstatic void 120433965Sjdpieee_slurp_sections (abfd) 120533965Sjdp bfd *abfd; 120633965Sjdp{ 120733965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 120833965Sjdp file_ptr offset = ieee->w.r.section_part; 120933965Sjdp char *name; 121033965Sjdp 121133965Sjdp if (offset != 0) 121233965Sjdp { 121333965Sjdp bfd_byte section_type[3]; 121489857Sobrien ieee_seek (ieee, offset); 121533965Sjdp while (true) 121633965Sjdp { 121733965Sjdp switch (this_byte (&(ieee->h))) 121833965Sjdp { 121933965Sjdp case ieee_section_type_enum: 122033965Sjdp { 122189857Sobrien asection *section; 122233965Sjdp unsigned int section_index; 122333965Sjdp next_byte (&(ieee->h)); 122433965Sjdp section_index = must_parse_int (&(ieee->h)); 122533965Sjdp 122633965Sjdp section = get_section_entry (abfd, ieee, section_index); 122733965Sjdp 122833965Sjdp section_type[0] = this_byte_and_next (&(ieee->h)); 122933965Sjdp 123033965Sjdp /* Set minimal section attributes. Attributes are 123133965Sjdp extended later, based on section contents. */ 123233965Sjdp 123333965Sjdp switch (section_type[0]) 123433965Sjdp { 123533965Sjdp case 0xC1: 123633965Sjdp /* Normal attributes for absolute sections */ 123733965Sjdp section_type[1] = this_byte (&(ieee->h)); 123833965Sjdp section->flags = SEC_ALLOC; 123933965Sjdp switch (section_type[1]) 124033965Sjdp { 124133965Sjdp case 0xD3: /* AS Absolute section attributes */ 124233965Sjdp next_byte (&(ieee->h)); 124333965Sjdp section_type[2] = this_byte (&(ieee->h)); 124433965Sjdp switch (section_type[2]) 124533965Sjdp { 124633965Sjdp case 0xD0: 124733965Sjdp /* Normal code */ 124833965Sjdp next_byte (&(ieee->h)); 124933965Sjdp section->flags |= SEC_CODE; 125033965Sjdp break; 125133965Sjdp case 0xC4: 125233965Sjdp /* Normal data */ 125333965Sjdp next_byte (&(ieee->h)); 125433965Sjdp section->flags |= SEC_DATA; 125533965Sjdp break; 125633965Sjdp case 0xD2: 125733965Sjdp next_byte (&(ieee->h)); 125833965Sjdp /* Normal rom data */ 125933965Sjdp section->flags |= SEC_ROM | SEC_DATA; 126033965Sjdp break; 126133965Sjdp default: 126233965Sjdp break; 126333965Sjdp } 126433965Sjdp } 126533965Sjdp break; 126633965Sjdp case 0xC3: /* Named relocatable sections (type C) */ 126733965Sjdp section_type[1] = this_byte (&(ieee->h)); 126833965Sjdp section->flags = SEC_ALLOC; 126933965Sjdp switch (section_type[1]) 127033965Sjdp { 127133965Sjdp case 0xD0: /* Normal code (CP) */ 127233965Sjdp next_byte (&(ieee->h)); 127333965Sjdp section->flags |= SEC_CODE; 127433965Sjdp break; 127533965Sjdp case 0xC4: /* Normal data (CD) */ 127633965Sjdp next_byte (&(ieee->h)); 127733965Sjdp section->flags |= SEC_DATA; 127833965Sjdp break; 127933965Sjdp case 0xD2: /* Normal rom data (CR) */ 128033965Sjdp next_byte (&(ieee->h)); 128133965Sjdp section->flags |= SEC_ROM | SEC_DATA; 128233965Sjdp break; 128333965Sjdp default: 128433965Sjdp break; 128533965Sjdp } 128633965Sjdp } 128733965Sjdp 128833965Sjdp /* Read section name, use it if non empty. */ 128933965Sjdp name = read_id (&ieee->h); 129033965Sjdp if (name[0]) 129133965Sjdp section->name = name; 129233965Sjdp 129333965Sjdp /* Skip these fields, which we don't care about */ 129433965Sjdp { 129533965Sjdp bfd_vma parent, brother, context; 129633965Sjdp parse_int (&(ieee->h), &parent); 129733965Sjdp parse_int (&(ieee->h), &brother); 129833965Sjdp parse_int (&(ieee->h), &context); 129933965Sjdp } 130033965Sjdp } 130133965Sjdp break; 130233965Sjdp case ieee_section_alignment_enum: 130333965Sjdp { 130433965Sjdp unsigned int section_index; 130533965Sjdp bfd_vma value; 130633965Sjdp asection *section; 130733965Sjdp next_byte (&(ieee->h)); 130833965Sjdp section_index = must_parse_int (&ieee->h); 130933965Sjdp section = get_section_entry (abfd, ieee, section_index); 131033965Sjdp if (section_index > ieee->section_count) 131133965Sjdp { 131233965Sjdp ieee->section_count = section_index; 131333965Sjdp } 131433965Sjdp section->alignment_power = 131533965Sjdp bfd_log2 (must_parse_int (&ieee->h)); 131633965Sjdp (void) parse_int (&(ieee->h), &value); 131733965Sjdp } 131833965Sjdp break; 131933965Sjdp case ieee_e2_first_byte_enum: 132033965Sjdp { 132189857Sobrien asection *section; 132289857Sobrien ieee_record_enum_type t; 132333965Sjdp 132489857Sobrien t = (ieee_record_enum_type) (read_2bytes (&(ieee->h))); 132533965Sjdp switch (t) 132633965Sjdp { 132733965Sjdp case ieee_section_size_enum: 132833965Sjdp section = ieee->section_table[must_parse_int (&(ieee->h))]; 132933965Sjdp section->_raw_size = must_parse_int (&(ieee->h)); 133033965Sjdp break; 133133965Sjdp case ieee_physical_region_size_enum: 133233965Sjdp section = ieee->section_table[must_parse_int (&(ieee->h))]; 133333965Sjdp section->_raw_size = must_parse_int (&(ieee->h)); 133433965Sjdp break; 133533965Sjdp case ieee_region_base_address_enum: 133633965Sjdp section = ieee->section_table[must_parse_int (&(ieee->h))]; 133733965Sjdp section->vma = must_parse_int (&(ieee->h)); 133833965Sjdp section->lma = section->vma; 133933965Sjdp break; 134033965Sjdp case ieee_mau_size_enum: 134133965Sjdp must_parse_int (&(ieee->h)); 134233965Sjdp must_parse_int (&(ieee->h)); 134333965Sjdp break; 134433965Sjdp case ieee_m_value_enum: 134533965Sjdp must_parse_int (&(ieee->h)); 134633965Sjdp must_parse_int (&(ieee->h)); 134733965Sjdp break; 134833965Sjdp case ieee_section_base_address_enum: 134933965Sjdp section = ieee->section_table[must_parse_int (&(ieee->h))]; 135033965Sjdp section->vma = must_parse_int (&(ieee->h)); 135133965Sjdp section->lma = section->vma; 135233965Sjdp break; 135333965Sjdp case ieee_section_offset_enum: 135433965Sjdp (void) must_parse_int (&(ieee->h)); 135533965Sjdp (void) must_parse_int (&(ieee->h)); 135633965Sjdp break; 135733965Sjdp default: 135833965Sjdp return; 135933965Sjdp } 136033965Sjdp } 136133965Sjdp break; 136233965Sjdp default: 136333965Sjdp return; 136433965Sjdp } 136533965Sjdp } 136633965Sjdp } 136733965Sjdp} 136833965Sjdp 136933965Sjdp/* Make a section for the debugging information, if any. We don't try 137033965Sjdp to interpret the debugging information; we just point the section 137133965Sjdp at the area in the file so that program which understand can dig it 137233965Sjdp out. */ 137333965Sjdp 137433965Sjdpstatic boolean 137533965Sjdpieee_slurp_debug (abfd) 137633965Sjdp bfd *abfd; 137733965Sjdp{ 137833965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 137933965Sjdp asection *sec; 138060484Sobrien file_ptr debug_end; 138133965Sjdp 138233965Sjdp if (ieee->w.r.debug_information_part == 0) 138333965Sjdp return true; 138433965Sjdp 138533965Sjdp sec = bfd_make_section (abfd, ".debug"); 138633965Sjdp if (sec == NULL) 138733965Sjdp return false; 138833965Sjdp sec->flags |= SEC_DEBUGGING | SEC_HAS_CONTENTS; 138933965Sjdp sec->filepos = ieee->w.r.debug_information_part; 139033965Sjdp 139189857Sobrien debug_end = ieee_part_after (ieee, ieee->w.r.debug_information_part); 139260484Sobrien sec->_raw_size = debug_end - ieee->w.r.debug_information_part; 139360484Sobrien 139433965Sjdp return true; 139533965Sjdp} 139633965Sjdp 139733965Sjdp/*********************************************************************** 139833965Sjdp* archive stuff 139933965Sjdp*/ 140033965Sjdp 140133965Sjdpconst bfd_target * 140233965Sjdpieee_archive_p (abfd) 140333965Sjdp bfd *abfd; 140433965Sjdp{ 140533965Sjdp char *library; 140633965Sjdp unsigned int i; 140733965Sjdp unsigned char buffer[512]; 140833965Sjdp file_ptr buffer_offset = 0; 140933965Sjdp ieee_ar_data_type *save = abfd->tdata.ieee_ar_data; 141033965Sjdp ieee_ar_data_type *ieee; 141189857Sobrien bfd_size_type alc_elts; 141233965Sjdp ieee_ar_obstack_type *elts = NULL; 141389857Sobrien bfd_size_type amt = sizeof (ieee_ar_data_type); 141433965Sjdp 141589857Sobrien abfd->tdata.ieee_ar_data = (ieee_ar_data_type *) bfd_alloc (abfd, amt); 141633965Sjdp if (!abfd->tdata.ieee_ar_data) 1417104834Sobrien goto error_ret_restore; 141833965Sjdp ieee = IEEE_AR_DATA (abfd); 141933965Sjdp 142089857Sobrien /* Ignore the return value here. It doesn't matter if we don't read 142189857Sobrien the entire buffer. We might have a very small ieee file. */ 142289857Sobrien bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd); 142333965Sjdp 142433965Sjdp ieee->h.first_byte = buffer; 142533965Sjdp ieee->h.input_p = buffer; 142633965Sjdp 142733965Sjdp ieee->h.abfd = abfd; 142833965Sjdp 142933965Sjdp if (this_byte (&(ieee->h)) != Module_Beginning) 143077298Sobrien goto got_wrong_format_error; 143133965Sjdp 143233965Sjdp next_byte (&(ieee->h)); 143333965Sjdp library = read_id (&(ieee->h)); 143433965Sjdp if (strcmp (library, "LIBRARY") != 0) 143577298Sobrien goto got_wrong_format_error; 143677298Sobrien 143777298Sobrien /* Throw away the filename. */ 143833965Sjdp read_id (&(ieee->h)); 143933965Sjdp 144033965Sjdp ieee->element_count = 0; 144133965Sjdp ieee->element_index = 0; 144233965Sjdp 144377298Sobrien next_byte (&(ieee->h)); /* Drop the ad part. */ 144477298Sobrien must_parse_int (&(ieee->h)); /* And the two dummy numbers. */ 144533965Sjdp must_parse_int (&(ieee->h)); 144633965Sjdp 144733965Sjdp alc_elts = 10; 144833965Sjdp elts = (ieee_ar_obstack_type *) bfd_malloc (alc_elts * sizeof *elts); 144933965Sjdp if (elts == NULL) 145033965Sjdp goto error_return; 145133965Sjdp 145277298Sobrien /* Read the index of the BB table. */ 145333965Sjdp while (1) 145433965Sjdp { 145533965Sjdp int rec; 145633965Sjdp ieee_ar_obstack_type *t; 145733965Sjdp 145833965Sjdp rec = read_2bytes (&(ieee->h)); 145933965Sjdp if (rec != (int) ieee_assign_value_to_variable_enum) 146033965Sjdp break; 146133965Sjdp 146233965Sjdp if (ieee->element_count >= alc_elts) 146333965Sjdp { 146433965Sjdp ieee_ar_obstack_type *n; 146533965Sjdp 146633965Sjdp alc_elts *= 2; 146733965Sjdp n = ((ieee_ar_obstack_type *) 146833965Sjdp bfd_realloc (elts, alc_elts * sizeof *elts)); 146933965Sjdp if (n == NULL) 147033965Sjdp goto error_return; 147133965Sjdp elts = n; 147233965Sjdp } 147333965Sjdp 147433965Sjdp t = &elts[ieee->element_count]; 147533965Sjdp ieee->element_count++; 147633965Sjdp 147733965Sjdp must_parse_int (&(ieee->h)); 147833965Sjdp t->file_offset = must_parse_int (&(ieee->h)); 147933965Sjdp t->abfd = (bfd *) NULL; 148033965Sjdp 148177298Sobrien /* Make sure that we don't go over the end of the buffer. */ 148289857Sobrien if ((size_t) ieee_pos (IEEE_DATA (abfd)) > sizeof (buffer) / 2) 148333965Sjdp { 148477298Sobrien /* Past half way, reseek and reprime. */ 148589857Sobrien buffer_offset += ieee_pos (IEEE_DATA (abfd)); 148633965Sjdp if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0) 148733965Sjdp goto error_return; 148877298Sobrien 148989857Sobrien /* Again ignore return value of bfd_bread. */ 149089857Sobrien bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd); 149133965Sjdp ieee->h.first_byte = buffer; 149233965Sjdp ieee->h.input_p = buffer; 149333965Sjdp } 149433965Sjdp } 149533965Sjdp 149689857Sobrien amt = ieee->element_count; 149789857Sobrien amt *= sizeof *ieee->elements; 149889857Sobrien ieee->elements = (ieee_ar_obstack_type *) bfd_alloc (abfd, amt); 149933965Sjdp if (ieee->elements == NULL) 150033965Sjdp goto error_return; 150177298Sobrien 150289857Sobrien memcpy (ieee->elements, elts, (size_t) amt); 150333965Sjdp free (elts); 150433965Sjdp elts = NULL; 150533965Sjdp 150677298Sobrien /* Now scan the area again, and replace BB offsets with file offsets. */ 150733965Sjdp for (i = 2; i < ieee->element_count; i++) 150833965Sjdp { 150933965Sjdp if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0) 151033965Sjdp goto error_return; 151177298Sobrien 151289857Sobrien /* Again ignore return value of bfd_bread. */ 151389857Sobrien bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd); 151433965Sjdp ieee->h.first_byte = buffer; 151533965Sjdp ieee->h.input_p = buffer; 151633965Sjdp 151777298Sobrien next_byte (&(ieee->h)); /* Drop F8. */ 151877298Sobrien next_byte (&(ieee->h)); /* Drop 14. */ 151977298Sobrien must_parse_int (&(ieee->h)); /* Drop size of block. */ 152089857Sobrien 152133965Sjdp if (must_parse_int (&(ieee->h)) != 0) 152277298Sobrien /* This object has been deleted. */ 152377298Sobrien ieee->elements[i].file_offset = 0; 152433965Sjdp else 152577298Sobrien ieee->elements[i].file_offset = must_parse_int (&(ieee->h)); 152633965Sjdp } 152733965Sjdp 152833965Sjdp /* abfd->has_armap = ;*/ 152933965Sjdp 153033965Sjdp return abfd->xvec; 153133965Sjdp 153260484Sobrien got_wrong_format_error: 153360484Sobrien bfd_set_error (bfd_error_wrong_format); 153433965Sjdp error_return: 153533965Sjdp if (elts != NULL) 153633965Sjdp free (elts); 1537104834Sobrien bfd_release (abfd, ieee); 1538104834Sobrien error_ret_restore: 1539104834Sobrien abfd->tdata.ieee_ar_data = save; 154077298Sobrien 154133965Sjdp return NULL; 154233965Sjdp} 154333965Sjdp 154433965Sjdpconst bfd_target * 154533965Sjdpieee_object_p (abfd) 154633965Sjdp bfd *abfd; 154733965Sjdp{ 154833965Sjdp char *processor; 154933965Sjdp unsigned int part; 155033965Sjdp ieee_data_type *ieee; 155133965Sjdp unsigned char buffer[300]; 155233965Sjdp ieee_data_type *save = IEEE_DATA (abfd); 155389857Sobrien bfd_size_type amt; 155433965Sjdp 155533965Sjdp abfd->tdata.ieee_data = 0; 155633965Sjdp ieee_mkobject (abfd); 155733965Sjdp 155833965Sjdp ieee = IEEE_DATA (abfd); 155933965Sjdp if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 156033965Sjdp goto fail; 156189857Sobrien /* Read the first few bytes in to see if it makes sense. Ignore 156289857Sobrien bfd_bread return value; The file might be very small. */ 156389857Sobrien bfd_bread ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd); 156433965Sjdp 156533965Sjdp ieee->h.input_p = buffer; 156633965Sjdp if (this_byte_and_next (&(ieee->h)) != Module_Beginning) 156733965Sjdp goto got_wrong_format; 156833965Sjdp 156933965Sjdp ieee->read_symbols = false; 157033965Sjdp ieee->read_data = false; 157133965Sjdp ieee->section_count = 0; 157233965Sjdp ieee->external_symbol_max_index = 0; 157333965Sjdp ieee->external_symbol_min_index = IEEE_PUBLIC_BASE; 157433965Sjdp ieee->external_reference_min_index = IEEE_REFERENCE_BASE; 157533965Sjdp ieee->external_reference_max_index = 0; 157633965Sjdp ieee->h.abfd = abfd; 157733965Sjdp ieee->section_table = NULL; 157833965Sjdp ieee->section_table_size = 0; 157933965Sjdp 158033965Sjdp processor = ieee->mb.processor = read_id (&(ieee->h)); 158133965Sjdp if (strcmp (processor, "LIBRARY") == 0) 158233965Sjdp goto got_wrong_format; 158333965Sjdp ieee->mb.module_name = read_id (&(ieee->h)); 158489857Sobrien if (abfd->filename == (const char *) NULL) 158533965Sjdp { 158633965Sjdp abfd->filename = ieee->mb.module_name; 158733965Sjdp } 158833965Sjdp /* Determine the architecture and machine type of the object file. 158933965Sjdp */ 159033965Sjdp { 159160484Sobrien const bfd_arch_info_type *arch; 159260484Sobrien char family[10]; 159360484Sobrien 159460484Sobrien /* IEEE does not specify the format of the processor identificaton 159560484Sobrien string, so the compiler is free to put in it whatever it wants. 159660484Sobrien We try here to recognize different processors belonging to the 159760484Sobrien m68k family. Code for other processors can be added here. */ 159860484Sobrien if ((processor[0] == '6') && (processor[1] == '8')) 159960484Sobrien { 160060484Sobrien if (processor[2] == '3') /* 683xx integrated processors */ 160160484Sobrien { 160260484Sobrien switch (processor[3]) 160360484Sobrien { 160460484Sobrien case '0': /* 68302, 68306, 68307 */ 160560484Sobrien case '2': /* 68322, 68328 */ 160660484Sobrien case '5': /* 68356 */ 160760484Sobrien strcpy (family, "68000"); /* MC68000-based controllers */ 160860484Sobrien break; 160960484Sobrien 161060484Sobrien case '3': /* 68330, 68331, 68332, 68333, 161160484Sobrien 68334, 68335, 68336, 68338 */ 161260484Sobrien case '6': /* 68360 */ 161360484Sobrien case '7': /* 68376 */ 161460484Sobrien strcpy (family, "68332"); /* CPU32 and CPU32+ */ 161560484Sobrien break; 161660484Sobrien 161760484Sobrien case '4': 161860484Sobrien if (processor[4] == '9') /* 68349 */ 161960484Sobrien strcpy (family, "68030"); /* CPU030 */ 162060484Sobrien else /* 68340, 68341 */ 162160484Sobrien strcpy (family, "68332"); /* CPU32 and CPU32+ */ 162260484Sobrien break; 162360484Sobrien 162460484Sobrien default: /* Does not exist yet */ 162560484Sobrien strcpy (family, "68332"); /* Guess it will be CPU32 */ 162660484Sobrien } 162760484Sobrien } 162889857Sobrien else if (TOUPPER (processor[3]) == 'F') /* 68F333 */ 162989857Sobrien strcpy (family, "68332"); /* CPU32 */ 163089857Sobrien else if ((TOUPPER (processor[3]) == 'C') /* Embedded controllers */ 163189857Sobrien && ((TOUPPER (processor[2]) == 'E') 163289857Sobrien || (TOUPPER (processor[2]) == 'H') 163389857Sobrien || (TOUPPER (processor[2]) == 'L'))) 163460484Sobrien { 163560484Sobrien strcpy (family, "68"); 163660484Sobrien strncat (family, processor + 4, 7); 163760484Sobrien family[9] = '\0'; 163860484Sobrien } 163960484Sobrien else /* "Regular" processors */ 164060484Sobrien { 164160484Sobrien strncpy (family, processor, 9); 164260484Sobrien family[9] = '\0'; 164360484Sobrien } 164460484Sobrien } 164560484Sobrien else if ((strncmp (processor, "cpu32", 5) == 0) /* CPU32 and CPU32+ */ 164660484Sobrien || (strncmp (processor, "CPU32", 5) == 0)) 164760484Sobrien strcpy (family, "68332"); 164860484Sobrien else 164960484Sobrien { 165060484Sobrien strncpy (family, processor, 9); 165160484Sobrien family[9] = '\0'; 165260484Sobrien } 165360484Sobrien 165460484Sobrien arch = bfd_scan_arch (family); 165533965Sjdp if (arch == 0) 165633965Sjdp goto got_wrong_format; 165733965Sjdp abfd->arch_info = arch; 165833965Sjdp } 165933965Sjdp 166033965Sjdp if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum) 166133965Sjdp { 166233965Sjdp goto fail; 166333965Sjdp } 166433965Sjdp next_byte (&(ieee->h)); 166533965Sjdp 1666104834Sobrien if (! parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau)) 166733965Sjdp { 166833965Sjdp goto fail; 166933965Sjdp } 1670104834Sobrien if (! parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address)) 167133965Sjdp { 167233965Sjdp goto fail; 167333965Sjdp } 167433965Sjdp 167533965Sjdp /* If there is a byte order info, take it */ 167633965Sjdp if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum || 167733965Sjdp this_byte (&(ieee->h)) == (int) ieee_variable_M_enum) 167833965Sjdp next_byte (&(ieee->h)); 167933965Sjdp 168033965Sjdp for (part = 0; part < N_W_VARIABLES; part++) 168133965Sjdp { 168233965Sjdp boolean ok; 168333965Sjdp if (read_2bytes (&(ieee->h)) != (int) ieee_assign_value_to_variable_enum) 168433965Sjdp { 168533965Sjdp goto fail; 168633965Sjdp } 168733965Sjdp if (this_byte_and_next (&(ieee->h)) != part) 168833965Sjdp { 168933965Sjdp goto fail; 169033965Sjdp } 169133965Sjdp 169233965Sjdp ieee->w.offset[part] = parse_i (&(ieee->h), &ok); 1693104834Sobrien if (! ok) 169433965Sjdp { 169533965Sjdp goto fail; 169633965Sjdp } 169733965Sjdp 169833965Sjdp } 169933965Sjdp 170033965Sjdp if (ieee->w.r.external_part != 0) 170133965Sjdp abfd->flags = HAS_SYMS; 170233965Sjdp 170333965Sjdp /* By now we know that this is a real IEEE file, we're going to read 170433965Sjdp the whole thing into memory so that we can run up and down it 170533965Sjdp quickly. We can work out how big the file is from the trailer 170633965Sjdp record */ 170733965Sjdp 170889857Sobrien amt = ieee->w.r.me_record + 1; 170933965Sjdp IEEE_DATA (abfd)->h.first_byte = 171089857Sobrien (unsigned char *) bfd_alloc (ieee->h.abfd, amt); 171133965Sjdp if (!IEEE_DATA (abfd)->h.first_byte) 171233965Sjdp goto fail; 171333965Sjdp if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 171433965Sjdp goto fail; 171533965Sjdp /* FIXME: Check return value. I'm not sure whether it needs to read 171633965Sjdp the entire buffer or not. */ 171789857Sobrien bfd_bread ((PTR) (IEEE_DATA (abfd)->h.first_byte), 171889857Sobrien (bfd_size_type) ieee->w.r.me_record + 1, abfd); 171933965Sjdp 172033965Sjdp ieee_slurp_sections (abfd); 172133965Sjdp 172233965Sjdp if (! ieee_slurp_debug (abfd)) 172333965Sjdp goto fail; 172433965Sjdp 172533965Sjdp /* Parse section data to activate file and section flags implied by 172633965Sjdp section contents. */ 172733965Sjdp 172833965Sjdp if (! ieee_slurp_section_data (abfd)) 172933965Sjdp goto fail; 173089857Sobrien 173133965Sjdp return abfd->xvec; 173233965Sjdpgot_wrong_format: 173333965Sjdp bfd_set_error (bfd_error_wrong_format); 173433965Sjdpfail: 1735104834Sobrien bfd_release (abfd, ieee); 173633965Sjdp abfd->tdata.ieee_data = save; 173733965Sjdp return (const bfd_target *) NULL; 173833965Sjdp} 173933965Sjdp 174089857Sobrienstatic void 174133965Sjdpieee_get_symbol_info (ignore_abfd, symbol, ret) 174260484Sobrien bfd *ignore_abfd ATTRIBUTE_UNUSED; 174333965Sjdp asymbol *symbol; 174433965Sjdp symbol_info *ret; 174533965Sjdp{ 174633965Sjdp bfd_symbol_info (symbol, ret); 174733965Sjdp if (symbol->name[0] == ' ') 174833965Sjdp ret->name = "* empty table entry "; 174933965Sjdp if (!symbol->section) 175033965Sjdp ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A'; 175133965Sjdp} 175233965Sjdp 175389857Sobrienstatic void 175489857Sobrienieee_print_symbol (abfd, afile, symbol, how) 175589857Sobrien bfd *abfd; 175633965Sjdp PTR afile; 175733965Sjdp asymbol *symbol; 175833965Sjdp bfd_print_symbol_type how; 175933965Sjdp{ 176033965Sjdp FILE *file = (FILE *) afile; 176133965Sjdp 176233965Sjdp switch (how) 176333965Sjdp { 176433965Sjdp case bfd_print_symbol_name: 176533965Sjdp fprintf (file, "%s", symbol->name); 176633965Sjdp break; 176733965Sjdp case bfd_print_symbol_more: 176833965Sjdp#if 0 176933965Sjdp fprintf (file, "%4x %2x", aout_symbol (symbol)->desc & 0xffff, 177033965Sjdp aout_symbol (symbol)->other & 0xff); 177133965Sjdp#endif 177233965Sjdp BFD_FAIL (); 177333965Sjdp break; 177433965Sjdp case bfd_print_symbol_all: 177533965Sjdp { 177633965Sjdp const char *section_name = 177733965Sjdp (symbol->section == (asection *) NULL 177833965Sjdp ? "*abs" 177933965Sjdp : symbol->section->name); 178033965Sjdp if (symbol->name[0] == ' ') 178133965Sjdp { 178233965Sjdp fprintf (file, "* empty table entry "); 178333965Sjdp } 178433965Sjdp else 178533965Sjdp { 178689857Sobrien bfd_print_symbol_vandf (abfd, (PTR) file, symbol); 178733965Sjdp 178833965Sjdp fprintf (file, " %-5s %04x %02x %s", 178933965Sjdp section_name, 179033965Sjdp (unsigned) ieee_symbol (symbol)->index, 179133965Sjdp (unsigned) 0, 179233965Sjdp symbol->name); 179333965Sjdp } 179433965Sjdp } 179533965Sjdp break; 179633965Sjdp } 179733965Sjdp} 179833965Sjdp 179933965Sjdpstatic boolean 180033965Sjdpdo_one (ieee, current_map, location_ptr, s, iterations) 180133965Sjdp ieee_data_type *ieee; 180233965Sjdp ieee_per_section_type *current_map; 180333965Sjdp unsigned char *location_ptr; 180433965Sjdp asection *s; 180533965Sjdp int iterations; 180633965Sjdp{ 180733965Sjdp switch (this_byte (&(ieee->h))) 180833965Sjdp { 180933965Sjdp case ieee_load_constant_bytes_enum: 181033965Sjdp { 181133965Sjdp unsigned int number_of_maus; 181233965Sjdp unsigned int i; 181333965Sjdp next_byte (&(ieee->h)); 181433965Sjdp number_of_maus = must_parse_int (&(ieee->h)); 181533965Sjdp 181633965Sjdp for (i = 0; i < number_of_maus; i++) 181733965Sjdp { 181833965Sjdp location_ptr[current_map->pc++] = this_byte (&(ieee->h)); 181933965Sjdp next_byte (&(ieee->h)); 182033965Sjdp } 182133965Sjdp } 182233965Sjdp break; 182333965Sjdp 182433965Sjdp case ieee_load_with_relocation_enum: 182533965Sjdp { 182633965Sjdp boolean loop = true; 182733965Sjdp next_byte (&(ieee->h)); 182833965Sjdp while (loop) 182933965Sjdp { 183033965Sjdp switch (this_byte (&(ieee->h))) 183133965Sjdp { 183233965Sjdp case ieee_variable_R_enum: 183333965Sjdp 183433965Sjdp case ieee_function_signed_open_b_enum: 183533965Sjdp case ieee_function_unsigned_open_b_enum: 183633965Sjdp case ieee_function_either_open_b_enum: 183733965Sjdp { 183833965Sjdp unsigned int extra = 4; 183933965Sjdp boolean pcrel = false; 184033965Sjdp asection *section; 184189857Sobrien ieee_reloc_type *r; 184289857Sobrien bfd_size_type amt = sizeof (ieee_reloc_type); 184389857Sobrien 184489857Sobrien r = (ieee_reloc_type *) bfd_alloc (ieee->h.abfd, amt); 184533965Sjdp if (!r) 184633965Sjdp return false; 184733965Sjdp 184833965Sjdp *(current_map->reloc_tail_ptr) = r; 184933965Sjdp current_map->reloc_tail_ptr = &r->next; 185033965Sjdp r->next = (ieee_reloc_type *) NULL; 185133965Sjdp next_byte (&(ieee->h)); 185233965Sjdp/* abort();*/ 185333965Sjdp r->relent.sym_ptr_ptr = 0; 185433965Sjdp parse_expression (ieee, 185533965Sjdp &r->relent.addend, 185633965Sjdp &r->symbol, 185733965Sjdp &pcrel, &extra, §ion); 185833965Sjdp r->relent.address = current_map->pc; 185933965Sjdp s->flags |= SEC_RELOC; 186033965Sjdp s->owner->flags |= HAS_RELOC; 186133965Sjdp s->reloc_count++; 186238889Sjdp if (r->relent.sym_ptr_ptr == NULL && section != NULL) 186338889Sjdp r->relent.sym_ptr_ptr = section->symbol_ptr_ptr; 186433965Sjdp 186533965Sjdp if (this_byte (&(ieee->h)) == (int) ieee_comma) 186633965Sjdp { 186733965Sjdp next_byte (&(ieee->h)); 186833965Sjdp /* Fetch number of bytes to pad */ 186933965Sjdp extra = must_parse_int (&(ieee->h)); 187033965Sjdp }; 187133965Sjdp 187233965Sjdp switch (this_byte (&(ieee->h))) 187333965Sjdp { 187433965Sjdp case ieee_function_signed_close_b_enum: 187533965Sjdp next_byte (&(ieee->h)); 187633965Sjdp break; 187733965Sjdp case ieee_function_unsigned_close_b_enum: 187833965Sjdp next_byte (&(ieee->h)); 187933965Sjdp break; 188033965Sjdp case ieee_function_either_close_b_enum: 188133965Sjdp next_byte (&(ieee->h)); 188233965Sjdp break; 188333965Sjdp default: 188433965Sjdp break; 188533965Sjdp } 188633965Sjdp /* Build a relocation entry for this type */ 188733965Sjdp /* If pc rel then stick -ve pc into instruction 188833965Sjdp and take out of reloc .. 188933965Sjdp 189033965Sjdp I've changed this. It's all too complicated. I 189133965Sjdp keep 0 in the instruction now. */ 189233965Sjdp 189333965Sjdp switch (extra) 189433965Sjdp { 189533965Sjdp case 0: 189633965Sjdp case 4: 189733965Sjdp 1898104834Sobrien if (pcrel) 189933965Sjdp { 190033965Sjdp#if KEEPMINUSPCININST 190189857Sobrien bfd_put_32 (ieee->h.abfd, -current_map->pc, 190289857Sobrien location_ptr + current_map->pc); 190333965Sjdp r->relent.howto = &rel32_howto; 190489857Sobrien r->relent.addend -= current_map->pc; 190533965Sjdp#else 190689857Sobrien bfd_put_32 (ieee->h.abfd, (bfd_vma) 0, location_ptr + 190733965Sjdp current_map->pc); 190833965Sjdp r->relent.howto = &rel32_howto; 190933965Sjdp#endif 191033965Sjdp } 191133965Sjdp else 191233965Sjdp { 191389857Sobrien bfd_put_32 (ieee->h.abfd, (bfd_vma) 0, 191489857Sobrien location_ptr + current_map->pc); 191533965Sjdp r->relent.howto = &abs32_howto; 191633965Sjdp } 191733965Sjdp current_map->pc += 4; 191833965Sjdp break; 191933965Sjdp case 2: 1920104834Sobrien if (pcrel) 192133965Sjdp { 192233965Sjdp#if KEEPMINUSPCININST 192389857Sobrien bfd_put_16 (ieee->h.abfd, (bfd_vma) -current_map->pc, 192489857Sobrien location_ptr + current_map->pc); 192533965Sjdp r->relent.addend -= current_map->pc; 192633965Sjdp r->relent.howto = &rel16_howto; 192733965Sjdp#else 192833965Sjdp 192989857Sobrien bfd_put_16 (ieee->h.abfd, (bfd_vma) 0, 193089857Sobrien location_ptr + current_map->pc); 193133965Sjdp r->relent.howto = &rel16_howto; 193233965Sjdp#endif 193333965Sjdp } 193433965Sjdp 193533965Sjdp else 193633965Sjdp { 193789857Sobrien bfd_put_16 (ieee->h.abfd, (bfd_vma) 0, 193889857Sobrien location_ptr + current_map->pc); 193933965Sjdp r->relent.howto = &abs16_howto; 194033965Sjdp } 194133965Sjdp current_map->pc += 2; 194233965Sjdp break; 194333965Sjdp case 1: 1944104834Sobrien if (pcrel) 194533965Sjdp { 194633965Sjdp#if KEEPMINUSPCININST 194733965Sjdp bfd_put_8 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc); 194833965Sjdp r->relent.addend -= current_map->pc; 194933965Sjdp r->relent.howto = &rel8_howto; 195033965Sjdp#else 195133965Sjdp bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc); 195233965Sjdp r->relent.howto = &rel8_howto; 195333965Sjdp#endif 195433965Sjdp } 195533965Sjdp else 195633965Sjdp { 195733965Sjdp bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc); 195833965Sjdp r->relent.howto = &abs8_howto; 195933965Sjdp } 196033965Sjdp current_map->pc += 1; 196133965Sjdp break; 196233965Sjdp 196333965Sjdp default: 196433965Sjdp BFD_FAIL (); 196533965Sjdp return false; 196633965Sjdp } 196733965Sjdp } 196833965Sjdp break; 196933965Sjdp default: 197033965Sjdp { 197133965Sjdp bfd_vma this_size; 1972104834Sobrien if (parse_int (&(ieee->h), &this_size)) 197333965Sjdp { 197433965Sjdp unsigned int i; 197533965Sjdp for (i = 0; i < this_size; i++) 197633965Sjdp { 197733965Sjdp location_ptr[current_map->pc++] = this_byte (&(ieee->h)); 197833965Sjdp next_byte (&(ieee->h)); 197933965Sjdp } 198033965Sjdp } 198133965Sjdp else 198233965Sjdp { 198333965Sjdp loop = false; 198433965Sjdp } 198533965Sjdp } 198633965Sjdp } 198733965Sjdp 198833965Sjdp /* Prevent more than the first load-item of an LR record 198933965Sjdp from being repeated (MRI convention). */ 199033965Sjdp if (iterations != 1) 199133965Sjdp loop = false; 199233965Sjdp } 199333965Sjdp } 199433965Sjdp } 199533965Sjdp return true; 199633965Sjdp} 199733965Sjdp 199833965Sjdp/* Read in all the section data and relocation stuff too */ 199933965Sjdpstatic boolean 200033965Sjdpieee_slurp_section_data (abfd) 200133965Sjdp bfd *abfd; 200233965Sjdp{ 200333965Sjdp bfd_byte *location_ptr = (bfd_byte *) NULL; 200433965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 200533965Sjdp unsigned int section_number; 200633965Sjdp 200733965Sjdp ieee_per_section_type *current_map = (ieee_per_section_type *) NULL; 200833965Sjdp asection *s; 200933965Sjdp /* Seek to the start of the data area */ 2010104834Sobrien if (ieee->read_data) 201133965Sjdp return true; 201233965Sjdp ieee->read_data = true; 201389857Sobrien ieee_seek (ieee, ieee->w.r.data_part); 201433965Sjdp 201533965Sjdp /* Allocate enough space for all the section contents */ 201633965Sjdp 201733965Sjdp for (s = abfd->sections; s != (asection *) NULL; s = s->next) 201833965Sjdp { 201933965Sjdp ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd; 202033965Sjdp if ((s->flags & SEC_DEBUGGING) != 0) 202133965Sjdp continue; 202233965Sjdp per->data = (bfd_byte *) bfd_alloc (ieee->h.abfd, s->_raw_size); 202333965Sjdp if (!per->data) 202433965Sjdp return false; 202533965Sjdp /*SUPPRESS 68*/ 202633965Sjdp per->reloc_tail_ptr = 202733965Sjdp (ieee_reloc_type **) & (s->relocation); 202833965Sjdp } 202933965Sjdp 203033965Sjdp while (true) 203133965Sjdp { 203233965Sjdp switch (this_byte (&(ieee->h))) 203333965Sjdp { 203433965Sjdp /* IF we see anything strange then quit */ 203533965Sjdp default: 203633965Sjdp return true; 203733965Sjdp 203833965Sjdp case ieee_set_current_section_enum: 203933965Sjdp next_byte (&(ieee->h)); 204033965Sjdp section_number = must_parse_int (&(ieee->h)); 204133965Sjdp s = ieee->section_table[section_number]; 204233965Sjdp s->flags |= SEC_LOAD | SEC_HAS_CONTENTS; 204333965Sjdp current_map = (ieee_per_section_type *) s->used_by_bfd; 204433965Sjdp location_ptr = current_map->data - s->vma; 204533965Sjdp /* The document I have says that Microtec's compilers reset */ 204633965Sjdp /* this after a sec section, even though the standard says not */ 204733965Sjdp /* to. SO .. */ 204833965Sjdp current_map->pc = s->vma; 204933965Sjdp break; 205033965Sjdp 205133965Sjdp case ieee_e2_first_byte_enum: 205233965Sjdp next_byte (&(ieee->h)); 205333965Sjdp switch (this_byte (&(ieee->h))) 205433965Sjdp { 205533965Sjdp case ieee_set_current_pc_enum & 0xff: 205633965Sjdp { 205733965Sjdp bfd_vma value; 205833965Sjdp ieee_symbol_index_type symbol; 205933965Sjdp unsigned int extra; 206033965Sjdp boolean pcrel; 206133965Sjdp next_byte (&(ieee->h)); 206289857Sobrien must_parse_int (&(ieee->h)); /* Throw away section #*/ 206333965Sjdp parse_expression (ieee, &value, 206433965Sjdp &symbol, 206533965Sjdp &pcrel, &extra, 206633965Sjdp 0); 206733965Sjdp current_map->pc = value; 206833965Sjdp BFD_ASSERT ((unsigned) (value - s->vma) <= s->_raw_size); 206933965Sjdp } 207033965Sjdp break; 207133965Sjdp 207233965Sjdp case ieee_value_starting_address_enum & 0xff: 207333965Sjdp next_byte (&(ieee->h)); 207433965Sjdp if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum) 207533965Sjdp next_byte (&(ieee->h)); 207633965Sjdp abfd->start_address = must_parse_int (&(ieee->h)); 207733965Sjdp /* We've got to the end of the data now - */ 207833965Sjdp return true; 207933965Sjdp default: 208033965Sjdp BFD_FAIL (); 208133965Sjdp return false; 208233965Sjdp } 208333965Sjdp break; 208433965Sjdp case ieee_repeat_data_enum: 208533965Sjdp { 208633965Sjdp /* Repeat the following LD or LR n times - we do this by 208733965Sjdp remembering the stream pointer before running it and 208833965Sjdp resetting it and running it n times. We special case 208933965Sjdp the repetition of a repeat_data/load_constant 209033965Sjdp */ 209133965Sjdp 209233965Sjdp unsigned int iterations; 209333965Sjdp unsigned char *start; 209433965Sjdp next_byte (&(ieee->h)); 209533965Sjdp iterations = must_parse_int (&(ieee->h)); 209633965Sjdp start = ieee->h.input_p; 209733965Sjdp if (start[0] == (int) ieee_load_constant_bytes_enum && 209833965Sjdp start[1] == 1) 209933965Sjdp { 210033965Sjdp while (iterations != 0) 210133965Sjdp { 210233965Sjdp location_ptr[current_map->pc++] = start[2]; 210333965Sjdp iterations--; 210433965Sjdp } 210533965Sjdp next_byte (&(ieee->h)); 210633965Sjdp next_byte (&(ieee->h)); 210733965Sjdp next_byte (&(ieee->h)); 210833965Sjdp } 210933965Sjdp else 211033965Sjdp { 211133965Sjdp while (iterations != 0) 211233965Sjdp { 211333965Sjdp ieee->h.input_p = start; 211433965Sjdp if (!do_one (ieee, current_map, location_ptr, s, 211589857Sobrien (int) iterations)) 211633965Sjdp return false; 211733965Sjdp iterations--; 211833965Sjdp } 211933965Sjdp } 212033965Sjdp } 212133965Sjdp break; 212233965Sjdp case ieee_load_constant_bytes_enum: 212333965Sjdp case ieee_load_with_relocation_enum: 212433965Sjdp { 212533965Sjdp if (!do_one (ieee, current_map, location_ptr, s, 1)) 212633965Sjdp return false; 212733965Sjdp } 212833965Sjdp } 212933965Sjdp } 213033965Sjdp} 213133965Sjdp 213289857Sobrienstatic boolean 213333965Sjdpieee_new_section_hook (abfd, newsect) 213433965Sjdp bfd *abfd; 213533965Sjdp asection *newsect; 213633965Sjdp{ 213733965Sjdp newsect->used_by_bfd = (PTR) 213889857Sobrien bfd_alloc (abfd, (bfd_size_type) sizeof (ieee_per_section_type)); 213933965Sjdp if (!newsect->used_by_bfd) 214033965Sjdp return false; 214133965Sjdp ieee_per_section (newsect)->data = (bfd_byte *) NULL; 214233965Sjdp ieee_per_section (newsect)->section = newsect; 214333965Sjdp return true; 214433965Sjdp} 214533965Sjdp 214689857Sobrienstatic long 214733965Sjdpieee_get_reloc_upper_bound (abfd, asect) 214833965Sjdp bfd *abfd; 214933965Sjdp sec_ptr asect; 215033965Sjdp{ 215133965Sjdp if ((asect->flags & SEC_DEBUGGING) != 0) 215233965Sjdp return 0; 215333965Sjdp if (! ieee_slurp_section_data (abfd)) 215433965Sjdp return -1; 215533965Sjdp return (asect->reloc_count + 1) * sizeof (arelent *); 215633965Sjdp} 215733965Sjdp 215833965Sjdpstatic boolean 215933965Sjdpieee_get_section_contents (abfd, section, location, offset, count) 216033965Sjdp bfd *abfd; 216133965Sjdp sec_ptr section; 216233965Sjdp PTR location; 216333965Sjdp file_ptr offset; 216433965Sjdp bfd_size_type count; 216533965Sjdp{ 216633965Sjdp ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd; 216733965Sjdp if ((section->flags & SEC_DEBUGGING) != 0) 216833965Sjdp return _bfd_generic_get_section_contents (abfd, section, location, 216933965Sjdp offset, count); 217033965Sjdp ieee_slurp_section_data (abfd); 217133965Sjdp (void) memcpy ((PTR) location, (PTR) (p->data + offset), (unsigned) count); 217233965Sjdp return true; 217333965Sjdp} 217433965Sjdp 217589857Sobrienstatic long 217633965Sjdpieee_canonicalize_reloc (abfd, section, relptr, symbols) 217733965Sjdp bfd *abfd; 217833965Sjdp sec_ptr section; 217933965Sjdp arelent **relptr; 218033965Sjdp asymbol **symbols; 218133965Sjdp{ 218233965Sjdp/* ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;*/ 218333965Sjdp ieee_reloc_type *src = (ieee_reloc_type *) (section->relocation); 218433965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 218533965Sjdp 218633965Sjdp if ((section->flags & SEC_DEBUGGING) != 0) 218733965Sjdp return 0; 218833965Sjdp 218933965Sjdp while (src != (ieee_reloc_type *) NULL) 219033965Sjdp { 219133965Sjdp /* Work out which symbol to attach it this reloc to */ 219233965Sjdp switch (src->symbol.letter) 219333965Sjdp { 219433965Sjdp case 'I': 219533965Sjdp src->relent.sym_ptr_ptr = 219633965Sjdp symbols + src->symbol.index + ieee->external_symbol_base_offset; 219733965Sjdp break; 219833965Sjdp case 'X': 219933965Sjdp src->relent.sym_ptr_ptr = 220033965Sjdp symbols + src->symbol.index + ieee->external_reference_base_offset; 220133965Sjdp break; 220233965Sjdp case 0: 220338889Sjdp if (src->relent.sym_ptr_ptr != NULL) 220438889Sjdp src->relent.sym_ptr_ptr = 220538889Sjdp src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr; 220633965Sjdp break; 220733965Sjdp default: 220833965Sjdp 220933965Sjdp BFD_FAIL (); 221033965Sjdp } 221133965Sjdp *relptr++ = &src->relent; 221233965Sjdp src = src->next; 221333965Sjdp } 221433965Sjdp *relptr = (arelent *) NULL; 221533965Sjdp return section->reloc_count; 221633965Sjdp} 221733965Sjdp 221833965Sjdpstatic int 221933965Sjdpcomp (ap, bp) 222089857Sobrien const PTR ap; 222189857Sobrien const PTR bp; 222233965Sjdp{ 222333965Sjdp arelent *a = *((arelent **) ap); 222433965Sjdp arelent *b = *((arelent **) bp); 222533965Sjdp return a->address - b->address; 222633965Sjdp} 222733965Sjdp 222833965Sjdp/* Write the section headers. */ 222933965Sjdp 223033965Sjdpstatic boolean 223133965Sjdpieee_write_section_part (abfd) 223233965Sjdp bfd *abfd; 223333965Sjdp{ 223433965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 223533965Sjdp asection *s; 223633965Sjdp ieee->w.r.section_part = bfd_tell (abfd); 223733965Sjdp for (s = abfd->sections; s != (asection *) NULL; s = s->next) 223833965Sjdp { 223933965Sjdp if (! bfd_is_abs_section (s) 224033965Sjdp && (s->flags & SEC_DEBUGGING) == 0) 224133965Sjdp { 224233965Sjdp if (! ieee_write_byte (abfd, ieee_section_type_enum) 224333965Sjdp || ! ieee_write_byte (abfd, 224433965Sjdp (bfd_byte) (s->index 224533965Sjdp + IEEE_SECTION_NUMBER_BASE))) 224633965Sjdp return false; 224733965Sjdp 224833965Sjdp if (abfd->flags & EXEC_P) 224933965Sjdp { 225033965Sjdp /* This image is executable, so output absolute sections */ 225133965Sjdp if (! ieee_write_byte (abfd, ieee_variable_A_enum) 225233965Sjdp || ! ieee_write_byte (abfd, ieee_variable_S_enum)) 225333965Sjdp return false; 225433965Sjdp } 225533965Sjdp else 225633965Sjdp { 225733965Sjdp if (! ieee_write_byte (abfd, ieee_variable_C_enum)) 225833965Sjdp return false; 225933965Sjdp } 226033965Sjdp 226133965Sjdp switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM)) 226233965Sjdp { 226333965Sjdp case SEC_CODE | SEC_LOAD: 226433965Sjdp case SEC_CODE: 226533965Sjdp if (! ieee_write_byte (abfd, ieee_variable_P_enum)) 226633965Sjdp return false; 226733965Sjdp break; 226833965Sjdp case SEC_DATA: 226933965Sjdp default: 227033965Sjdp if (! ieee_write_byte (abfd, ieee_variable_D_enum)) 227133965Sjdp return false; 227233965Sjdp break; 227333965Sjdp case SEC_ROM: 227433965Sjdp case SEC_ROM | SEC_DATA: 227533965Sjdp case SEC_ROM | SEC_LOAD: 227633965Sjdp case SEC_ROM | SEC_DATA | SEC_LOAD: 227733965Sjdp if (! ieee_write_byte (abfd, ieee_variable_R_enum)) 227833965Sjdp return false; 227933965Sjdp } 228033965Sjdp 228133965Sjdp 228233965Sjdp if (! ieee_write_id (abfd, s->name)) 228333965Sjdp return false; 228433965Sjdp#if 0 228533965Sjdp ieee_write_int (abfd, 0); /* Parent */ 228633965Sjdp ieee_write_int (abfd, 0); /* Brother */ 228733965Sjdp ieee_write_int (abfd, 0); /* Context */ 228833965Sjdp#endif 228933965Sjdp /* Alignment */ 229033965Sjdp if (! ieee_write_byte (abfd, ieee_section_alignment_enum) 229133965Sjdp || ! ieee_write_byte (abfd, 229233965Sjdp (bfd_byte) (s->index 229333965Sjdp + IEEE_SECTION_NUMBER_BASE)) 229489857Sobrien || ! ieee_write_int (abfd, (bfd_vma) 1 << s->alignment_power)) 229533965Sjdp return false; 229633965Sjdp 229733965Sjdp /* Size */ 229833965Sjdp if (! ieee_write_2bytes (abfd, ieee_section_size_enum) 229933965Sjdp || ! ieee_write_byte (abfd, 230033965Sjdp (bfd_byte) (s->index 230133965Sjdp + IEEE_SECTION_NUMBER_BASE)) 230233965Sjdp || ! ieee_write_int (abfd, s->_raw_size)) 230333965Sjdp return false; 230433965Sjdp if (abfd->flags & EXEC_P) 230533965Sjdp { 230633965Sjdp /* Relocateable sections don't have asl records */ 230733965Sjdp /* Vma */ 230833965Sjdp if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum) 230933965Sjdp || ! ieee_write_byte (abfd, 231033965Sjdp ((bfd_byte) 231133965Sjdp (s->index 231233965Sjdp + IEEE_SECTION_NUMBER_BASE))) 231333965Sjdp || ! ieee_write_int (abfd, s->lma)) 231433965Sjdp return false; 231533965Sjdp } 231633965Sjdp } 231733965Sjdp } 231833965Sjdp 231933965Sjdp return true; 232033965Sjdp} 232133965Sjdp 232233965Sjdp 232333965Sjdpstatic boolean 232433965Sjdpdo_with_relocs (abfd, s) 232533965Sjdp bfd *abfd; 232633965Sjdp asection *s; 232733965Sjdp{ 232833965Sjdp unsigned int number_of_maus_in_address = 232933965Sjdp bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd); 233033965Sjdp unsigned int relocs_to_go = s->reloc_count; 233133965Sjdp bfd_byte *stream = ieee_per_section (s)->data; 233233965Sjdp arelent **p = s->orelocation; 233333965Sjdp bfd_size_type current_byte_index = 0; 233433965Sjdp 233533965Sjdp qsort (s->orelocation, 233633965Sjdp relocs_to_go, 233733965Sjdp sizeof (arelent **), 233833965Sjdp comp); 233933965Sjdp 234033965Sjdp /* Output the section preheader */ 234133965Sjdp if (! ieee_write_byte (abfd, ieee_set_current_section_enum) 234233965Sjdp || ! ieee_write_byte (abfd, 234333965Sjdp (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)) 234433965Sjdp || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum) 234533965Sjdp || ! ieee_write_byte (abfd, 234633965Sjdp (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))) 234733965Sjdp return false; 234889857Sobrien 234933965Sjdp if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0) 235033965Sjdp { 235133965Sjdp if (! ieee_write_int (abfd, s->lma)) 235233965Sjdp return false; 235333965Sjdp } 235433965Sjdp else 235533965Sjdp { 235689857Sobrien if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0)) 235733965Sjdp return false; 235833965Sjdp } 235933965Sjdp 236033965Sjdp if (relocs_to_go == 0) 236133965Sjdp { 236233965Sjdp /* If there aren't any relocations then output the load constant 236333965Sjdp byte opcode rather than the load with relocation opcode */ 236433965Sjdp 236533965Sjdp while (current_byte_index < s->_raw_size) 236633965Sjdp { 236733965Sjdp bfd_size_type run; 236833965Sjdp unsigned int MAXRUN = 127; 236933965Sjdp run = MAXRUN; 237033965Sjdp if (run > s->_raw_size - current_byte_index) 237133965Sjdp { 237233965Sjdp run = s->_raw_size - current_byte_index; 237333965Sjdp } 237433965Sjdp 237533965Sjdp if (run != 0) 237633965Sjdp { 237733965Sjdp if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)) 237833965Sjdp return false; 237933965Sjdp /* Output a stream of bytes */ 238033965Sjdp if (! ieee_write_int (abfd, run)) 238133965Sjdp return false; 238289857Sobrien if (bfd_bwrite ((PTR) (stream + current_byte_index), run, abfd) 238333965Sjdp != run) 238433965Sjdp return false; 238533965Sjdp current_byte_index += run; 238633965Sjdp } 238733965Sjdp } 238833965Sjdp } 238933965Sjdp else 239033965Sjdp { 239133965Sjdp if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum)) 239233965Sjdp return false; 239333965Sjdp 239433965Sjdp /* Output the data stream as the longest sequence of bytes 239533965Sjdp possible, allowing for the a reasonable packet size and 239633965Sjdp relocation stuffs. */ 239733965Sjdp 239833965Sjdp if ((PTR) stream == (PTR) NULL) 239933965Sjdp { 240033965Sjdp /* Outputting a section without data, fill it up */ 2401104834Sobrien stream = (unsigned char *) bfd_zalloc (abfd, s->_raw_size); 240233965Sjdp if (!stream) 240333965Sjdp return false; 240433965Sjdp } 240533965Sjdp while (current_byte_index < s->_raw_size) 240633965Sjdp { 240733965Sjdp bfd_size_type run; 240833965Sjdp unsigned int MAXRUN = 127; 240933965Sjdp if (relocs_to_go) 241033965Sjdp { 241133965Sjdp run = (*p)->address - current_byte_index; 241233965Sjdp if (run > MAXRUN) 241333965Sjdp run = MAXRUN; 241433965Sjdp } 241533965Sjdp else 241633965Sjdp { 241733965Sjdp run = MAXRUN; 241833965Sjdp } 241933965Sjdp if (run > s->_raw_size - current_byte_index) 242033965Sjdp { 242133965Sjdp run = s->_raw_size - current_byte_index; 242233965Sjdp } 242333965Sjdp 242433965Sjdp if (run != 0) 242533965Sjdp { 242633965Sjdp /* Output a stream of bytes */ 242733965Sjdp if (! ieee_write_int (abfd, run)) 242833965Sjdp return false; 242989857Sobrien if (bfd_bwrite ((PTR) (stream + current_byte_index), run, abfd) 243033965Sjdp != run) 243133965Sjdp return false; 243233965Sjdp current_byte_index += run; 243333965Sjdp } 243433965Sjdp /* Output any relocations here */ 243533965Sjdp if (relocs_to_go && (*p) && (*p)->address == current_byte_index) 243633965Sjdp { 243733965Sjdp while (relocs_to_go 243833965Sjdp && (*p) && (*p)->address == current_byte_index) 243933965Sjdp { 244033965Sjdp arelent *r = *p; 244133965Sjdp bfd_signed_vma ov; 244233965Sjdp 244333965Sjdp#if 0 244433965Sjdp if (r->howto->pc_relative) 244533965Sjdp { 244633965Sjdp r->addend += current_byte_index; 244733965Sjdp } 244833965Sjdp#endif 244933965Sjdp 245033965Sjdp switch (r->howto->size) 245133965Sjdp { 245233965Sjdp case 2: 245333965Sjdp 245433965Sjdp ov = bfd_get_signed_32 (abfd, 245533965Sjdp stream + current_byte_index); 245633965Sjdp current_byte_index += 4; 245733965Sjdp break; 245833965Sjdp case 1: 245933965Sjdp ov = bfd_get_signed_16 (abfd, 246033965Sjdp stream + current_byte_index); 246133965Sjdp current_byte_index += 2; 246233965Sjdp break; 246333965Sjdp case 0: 246433965Sjdp ov = bfd_get_signed_8 (abfd, 246533965Sjdp stream + current_byte_index); 246633965Sjdp current_byte_index++; 246733965Sjdp break; 246833965Sjdp default: 246933965Sjdp ov = 0; 247033965Sjdp BFD_FAIL (); 247133965Sjdp return false; 247233965Sjdp } 247333965Sjdp 247433965Sjdp ov &= r->howto->src_mask; 247533965Sjdp 247633965Sjdp if (r->howto->pc_relative 247733965Sjdp && ! r->howto->pcrel_offset) 247833965Sjdp ov += r->address; 247933965Sjdp 248033965Sjdp if (! ieee_write_byte (abfd, 248133965Sjdp ieee_function_either_open_b_enum)) 248233965Sjdp return false; 248333965Sjdp 248433965Sjdp/* abort();*/ 248533965Sjdp 248633965Sjdp if (r->sym_ptr_ptr != (asymbol **) NULL) 248733965Sjdp { 248833965Sjdp if (! ieee_write_expression (abfd, r->addend + ov, 248933965Sjdp *(r->sym_ptr_ptr), 249033965Sjdp r->howto->pc_relative, 249189857Sobrien (unsigned) s->index)) 249233965Sjdp return false; 249333965Sjdp } 249433965Sjdp else 249533965Sjdp { 249633965Sjdp if (! ieee_write_expression (abfd, r->addend + ov, 249733965Sjdp (asymbol *) NULL, 249833965Sjdp r->howto->pc_relative, 249989857Sobrien (unsigned) s->index)) 250033965Sjdp return false; 250133965Sjdp } 250233965Sjdp 250333965Sjdp if (number_of_maus_in_address 250433965Sjdp != bfd_get_reloc_size (r->howto)) 250533965Sjdp { 250689857Sobrien bfd_vma rsize = bfd_get_reloc_size (r->howto); 250789857Sobrien if (! ieee_write_int (abfd, rsize)) 250833965Sjdp return false; 250933965Sjdp } 251033965Sjdp if (! ieee_write_byte (abfd, 251133965Sjdp ieee_function_either_close_b_enum)) 251233965Sjdp return false; 251333965Sjdp 251433965Sjdp relocs_to_go--; 251533965Sjdp p++; 251633965Sjdp } 251733965Sjdp 251833965Sjdp } 251933965Sjdp } 252033965Sjdp } 252133965Sjdp 252233965Sjdp return true; 252333965Sjdp} 252433965Sjdp 252533965Sjdp/* If there are no relocations in the output section then we can be 252633965Sjdp clever about how we write. We block items up into a max of 127 252733965Sjdp bytes. */ 252833965Sjdp 252933965Sjdpstatic boolean 253033965Sjdpdo_as_repeat (abfd, s) 253133965Sjdp bfd *abfd; 253233965Sjdp asection *s; 253333965Sjdp{ 253433965Sjdp if (s->_raw_size) 253533965Sjdp { 253633965Sjdp if (! ieee_write_byte (abfd, ieee_set_current_section_enum) 253733965Sjdp || ! ieee_write_byte (abfd, 253833965Sjdp (bfd_byte) (s->index 253933965Sjdp + IEEE_SECTION_NUMBER_BASE)) 254033965Sjdp || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8) 254133965Sjdp || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff) 254233965Sjdp || ! ieee_write_byte (abfd, 254333965Sjdp (bfd_byte) (s->index 254489857Sobrien + IEEE_SECTION_NUMBER_BASE))) 254589857Sobrien return false; 254689857Sobrien 254789857Sobrien if ((abfd->flags & EXEC_P) != 0) 254889857Sobrien { 254989857Sobrien if (! ieee_write_int (abfd, s->lma)) 255089857Sobrien return false; 255189857Sobrien } 255289857Sobrien else 255389857Sobrien { 255489857Sobrien if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0)) 255589857Sobrien return false; 255689857Sobrien } 255789857Sobrien 255889857Sobrien if (! ieee_write_byte (abfd, ieee_repeat_data_enum) 255933965Sjdp || ! ieee_write_int (abfd, s->_raw_size) 256033965Sjdp || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum) 256133965Sjdp || ! ieee_write_byte (abfd, 1) 256233965Sjdp || ! ieee_write_byte (abfd, 0)) 256333965Sjdp return false; 256433965Sjdp } 256533965Sjdp 256633965Sjdp return true; 256733965Sjdp} 256833965Sjdp 256933965Sjdpstatic boolean 257033965Sjdpdo_without_relocs (abfd, s) 257133965Sjdp bfd *abfd; 257233965Sjdp asection *s; 257333965Sjdp{ 257433965Sjdp bfd_byte *stream = ieee_per_section (s)->data; 257533965Sjdp 257633965Sjdp if (stream == 0 || ((s->flags & SEC_LOAD) == 0)) 257733965Sjdp { 257833965Sjdp if (! do_as_repeat (abfd, s)) 257933965Sjdp return false; 258033965Sjdp } 258133965Sjdp else 258233965Sjdp { 258333965Sjdp unsigned int i; 258433965Sjdp for (i = 0; i < s->_raw_size; i++) 258533965Sjdp { 258633965Sjdp if (stream[i] != 0) 258733965Sjdp { 258833965Sjdp if (! do_with_relocs (abfd, s)) 258933965Sjdp return false; 259033965Sjdp return true; 259133965Sjdp } 259233965Sjdp } 259333965Sjdp if (! do_as_repeat (abfd, s)) 259433965Sjdp return false; 259533965Sjdp } 259633965Sjdp 259733965Sjdp return true; 259833965Sjdp} 259933965Sjdp 260033965Sjdp 260133965Sjdpstatic unsigned char *output_ptr_start; 260233965Sjdpstatic unsigned char *output_ptr; 260333965Sjdpstatic unsigned char *output_ptr_end; 260433965Sjdpstatic unsigned char *input_ptr_start; 260533965Sjdpstatic unsigned char *input_ptr; 260633965Sjdpstatic unsigned char *input_ptr_end; 260733965Sjdpstatic bfd *input_bfd; 260833965Sjdpstatic bfd *output_bfd; 260933965Sjdpstatic int output_buffer; 261033965Sjdp 261189857Sobrienstatic boolean 261289857Sobrienieee_mkobject (abfd) 261389857Sobrien bfd *abfd; 261489857Sobrien{ 261589857Sobrien bfd_size_type amt; 261689857Sobrien 261789857Sobrien output_ptr_start = NULL; 261889857Sobrien output_ptr = NULL; 261989857Sobrien output_ptr_end = NULL; 262089857Sobrien input_ptr_start = NULL; 262189857Sobrien input_ptr = NULL; 262289857Sobrien input_ptr_end = NULL; 262389857Sobrien input_bfd = NULL; 262489857Sobrien output_bfd = NULL; 262589857Sobrien output_buffer = 0; 262689857Sobrien amt = sizeof (ieee_data_type); 262789857Sobrien abfd->tdata.ieee_data = (ieee_data_type *) bfd_zalloc (abfd, amt); 2628104834Sobrien return abfd->tdata.ieee_data != NULL; 262989857Sobrien} 263089857Sobrien 263133965Sjdpstatic void 263233965Sjdpfill () 263333965Sjdp{ 263489857Sobrien bfd_size_type amt = input_ptr_end - input_ptr_start; 263533965Sjdp /* FIXME: Check return value. I'm not sure whether it needs to read 263633965Sjdp the entire buffer or not. */ 263789857Sobrien bfd_bread ((PTR) input_ptr_start, amt, input_bfd); 263833965Sjdp input_ptr = input_ptr_start; 263933965Sjdp} 264089857Sobrien 264133965Sjdpstatic void 264233965Sjdpflush () 264333965Sjdp{ 264489857Sobrien bfd_size_type amt = output_ptr - output_ptr_start; 264589857Sobrien if (bfd_bwrite ((PTR) (output_ptr_start), amt, output_bfd) != amt) 264633965Sjdp abort (); 264733965Sjdp output_ptr = output_ptr_start; 264833965Sjdp output_buffer++; 264933965Sjdp} 265033965Sjdp 265133965Sjdp#define THIS() ( *input_ptr ) 265233965Sjdp#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); } 265333965Sjdp#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end) flush(); } 265433965Sjdp 265533965Sjdpstatic void 265633965Sjdpwrite_int (value) 265733965Sjdp int value; 265833965Sjdp{ 265933965Sjdp if (value >= 0 && value <= 127) 266033965Sjdp { 266133965Sjdp OUT (value); 266233965Sjdp } 266333965Sjdp else 266433965Sjdp { 266533965Sjdp unsigned int length; 266633965Sjdp /* How many significant bytes ? */ 266733965Sjdp /* FIXME FOR LONGER INTS */ 266833965Sjdp if (value & 0xff000000) 266933965Sjdp { 267033965Sjdp length = 4; 267133965Sjdp } 267233965Sjdp else if (value & 0x00ff0000) 267333965Sjdp { 267433965Sjdp length = 3; 267533965Sjdp } 267633965Sjdp else if (value & 0x0000ff00) 267733965Sjdp { 267833965Sjdp length = 2; 267933965Sjdp } 268033965Sjdp else 268133965Sjdp length = 1; 268233965Sjdp 268333965Sjdp OUT ((int) ieee_number_repeat_start_enum + length); 268433965Sjdp switch (length) 268533965Sjdp { 268633965Sjdp case 4: 268733965Sjdp OUT (value >> 24); 268833965Sjdp case 3: 268933965Sjdp OUT (value >> 16); 269033965Sjdp case 2: 269133965Sjdp OUT (value >> 8); 269233965Sjdp case 1: 269333965Sjdp OUT (value); 269433965Sjdp } 269533965Sjdp 269633965Sjdp } 269733965Sjdp} 269833965Sjdp 269933965Sjdpstatic void 270033965Sjdpcopy_id () 270133965Sjdp{ 270233965Sjdp int length = THIS (); 270333965Sjdp char ch; 270433965Sjdp OUT (length); 270533965Sjdp NEXT (); 270633965Sjdp while (length--) 270733965Sjdp { 270833965Sjdp ch = THIS (); 270933965Sjdp OUT (ch); 271033965Sjdp NEXT (); 271133965Sjdp } 271233965Sjdp} 271333965Sjdp 271433965Sjdp#define VAR(x) ((x | 0x80)) 271533965Sjdpstatic void 271633965Sjdpcopy_expression () 271733965Sjdp{ 271833965Sjdp int stack[10]; 271933965Sjdp int *tos = stack; 272089857Sobrien int value; 272133965Sjdp while (1) 272233965Sjdp { 272333965Sjdp switch (THIS ()) 272433965Sjdp { 272533965Sjdp case 0x84: 272633965Sjdp NEXT (); 272733965Sjdp value = THIS (); 272833965Sjdp NEXT (); 272933965Sjdp value = (value << 8) | THIS (); 273033965Sjdp NEXT (); 273133965Sjdp value = (value << 8) | THIS (); 273233965Sjdp NEXT (); 273333965Sjdp value = (value << 8) | THIS (); 273433965Sjdp NEXT (); 273533965Sjdp *tos++ = value; 273633965Sjdp break; 273733965Sjdp case 0x83: 273833965Sjdp NEXT (); 273933965Sjdp value = THIS (); 274033965Sjdp NEXT (); 274133965Sjdp value = (value << 8) | THIS (); 274233965Sjdp NEXT (); 274333965Sjdp value = (value << 8) | THIS (); 274433965Sjdp NEXT (); 274533965Sjdp *tos++ = value; 274633965Sjdp break; 274733965Sjdp case 0x82: 274833965Sjdp NEXT (); 274933965Sjdp value = THIS (); 275033965Sjdp NEXT (); 275133965Sjdp value = (value << 8) | THIS (); 275233965Sjdp NEXT (); 275333965Sjdp *tos++ = value; 275433965Sjdp break; 275533965Sjdp case 0x81: 275633965Sjdp NEXT (); 275733965Sjdp value = THIS (); 275833965Sjdp NEXT (); 275933965Sjdp *tos++ = value; 276033965Sjdp break; 276133965Sjdp case 0x80: 276233965Sjdp NEXT (); 276333965Sjdp *tos++ = 0; 276433965Sjdp break; 276533965Sjdp default: 276633965Sjdp if (THIS () > 0x84) 276733965Sjdp { 276833965Sjdp /* Not a number, just bug out with the answer */ 276933965Sjdp write_int (*(--tos)); 277033965Sjdp return; 277133965Sjdp } 277233965Sjdp *tos++ = THIS (); 277333965Sjdp NEXT (); 277433965Sjdp break; 277533965Sjdp case 0xa5: 277633965Sjdp /* PLUS anything */ 277789857Sobrien value = *(--tos); 277889857Sobrien value += *(--tos); 277989857Sobrien *tos++ = value; 278089857Sobrien NEXT (); 278133965Sjdp break; 278233965Sjdp case VAR ('R'): 278333965Sjdp { 278433965Sjdp int section_number; 278533965Sjdp ieee_data_type *ieee; 278633965Sjdp asection *s; 278733965Sjdp NEXT (); 278833965Sjdp section_number = THIS (); 278933965Sjdp 279033965Sjdp NEXT (); 279133965Sjdp ieee = IEEE_DATA (input_bfd); 279233965Sjdp s = ieee->section_table[section_number]; 279389857Sobrien value = 0; 279433965Sjdp if (s->output_section) 279589857Sobrien value = s->output_section->lma; 279633965Sjdp value += s->output_offset; 279733965Sjdp *tos++ = value; 279833965Sjdp } 279933965Sjdp break; 280033965Sjdp case 0x90: 280133965Sjdp { 280233965Sjdp NEXT (); 280333965Sjdp write_int (*(--tos)); 280433965Sjdp OUT (0x90); 280533965Sjdp return; 280633965Sjdp } 280733965Sjdp } 280833965Sjdp } 280933965Sjdp} 281033965Sjdp 281133965Sjdp/* Drop the int in the buffer, and copy a null into the gap, which we 281233965Sjdp will overwrite later */ 281333965Sjdp 281433965Sjdpstatic void 281533965Sjdpfill_int (buf) 281633965Sjdp struct output_buffer_struct *buf; 281733965Sjdp{ 281833965Sjdp if (buf->buffer == output_buffer) 281933965Sjdp { 282033965Sjdp /* Still a chance to output the size */ 282133965Sjdp int value = output_ptr - buf->ptrp + 3; 282233965Sjdp buf->ptrp[0] = value >> 24; 282333965Sjdp buf->ptrp[1] = value >> 16; 282433965Sjdp buf->ptrp[2] = value >> 8; 282533965Sjdp buf->ptrp[3] = value >> 0; 282633965Sjdp } 282733965Sjdp} 282833965Sjdp 282933965Sjdpstatic void 283033965Sjdpdrop_int (buf) 283133965Sjdp struct output_buffer_struct *buf; 283233965Sjdp{ 283333965Sjdp int type = THIS (); 283433965Sjdp int ch; 283533965Sjdp if (type <= 0x84) 283633965Sjdp { 283733965Sjdp NEXT (); 283833965Sjdp switch (type) 283933965Sjdp { 284033965Sjdp case 0x84: 284133965Sjdp ch = THIS (); 284233965Sjdp NEXT (); 284333965Sjdp case 0x83: 284433965Sjdp ch = THIS (); 284533965Sjdp NEXT (); 284633965Sjdp case 0x82: 284733965Sjdp ch = THIS (); 284833965Sjdp NEXT (); 284933965Sjdp case 0x81: 285033965Sjdp ch = THIS (); 285133965Sjdp NEXT (); 285233965Sjdp case 0x80: 285333965Sjdp break; 285433965Sjdp } 285533965Sjdp } 285633965Sjdp OUT (0x84); 285733965Sjdp buf->ptrp = output_ptr; 285833965Sjdp buf->buffer = output_buffer; 285933965Sjdp OUT (0); 286033965Sjdp OUT (0); 286133965Sjdp OUT (0); 286233965Sjdp OUT (0); 286333965Sjdp} 286433965Sjdp 286533965Sjdpstatic void 286633965Sjdpcopy_int () 286733965Sjdp{ 286833965Sjdp int type = THIS (); 286933965Sjdp int ch; 287033965Sjdp if (type <= 0x84) 287133965Sjdp { 287233965Sjdp OUT (type); 287333965Sjdp NEXT (); 287433965Sjdp switch (type) 287533965Sjdp { 287633965Sjdp case 0x84: 287733965Sjdp ch = THIS (); 287833965Sjdp NEXT (); 287933965Sjdp OUT (ch); 288033965Sjdp case 0x83: 288133965Sjdp ch = THIS (); 288233965Sjdp NEXT (); 288333965Sjdp OUT (ch); 288433965Sjdp case 0x82: 288533965Sjdp ch = THIS (); 288633965Sjdp NEXT (); 288733965Sjdp OUT (ch); 288833965Sjdp case 0x81: 288933965Sjdp ch = THIS (); 289033965Sjdp NEXT (); 289133965Sjdp OUT (ch); 289233965Sjdp case 0x80: 289333965Sjdp break; 289433965Sjdp } 289533965Sjdp } 289633965Sjdp} 289733965Sjdp 289833965Sjdp#define ID copy_id() 289933965Sjdp#define INT copy_int() 290033965Sjdp#define EXP copy_expression() 290133965Sjdp#define INTn(q) copy_int() 290233965Sjdp#define EXPn(q) copy_expression() 290333965Sjdp 290433965Sjdpstatic void 290533965Sjdpf1_record () 290633965Sjdp{ 290733965Sjdp int ch; 290833965Sjdp /* ATN record */ 290933965Sjdp NEXT (); 291033965Sjdp ch = THIS (); 291133965Sjdp switch (ch) 291233965Sjdp { 291333965Sjdp default: 291433965Sjdp OUT (0xf1); 291533965Sjdp OUT (ch); 291633965Sjdp break; 291733965Sjdp case 0xc9: 291833965Sjdp NEXT (); 291933965Sjdp OUT (0xf1); 292033965Sjdp OUT (0xc9); 292133965Sjdp INT; 292233965Sjdp INT; 292333965Sjdp ch = THIS (); 292433965Sjdp switch (ch) 292533965Sjdp { 292633965Sjdp case 0x16: 292733965Sjdp NEXT (); 292833965Sjdp break; 292933965Sjdp case 0x01: 293033965Sjdp NEXT (); 293133965Sjdp break; 293233965Sjdp case 0x00: 293333965Sjdp NEXT (); 293433965Sjdp INT; 293533965Sjdp break; 293633965Sjdp case 0x03: 293733965Sjdp NEXT (); 293833965Sjdp INT; 293933965Sjdp break; 294033965Sjdp case 0x13: 294133965Sjdp EXPn (instruction address); 294233965Sjdp break; 294333965Sjdp default: 294433965Sjdp break; 294533965Sjdp } 294633965Sjdp break; 294733965Sjdp case 0xd8: 294833965Sjdp /* EXternal ref */ 294933965Sjdp NEXT (); 295033965Sjdp OUT (0xf1); 295133965Sjdp OUT (0xd8); 295233965Sjdp EXP; 295333965Sjdp EXP; 295433965Sjdp EXP; 295533965Sjdp EXP; 295633965Sjdp break; 295733965Sjdp case 0xce: 295833965Sjdp NEXT (); 295933965Sjdp OUT (0xf1); 296033965Sjdp OUT (0xce); 296133965Sjdp INT; 296233965Sjdp INT; 296333965Sjdp ch = THIS (); 296433965Sjdp INT; 296533965Sjdp switch (ch) 296633965Sjdp { 296733965Sjdp case 0x01: 296833965Sjdp INT; 296933965Sjdp INT; 297033965Sjdp break; 297133965Sjdp case 0x02: 297233965Sjdp INT; 297333965Sjdp break; 297433965Sjdp case 0x04: 297533965Sjdp EXPn (external function); 297633965Sjdp break; 297733965Sjdp case 0x05: 297833965Sjdp break; 297933965Sjdp case 0x07: 298033965Sjdp INTn (line number); 298133965Sjdp INT; 298233965Sjdp case 0x08: 298333965Sjdp break; 298433965Sjdp case 0x0a: 298533965Sjdp INTn (locked register); 298633965Sjdp INT; 298733965Sjdp break; 298833965Sjdp case 0x3f: 298933965Sjdp copy_till_end (); 299033965Sjdp break; 299133965Sjdp case 0x3e: 299233965Sjdp copy_till_end (); 299333965Sjdp break; 299433965Sjdp case 0x40: 299533965Sjdp copy_till_end (); 299633965Sjdp break; 299733965Sjdp case 0x41: 299833965Sjdp ID; 299933965Sjdp break; 300033965Sjdp } 300133965Sjdp } 300233965Sjdp 300333965Sjdp} 300433965Sjdp 300533965Sjdpstatic void 300633965Sjdpf0_record () 300733965Sjdp{ 300833965Sjdp /* Attribute record */ 300933965Sjdp NEXT (); 301033965Sjdp OUT (0xf0); 301133965Sjdp INTn (Symbol name); 301233965Sjdp ID; 301333965Sjdp} 301433965Sjdp 301533965Sjdpstatic void 301633965Sjdpcopy_till_end () 301733965Sjdp{ 301833965Sjdp int ch = THIS (); 301933965Sjdp while (1) 302033965Sjdp { 302133965Sjdp while (ch <= 0x80) 302233965Sjdp { 302333965Sjdp OUT (ch); 302433965Sjdp NEXT (); 302533965Sjdp ch = THIS (); 302633965Sjdp } 302733965Sjdp switch (ch) 302833965Sjdp { 302933965Sjdp case 0x84: 303033965Sjdp OUT (THIS ()); 303133965Sjdp NEXT (); 303233965Sjdp case 0x83: 303333965Sjdp OUT (THIS ()); 303433965Sjdp NEXT (); 303533965Sjdp case 0x82: 303633965Sjdp OUT (THIS ()); 303733965Sjdp NEXT (); 303833965Sjdp case 0x81: 303933965Sjdp OUT (THIS ()); 304033965Sjdp NEXT (); 304133965Sjdp OUT (THIS ()); 304233965Sjdp NEXT (); 304333965Sjdp 304433965Sjdp ch = THIS (); 304533965Sjdp break; 304633965Sjdp default: 304733965Sjdp return; 304833965Sjdp } 304933965Sjdp } 305033965Sjdp 305133965Sjdp} 305233965Sjdp 305333965Sjdpstatic void 305433965Sjdpf2_record () 305533965Sjdp{ 305633965Sjdp NEXT (); 305733965Sjdp OUT (0xf2); 305833965Sjdp INT; 305933965Sjdp NEXT (); 306033965Sjdp OUT (0xce); 306133965Sjdp INT; 306233965Sjdp copy_till_end (); 306333965Sjdp} 306433965Sjdp 306533965Sjdp 306633965Sjdpstatic void 306733965Sjdpf8_record () 306833965Sjdp{ 306933965Sjdp int ch; 307033965Sjdp NEXT (); 307133965Sjdp ch = THIS (); 307233965Sjdp switch (ch) 307333965Sjdp { 307433965Sjdp case 0x01: 307533965Sjdp case 0x02: 307633965Sjdp case 0x03: 307733965Sjdp /* Unique typedefs for module */ 307833965Sjdp /* GLobal typedefs */ 307933965Sjdp /* High level module scope beginning */ 308033965Sjdp { 308133965Sjdp struct output_buffer_struct ob; 308233965Sjdp NEXT (); 308333965Sjdp OUT (0xf8); 308433965Sjdp OUT (ch); 308533965Sjdp drop_int (&ob); 308633965Sjdp ID; 308733965Sjdp 308833965Sjdp block (); 308933965Sjdp 309033965Sjdp NEXT (); 309133965Sjdp fill_int (&ob); 309233965Sjdp OUT (0xf9); 309333965Sjdp } 309433965Sjdp break; 309533965Sjdp case 0x04: 309633965Sjdp /* Global function */ 309733965Sjdp { 309833965Sjdp struct output_buffer_struct ob; 309933965Sjdp NEXT (); 310033965Sjdp OUT (0xf8); 310133965Sjdp OUT (0x04); 310233965Sjdp drop_int (&ob); 310333965Sjdp ID; 310433965Sjdp INTn (stack size); 310533965Sjdp INTn (ret val); 310633965Sjdp EXPn (offset); 310733965Sjdp 310833965Sjdp block (); 310933965Sjdp 311033965Sjdp NEXT (); 311133965Sjdp OUT (0xf9); 311233965Sjdp EXPn (size of block); 311333965Sjdp fill_int (&ob); 311433965Sjdp } 311533965Sjdp break; 311633965Sjdp 311733965Sjdp case 0x05: 311833965Sjdp /* File name for source line numbers */ 311933965Sjdp { 312033965Sjdp struct output_buffer_struct ob; 312133965Sjdp NEXT (); 312233965Sjdp OUT (0xf8); 312333965Sjdp OUT (0x05); 312433965Sjdp drop_int (&ob); 312533965Sjdp ID; 312633965Sjdp INTn (year); 312733965Sjdp INTn (month); 312833965Sjdp INTn (day); 312933965Sjdp INTn (hour); 313033965Sjdp INTn (monute); 313133965Sjdp INTn (second); 313233965Sjdp block (); 313333965Sjdp NEXT (); 313433965Sjdp OUT (0xf9); 313533965Sjdp fill_int (&ob); 313633965Sjdp } 313733965Sjdp break; 313833965Sjdp 313933965Sjdp case 0x06: 314033965Sjdp /* Local function */ 314133965Sjdp { 314233965Sjdp struct output_buffer_struct ob; 314333965Sjdp NEXT (); 314433965Sjdp OUT (0xf8); 314533965Sjdp OUT (0x06); 314633965Sjdp drop_int (&ob); 314733965Sjdp ID; 314833965Sjdp INTn (stack size); 314933965Sjdp INTn (type return); 315033965Sjdp EXPn (offset); 315133965Sjdp block (); 315233965Sjdp NEXT (); 315333965Sjdp OUT (0xf9); 315433965Sjdp EXPn (size); 315533965Sjdp fill_int (&ob); 315633965Sjdp } 315733965Sjdp break; 315833965Sjdp 315933965Sjdp case 0x0a: 316033965Sjdp /* Assembler module scope beginning -*/ 316133965Sjdp { 316233965Sjdp struct output_buffer_struct ob; 316333965Sjdp 316433965Sjdp NEXT (); 316533965Sjdp OUT (0xf8); 316633965Sjdp OUT (0x0a); 316733965Sjdp drop_int (&ob); 316833965Sjdp ID; 316933965Sjdp ID; 317033965Sjdp INT; 317133965Sjdp ID; 317233965Sjdp INT; 317333965Sjdp INT; 317433965Sjdp INT; 317533965Sjdp INT; 317633965Sjdp INT; 317733965Sjdp INT; 317833965Sjdp 317933965Sjdp block (); 318033965Sjdp 318133965Sjdp NEXT (); 318233965Sjdp OUT (0xf9); 318333965Sjdp fill_int (&ob); 318433965Sjdp } 318533965Sjdp break; 318633965Sjdp case 0x0b: 318733965Sjdp { 318833965Sjdp struct output_buffer_struct ob; 318933965Sjdp NEXT (); 319033965Sjdp OUT (0xf8); 319133965Sjdp OUT (0x0b); 319233965Sjdp drop_int (&ob); 319333965Sjdp ID; 319433965Sjdp INT; 319533965Sjdp INTn (section index); 319633965Sjdp EXPn (offset); 319733965Sjdp INTn (stuff); 319833965Sjdp 319933965Sjdp block (); 320033965Sjdp 320133965Sjdp OUT (0xf9); 320233965Sjdp NEXT (); 320333965Sjdp EXPn (Size in Maus); 320433965Sjdp fill_int (&ob); 320533965Sjdp } 320633965Sjdp break; 320733965Sjdp } 320833965Sjdp} 320933965Sjdp 321033965Sjdpstatic void 321133965Sjdpe2_record () 321233965Sjdp{ 321333965Sjdp OUT (0xe2); 321433965Sjdp NEXT (); 321533965Sjdp OUT (0xce); 321633965Sjdp NEXT (); 321733965Sjdp INT; 321833965Sjdp EXP; 321933965Sjdp} 322033965Sjdp 322133965Sjdpstatic void 322233965Sjdpblock () 322333965Sjdp{ 322433965Sjdp int ch; 322533965Sjdp while (1) 322633965Sjdp { 322733965Sjdp ch = THIS (); 322833965Sjdp switch (ch) 322933965Sjdp { 323033965Sjdp case 0xe1: 323133965Sjdp case 0xe5: 323233965Sjdp return; 323333965Sjdp case 0xf9: 323433965Sjdp return; 323533965Sjdp case 0xf0: 323633965Sjdp f0_record (); 323733965Sjdp break; 323833965Sjdp case 0xf1: 323933965Sjdp f1_record (); 324033965Sjdp break; 324133965Sjdp case 0xf2: 324233965Sjdp f2_record (); 324333965Sjdp break; 324433965Sjdp case 0xf8: 324533965Sjdp f8_record (); 324633965Sjdp break; 324733965Sjdp case 0xe2: 324833965Sjdp e2_record (); 324933965Sjdp break; 325033965Sjdp 325133965Sjdp } 325233965Sjdp } 325333965Sjdp} 325433965Sjdp 325533965Sjdp 325633965Sjdp 325733965Sjdp/* relocate_debug, 325833965Sjdp moves all the debug information from the source bfd to the output 325933965Sjdp bfd, and relocates any expressions it finds 326033965Sjdp*/ 326133965Sjdp 326233965Sjdpstatic void 326333965Sjdprelocate_debug (output, input) 326460484Sobrien bfd *output ATTRIBUTE_UNUSED; 326533965Sjdp bfd *input; 326633965Sjdp{ 326733965Sjdp#define IBS 400 326833965Sjdp#define OBS 400 326933965Sjdp unsigned char input_buffer[IBS]; 327033965Sjdp 327133965Sjdp input_ptr_start = input_ptr = input_buffer; 327233965Sjdp input_ptr_end = input_buffer + IBS; 327333965Sjdp input_bfd = input; 327433965Sjdp /* FIXME: Check return value. I'm not sure whether it needs to read 327533965Sjdp the entire buffer or not. */ 327689857Sobrien bfd_bread ((PTR) input_ptr_start, (bfd_size_type) IBS, input); 327733965Sjdp block (); 327833965Sjdp} 327933965Sjdp 328077298Sobrien/* Gather together all the debug information from each input BFD into 328177298Sobrien one place, relocating it and emitting it as we go. */ 328233965Sjdp 328333965Sjdpstatic boolean 328433965Sjdpieee_write_debug_part (abfd) 328533965Sjdp bfd *abfd; 328633965Sjdp{ 328733965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 328833965Sjdp bfd_chain_type *chain = ieee->chain_root; 328989857Sobrien unsigned char obuff[OBS]; 329033965Sjdp boolean some_debug = false; 329133965Sjdp file_ptr here = bfd_tell (abfd); 329233965Sjdp 329389857Sobrien output_ptr_start = output_ptr = obuff; 329489857Sobrien output_ptr_end = obuff + OBS; 329589857Sobrien output_ptr = obuff; 329633965Sjdp output_bfd = abfd; 329733965Sjdp 329833965Sjdp if (chain == (bfd_chain_type *) NULL) 329933965Sjdp { 330033965Sjdp asection *s; 330133965Sjdp 330233965Sjdp for (s = abfd->sections; s != NULL; s = s->next) 330333965Sjdp if ((s->flags & SEC_DEBUGGING) != 0) 330433965Sjdp break; 330533965Sjdp if (s == NULL) 330633965Sjdp { 330733965Sjdp ieee->w.r.debug_information_part = 0; 330833965Sjdp return true; 330933965Sjdp } 331033965Sjdp 331133965Sjdp ieee->w.r.debug_information_part = here; 331289857Sobrien if (bfd_bwrite (s->contents, s->_raw_size, abfd) != s->_raw_size) 331333965Sjdp return false; 331433965Sjdp } 331533965Sjdp else 331633965Sjdp { 331733965Sjdp while (chain != (bfd_chain_type *) NULL) 331833965Sjdp { 331933965Sjdp bfd *entry = chain->this; 332033965Sjdp ieee_data_type *entry_ieee = IEEE_DATA (entry); 332133965Sjdp if (entry_ieee->w.r.debug_information_part) 332233965Sjdp { 332333965Sjdp if (bfd_seek (entry, entry_ieee->w.r.debug_information_part, 332489857Sobrien SEEK_SET) != 0) 332533965Sjdp return false; 332633965Sjdp relocate_debug (abfd, entry); 332733965Sjdp } 332833965Sjdp 332933965Sjdp chain = chain->next; 333033965Sjdp } 333133965Sjdp if (some_debug) 333233965Sjdp { 333333965Sjdp ieee->w.r.debug_information_part = here; 333433965Sjdp } 333533965Sjdp else 333633965Sjdp { 333733965Sjdp ieee->w.r.debug_information_part = 0; 333833965Sjdp } 333933965Sjdp 334033965Sjdp flush (); 334133965Sjdp } 334233965Sjdp 334333965Sjdp return true; 334433965Sjdp} 334533965Sjdp 334633965Sjdp/* Write the data in an ieee way. */ 334733965Sjdp 334833965Sjdpstatic boolean 334933965Sjdpieee_write_data_part (abfd) 335033965Sjdp bfd *abfd; 335133965Sjdp{ 335233965Sjdp asection *s; 335333965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 335433965Sjdp ieee->w.r.data_part = bfd_tell (abfd); 335533965Sjdp for (s = abfd->sections; s != (asection *) NULL; s = s->next) 335633965Sjdp { 335733965Sjdp /* Skip sections that have no loadable contents (.bss, 335833965Sjdp debugging, etc.) */ 335933965Sjdp if ((s->flags & SEC_LOAD) == 0) 336033965Sjdp continue; 336133965Sjdp 336233965Sjdp /* Sort the reloc records so we can insert them in the correct 336333965Sjdp places */ 336433965Sjdp if (s->reloc_count != 0) 336533965Sjdp { 336633965Sjdp if (! do_with_relocs (abfd, s)) 336733965Sjdp return false; 336833965Sjdp } 336933965Sjdp else 337033965Sjdp { 337133965Sjdp if (! do_without_relocs (abfd, s)) 337233965Sjdp return false; 337333965Sjdp } 337433965Sjdp } 337533965Sjdp 337633965Sjdp return true; 337733965Sjdp} 337833965Sjdp 337933965Sjdp 338033965Sjdpstatic boolean 338133965Sjdpinit_for_output (abfd) 338233965Sjdp bfd *abfd; 338333965Sjdp{ 338433965Sjdp asection *s; 338533965Sjdp for (s = abfd->sections; s != (asection *) NULL; s = s->next) 338633965Sjdp { 338733965Sjdp if ((s->flags & SEC_DEBUGGING) != 0) 338833965Sjdp continue; 338933965Sjdp if (s->_raw_size != 0) 339033965Sjdp { 339189857Sobrien bfd_size_type size = s->_raw_size; 339289857Sobrien ieee_per_section (s)->data = (bfd_byte *) (bfd_alloc (abfd, size)); 339333965Sjdp if (!ieee_per_section (s)->data) 339433965Sjdp return false; 339533965Sjdp } 339633965Sjdp } 339733965Sjdp return true; 339833965Sjdp} 339933965Sjdp 340033965Sjdp/** exec and core file sections */ 340133965Sjdp 340233965Sjdp/* set section contents is complicated with IEEE since the format is 340333965Sjdp* not a byte image, but a record stream. 340433965Sjdp*/ 340589857Sobrienstatic boolean 340633965Sjdpieee_set_section_contents (abfd, section, location, offset, count) 340733965Sjdp bfd *abfd; 340833965Sjdp sec_ptr section; 340933965Sjdp PTR location; 341033965Sjdp file_ptr offset; 341133965Sjdp bfd_size_type count; 341233965Sjdp{ 341333965Sjdp if ((section->flags & SEC_DEBUGGING) != 0) 341433965Sjdp { 341533965Sjdp if (section->contents == NULL) 341633965Sjdp { 341789857Sobrien bfd_size_type size = section->_raw_size; 341889857Sobrien section->contents = (unsigned char *) bfd_alloc (abfd, size); 341933965Sjdp if (section->contents == NULL) 342033965Sjdp return false; 342133965Sjdp } 342233965Sjdp /* bfd_set_section_contents has already checked that everything 342333965Sjdp is within range. */ 342489857Sobrien memcpy (section->contents + offset, location, (size_t) count); 342533965Sjdp return true; 342633965Sjdp } 342733965Sjdp 342833965Sjdp if (ieee_per_section (section)->data == (bfd_byte *) NULL) 342933965Sjdp { 343033965Sjdp if (!init_for_output (abfd)) 343133965Sjdp return false; 343233965Sjdp } 343333965Sjdp memcpy ((PTR) (ieee_per_section (section)->data + offset), 343433965Sjdp (PTR) location, 343533965Sjdp (unsigned int) count); 343633965Sjdp return true; 343733965Sjdp} 343833965Sjdp 343933965Sjdp/* Write the external symbols of a file. IEEE considers two sorts of 344033965Sjdp external symbols, public, and referenced. It uses to internal 344133965Sjdp forms to index them as well. When we write them out we turn their 344233965Sjdp symbol values into indexes from the right base. */ 344333965Sjdp 344433965Sjdpstatic boolean 344533965Sjdpieee_write_external_part (abfd) 344633965Sjdp bfd *abfd; 344733965Sjdp{ 344833965Sjdp asymbol **q; 344933965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 345033965Sjdp 345133965Sjdp unsigned int reference_index = IEEE_REFERENCE_BASE; 345233965Sjdp unsigned int public_index = IEEE_PUBLIC_BASE + 2; 345333965Sjdp file_ptr here = bfd_tell (abfd); 345433965Sjdp boolean hadone = false; 345533965Sjdp if (abfd->outsymbols != (asymbol **) NULL) 345633965Sjdp { 345733965Sjdp 345833965Sjdp for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++) 345933965Sjdp { 346033965Sjdp asymbol *p = *q; 346133965Sjdp if (bfd_is_und_section (p->section)) 346233965Sjdp { 346333965Sjdp /* This must be a symbol reference .. */ 346433965Sjdp if (! ieee_write_byte (abfd, ieee_external_reference_enum) 346589857Sobrien || ! ieee_write_int (abfd, (bfd_vma) reference_index) 346633965Sjdp || ! ieee_write_id (abfd, p->name)) 346733965Sjdp return false; 346833965Sjdp p->value = reference_index; 346933965Sjdp reference_index++; 347033965Sjdp hadone = true; 347133965Sjdp } 347233965Sjdp else if (bfd_is_com_section (p->section)) 347333965Sjdp { 347433965Sjdp /* This is a weak reference */ 347533965Sjdp if (! ieee_write_byte (abfd, ieee_external_reference_enum) 347689857Sobrien || ! ieee_write_int (abfd, (bfd_vma) reference_index) 347733965Sjdp || ! ieee_write_id (abfd, p->name) 347833965Sjdp || ! ieee_write_byte (abfd, 347933965Sjdp ieee_weak_external_reference_enum) 348089857Sobrien || ! ieee_write_int (abfd, (bfd_vma) reference_index) 348133965Sjdp || ! ieee_write_int (abfd, p->value)) 348233965Sjdp return false; 348333965Sjdp p->value = reference_index; 348433965Sjdp reference_index++; 348533965Sjdp hadone = true; 348633965Sjdp } 348733965Sjdp else if (p->flags & BSF_GLOBAL) 348833965Sjdp { 348933965Sjdp /* This must be a symbol definition */ 349033965Sjdp 349133965Sjdp if (! ieee_write_byte (abfd, ieee_external_symbol_enum) 349289857Sobrien || ! ieee_write_int (abfd, (bfd_vma) public_index) 349333965Sjdp || ! ieee_write_id (abfd, p->name) 349433965Sjdp || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum) 349589857Sobrien || ! ieee_write_int (abfd, (bfd_vma) public_index) 349633965Sjdp || ! ieee_write_byte (abfd, 15) /* instruction address */ 349733965Sjdp || ! ieee_write_byte (abfd, 19) /* static symbol */ 349833965Sjdp || ! ieee_write_byte (abfd, 1)) /* one of them */ 349933965Sjdp return false; 350033965Sjdp 350133965Sjdp /* Write out the value */ 350233965Sjdp if (! ieee_write_2bytes (abfd, ieee_value_record_enum) 350389857Sobrien || ! ieee_write_int (abfd, (bfd_vma) public_index)) 350433965Sjdp return false; 350533965Sjdp if (! bfd_is_abs_section (p->section)) 350633965Sjdp { 350733965Sjdp if (abfd->flags & EXEC_P) 350833965Sjdp { 350933965Sjdp /* If fully linked, then output all symbols 351033965Sjdp relocated */ 351133965Sjdp if (! (ieee_write_int 351233965Sjdp (abfd, 351333965Sjdp (p->value 351433965Sjdp + p->section->output_offset 351533965Sjdp + p->section->output_section->vma)))) 351633965Sjdp return false; 351733965Sjdp } 351833965Sjdp else 351933965Sjdp { 352033965Sjdp if (! (ieee_write_expression 352133965Sjdp (abfd, 352233965Sjdp p->value + p->section->output_offset, 352333965Sjdp p->section->output_section->symbol, 352433965Sjdp false, 0))) 352533965Sjdp return false; 352633965Sjdp } 352733965Sjdp } 352833965Sjdp else 352933965Sjdp { 353033965Sjdp if (! ieee_write_expression (abfd, 353133965Sjdp p->value, 353233965Sjdp bfd_abs_section_ptr->symbol, 353333965Sjdp false, 0)) 353433965Sjdp return false; 353533965Sjdp } 353633965Sjdp p->value = public_index; 353733965Sjdp public_index++; 353833965Sjdp hadone = true; 353933965Sjdp } 354033965Sjdp else 354133965Sjdp { 354233965Sjdp /* This can happen - when there are gaps in the symbols read */ 354333965Sjdp /* from an input ieee file */ 354433965Sjdp } 354533965Sjdp } 354633965Sjdp } 354733965Sjdp if (hadone) 354833965Sjdp ieee->w.r.external_part = here; 354933965Sjdp 355033965Sjdp return true; 355133965Sjdp} 355233965Sjdp 355333965Sjdp 355489857Sobrienstatic const unsigned char exten[] = 355533965Sjdp{ 355633965Sjdp 0xf0, 0x20, 0x00, 355733965Sjdp 0xf1, 0xce, 0x20, 0x00, 37, 3, 3, /* Set version 3 rev 3 */ 355833965Sjdp 0xf1, 0xce, 0x20, 0x00, 39, 2,/* keep symbol in original case */ 355933965Sjdp 0xf1, 0xce, 0x20, 0x00, 38 /* set object type relocateable to x */ 356033965Sjdp}; 356133965Sjdp 356289857Sobrienstatic const unsigned char envi[] = 356333965Sjdp{ 356433965Sjdp 0xf0, 0x21, 0x00, 356533965Sjdp 356633965Sjdp/* 0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11, 356733965Sjdp 0x19, 0x2c, 356833965Sjdp*/ 356933965Sjdp 0xf1, 0xce, 0x21, 00, 52, 0x00, /* exec ok */ 357033965Sjdp 357133965Sjdp 0xf1, 0xce, 0x21, 0, 53, 0x03,/* host unix */ 357233965Sjdp/* 0xf1, 0xce, 0x21, 0, 54, 2,1,1 tool & version # */ 357333965Sjdp}; 357433965Sjdp 357533965Sjdpstatic boolean 357633965Sjdpieee_write_me_part (abfd) 357733965Sjdp bfd *abfd; 357833965Sjdp{ 357933965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 358033965Sjdp ieee->w.r.trailer_part = bfd_tell (abfd); 358133965Sjdp if (abfd->start_address) 358233965Sjdp { 358333965Sjdp if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum) 358433965Sjdp || ! ieee_write_byte (abfd, ieee_function_either_open_b_enum) 358533965Sjdp || ! ieee_write_int (abfd, abfd->start_address) 358633965Sjdp || ! ieee_write_byte (abfd, ieee_function_either_close_b_enum)) 358733965Sjdp return false; 358833965Sjdp } 358933965Sjdp ieee->w.r.me_record = bfd_tell (abfd); 359033965Sjdp if (! ieee_write_byte (abfd, ieee_module_end_enum)) 359133965Sjdp return false; 359233965Sjdp return true; 359333965Sjdp} 359433965Sjdp 359533965Sjdp/* Write out the IEEE processor ID. */ 359633965Sjdp 359733965Sjdpstatic boolean 359833965Sjdpieee_write_processor (abfd) 359933965Sjdp bfd *abfd; 360033965Sjdp{ 360133965Sjdp const bfd_arch_info_type *arch; 360233965Sjdp 360333965Sjdp arch = bfd_get_arch_info (abfd); 360433965Sjdp switch (arch->arch) 360533965Sjdp { 360633965Sjdp default: 360733965Sjdp if (! ieee_write_id (abfd, bfd_printable_name (abfd))) 360833965Sjdp return false; 360933965Sjdp break; 361033965Sjdp 361133965Sjdp case bfd_arch_a29k: 361233965Sjdp if (! ieee_write_id (abfd, "29000")) 361333965Sjdp return false; 361433965Sjdp break; 361533965Sjdp 361633965Sjdp case bfd_arch_h8300: 361733965Sjdp if (! ieee_write_id (abfd, "H8/300")) 361833965Sjdp return false; 361933965Sjdp break; 362033965Sjdp 362133965Sjdp case bfd_arch_h8500: 362233965Sjdp if (! ieee_write_id (abfd, "H8/500")) 362333965Sjdp return false; 362433965Sjdp break; 362533965Sjdp 362633965Sjdp case bfd_arch_i960: 362733965Sjdp switch (arch->mach) 362833965Sjdp { 362933965Sjdp default: 363033965Sjdp case bfd_mach_i960_core: 363133965Sjdp case bfd_mach_i960_ka_sa: 363233965Sjdp if (! ieee_write_id (abfd, "80960KA")) 363333965Sjdp return false; 363433965Sjdp break; 363533965Sjdp 363633965Sjdp case bfd_mach_i960_kb_sb: 363733965Sjdp if (! ieee_write_id (abfd, "80960KB")) 363833965Sjdp return false; 363933965Sjdp break; 364033965Sjdp 364133965Sjdp case bfd_mach_i960_ca: 364233965Sjdp if (! ieee_write_id (abfd, "80960CA")) 364333965Sjdp return false; 364433965Sjdp break; 364533965Sjdp 364633965Sjdp case bfd_mach_i960_mc: 364733965Sjdp case bfd_mach_i960_xa: 364833965Sjdp if (! ieee_write_id (abfd, "80960MC")) 364933965Sjdp return false; 365033965Sjdp break; 365133965Sjdp } 365233965Sjdp break; 365333965Sjdp 365433965Sjdp case bfd_arch_m68k: 365533965Sjdp { 365660484Sobrien const char *id; 365733965Sjdp 365860484Sobrien switch (arch->mach) 365960484Sobrien { 366060484Sobrien default: id = "68020"; break; 366160484Sobrien case bfd_mach_m68000: id = "68000"; break; 366260484Sobrien case bfd_mach_m68008: id = "68008"; break; 366360484Sobrien case bfd_mach_m68010: id = "68010"; break; 366460484Sobrien case bfd_mach_m68020: id = "68020"; break; 366560484Sobrien case bfd_mach_m68030: id = "68030"; break; 366660484Sobrien case bfd_mach_m68040: id = "68040"; break; 366760484Sobrien case bfd_mach_m68060: id = "68060"; break; 366860484Sobrien case bfd_mach_cpu32: id = "cpu32"; break; 366978828Sobrien case bfd_mach_mcf5200:id = "5200"; break; 367078828Sobrien case bfd_mach_mcf5206e:id = "5206e"; break; 367178828Sobrien case bfd_mach_mcf5307:id = "5307"; break; 367278828Sobrien case bfd_mach_mcf5407:id = "5407"; break; 367360484Sobrien } 367460484Sobrien 367560484Sobrien if (! ieee_write_id (abfd, id)) 367633965Sjdp return false; 367733965Sjdp } 367833965Sjdp break; 367933965Sjdp } 368033965Sjdp 368133965Sjdp return true; 368233965Sjdp} 368333965Sjdp 368489857Sobrienstatic boolean 368533965Sjdpieee_write_object_contents (abfd) 368633965Sjdp bfd *abfd; 368733965Sjdp{ 368833965Sjdp ieee_data_type *ieee = IEEE_DATA (abfd); 368933965Sjdp unsigned int i; 369033965Sjdp file_ptr old; 369133965Sjdp 369233965Sjdp /* Fast forward over the header area */ 369333965Sjdp if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 369433965Sjdp return false; 369533965Sjdp 369633965Sjdp if (! ieee_write_byte (abfd, ieee_module_beginning_enum) 369733965Sjdp || ! ieee_write_processor (abfd) 369833965Sjdp || ! ieee_write_id (abfd, abfd->filename)) 369933965Sjdp return false; 370033965Sjdp 370133965Sjdp /* Fast forward over the variable bits */ 370233965Sjdp if (! ieee_write_byte (abfd, ieee_address_descriptor_enum)) 370333965Sjdp return false; 370433965Sjdp 370533965Sjdp /* Bits per MAU */ 370633965Sjdp if (! ieee_write_byte (abfd, (bfd_byte) (bfd_arch_bits_per_byte (abfd)))) 370733965Sjdp return false; 370833965Sjdp /* MAU's per address */ 370933965Sjdp if (! ieee_write_byte (abfd, 371033965Sjdp (bfd_byte) (bfd_arch_bits_per_address (abfd) 371133965Sjdp / bfd_arch_bits_per_byte (abfd)))) 371233965Sjdp return false; 371333965Sjdp 371433965Sjdp old = bfd_tell (abfd); 371533965Sjdp if (bfd_seek (abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR) != 0) 371633965Sjdp return false; 371733965Sjdp 371833965Sjdp ieee->w.r.extension_record = bfd_tell (abfd); 371989857Sobrien if (bfd_bwrite ((char *) exten, (bfd_size_type) sizeof (exten), abfd) 372089857Sobrien != sizeof (exten)) 372133965Sjdp return false; 372233965Sjdp if (abfd->flags & EXEC_P) 372333965Sjdp { 372433965Sjdp if (! ieee_write_byte (abfd, 0x1)) /* Absolute */ 372533965Sjdp return false; 372633965Sjdp } 372733965Sjdp else 372833965Sjdp { 372933965Sjdp if (! ieee_write_byte (abfd, 0x2)) /* Relocateable */ 373033965Sjdp return false; 373133965Sjdp } 373233965Sjdp 373333965Sjdp ieee->w.r.environmental_record = bfd_tell (abfd); 373489857Sobrien if (bfd_bwrite ((char *) envi, (bfd_size_type) sizeof (envi), abfd) 373589857Sobrien != sizeof (envi)) 373633965Sjdp return false; 373733965Sjdp 373833965Sjdp /* The HP emulator database requires a timestamp in the file. */ 373933965Sjdp { 374033965Sjdp time_t now; 374133965Sjdp const struct tm *t; 374233965Sjdp 374333965Sjdp time (&now); 374433965Sjdp t = (struct tm *) localtime (&now); 374533965Sjdp if (! ieee_write_2bytes (abfd, (int) ieee_atn_record_enum) 374633965Sjdp || ! ieee_write_byte (abfd, 0x21) 374733965Sjdp || ! ieee_write_byte (abfd, 0) 374833965Sjdp || ! ieee_write_byte (abfd, 50) 374989857Sobrien || ! ieee_write_int (abfd, (bfd_vma) (t->tm_year + 1900)) 375089857Sobrien || ! ieee_write_int (abfd, (bfd_vma) (t->tm_mon + 1)) 375189857Sobrien || ! ieee_write_int (abfd, (bfd_vma) t->tm_mday) 375289857Sobrien || ! ieee_write_int (abfd, (bfd_vma) t->tm_hour) 375389857Sobrien || ! ieee_write_int (abfd, (bfd_vma) t->tm_min) 375489857Sobrien || ! ieee_write_int (abfd, (bfd_vma) t->tm_sec)) 375533965Sjdp return false; 375633965Sjdp } 375733965Sjdp 375833965Sjdp output_bfd = abfd; 375933965Sjdp 376033965Sjdp flush (); 376133965Sjdp 376233965Sjdp if (! ieee_write_section_part (abfd)) 376333965Sjdp return false; 376433965Sjdp /* First write the symbols. This changes their values into table 376533965Sjdp indeces so we cant use it after this point. */ 376633965Sjdp if (! ieee_write_external_part (abfd)) 376733965Sjdp return false; 376833965Sjdp 376933965Sjdp /* ieee_write_byte(abfd, ieee_record_seperator_enum);*/ 377033965Sjdp 377133965Sjdp /* ieee_write_byte(abfd, ieee_record_seperator_enum);*/ 377233965Sjdp 377333965Sjdp 377433965Sjdp /* Write any debugs we have been told about. */ 377533965Sjdp if (! ieee_write_debug_part (abfd)) 377633965Sjdp return false; 377733965Sjdp 377833965Sjdp /* Can only write the data once the symbols have been written, since 377933965Sjdp the data contains relocation information which points to the 378033965Sjdp symbols. */ 378133965Sjdp if (! ieee_write_data_part (abfd)) 378233965Sjdp return false; 378333965Sjdp 378433965Sjdp /* At the end we put the end! */ 378533965Sjdp if (! ieee_write_me_part (abfd)) 378633965Sjdp return false; 378733965Sjdp 378833965Sjdp /* Generate the header */ 378933965Sjdp if (bfd_seek (abfd, old, SEEK_SET) != 0) 379033965Sjdp return false; 379133965Sjdp 379233965Sjdp for (i = 0; i < N_W_VARIABLES; i++) 379333965Sjdp { 379433965Sjdp if (! ieee_write_2bytes (abfd, ieee_assign_value_to_variable_enum) 379533965Sjdp || ! ieee_write_byte (abfd, (bfd_byte) i) 379689857Sobrien || ! ieee_write_int5_out (abfd, (bfd_vma) ieee->w.offset[i])) 379733965Sjdp return false; 379833965Sjdp } 379933965Sjdp 380033965Sjdp return true; 380133965Sjdp} 380233965Sjdp 380333965Sjdp/* Native-level interface to symbols. */ 380433965Sjdp 380533965Sjdp/* We read the symbols into a buffer, which is discarded when this 380633965Sjdp function exits. We read the strings into a buffer large enough to 380733965Sjdp hold them all plus all the cached symbol entries. */ 380833965Sjdp 380989857Sobrienstatic asymbol * 381033965Sjdpieee_make_empty_symbol (abfd) 381133965Sjdp bfd *abfd; 381233965Sjdp{ 381389857Sobrien bfd_size_type amt = sizeof (ieee_symbol_type); 381489857Sobrien ieee_symbol_type *new = (ieee_symbol_type *) bfd_zalloc (abfd, amt); 381533965Sjdp if (!new) 381633965Sjdp return NULL; 381733965Sjdp new->symbol.the_bfd = abfd; 381833965Sjdp return &new->symbol; 381933965Sjdp} 382033965Sjdp 382133965Sjdpstatic bfd * 382233965Sjdpieee_openr_next_archived_file (arch, prev) 382333965Sjdp bfd *arch; 382433965Sjdp bfd *prev; 382533965Sjdp{ 382633965Sjdp ieee_ar_data_type *ar = IEEE_AR_DATA (arch); 382733965Sjdp /* take the next one from the arch state, or reset */ 382833965Sjdp if (prev == (bfd *) NULL) 382933965Sjdp { 383033965Sjdp /* Reset the index - the first two entries are bogus*/ 383133965Sjdp ar->element_index = 2; 383233965Sjdp } 383333965Sjdp while (true) 383433965Sjdp { 383533965Sjdp ieee_ar_obstack_type *p = ar->elements + ar->element_index; 383633965Sjdp ar->element_index++; 383733965Sjdp if (ar->element_index <= ar->element_count) 383833965Sjdp { 383933965Sjdp if (p->file_offset != (file_ptr) 0) 384033965Sjdp { 384133965Sjdp if (p->abfd == (bfd *) NULL) 384233965Sjdp { 384333965Sjdp p->abfd = _bfd_create_empty_archive_element_shell (arch); 384433965Sjdp p->abfd->origin = p->file_offset; 384533965Sjdp } 384633965Sjdp return p->abfd; 384733965Sjdp } 384833965Sjdp } 384933965Sjdp else 385033965Sjdp { 385133965Sjdp bfd_set_error (bfd_error_no_more_archived_files); 385233965Sjdp return (bfd *) NULL; 385333965Sjdp } 385433965Sjdp 385533965Sjdp } 385633965Sjdp} 385733965Sjdp 385833965Sjdpstatic boolean 385989857Sobrienieee_find_nearest_line (abfd, section, symbols, offset, filename_ptr, 386089857Sobrien functionname_ptr, line_ptr) 386160484Sobrien bfd *abfd ATTRIBUTE_UNUSED; 386260484Sobrien asection *section ATTRIBUTE_UNUSED; 386360484Sobrien asymbol **symbols ATTRIBUTE_UNUSED; 386460484Sobrien bfd_vma offset ATTRIBUTE_UNUSED; 386560484Sobrien const char **filename_ptr ATTRIBUTE_UNUSED; 386660484Sobrien const char **functionname_ptr ATTRIBUTE_UNUSED; 386760484Sobrien unsigned int *line_ptr ATTRIBUTE_UNUSED; 386833965Sjdp{ 386933965Sjdp return false; 387033965Sjdp} 387133965Sjdp 387233965Sjdpstatic int 387333965Sjdpieee_generic_stat_arch_elt (abfd, buf) 387433965Sjdp bfd *abfd; 387533965Sjdp struct stat *buf; 387633965Sjdp{ 387738889Sjdp ieee_ar_data_type *ar = (ieee_ar_data_type *) NULL; 387833965Sjdp ieee_data_type *ieee; 387933965Sjdp 388038889Sjdp if (abfd->my_archive != NULL) 388138889Sjdp ar = abfd->my_archive->tdata.ieee_ar_data; 388233965Sjdp if (ar == (ieee_ar_data_type *) NULL) 388333965Sjdp { 388433965Sjdp bfd_set_error (bfd_error_invalid_operation); 388533965Sjdp return -1; 388633965Sjdp } 388733965Sjdp 388833965Sjdp if (IEEE_DATA (abfd) == NULL) 388933965Sjdp { 389033965Sjdp if (ieee_object_p (abfd) == NULL) 389133965Sjdp { 389233965Sjdp bfd_set_error (bfd_error_wrong_format); 389333965Sjdp return -1; 389433965Sjdp } 389533965Sjdp } 389633965Sjdp 389733965Sjdp ieee = IEEE_DATA (abfd); 389833965Sjdp 389933965Sjdp buf->st_size = ieee->w.r.me_record + 1; 390033965Sjdp buf->st_mode = 0644; 390133965Sjdp return 0; 390233965Sjdp} 390333965Sjdp 390433965Sjdpstatic int 390533965Sjdpieee_sizeof_headers (abfd, x) 390660484Sobrien bfd *abfd ATTRIBUTE_UNUSED; 390760484Sobrien boolean x ATTRIBUTE_UNUSED; 390833965Sjdp{ 390933965Sjdp return 0; 391033965Sjdp} 391133965Sjdp 391233965Sjdp 391333965Sjdp/* The debug info routines are never used. */ 391433965Sjdp#if 0 391533965Sjdp 391633965Sjdpstatic void 391733965Sjdpieee_bfd_debug_info_start (abfd) 391833965Sjdp bfd *abfd; 391933965Sjdp{ 392033965Sjdp 392133965Sjdp} 392233965Sjdp 392333965Sjdpstatic void 392433965Sjdpieee_bfd_debug_info_end (abfd) 392533965Sjdp bfd *abfd; 392633965Sjdp{ 392733965Sjdp 392833965Sjdp} 392933965Sjdp 393033965Sjdp 393133965Sjdp/* Add this section to the list of sections we have debug info for, to 393233965Sjdp be ready to output it at close time 393333965Sjdp */ 393433965Sjdpstatic void 393533965Sjdpieee_bfd_debug_info_accumulate (abfd, section) 393633965Sjdp bfd *abfd; 393733965Sjdp asection *section; 393833965Sjdp{ 393933965Sjdp ieee_data_type *ieee = IEEE_DATA (section->owner); 394033965Sjdp ieee_data_type *output_ieee = IEEE_DATA (abfd); 394133965Sjdp /* can only accumulate data from other ieee bfds */ 394233965Sjdp if (section->owner->xvec != abfd->xvec) 394333965Sjdp return; 394433965Sjdp /* Only bother once per bfd */ 3945104834Sobrien if (ieee->done_debug) 394633965Sjdp return; 394733965Sjdp ieee->done_debug = true; 394833965Sjdp 394933965Sjdp /* Don't bother if there is no debug info */ 395033965Sjdp if (ieee->w.r.debug_information_part == 0) 395133965Sjdp return; 395233965Sjdp 395333965Sjdp 395433965Sjdp /* Add to chain */ 395533965Sjdp { 395689857Sobrien bfd_size_type amt = sizeof (bfd_chain_type); 395789857Sobrien bfd_chain_type *n = (bfd_chain_type *) bfd_alloc (abfd, amt); 395833965Sjdp if (!n) 395933965Sjdp abort (); /* FIXME */ 396033965Sjdp n->this = section->owner; 396133965Sjdp n->next = (bfd_chain_type *) NULL; 396233965Sjdp 396333965Sjdp if (output_ieee->chain_head) 396433965Sjdp { 396533965Sjdp output_ieee->chain_head->next = n; 396633965Sjdp } 396733965Sjdp else 396833965Sjdp { 396933965Sjdp output_ieee->chain_root = n; 397033965Sjdp 397133965Sjdp } 397233965Sjdp output_ieee->chain_head = n; 397333965Sjdp } 397433965Sjdp} 397533965Sjdp 397633965Sjdp#endif 397733965Sjdp 397833965Sjdp#define ieee_close_and_cleanup _bfd_generic_close_and_cleanup 397933965Sjdp#define ieee_bfd_free_cached_info _bfd_generic_bfd_free_cached_info 398033965Sjdp 398133965Sjdp#define ieee_slurp_armap bfd_true 398233965Sjdp#define ieee_slurp_extended_name_table bfd_true 398333965Sjdp#define ieee_construct_extended_name_table \ 398433965Sjdp ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ 398533965Sjdp bfd_true) 398633965Sjdp#define ieee_truncate_arname bfd_dont_truncate_arname 398733965Sjdp#define ieee_write_armap \ 398833965Sjdp ((boolean (*) \ 398933965Sjdp PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ 399033965Sjdp bfd_true) 399133965Sjdp#define ieee_read_ar_hdr bfd_nullvoidptr 399233965Sjdp#define ieee_update_armap_timestamp bfd_true 399333965Sjdp#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index 399433965Sjdp 399533965Sjdp#define ieee_bfd_is_local_label_name bfd_generic_is_local_label_name 399633965Sjdp#define ieee_get_lineno _bfd_nosymbols_get_lineno 399733965Sjdp#define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol 399833965Sjdp#define ieee_read_minisymbols _bfd_generic_read_minisymbols 399933965Sjdp#define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol 400033965Sjdp 400133965Sjdp#define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup 400233965Sjdp 400333965Sjdp#define ieee_set_arch_mach _bfd_generic_set_arch_mach 400433965Sjdp 400533965Sjdp#define ieee_get_section_contents_in_window \ 400633965Sjdp _bfd_generic_get_section_contents_in_window 400733965Sjdp#define ieee_bfd_get_relocated_section_contents \ 400833965Sjdp bfd_generic_get_relocated_section_contents 400933965Sjdp#define ieee_bfd_relax_section bfd_generic_relax_section 401060484Sobrien#define ieee_bfd_gc_sections bfd_generic_gc_sections 401189857Sobrien#define ieee_bfd_merge_sections bfd_generic_merge_sections 4012104834Sobrien#define ieee_bfd_discard_group bfd_generic_discard_group 401333965Sjdp#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create 4014104834Sobrien#define ieee_bfd_link_hash_table_free _bfd_generic_link_hash_table_free 401533965Sjdp#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols 4016104834Sobrien#define ieee_bfd_link_just_syms _bfd_generic_link_just_syms 401733965Sjdp#define ieee_bfd_final_link _bfd_generic_final_link 401833965Sjdp#define ieee_bfd_link_split_section _bfd_generic_link_split_section 401933965Sjdp 402033965Sjdp/*SUPPRESS 460 */ 402133965Sjdpconst bfd_target ieee_vec = 402233965Sjdp{ 402333965Sjdp "ieee", /* name */ 402433965Sjdp bfd_target_ieee_flavour, 402533965Sjdp BFD_ENDIAN_UNKNOWN, /* target byte order */ 402633965Sjdp BFD_ENDIAN_UNKNOWN, /* target headers byte order */ 402733965Sjdp (HAS_RELOC | EXEC_P | /* object flags */ 402833965Sjdp HAS_LINENO | HAS_DEBUG | 402933965Sjdp HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 403033965Sjdp (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS 403133965Sjdp | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ 403233965Sjdp '_', /* leading underscore */ 403333965Sjdp ' ', /* ar_pad_char */ 403433965Sjdp 16, /* ar_max_namelen */ 403533965Sjdp bfd_getb64, bfd_getb_signed_64, bfd_putb64, 403633965Sjdp bfd_getb32, bfd_getb_signed_32, bfd_putb32, 403733965Sjdp bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ 403833965Sjdp bfd_getb64, bfd_getb_signed_64, bfd_putb64, 403933965Sjdp bfd_getb32, bfd_getb_signed_32, bfd_putb32, 404033965Sjdp bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ 404133965Sjdp 404233965Sjdp {_bfd_dummy_target, 404333965Sjdp ieee_object_p, /* bfd_check_format */ 404433965Sjdp ieee_archive_p, 404533965Sjdp _bfd_dummy_target, 404633965Sjdp }, 404733965Sjdp { 404833965Sjdp bfd_false, 404933965Sjdp ieee_mkobject, 405033965Sjdp _bfd_generic_mkarchive, 405133965Sjdp bfd_false 405233965Sjdp }, 405333965Sjdp { 405433965Sjdp bfd_false, 405533965Sjdp ieee_write_object_contents, 405633965Sjdp _bfd_write_archive_contents, 405733965Sjdp bfd_false, 405833965Sjdp }, 405933965Sjdp 406089857Sobrien /* ieee_close_and_cleanup, ieee_bfd_free_cached_info, ieee_new_section_hook, 406189857Sobrien ieee_get_section_contents, ieee_get_section_contents_in_window */ 406233965Sjdp BFD_JUMP_TABLE_GENERIC (ieee), 406389857Sobrien 406433965Sjdp BFD_JUMP_TABLE_COPY (_bfd_generic), 406533965Sjdp BFD_JUMP_TABLE_CORE (_bfd_nocore), 406689857Sobrien 406789857Sobrien /* ieee_slurp_armap, ieee_slurp_extended_name_table, 406889857Sobrien ieee_construct_extended_name_table, ieee_truncate_arname, 406989857Sobrien ieee_write_armap, ieee_read_ar_hdr, ieee_openr_next_archived_file, 407089857Sobrien ieee_get_elt_at_index, ieee_generic_stat_arch_elt, 407189857Sobrien ieee_update_armap_timestamp */ 407233965Sjdp BFD_JUMP_TABLE_ARCHIVE (ieee), 407389857Sobrien 407489857Sobrien /* ieee_get_symtab_upper_bound, ieee_get_symtab, ieee_make_empty_symbol, 407589857Sobrien ieee_print_symbol, ieee_get_symbol_info, ieee_bfd_is_local_label_name, 407689857Sobrien ieee_get_lineno, ieee_find_nearest_line, ieee_bfd_make_debug_symbol, 407789857Sobrien ieee_read_minisymbols, ieee_minisymbol_to_symbol */ 407833965Sjdp BFD_JUMP_TABLE_SYMBOLS (ieee), 407989857Sobrien 408089857Sobrien /* ieee_get_reloc_upper_bound, ieee_canonicalize_reloc, 408189857Sobrien ieee_bfd_reloc_type_lookup */ 408233965Sjdp BFD_JUMP_TABLE_RELOCS (ieee), 408389857Sobrien 408489857Sobrien /* ieee_set_arch_mach, ieee_set_section_contents */ 408533965Sjdp BFD_JUMP_TABLE_WRITE (ieee), 408689857Sobrien 408789857Sobrien /* ieee_sizeof_headers, ieee_bfd_get_relocated_section_contents, 408889857Sobrien ieee_bfd_relax_section, ieee_bfd_link_hash_table_create, 4089104834Sobrien _bfd_generic_link_hash_table_free, 409089857Sobrien ieee_bfd_link_add_symbols, ieee_bfd_final_link, 409189857Sobrien ieee_bfd_link_split_section, ieee_bfd_gc_sections, 409289857Sobrien ieee_bfd_merge_sections */ 409333965Sjdp BFD_JUMP_TABLE_LINK (ieee), 409489857Sobrien 409533965Sjdp BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 409633965Sjdp 409760484Sobrien NULL, 409889857Sobrien 409933965Sjdp (PTR) 0 410033965Sjdp}; 4101