12159047fSniklas /* BFD back-end for oasys objects.
2c074d1c9Sdrahn Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001,
3c074d1c9Sdrahn 2002, 2003 Free Software Foundation, Inc.
42159047fSniklas Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>.
52159047fSniklas
62159047fSniklas This file is part of BFD, the Binary File Descriptor library.
72159047fSniklas
82159047fSniklas This program is free software; you can redistribute it and/or modify
92159047fSniklas it under the terms of the GNU General Public License as published by
102159047fSniklas the Free Software Foundation; either version 2 of the License, or
112159047fSniklas (at your option) any later version.
122159047fSniklas
132159047fSniklas This program is distributed in the hope that it will be useful,
142159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
162159047fSniklas GNU General Public License for more details.
172159047fSniklas
182159047fSniklas You should have received a copy of the GNU General Public License
192159047fSniklas along with this program; if not, write to the Free Software
202159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
212159047fSniklas
222159047fSniklas #define UNDERSCORE_HACK 1
232159047fSniklas #include "bfd.h"
242159047fSniklas #include "sysdep.h"
25c074d1c9Sdrahn #include "safe-ctype.h"
262159047fSniklas #include "libbfd.h"
272159047fSniklas #include "oasys.h"
282159047fSniklas #include "liboasys.h"
292159047fSniklas
30c074d1c9Sdrahn static bfd_boolean oasys_slurp_section_data
31c074d1c9Sdrahn PARAMS ((bfd * const));
32c074d1c9Sdrahn static bfd_boolean oasys_read_record
33c074d1c9Sdrahn PARAMS ((bfd *, oasys_record_union_type *));
34c074d1c9Sdrahn static bfd_boolean oasys_write_sections
35c074d1c9Sdrahn PARAMS ((bfd *));
36c074d1c9Sdrahn static bfd_boolean oasys_write_record
37c074d1c9Sdrahn PARAMS ((bfd *, oasys_record_enum_type, oasys_record_union_type *, size_t));
38c074d1c9Sdrahn static bfd_boolean oasys_write_syms
39c074d1c9Sdrahn PARAMS ((bfd *));
40c074d1c9Sdrahn static bfd_boolean oasys_write_header
41c074d1c9Sdrahn PARAMS ((bfd *));
42c074d1c9Sdrahn static bfd_boolean oasys_write_end
43c074d1c9Sdrahn PARAMS ((bfd *));
44c074d1c9Sdrahn static bfd_boolean oasys_write_data
45c074d1c9Sdrahn PARAMS ((bfd *));
46c074d1c9Sdrahn static size_t oasys_string_length
47c074d1c9Sdrahn PARAMS ((oasys_record_union_type *));
48c074d1c9Sdrahn static bfd_boolean oasys_slurp_symbol_table
49c074d1c9Sdrahn PARAMS ((bfd *const));
50c074d1c9Sdrahn static long int oasys_get_symtab_upper_bound
51c074d1c9Sdrahn PARAMS ((bfd *const));
52c074d1c9Sdrahn static const bfd_target *oasys_archive_p
53c074d1c9Sdrahn PARAMS ((bfd *));
54c074d1c9Sdrahn static bfd_boolean oasys_mkobject
55c074d1c9Sdrahn PARAMS ((bfd *));
56c074d1c9Sdrahn static const bfd_target *oasys_object_p
57c074d1c9Sdrahn PARAMS ((bfd *));
58c074d1c9Sdrahn static void oasys_get_symbol_info
59c074d1c9Sdrahn PARAMS ((bfd *, asymbol *, symbol_info *));
60c074d1c9Sdrahn static void oasys_print_symbol
61c074d1c9Sdrahn PARAMS ((bfd *, void *, asymbol *, bfd_print_symbol_type));
62c074d1c9Sdrahn static bfd_boolean oasys_new_section_hook
63c074d1c9Sdrahn PARAMS ((bfd *, asection *));
64c074d1c9Sdrahn static long int oasys_get_reloc_upper_bound
65c074d1c9Sdrahn PARAMS ((bfd *, sec_ptr));
66c074d1c9Sdrahn static bfd_boolean oasys_get_section_contents
67c074d1c9Sdrahn PARAMS ((bfd *, sec_ptr, void *, file_ptr, bfd_size_type));
68c074d1c9Sdrahn static int comp
69c074d1c9Sdrahn PARAMS ((const void *, const void *));
70c074d1c9Sdrahn static bfd_boolean oasys_write_object_contents
71c074d1c9Sdrahn PARAMS ((bfd *));
72c074d1c9Sdrahn static bfd_boolean oasys_set_section_contents
73*007c2a45Smiod PARAMS ((bfd *, sec_ptr, const void *, file_ptr, bfd_size_type));
74c074d1c9Sdrahn static asymbol *oasys_make_empty_symbol
75c074d1c9Sdrahn PARAMS ((bfd *));
76c074d1c9Sdrahn static bfd *oasys_openr_next_archived_file
77c074d1c9Sdrahn PARAMS ((bfd *, bfd *));
78c074d1c9Sdrahn static bfd_boolean oasys_find_nearest_line
79c074d1c9Sdrahn PARAMS ((bfd *, asection *, asymbol **, bfd_vma,
80c074d1c9Sdrahn const char **, const char **, unsigned int *));
81c074d1c9Sdrahn static int oasys_generic_stat_arch_elt
82c074d1c9Sdrahn PARAMS ((bfd *, struct stat *));
83c074d1c9Sdrahn static int oasys_sizeof_headers
84c074d1c9Sdrahn PARAMS ((bfd *, bfd_boolean));
852159047fSniklas
86*007c2a45Smiod long oasys_canonicalize_symtab
87c074d1c9Sdrahn PARAMS ((bfd *, asymbol **));
88c074d1c9Sdrahn long oasys_canonicalize_reloc
89c074d1c9Sdrahn PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
902159047fSniklas
91c074d1c9Sdrahn /* Read in all the section data and relocation stuff too. */
922159047fSniklas
93c074d1c9Sdrahn static bfd_boolean
oasys_read_record(abfd,record)942159047fSniklas oasys_read_record (abfd, record)
952159047fSniklas bfd *abfd;
962159047fSniklas oasys_record_union_type *record;
972159047fSniklas {
98c074d1c9Sdrahn bfd_size_type amt = sizeof (record->header);
99c074d1c9Sdrahn if (bfd_bread ((PTR) record, amt, abfd) != amt)
100c074d1c9Sdrahn return FALSE;
1012159047fSniklas
102c074d1c9Sdrahn amt = record->header.length - sizeof (record->header);
103c074d1c9Sdrahn if ((long) amt <= 0)
104c074d1c9Sdrahn return TRUE;
105c074d1c9Sdrahn if (bfd_bread ((PTR) ((char *) record + sizeof (record->header)), amt, abfd)
106c074d1c9Sdrahn != amt)
107c074d1c9Sdrahn return FALSE;
108c074d1c9Sdrahn return TRUE;
1092159047fSniklas }
110c074d1c9Sdrahn
1112159047fSniklas static size_t
oasys_string_length(record)1122159047fSniklas oasys_string_length (record)
1132159047fSniklas oasys_record_union_type *record;
1142159047fSniklas {
1152159047fSniklas return record->header.length
1162159047fSniklas - ((char *) record->symbol.name - (char *) record);
1172159047fSniklas }
1182159047fSniklas
1192159047fSniklas /*****************************************************************************/
1202159047fSniklas
1212159047fSniklas /*
1222159047fSniklas
1232159047fSniklas Slurp the symbol table by reading in all the records at the start file
1242159047fSniklas till we get to the first section record.
1252159047fSniklas
1262159047fSniklas We'll sort the symbolss into two lists, defined and undefined. The
1272159047fSniklas undefined symbols will be placed into the table according to their
1282159047fSniklas refno.
1292159047fSniklas
1302159047fSniklas We do this by placing all undefined symbols at the front of the table
1312159047fSniklas moving in, and the defined symbols at the end of the table moving back.
1322159047fSniklas
1332159047fSniklas */
1342159047fSniklas
135c074d1c9Sdrahn static bfd_boolean
oasys_slurp_symbol_table(abfd)1362159047fSniklas oasys_slurp_symbol_table (abfd)
137c074d1c9Sdrahn bfd *const abfd;
1382159047fSniklas {
1392159047fSniklas oasys_record_union_type record;
1402159047fSniklas oasys_data_type *data = OASYS_DATA (abfd);
141c074d1c9Sdrahn bfd_boolean loop = TRUE;
1422159047fSniklas asymbol *dest_defined;
1432159047fSniklas asymbol *dest;
1442159047fSniklas char *string_ptr;
145c074d1c9Sdrahn bfd_size_type amt;
1462159047fSniklas
1472159047fSniklas if (data->symbols != (asymbol *) NULL)
1482159047fSniklas {
149c074d1c9Sdrahn return TRUE;
1502159047fSniklas }
1512159047fSniklas /* Buy enough memory for all the symbols and all the names */
152c074d1c9Sdrahn amt = abfd->symcount;
153c074d1c9Sdrahn amt *= sizeof (asymbol);
154c074d1c9Sdrahn data->symbols = (asymbol *) bfd_alloc (abfd, amt);
155c074d1c9Sdrahn
156c074d1c9Sdrahn amt = data->symbol_string_length;
1572159047fSniklas #ifdef UNDERSCORE_HACK
1582159047fSniklas /* buy 1 more char for each symbol to keep the underscore in*/
159c074d1c9Sdrahn amt += abfd->symcount;
1602159047fSniklas #endif
161c074d1c9Sdrahn data->strings = bfd_alloc (abfd, amt);
162c074d1c9Sdrahn
1632159047fSniklas if (!data->symbols || !data->strings)
164c074d1c9Sdrahn return FALSE;
1652159047fSniklas
1662159047fSniklas dest_defined = data->symbols + abfd->symcount - 1;
1672159047fSniklas
1682159047fSniklas string_ptr = data->strings;
1692159047fSniklas if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
170c074d1c9Sdrahn return FALSE;
1712159047fSniklas while (loop)
1722159047fSniklas {
1732159047fSniklas
1742159047fSniklas if (! oasys_read_record (abfd, &record))
175c074d1c9Sdrahn return FALSE;
1762159047fSniklas switch (record.header.type)
1772159047fSniklas {
1782159047fSniklas case oasys_record_is_header_enum:
1792159047fSniklas break;
1802159047fSniklas case oasys_record_is_local_enum:
1812159047fSniklas case oasys_record_is_symbol_enum:
1822159047fSniklas {
1832159047fSniklas int flag = record.header.type == (int) oasys_record_is_local_enum ?
1842159047fSniklas (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
1852159047fSniklas
1862159047fSniklas
1872159047fSniklas size_t length = oasys_string_length (&record);
1882159047fSniklas switch (record.symbol.relb & RELOCATION_TYPE_BITS)
1892159047fSniklas {
1902159047fSniklas case RELOCATION_TYPE_ABS:
1912159047fSniklas dest = dest_defined--;
1922159047fSniklas dest->section = bfd_abs_section_ptr;
1932159047fSniklas dest->flags = 0;
1942159047fSniklas
1952159047fSniklas break;
1962159047fSniklas case RELOCATION_TYPE_REL:
1972159047fSniklas dest = dest_defined--;
1982159047fSniklas dest->section =
1992159047fSniklas OASYS_DATA (abfd)->sections[record.symbol.relb &
2002159047fSniklas RELOCATION_SECT_BITS];
2012159047fSniklas if (record.header.type == (int) oasys_record_is_local_enum)
2022159047fSniklas {
2032159047fSniklas dest->flags = BSF_LOCAL;
2042159047fSniklas if (dest->section == (asection *) (~0))
2052159047fSniklas {
2062159047fSniklas /* It seems that sometimes internal symbols are tied up, but
2072159047fSniklas still get output, even though there is no
2082159047fSniklas section */
2092159047fSniklas dest->section = 0;
2102159047fSniklas }
2112159047fSniklas }
2122159047fSniklas else
2132159047fSniklas {
2142159047fSniklas
2152159047fSniklas dest->flags = flag;
2162159047fSniklas }
2172159047fSniklas break;
2182159047fSniklas case RELOCATION_TYPE_UND:
219c074d1c9Sdrahn dest = data->symbols + H_GET_16 (abfd, record.symbol.refno);
2202159047fSniklas dest->section = bfd_und_section_ptr;
2212159047fSniklas break;
2222159047fSniklas case RELOCATION_TYPE_COM:
2232159047fSniklas dest = dest_defined--;
2242159047fSniklas dest->name = string_ptr;
2252159047fSniklas dest->the_bfd = abfd;
2262159047fSniklas
2272159047fSniklas dest->section = bfd_com_section_ptr;
2282159047fSniklas
2292159047fSniklas break;
2302159047fSniklas default:
2312159047fSniklas dest = dest_defined--;
2322159047fSniklas BFD_ASSERT (0);
2332159047fSniklas break;
2342159047fSniklas }
2352159047fSniklas dest->name = string_ptr;
2362159047fSniklas dest->the_bfd = abfd;
2372159047fSniklas dest->udata.p = (PTR) NULL;
238c074d1c9Sdrahn dest->value = H_GET_32 (abfd, record.symbol.value);
2392159047fSniklas
2402159047fSniklas #ifdef UNDERSCORE_HACK
2412159047fSniklas if (record.symbol.name[0] != '_')
2422159047fSniklas {
2432159047fSniklas string_ptr[0] = '_';
2442159047fSniklas string_ptr++;
2452159047fSniklas }
2462159047fSniklas #endif
2472159047fSniklas memcpy (string_ptr, record.symbol.name, length);
2482159047fSniklas
2492159047fSniklas
2502159047fSniklas string_ptr[length] = 0;
2512159047fSniklas string_ptr += length + 1;
2522159047fSniklas }
2532159047fSniklas break;
2542159047fSniklas default:
255c074d1c9Sdrahn loop = FALSE;
2562159047fSniklas }
2572159047fSniklas }
258c074d1c9Sdrahn return TRUE;
2592159047fSniklas }
2602159047fSniklas
2612159047fSniklas static long
oasys_get_symtab_upper_bound(abfd)2622159047fSniklas oasys_get_symtab_upper_bound (abfd)
263c074d1c9Sdrahn bfd *const abfd;
2642159047fSniklas {
2652159047fSniklas if (! oasys_slurp_symbol_table (abfd))
2662159047fSniklas return -1;
2672159047fSniklas
2682159047fSniklas return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *));
2692159047fSniklas }
2702159047fSniklas
2712159047fSniklas extern const bfd_target oasys_vec;
2722159047fSniklas
2732159047fSniklas long
oasys_canonicalize_symtab(abfd,location)274*007c2a45Smiod oasys_canonicalize_symtab (abfd, location)
2752159047fSniklas bfd *abfd;
2762159047fSniklas asymbol **location;
2772159047fSniklas {
2782159047fSniklas asymbol *symbase;
2792159047fSniklas unsigned int counter;
280c074d1c9Sdrahn if (! oasys_slurp_symbol_table (abfd))
2812159047fSniklas {
2822159047fSniklas return -1;
2832159047fSniklas }
2842159047fSniklas symbase = OASYS_DATA (abfd)->symbols;
2852159047fSniklas for (counter = 0; counter < abfd->symcount; counter++)
2862159047fSniklas {
2872159047fSniklas *(location++) = symbase++;
2882159047fSniklas }
2892159047fSniklas *location = 0;
2902159047fSniklas return abfd->symcount;
2912159047fSniklas }
2922159047fSniklas
2932159047fSniklas /***********************************************************************
2942159047fSniklas * archive stuff
2952159047fSniklas */
2962159047fSniklas
2972159047fSniklas static const bfd_target *
oasys_archive_p(abfd)2982159047fSniklas oasys_archive_p (abfd)
2992159047fSniklas bfd *abfd;
3002159047fSniklas {
3012159047fSniklas oasys_archive_header_type header;
3022159047fSniklas oasys_extarchive_header_type header_ext;
3032159047fSniklas unsigned int i;
3042159047fSniklas file_ptr filepos;
305c074d1c9Sdrahn bfd_size_type amt;
3062159047fSniklas
307c074d1c9Sdrahn amt = sizeof (header_ext);
308c074d1c9Sdrahn if (bfd_seek (abfd, (file_ptr) 0, 0) != 0
309c074d1c9Sdrahn || bfd_bread ((PTR) &header_ext, amt, abfd) != amt)
3102159047fSniklas {
3112159047fSniklas if (bfd_get_error () != bfd_error_system_call)
3122159047fSniklas bfd_set_error (bfd_error_wrong_format);
3132159047fSniklas return NULL;
3142159047fSniklas }
3152159047fSniklas
316c074d1c9Sdrahn header.version = H_GET_32 (abfd, header_ext.version);
317c074d1c9Sdrahn header.mod_count = H_GET_32 (abfd, header_ext.mod_count);
318c074d1c9Sdrahn header.mod_tbl_offset = H_GET_32 (abfd, header_ext.mod_tbl_offset);
319c074d1c9Sdrahn header.sym_tbl_size = H_GET_32 (abfd, header_ext.sym_tbl_size);
320c074d1c9Sdrahn header.sym_count = H_GET_32 (abfd, header_ext.sym_count);
321c074d1c9Sdrahn header.sym_tbl_offset = H_GET_32 (abfd, header_ext.sym_tbl_offset);
322c074d1c9Sdrahn header.xref_count = H_GET_32 (abfd, header_ext.xref_count);
323c074d1c9Sdrahn header.xref_lst_offset = H_GET_32 (abfd, header_ext.xref_lst_offset);
3242159047fSniklas
3252159047fSniklas /*
3262159047fSniklas There isn't a magic number in an Oasys archive, so the best we
327*007c2a45Smiod can do to verify reasonableness is to make sure that the values in
3282159047fSniklas the header are too weird
3292159047fSniklas */
3302159047fSniklas
3312159047fSniklas if (header.version > 10000 ||
3322159047fSniklas header.mod_count > 10000 ||
3332159047fSniklas header.sym_count > 100000 ||
3342159047fSniklas header.xref_count > 100000)
3352159047fSniklas return (const bfd_target *) NULL;
3362159047fSniklas
3372159047fSniklas /*
3382159047fSniklas That all worked, let's buy the space for the header and read in
3392159047fSniklas the headers.
3402159047fSniklas */
3412159047fSniklas {
342c074d1c9Sdrahn oasys_ar_data_type *ar;
343c074d1c9Sdrahn oasys_module_info_type *module;
3442159047fSniklas oasys_module_table_type record;
3452159047fSniklas
346c074d1c9Sdrahn amt = sizeof (oasys_ar_data_type);
347c074d1c9Sdrahn ar = (oasys_ar_data_type *) bfd_alloc (abfd, amt);
348c074d1c9Sdrahn
349c074d1c9Sdrahn amt = header.mod_count;
350c074d1c9Sdrahn amt *= sizeof (oasys_module_info_type);
351c074d1c9Sdrahn module = (oasys_module_info_type *) bfd_alloc (abfd, amt);
352c074d1c9Sdrahn
3532159047fSniklas if (!ar || !module)
3542159047fSniklas return NULL;
3552159047fSniklas
3562159047fSniklas abfd->tdata.oasys_ar_data = ar;
3572159047fSniklas ar->module = module;
3582159047fSniklas ar->module_count = header.mod_count;
3592159047fSniklas
3602159047fSniklas filepos = header.mod_tbl_offset;
3612159047fSniklas for (i = 0; i < header.mod_count; i++)
3622159047fSniklas {
3632159047fSniklas if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
3642159047fSniklas return NULL;
3652159047fSniklas
3662159047fSniklas /* There are two ways of specifying the archive header */
3672159047fSniklas
3682159047fSniklas if (0)
3692159047fSniklas {
3702159047fSniklas oasys_extmodule_table_type_a_type record_ext;
371c074d1c9Sdrahn
372c074d1c9Sdrahn amt = sizeof (record_ext);
373c074d1c9Sdrahn if (bfd_bread ((PTR) &record_ext, amt, abfd) != amt)
3742159047fSniklas return NULL;
3752159047fSniklas
376c074d1c9Sdrahn record.mod_size = H_GET_32 (abfd, record_ext.mod_size);
377c074d1c9Sdrahn record.file_offset = H_GET_32 (abfd, record_ext.file_offset);
3782159047fSniklas
379c074d1c9Sdrahn record.dep_count = H_GET_32 (abfd, record_ext.dep_count);
380c074d1c9Sdrahn record.depee_count = H_GET_32 (abfd, record_ext.depee_count);
381c074d1c9Sdrahn record.sect_count = H_GET_32 (abfd, record_ext.sect_count);
3822159047fSniklas
383c074d1c9Sdrahn module[i].name = bfd_alloc (abfd, (bfd_size_type) 33);
3842159047fSniklas if (!module[i].name)
3852159047fSniklas return NULL;
3862159047fSniklas
3872159047fSniklas memcpy (module[i].name, record_ext.mod_name, 33);
3882159047fSniklas filepos +=
3892159047fSniklas sizeof (record_ext) +
3902159047fSniklas record.dep_count * 4 +
3912159047fSniklas record.depee_count * 4 +
3922159047fSniklas record.sect_count * 8 + 187;
3932159047fSniklas }
3942159047fSniklas else
3952159047fSniklas {
3962159047fSniklas oasys_extmodule_table_type_b_type record_ext;
397c074d1c9Sdrahn
398c074d1c9Sdrahn amt = sizeof (record_ext);
399c074d1c9Sdrahn if (bfd_bread ((PTR) &record_ext, amt, abfd) != amt)
4002159047fSniklas return NULL;
4012159047fSniklas
402c074d1c9Sdrahn record.mod_size = H_GET_32 (abfd, record_ext.mod_size);
403c074d1c9Sdrahn record.file_offset = H_GET_32 (abfd, record_ext.file_offset);
4042159047fSniklas
405c074d1c9Sdrahn record.dep_count = H_GET_32 (abfd, record_ext.dep_count);
406c074d1c9Sdrahn record.depee_count = H_GET_32 (abfd, record_ext.depee_count);
407c074d1c9Sdrahn record.sect_count = H_GET_32 (abfd, record_ext.sect_count);
408c074d1c9Sdrahn record.module_name_size = H_GET_32 (abfd,
409c074d1c9Sdrahn record_ext.mod_name_length);
4102159047fSniklas
411c074d1c9Sdrahn amt = record.module_name_size;
412c074d1c9Sdrahn module[i].name = bfd_alloc (abfd, amt + 1);
4132159047fSniklas if (!module[i].name)
4142159047fSniklas return NULL;
415c074d1c9Sdrahn if (bfd_bread ((PTR) module[i].name, amt, abfd) != amt)
4162159047fSniklas return NULL;
4172159047fSniklas module[i].name[record.module_name_size] = 0;
418c074d1c9Sdrahn filepos += (sizeof (record_ext)
419c074d1c9Sdrahn + record.dep_count * 4
420c074d1c9Sdrahn + record.module_name_size + 1);
4212159047fSniklas }
4222159047fSniklas
4232159047fSniklas module[i].size = record.mod_size;
4242159047fSniklas module[i].pos = record.file_offset;
4252159047fSniklas module[i].abfd = 0;
4262159047fSniklas }
4272159047fSniklas }
4282159047fSniklas return abfd->xvec;
4292159047fSniklas }
4302159047fSniklas
431c074d1c9Sdrahn static bfd_boolean
oasys_mkobject(abfd)4322159047fSniklas oasys_mkobject (abfd)
4332159047fSniklas bfd *abfd;
4342159047fSniklas {
435c074d1c9Sdrahn bfd_size_type amt = sizeof (oasys_data_type);
436c074d1c9Sdrahn abfd->tdata.oasys_obj_data = (oasys_data_type *) bfd_alloc (abfd, amt);
437c074d1c9Sdrahn return abfd->tdata.oasys_obj_data != NULL;
4382159047fSniklas }
4392159047fSniklas
4402159047fSniklas #define MAX_SECS 16
4412159047fSniklas static const bfd_target *
oasys_object_p(abfd)4422159047fSniklas oasys_object_p (abfd)
4432159047fSniklas bfd *abfd;
4442159047fSniklas {
4452159047fSniklas oasys_data_type *oasys;
4462159047fSniklas oasys_data_type *save = OASYS_DATA (abfd);
447c074d1c9Sdrahn bfd_boolean loop = TRUE;
448c074d1c9Sdrahn bfd_boolean had_usefull = FALSE;
4492159047fSniklas
4502159047fSniklas abfd->tdata.oasys_obj_data = 0;
4512159047fSniklas oasys_mkobject (abfd);
4522159047fSniklas oasys = OASYS_DATA (abfd);
4532159047fSniklas memset ((PTR) oasys->sections, 0xff, sizeof (oasys->sections));
4542159047fSniklas
4552159047fSniklas /* Point to the start of the file */
4562159047fSniklas if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
4572159047fSniklas goto fail;
4582159047fSniklas oasys->symbol_string_length = 0;
4592159047fSniklas /* Inspect the records, but only keep the section info -
4602159047fSniklas remember the size of the symbols
4612159047fSniklas */
4622159047fSniklas oasys->first_data_record = 0;
4632159047fSniklas while (loop)
4642159047fSniklas {
4652159047fSniklas oasys_record_union_type record;
4662159047fSniklas if (! oasys_read_record (abfd, &record))
4672159047fSniklas goto fail;
4682159047fSniklas if ((size_t) record.header.length < (size_t) sizeof (record.header))
4692159047fSniklas goto fail;
4702159047fSniklas
4712159047fSniklas
4722159047fSniklas switch ((oasys_record_enum_type) (record.header.type))
4732159047fSniklas {
4742159047fSniklas case oasys_record_is_header_enum:
475c074d1c9Sdrahn had_usefull = TRUE;
4762159047fSniklas break;
4772159047fSniklas case oasys_record_is_symbol_enum:
4782159047fSniklas case oasys_record_is_local_enum:
4792159047fSniklas /* Count symbols and remember their size for a future malloc */
4802159047fSniklas abfd->symcount++;
4812159047fSniklas oasys->symbol_string_length += 1 + oasys_string_length (&record);
482c074d1c9Sdrahn had_usefull = TRUE;
4832159047fSniklas break;
4842159047fSniklas case oasys_record_is_section_enum:
4852159047fSniklas {
4862159047fSniklas asection *s;
4872159047fSniklas char *buffer;
4882159047fSniklas unsigned int section_number;
4892159047fSniklas if (record.section.header.length != sizeof (record.section))
4902159047fSniklas {
4912159047fSniklas goto fail;
4922159047fSniklas }
493c074d1c9Sdrahn buffer = bfd_alloc (abfd, (bfd_size_type) 3);
4942159047fSniklas if (!buffer)
4952159047fSniklas goto fail;
4962159047fSniklas section_number = record.section.relb & RELOCATION_SECT_BITS;
4972159047fSniklas sprintf (buffer, "%u", section_number);
4982159047fSniklas s = bfd_make_section (abfd, buffer);
4992159047fSniklas oasys->sections[section_number] = s;
5002159047fSniklas switch (record.section.relb & RELOCATION_TYPE_BITS)
5012159047fSniklas {
5022159047fSniklas case RELOCATION_TYPE_ABS:
5032159047fSniklas case RELOCATION_TYPE_REL:
5042159047fSniklas break;
5052159047fSniklas case RELOCATION_TYPE_UND:
5062159047fSniklas case RELOCATION_TYPE_COM:
5072159047fSniklas BFD_FAIL ();
5082159047fSniklas }
5092159047fSniklas
510c074d1c9Sdrahn s->_raw_size = H_GET_32 (abfd, record.section.value);
511c074d1c9Sdrahn s->vma = H_GET_32 (abfd, record.section.vma);
5122159047fSniklas s->flags = 0;
513c074d1c9Sdrahn had_usefull = TRUE;
5142159047fSniklas }
5152159047fSniklas break;
5162159047fSniklas case oasys_record_is_data_enum:
5172159047fSniklas oasys->first_data_record = bfd_tell (abfd) - record.header.length;
5182159047fSniklas case oasys_record_is_debug_enum:
5192159047fSniklas case oasys_record_is_module_enum:
5202159047fSniklas case oasys_record_is_named_section_enum:
5212159047fSniklas case oasys_record_is_end_enum:
522c074d1c9Sdrahn if (! had_usefull)
5232159047fSniklas goto fail;
524c074d1c9Sdrahn loop = FALSE;
5252159047fSniklas break;
5262159047fSniklas default:
5272159047fSniklas goto fail;
5282159047fSniklas }
5292159047fSniklas }
5302159047fSniklas oasys->symbols = (asymbol *) NULL;
5312159047fSniklas /*
5322159047fSniklas Oasys support several architectures, but I can't see a simple way
5332159047fSniklas to discover which one is in a particular file - we'll guess
5342159047fSniklas */
5352159047fSniklas bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
5362159047fSniklas if (abfd->symcount != 0)
5372159047fSniklas {
5382159047fSniklas abfd->flags |= HAS_SYMS;
5392159047fSniklas }
5402159047fSniklas
5412159047fSniklas /*
5422159047fSniklas We don't know if a section has data until we've read it..
5432159047fSniklas */
5442159047fSniklas
5452159047fSniklas oasys_slurp_section_data (abfd);
5462159047fSniklas
5472159047fSniklas
5482159047fSniklas return abfd->xvec;
5492159047fSniklas
5502159047fSniklas fail:
5512159047fSniklas (void) bfd_release (abfd, oasys);
5522159047fSniklas abfd->tdata.oasys_obj_data = save;
5532159047fSniklas return (const bfd_target *) NULL;
5542159047fSniklas }
5552159047fSniklas
5562159047fSniklas
5572159047fSniklas static void
oasys_get_symbol_info(ignore_abfd,symbol,ret)5582159047fSniklas oasys_get_symbol_info (ignore_abfd, symbol, ret)
559b305b0f1Sespie bfd *ignore_abfd ATTRIBUTE_UNUSED;
5602159047fSniklas asymbol *symbol;
5612159047fSniklas symbol_info *ret;
5622159047fSniklas {
5632159047fSniklas bfd_symbol_info (symbol, ret);
5642159047fSniklas if (!symbol->section)
5652159047fSniklas ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
5662159047fSniklas }
5672159047fSniklas
5682159047fSniklas static void
oasys_print_symbol(abfd,afile,symbol,how)569c074d1c9Sdrahn oasys_print_symbol (abfd, afile, symbol, how)
570c074d1c9Sdrahn bfd *abfd;
5712159047fSniklas PTR afile;
5722159047fSniklas asymbol *symbol;
5732159047fSniklas bfd_print_symbol_type how;
5742159047fSniklas {
5752159047fSniklas FILE *file = (FILE *) afile;
5762159047fSniklas
5772159047fSniklas switch (how)
5782159047fSniklas {
5792159047fSniklas case bfd_print_symbol_name:
5802159047fSniklas case bfd_print_symbol_more:
5812159047fSniklas fprintf (file, "%s", symbol->name);
5822159047fSniklas break;
5832159047fSniklas case bfd_print_symbol_all:
5842159047fSniklas {
585c074d1c9Sdrahn const char *section_name = symbol->section == (asection *) NULL ?
586c074d1c9Sdrahn (const char *) "*abs" : symbol->section->name;
5872159047fSniklas
588c074d1c9Sdrahn bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
5892159047fSniklas
5902159047fSniklas fprintf (file, " %-5s %s",
5912159047fSniklas section_name,
5922159047fSniklas symbol->name);
5932159047fSniklas }
5942159047fSniklas break;
5952159047fSniklas }
5962159047fSniklas }
5972159047fSniklas /*
5982159047fSniklas The howto table is build using the top two bits of a reloc byte to
5992159047fSniklas index into it. The bits are PCREL,WORD/LONG
6002159047fSniklas */
6012159047fSniklas static reloc_howto_type howto_table[] =
6022159047fSniklas {
6032159047fSniklas
604c074d1c9Sdrahn HOWTO (0, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, 0, "abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
605c074d1c9Sdrahn HOWTO (0, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "abs32", TRUE, 0xffffffff, 0xffffffff, FALSE),
606c074d1c9Sdrahn HOWTO (0, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "pcrel16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
607c074d1c9Sdrahn HOWTO (0, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0, "pcrel32", TRUE, 0xffffffff, 0xffffffff, FALSE)
6082159047fSniklas };
6092159047fSniklas
6102159047fSniklas /* Read in all the section data and relocation stuff too */
611c074d1c9Sdrahn static bfd_boolean
oasys_slurp_section_data(abfd)6122159047fSniklas oasys_slurp_section_data (abfd)
613c074d1c9Sdrahn bfd *const abfd;
6142159047fSniklas {
6152159047fSniklas oasys_record_union_type record;
6162159047fSniklas oasys_data_type *data = OASYS_DATA (abfd);
617c074d1c9Sdrahn bfd_boolean loop = TRUE;
6182159047fSniklas oasys_per_section_type *per;
6192159047fSniklas asection *s;
620c074d1c9Sdrahn bfd_size_type amt;
6212159047fSniklas
6222159047fSniklas /* See if the data has been slurped already .. */
6232159047fSniklas for (s = abfd->sections; s != (asection *) NULL; s = s->next)
6242159047fSniklas {
6252159047fSniklas per = oasys_per_section (s);
626c074d1c9Sdrahn if (per->initialized)
627c074d1c9Sdrahn return TRUE;
6282159047fSniklas }
6292159047fSniklas
6302159047fSniklas if (data->first_data_record == 0)
631c074d1c9Sdrahn return TRUE;
6322159047fSniklas
6332159047fSniklas if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0)
634c074d1c9Sdrahn return FALSE;
6352159047fSniklas while (loop)
6362159047fSniklas {
6372159047fSniklas if (! oasys_read_record (abfd, &record))
638c074d1c9Sdrahn return FALSE;
6392159047fSniklas switch (record.header.type)
6402159047fSniklas {
6412159047fSniklas case oasys_record_is_header_enum:
6422159047fSniklas break;
6432159047fSniklas case oasys_record_is_data_enum:
6442159047fSniklas {
6452159047fSniklas
6462159047fSniklas bfd_byte *src = record.data.data;
6472159047fSniklas bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length;
6482159047fSniklas bfd_byte *dst_ptr;
6492159047fSniklas bfd_byte *dst_base_ptr;
6502159047fSniklas unsigned int relbit;
6512159047fSniklas unsigned int count;
6522159047fSniklas asection *section =
6532159047fSniklas data->sections[record.data.relb & RELOCATION_SECT_BITS];
6542159047fSniklas bfd_vma dst_offset;
6552159047fSniklas
6562159047fSniklas per = oasys_per_section (section);
6572159047fSniklas
658c074d1c9Sdrahn if (! per->initialized)
6592159047fSniklas {
6602159047fSniklas per->data = (bfd_byte *) bfd_zalloc (abfd, section->_raw_size);
6612159047fSniklas if (!per->data)
662c074d1c9Sdrahn return FALSE;
663c074d1c9Sdrahn per->reloc_tail_ptr
664c074d1c9Sdrahn = (oasys_reloc_type **) §ion->relocation;
665c074d1c9Sdrahn per->had_vma = FALSE;
666c074d1c9Sdrahn per->initialized = TRUE;
6672159047fSniklas section->reloc_count = 0;
6682159047fSniklas section->flags = SEC_ALLOC;
6692159047fSniklas }
6702159047fSniklas
671c074d1c9Sdrahn dst_offset = H_GET_32 (abfd, record.data.addr);
672c074d1c9Sdrahn if (! per->had_vma)
6732159047fSniklas {
6742159047fSniklas /* Take the first vma we see as the base */
6752159047fSniklas section->vma = dst_offset;
676c074d1c9Sdrahn per->had_vma = TRUE;
6772159047fSniklas }
6782159047fSniklas
6792159047fSniklas dst_offset -= section->vma;
6802159047fSniklas
6812159047fSniklas dst_base_ptr = oasys_per_section (section)->data;
6822159047fSniklas dst_ptr = oasys_per_section (section)->data +
6832159047fSniklas dst_offset;
6842159047fSniklas
6852159047fSniklas if (src < end_src)
6862159047fSniklas {
6872159047fSniklas section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
6882159047fSniklas }
6892159047fSniklas while (src < end_src)
6902159047fSniklas {
6912159047fSniklas unsigned char mod_byte = *src++;
6922159047fSniklas size_t gap = end_src - src;
6932159047fSniklas
6942159047fSniklas count = 8;
6952159047fSniklas if (mod_byte == 0 && gap >= 8)
6962159047fSniklas {
6972159047fSniklas dst_ptr[0] = src[0];
6982159047fSniklas dst_ptr[1] = src[1];
6992159047fSniklas dst_ptr[2] = src[2];
7002159047fSniklas dst_ptr[3] = src[3];
7012159047fSniklas dst_ptr[4] = src[4];
7022159047fSniklas dst_ptr[5] = src[5];
7032159047fSniklas dst_ptr[6] = src[6];
7042159047fSniklas dst_ptr[7] = src[7];
7052159047fSniklas dst_ptr += 8;
7062159047fSniklas src += 8;
7072159047fSniklas }
7082159047fSniklas else
7092159047fSniklas {
7102159047fSniklas for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1)
7112159047fSniklas {
7122159047fSniklas if (relbit & mod_byte)
7132159047fSniklas {
7142159047fSniklas unsigned char reloc = *src;
7152159047fSniklas /* This item needs to be relocated */
7162159047fSniklas switch (reloc & RELOCATION_TYPE_BITS)
7172159047fSniklas {
7182159047fSniklas case RELOCATION_TYPE_ABS:
7192159047fSniklas
7202159047fSniklas break;
7212159047fSniklas
7222159047fSniklas case RELOCATION_TYPE_REL:
7232159047fSniklas {
7242159047fSniklas /* Relocate the item relative to the section */
725c074d1c9Sdrahn oasys_reloc_type *r;
726c074d1c9Sdrahn
727c074d1c9Sdrahn amt = sizeof (oasys_reloc_type);
728c074d1c9Sdrahn r = (oasys_reloc_type *) bfd_alloc (abfd,
729c074d1c9Sdrahn amt);
7302159047fSniklas if (!r)
731c074d1c9Sdrahn return FALSE;
7322159047fSniklas *(per->reloc_tail_ptr) = r;
7332159047fSniklas per->reloc_tail_ptr = &r->next;
7342159047fSniklas r->next = (oasys_reloc_type *) NULL;
7352159047fSniklas /* Reference to undefined symbol */
7362159047fSniklas src++;
7372159047fSniklas /* There is no symbol */
7382159047fSniklas r->symbol = 0;
7392159047fSniklas /* Work out the howto */
7402159047fSniklas abort ();
7412159047fSniklas #if 0
7422159047fSniklas r->relent.section =
7432159047fSniklas data->sections[reloc &
7442159047fSniklas RELOCATION_SECT_BITS];
7452159047fSniklas
7462159047fSniklas r->relent.addend = -
7472159047fSniklas r->relent.section->vma;
7482159047fSniklas #endif
7492159047fSniklas r->relent.address = dst_ptr - dst_base_ptr;
7502159047fSniklas r->relent.howto = &howto_table[reloc >> 6];
7512159047fSniklas r->relent.sym_ptr_ptr = (asymbol **) NULL;
7522159047fSniklas section->reloc_count++;
7532159047fSniklas
754c074d1c9Sdrahn /* Fake up the data to look like
755c074d1c9Sdrahn it's got the -ve pc in it, this
756c074d1c9Sdrahn makes it much easier to convert
757c074d1c9Sdrahn into other formats. This is done
758c074d1c9Sdrahn by hitting the addend. */
759c074d1c9Sdrahn if (r->relent.howto->pc_relative)
7602159047fSniklas r->relent.addend -= dst_ptr - dst_base_ptr;
7612159047fSniklas }
7622159047fSniklas break;
7632159047fSniklas
7642159047fSniklas
7652159047fSniklas case RELOCATION_TYPE_UND:
7662159047fSniklas {
767c074d1c9Sdrahn oasys_reloc_type *r;
768c074d1c9Sdrahn
769c074d1c9Sdrahn amt = sizeof (oasys_reloc_type);
770c074d1c9Sdrahn r = (oasys_reloc_type *) bfd_alloc (abfd,
771c074d1c9Sdrahn amt);
7722159047fSniklas if (!r)
773c074d1c9Sdrahn return FALSE;
7742159047fSniklas *(per->reloc_tail_ptr) = r;
7752159047fSniklas per->reloc_tail_ptr = &r->next;
7762159047fSniklas r->next = (oasys_reloc_type *) NULL;
7772159047fSniklas /* Reference to undefined symbol */
7782159047fSniklas src++;
7792159047fSniklas /* Get symbol number */
7802159047fSniklas r->symbol = (src[0] << 8) | src[1];
7812159047fSniklas /* Work out the howto */
7822159047fSniklas abort ();
7832159047fSniklas
7842159047fSniklas #if 0
7852159047fSniklas r->relent.section = (asection
7862159047fSniklas *) NULL;
7872159047fSniklas #endif
7882159047fSniklas r->relent.addend = 0;
7892159047fSniklas r->relent.address = dst_ptr - dst_base_ptr;
7902159047fSniklas r->relent.howto = &howto_table[reloc >> 6];
7912159047fSniklas r->relent.sym_ptr_ptr = (asymbol **) NULL;
7922159047fSniklas section->reloc_count++;
7932159047fSniklas
7942159047fSniklas src += 2;
795c074d1c9Sdrahn /* Fake up the data to look like
796c074d1c9Sdrahn it's got the -ve pc in it, this
797c074d1c9Sdrahn makes it much easier to convert
798c074d1c9Sdrahn into other formats. This is done
799c074d1c9Sdrahn by hitting the addend. */
800c074d1c9Sdrahn if (r->relent.howto->pc_relative)
8012159047fSniklas r->relent.addend -= dst_ptr - dst_base_ptr;
8022159047fSniklas }
8032159047fSniklas break;
8042159047fSniklas case RELOCATION_TYPE_COM:
8052159047fSniklas BFD_FAIL ();
8062159047fSniklas }
8072159047fSniklas }
8082159047fSniklas *dst_ptr++ = *src++;
8092159047fSniklas }
8102159047fSniklas }
8112159047fSniklas }
8122159047fSniklas }
8132159047fSniklas break;
8142159047fSniklas case oasys_record_is_local_enum:
8152159047fSniklas case oasys_record_is_symbol_enum:
8162159047fSniklas case oasys_record_is_section_enum:
8172159047fSniklas break;
8182159047fSniklas default:
819c074d1c9Sdrahn loop = FALSE;
8202159047fSniklas }
8212159047fSniklas }
8222159047fSniklas
823c074d1c9Sdrahn return TRUE;
8242159047fSniklas
8252159047fSniklas }
8262159047fSniklas
827c074d1c9Sdrahn static bfd_boolean
oasys_new_section_hook(abfd,newsect)8282159047fSniklas oasys_new_section_hook (abfd, newsect)
8292159047fSniklas bfd *abfd;
8302159047fSniklas asection *newsect;
8312159047fSniklas {
8322159047fSniklas newsect->used_by_bfd = (PTR)
833c074d1c9Sdrahn bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type));
8342159047fSniklas if (!newsect->used_by_bfd)
835c074d1c9Sdrahn return FALSE;
8362159047fSniklas oasys_per_section (newsect)->data = (bfd_byte *) NULL;
8372159047fSniklas oasys_per_section (newsect)->section = newsect;
8382159047fSniklas oasys_per_section (newsect)->offset = 0;
839c074d1c9Sdrahn oasys_per_section (newsect)->initialized = FALSE;
8402159047fSniklas newsect->alignment_power = 1;
8412159047fSniklas /* Turn the section string into an index */
8422159047fSniklas
8432159047fSniklas sscanf (newsect->name, "%u", &newsect->target_index);
8442159047fSniklas
845c074d1c9Sdrahn return TRUE;
8462159047fSniklas }
8472159047fSniklas
8482159047fSniklas
8492159047fSniklas static long
oasys_get_reloc_upper_bound(abfd,asect)8502159047fSniklas oasys_get_reloc_upper_bound (abfd, asect)
8512159047fSniklas bfd *abfd;
8522159047fSniklas sec_ptr asect;
8532159047fSniklas {
8542159047fSniklas if (! oasys_slurp_section_data (abfd))
8552159047fSniklas return -1;
8562159047fSniklas return (asect->reloc_count + 1) * sizeof (arelent *);
8572159047fSniklas }
8582159047fSniklas
859c074d1c9Sdrahn static bfd_boolean
oasys_get_section_contents(abfd,section,location,offset,count)8602159047fSniklas oasys_get_section_contents (abfd, section, location, offset, count)
8612159047fSniklas bfd *abfd;
8622159047fSniklas sec_ptr section;
8632159047fSniklas PTR location;
8642159047fSniklas file_ptr offset;
8652159047fSniklas bfd_size_type count;
8662159047fSniklas {
867c074d1c9Sdrahn oasys_per_section_type *p = oasys_per_section (section);
8682159047fSniklas oasys_slurp_section_data (abfd);
869c074d1c9Sdrahn if (! p->initialized)
8702159047fSniklas {
871c074d1c9Sdrahn (void) memset (location, 0, (size_t) count);
8722159047fSniklas }
8732159047fSniklas else
8742159047fSniklas {
875c074d1c9Sdrahn (void) memcpy (location, (PTR) (p->data + offset), (size_t) count);
8762159047fSniklas }
877c074d1c9Sdrahn return TRUE;
8782159047fSniklas }
8792159047fSniklas
8802159047fSniklas
8812159047fSniklas long
oasys_canonicalize_reloc(ignore_abfd,section,relptr,symbols)8822159047fSniklas oasys_canonicalize_reloc (ignore_abfd, section, relptr, symbols)
883b305b0f1Sespie bfd *ignore_abfd ATTRIBUTE_UNUSED;
8842159047fSniklas sec_ptr section;
8852159047fSniklas arelent **relptr;
886b305b0f1Sespie asymbol **symbols ATTRIBUTE_UNUSED;
8872159047fSniklas {
8882159047fSniklas unsigned int reloc_count = 0;
8892159047fSniklas oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation);
8902159047fSniklas while (src != (oasys_reloc_type *) NULL)
8912159047fSniklas {
8922159047fSniklas abort ();
8932159047fSniklas
8942159047fSniklas #if 0
8952159047fSniklas if (src->relent.section == (asection *) NULL)
8962159047fSniklas {
8972159047fSniklas src->relent.sym_ptr_ptr = symbols + src->symbol;
8982159047fSniklas }
8992159047fSniklas #endif
9002159047fSniklas
9012159047fSniklas *relptr++ = &src->relent;
9022159047fSniklas src = src->next;
9032159047fSniklas reloc_count++;
9042159047fSniklas }
9052159047fSniklas *relptr = (arelent *) NULL;
9062159047fSniklas return section->reloc_count = reloc_count;
9072159047fSniklas }
9082159047fSniklas
9092159047fSniklas
9102159047fSniklas
9112159047fSniklas
9122159047fSniklas /* Writing */
9132159047fSniklas
9142159047fSniklas
9152159047fSniklas /* Calculate the checksum and write one record */
916c074d1c9Sdrahn static bfd_boolean
oasys_write_record(abfd,type,record,size)9172159047fSniklas oasys_write_record (abfd, type, record, size)
9182159047fSniklas bfd *abfd;
9192159047fSniklas oasys_record_enum_type type;
9202159047fSniklas oasys_record_union_type *record;
9212159047fSniklas size_t size;
9222159047fSniklas {
9232159047fSniklas int checksum;
9242159047fSniklas size_t i;
9252159047fSniklas unsigned char *ptr;
9262159047fSniklas
9272159047fSniklas record->header.length = size;
9282159047fSniklas record->header.type = (int) type;
9292159047fSniklas record->header.check_sum = 0;
9302159047fSniklas record->header.fill = 0;
9312159047fSniklas ptr = (unsigned char *) &record->pad[0];
9322159047fSniklas checksum = 0;
9332159047fSniklas for (i = 0; i < size; i++)
9342159047fSniklas {
9352159047fSniklas checksum += *ptr++;
9362159047fSniklas }
9372159047fSniklas record->header.check_sum = 0xff & (-checksum);
938c074d1c9Sdrahn if (bfd_bwrite ((PTR) record, (bfd_size_type) size, abfd) != size)
939c074d1c9Sdrahn return FALSE;
940c074d1c9Sdrahn return TRUE;
9412159047fSniklas }
9422159047fSniklas
9432159047fSniklas
9442159047fSniklas /* Write out all the symbols */
945c074d1c9Sdrahn static bfd_boolean
oasys_write_syms(abfd)9462159047fSniklas oasys_write_syms (abfd)
9472159047fSniklas bfd *abfd;
9482159047fSniklas {
9492159047fSniklas unsigned int count;
9502159047fSniklas asymbol **generic = bfd_get_outsymbols (abfd);
9512159047fSniklas unsigned int index = 0;
9522159047fSniklas for (count = 0; count < bfd_get_symcount (abfd); count++)
9532159047fSniklas {
9542159047fSniklas
9552159047fSniklas oasys_symbol_record_type symbol;
956c074d1c9Sdrahn asymbol *const g = generic[count];
9572159047fSniklas
958c074d1c9Sdrahn const char *src = g->name;
9592159047fSniklas char *dst = symbol.name;
9602159047fSniklas unsigned int l = 0;
9612159047fSniklas
9622159047fSniklas if (bfd_is_com_section (g->section))
9632159047fSniklas {
9642159047fSniklas symbol.relb = RELOCATION_TYPE_COM;
965c074d1c9Sdrahn H_PUT_16 (abfd, index, symbol.refno);
9662159047fSniklas index++;
9672159047fSniklas }
9682159047fSniklas else if (bfd_is_abs_section (g->section))
9692159047fSniklas {
9702159047fSniklas symbol.relb = RELOCATION_TYPE_ABS;
971c074d1c9Sdrahn H_PUT_16 (abfd, 0, symbol.refno);
9722159047fSniklas
9732159047fSniklas }
9742159047fSniklas else if (bfd_is_und_section (g->section))
9752159047fSniklas {
9762159047fSniklas symbol.relb = RELOCATION_TYPE_UND;
977c074d1c9Sdrahn H_PUT_16 (abfd, index, symbol.refno);
9782159047fSniklas /* Overload the value field with the output index number */
9792159047fSniklas index++;
9802159047fSniklas }
9812159047fSniklas else if (g->flags & BSF_DEBUGGING)
9822159047fSniklas {
9832159047fSniklas /* throw it away */
9842159047fSniklas continue;
9852159047fSniklas }
9862159047fSniklas else
9872159047fSniklas {
9882159047fSniklas if (g->section == (asection *) NULL)
9892159047fSniklas {
9902159047fSniklas /* Sometime, the oasys tools give out a symbol with illegal
9912159047fSniklas bits in it, we'll output it in the same broken way */
9922159047fSniklas
9932159047fSniklas symbol.relb = RELOCATION_TYPE_REL | 0;
9942159047fSniklas }
9952159047fSniklas else
9962159047fSniklas {
9972159047fSniklas symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
9982159047fSniklas }
999c074d1c9Sdrahn H_PUT_16 (abfd, 0, symbol.refno);
10002159047fSniklas }
10012159047fSniklas #ifdef UNDERSCORE_HACK
10022159047fSniklas if (src[l] == '_')
10032159047fSniklas dst[l++] = '.';
10042159047fSniklas #endif
10052159047fSniklas while (src[l])
10062159047fSniklas {
10072159047fSniklas dst[l] = src[l];
10082159047fSniklas l++;
10092159047fSniklas }
10102159047fSniklas
1011c074d1c9Sdrahn H_PUT_32 (abfd, g->value, symbol.value);
10122159047fSniklas
10132159047fSniklas
10142159047fSniklas if (g->flags & BSF_LOCAL)
10152159047fSniklas {
10162159047fSniklas if (! oasys_write_record (abfd,
10172159047fSniklas oasys_record_is_local_enum,
10182159047fSniklas (oasys_record_union_type *) & symbol,
10192159047fSniklas offsetof (oasys_symbol_record_type,
10202159047fSniklas name[0]) + l))
1021c074d1c9Sdrahn return FALSE;
10222159047fSniklas }
10232159047fSniklas else
10242159047fSniklas {
10252159047fSniklas if (! oasys_write_record (abfd,
10262159047fSniklas oasys_record_is_symbol_enum,
10272159047fSniklas (oasys_record_union_type *) & symbol,
10282159047fSniklas offsetof (oasys_symbol_record_type,
10292159047fSniklas name[0]) + l))
1030c074d1c9Sdrahn return FALSE;
10312159047fSniklas }
10322159047fSniklas g->value = index - 1;
10332159047fSniklas }
10342159047fSniklas
1035c074d1c9Sdrahn return TRUE;
10362159047fSniklas }
10372159047fSniklas
10382159047fSniklas
10392159047fSniklas /* Write a section header for each section */
1040c074d1c9Sdrahn static bfd_boolean
oasys_write_sections(abfd)10412159047fSniklas oasys_write_sections (abfd)
10422159047fSniklas bfd *abfd;
10432159047fSniklas {
10442159047fSniklas asection *s;
10452159047fSniklas static oasys_section_record_type out;
10462159047fSniklas
10472159047fSniklas for (s = abfd->sections; s != (asection *) NULL; s = s->next)
10482159047fSniklas {
1049c074d1c9Sdrahn if (!ISDIGIT (s->name[0]))
10502159047fSniklas {
10512159047fSniklas (*_bfd_error_handler)
1052b305b0f1Sespie (_("%s: can not represent section `%s' in oasys"),
10532159047fSniklas bfd_get_filename (abfd), s->name);
10542159047fSniklas bfd_set_error (bfd_error_nonrepresentable_section);
1055c074d1c9Sdrahn return FALSE;
10562159047fSniklas }
10572159047fSniklas out.relb = RELOCATION_TYPE_REL | s->target_index;
1058c074d1c9Sdrahn H_PUT_32 (abfd, s->_cooked_size, out.value);
1059c074d1c9Sdrahn H_PUT_32 (abfd, s->vma, out.vma);
10602159047fSniklas
10612159047fSniklas if (! oasys_write_record (abfd,
10622159047fSniklas oasys_record_is_section_enum,
10632159047fSniklas (oasys_record_union_type *) & out,
10642159047fSniklas sizeof (out)))
1065c074d1c9Sdrahn return FALSE;
10662159047fSniklas }
1067c074d1c9Sdrahn return TRUE;
10682159047fSniklas }
10692159047fSniklas
1070c074d1c9Sdrahn static bfd_boolean
oasys_write_header(abfd)10712159047fSniklas oasys_write_header (abfd)
10722159047fSniklas bfd *abfd;
10732159047fSniklas {
10742159047fSniklas /* Create and write the header */
10752159047fSniklas oasys_header_record_type r;
10762159047fSniklas size_t length = strlen (abfd->filename);
10772159047fSniklas if (length > (size_t) sizeof (r.module_name))
10782159047fSniklas {
10792159047fSniklas length = sizeof (r.module_name);
10802159047fSniklas }
10812159047fSniklas
10822159047fSniklas (void) memcpy (r.module_name,
10832159047fSniklas abfd->filename,
10842159047fSniklas length);
10852159047fSniklas (void) memset (r.module_name + length,
10862159047fSniklas ' ',
10872159047fSniklas sizeof (r.module_name) - length);
10882159047fSniklas
10892159047fSniklas r.version_number = OASYS_VERSION_NUMBER;
10902159047fSniklas r.rev_number = OASYS_REV_NUMBER;
10912159047fSniklas if (! oasys_write_record (abfd,
10922159047fSniklas oasys_record_is_header_enum,
10932159047fSniklas (oasys_record_union_type *) & r,
10942159047fSniklas offsetof (oasys_header_record_type,
10952159047fSniklas description[0])))
1096c074d1c9Sdrahn return FALSE;
10972159047fSniklas
1098c074d1c9Sdrahn return TRUE;
10992159047fSniklas }
11002159047fSniklas
1101c074d1c9Sdrahn static bfd_boolean
oasys_write_end(abfd)11022159047fSniklas oasys_write_end (abfd)
11032159047fSniklas bfd *abfd;
11042159047fSniklas {
11052159047fSniklas oasys_end_record_type end;
11062159047fSniklas unsigned char null = 0;
11072159047fSniklas end.relb = RELOCATION_TYPE_ABS;
1108c074d1c9Sdrahn H_PUT_32 (abfd, abfd->start_address, end.entry);
1109c074d1c9Sdrahn H_PUT_16 (abfd, 0, end.fill);
11102159047fSniklas end.zero = 0;
11112159047fSniklas if (! oasys_write_record (abfd,
11122159047fSniklas oasys_record_is_end_enum,
11132159047fSniklas (oasys_record_union_type *) & end,
11142159047fSniklas sizeof (end)))
1115c074d1c9Sdrahn return FALSE;
1116c074d1c9Sdrahn if (bfd_bwrite ((PTR) &null, (bfd_size_type) 1, abfd) != 1)
1117c074d1c9Sdrahn return FALSE;
1118c074d1c9Sdrahn return TRUE;
11192159047fSniklas }
11202159047fSniklas
11212159047fSniklas static int
comp(ap,bp)11222159047fSniklas comp (ap, bp)
1123c074d1c9Sdrahn const PTR ap;
1124c074d1c9Sdrahn const PTR bp;
11252159047fSniklas {
11262159047fSniklas arelent *a = *((arelent **) ap);
11272159047fSniklas arelent *b = *((arelent **) bp);
11282159047fSniklas return a->address - b->address;
11292159047fSniklas }
11302159047fSniklas
11312159047fSniklas /*
11322159047fSniklas Writing data..
11332159047fSniklas
11342159047fSniklas */
1135c074d1c9Sdrahn static bfd_boolean
oasys_write_data(abfd)11362159047fSniklas oasys_write_data (abfd)
11372159047fSniklas bfd *abfd;
11382159047fSniklas {
11392159047fSniklas asection *s;
11402159047fSniklas for (s = abfd->sections; s != (asection *) NULL; s = s->next)
11412159047fSniklas {
11422159047fSniklas if (s->flags & SEC_LOAD)
11432159047fSniklas {
11442159047fSniklas bfd_byte *raw_data = oasys_per_section (s)->data;
11452159047fSniklas oasys_data_record_type processed_data;
11462159047fSniklas bfd_size_type current_byte_index = 0;
11472159047fSniklas unsigned int relocs_to_go = s->reloc_count;
11482159047fSniklas arelent **p = s->orelocation;
11492159047fSniklas if (s->reloc_count != 0)
11502159047fSniklas {
11512159047fSniklas /* Sort the reloc records so it's easy to insert the relocs into the
11522159047fSniklas data */
11532159047fSniklas
11542159047fSniklas qsort (s->orelocation,
11552159047fSniklas s->reloc_count,
11562159047fSniklas sizeof (arelent **),
11572159047fSniklas comp);
11582159047fSniklas }
11592159047fSniklas current_byte_index = 0;
11602159047fSniklas processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
11612159047fSniklas
11622159047fSniklas while (current_byte_index < s->_cooked_size)
11632159047fSniklas {
11642159047fSniklas /* Scan forwards by eight bytes or however much is left and see if
11652159047fSniklas there are any relocations going on */
11662159047fSniklas bfd_byte *mod = &processed_data.data[0];
11672159047fSniklas bfd_byte *dst = &processed_data.data[1];
11682159047fSniklas
11692159047fSniklas unsigned int i = 0;
11702159047fSniklas *mod = 0;
11712159047fSniklas
11722159047fSniklas
1173c074d1c9Sdrahn H_PUT_32 (abfd, s->vma + current_byte_index,
11742159047fSniklas processed_data.addr);
11752159047fSniklas
11762159047fSniklas /* Don't start a relocation unless you're sure you can finish it
11772159047fSniklas within the same data record. The worst case relocation is a
11782159047fSniklas 4-byte relocatable value which is split across two modification
11792159047fSniklas bytes (1 relocation byte + 2 symbol reference bytes + 2 data +
11802159047fSniklas 1 modification byte + 2 data = 8 bytes total). That's where
11812159047fSniklas the magic number 8 comes from.
11822159047fSniklas */
11832159047fSniklas while (current_byte_index < s->_raw_size && dst <=
11842159047fSniklas &processed_data.data[sizeof (processed_data.data) - 8])
11852159047fSniklas {
11862159047fSniklas
11872159047fSniklas
11882159047fSniklas if (relocs_to_go != 0)
11892159047fSniklas {
11902159047fSniklas arelent *r = *p;
11912159047fSniklas reloc_howto_type *const how = r->howto;
11922159047fSniklas /* There is a relocation, is it for this byte ? */
11932159047fSniklas if (r->address == current_byte_index)
11942159047fSniklas {
11952159047fSniklas unsigned char rel_byte;
11962159047fSniklas
11972159047fSniklas p++;
11982159047fSniklas relocs_to_go--;
11992159047fSniklas
12002159047fSniklas *mod |= (1 << i);
12012159047fSniklas if (how->pc_relative)
12022159047fSniklas {
12032159047fSniklas rel_byte = RELOCATION_PCREL_BIT;
12042159047fSniklas
12052159047fSniklas /* Also patch the raw data so that it doesn't have
12062159047fSniklas the -ve stuff any more */
12072159047fSniklas if (how->size != 2)
12082159047fSniklas {
12092159047fSniklas bfd_put_16 (abfd,
12102159047fSniklas bfd_get_16 (abfd, raw_data) +
12112159047fSniklas current_byte_index, raw_data);
12122159047fSniklas }
12132159047fSniklas
12142159047fSniklas else
12152159047fSniklas {
12162159047fSniklas bfd_put_32 (abfd,
12172159047fSniklas bfd_get_32 (abfd, raw_data) +
12182159047fSniklas current_byte_index, raw_data);
12192159047fSniklas }
12202159047fSniklas }
12212159047fSniklas else
12222159047fSniklas {
12232159047fSniklas rel_byte = 0;
12242159047fSniklas }
12252159047fSniklas if (how->size == 2)
12262159047fSniklas {
12272159047fSniklas rel_byte |= RELOCATION_32BIT_BIT;
12282159047fSniklas }
12292159047fSniklas
12302159047fSniklas /* Is this a section relative relocation, or a symbol
12312159047fSniklas relative relocation ? */
12322159047fSniklas abort ();
12332159047fSniklas
12342159047fSniklas #if 0
12352159047fSniklas if (r->section != (asection *) NULL)
12362159047fSniklas {
12372159047fSniklas /* The relent has a section attached, so it must be section
12382159047fSniklas relative */
12392159047fSniklas rel_byte |= RELOCATION_TYPE_REL;
12402159047fSniklas rel_byte |= r->section->output_section->target_index;
12412159047fSniklas *dst++ = rel_byte;
12422159047fSniklas }
12432159047fSniklas else
12442159047fSniklas #endif
12452159047fSniklas {
1246c074d1c9Sdrahn asymbol *sym = *(r->sym_ptr_ptr);
12472159047fSniklas
12482159047fSniklas /* If this symbol has a section attached, then it
12492159047fSniklas has already been resolved. Change from a symbol
12502159047fSniklas ref to a section ref */
1251c074d1c9Sdrahn if (sym->section != (asection *) NULL)
12522159047fSniklas {
12532159047fSniklas rel_byte |= RELOCATION_TYPE_REL;
12542159047fSniklas rel_byte |=
1255c074d1c9Sdrahn sym->section->output_section->target_index;
12562159047fSniklas *dst++ = rel_byte;
12572159047fSniklas }
12582159047fSniklas else
12592159047fSniklas {
12602159047fSniklas rel_byte |= RELOCATION_TYPE_UND;
12612159047fSniklas *dst++ = rel_byte;
12622159047fSniklas /* Next two bytes are a symbol index - we can get
12632159047fSniklas this from the symbol value which has been zapped
12642159047fSniklas into the symbol index in the table when the
12652159047fSniklas symbol table was written
12662159047fSniklas */
1267c074d1c9Sdrahn *dst++ = sym->value >> 8;
1268c074d1c9Sdrahn *dst++ = sym->value;
12692159047fSniklas }
12702159047fSniklas }
12712159047fSniklas #define ADVANCE { if (++i >= 8) { i = 0; mod = dst++; *mod = 0; } current_byte_index++; }
12722159047fSniklas /* relocations never occur from an unloadable section,
12732159047fSniklas so we can assume that raw_data is not NULL
12742159047fSniklas */
12752159047fSniklas *dst++ = *raw_data++;
12762159047fSniklas ADVANCE
12772159047fSniklas * dst++ = *raw_data++;
12782159047fSniklas ADVANCE
12792159047fSniklas if (how->size == 2)
12802159047fSniklas {
12812159047fSniklas *dst++ = *raw_data++;
12822159047fSniklas ADVANCE
12832159047fSniklas * dst++ = *raw_data++;
12842159047fSniklas ADVANCE
12852159047fSniklas }
12862159047fSniklas continue;
12872159047fSniklas }
12882159047fSniklas }
12892159047fSniklas /* If this is coming from an unloadable section then copy
12902159047fSniklas zeros */
12912159047fSniklas if (raw_data == NULL)
12922159047fSniklas {
12932159047fSniklas *dst++ = 0;
12942159047fSniklas }
12952159047fSniklas else
12962159047fSniklas {
12972159047fSniklas *dst++ = *raw_data++;
12982159047fSniklas }
12992159047fSniklas ADVANCE
13002159047fSniklas }
13012159047fSniklas
13022159047fSniklas /* Don't write a useless null modification byte */
13032159047fSniklas if (dst == mod + 1)
13042159047fSniklas {
13052159047fSniklas --dst;
13062159047fSniklas }
13072159047fSniklas
1308c074d1c9Sdrahn if (! (oasys_write_record
1309c074d1c9Sdrahn (abfd, oasys_record_is_data_enum,
1310c074d1c9Sdrahn ((oasys_record_union_type *) &processed_data),
1311c074d1c9Sdrahn (size_t) (dst - (bfd_byte *) &processed_data))))
1312c074d1c9Sdrahn return FALSE;
13132159047fSniklas }
13142159047fSniklas }
13152159047fSniklas }
13162159047fSniklas
1317c074d1c9Sdrahn return TRUE;
13182159047fSniklas }
13192159047fSniklas
1320c074d1c9Sdrahn static bfd_boolean
oasys_write_object_contents(abfd)13212159047fSniklas oasys_write_object_contents (abfd)
13222159047fSniklas bfd *abfd;
13232159047fSniklas {
13242159047fSniklas if (! oasys_write_header (abfd))
1325c074d1c9Sdrahn return FALSE;
13262159047fSniklas if (! oasys_write_syms (abfd))
1327c074d1c9Sdrahn return FALSE;
13282159047fSniklas if (! oasys_write_sections (abfd))
1329c074d1c9Sdrahn return FALSE;
13302159047fSniklas if (! oasys_write_data (abfd))
1331c074d1c9Sdrahn return FALSE;
13322159047fSniklas if (! oasys_write_end (abfd))
1333c074d1c9Sdrahn return FALSE;
1334c074d1c9Sdrahn return TRUE;
13352159047fSniklas }
13362159047fSniklas
13372159047fSniklas
13382159047fSniklas
13392159047fSniklas
13402159047fSniklas /** exec and core file sections */
13412159047fSniklas
13422159047fSniklas /* set section contents is complicated with OASYS since the format is
13432159047fSniklas * not a byte image, but a record stream.
13442159047fSniklas */
1345c074d1c9Sdrahn static bfd_boolean
oasys_set_section_contents(abfd,section,location,offset,count)13462159047fSniklas oasys_set_section_contents (abfd, section, location, offset, count)
13472159047fSniklas bfd *abfd;
13482159047fSniklas sec_ptr section;
1349*007c2a45Smiod const PTR location;
13502159047fSniklas file_ptr offset;
13512159047fSniklas bfd_size_type count;
13522159047fSniklas {
13532159047fSniklas if (count != 0)
13542159047fSniklas {
13552159047fSniklas if (oasys_per_section (section)->data == (bfd_byte *) NULL)
13562159047fSniklas {
13572159047fSniklas oasys_per_section (section)->data =
13582159047fSniklas (bfd_byte *) (bfd_alloc (abfd, section->_cooked_size));
13592159047fSniklas if (!oasys_per_section (section)->data)
1360c074d1c9Sdrahn return FALSE;
13612159047fSniklas }
13622159047fSniklas (void) memcpy ((PTR) (oasys_per_section (section)->data + offset),
13632159047fSniklas location,
13642159047fSniklas (size_t) count);
13652159047fSniklas }
1366c074d1c9Sdrahn return TRUE;
13672159047fSniklas }
13682159047fSniklas
13692159047fSniklas
13702159047fSniklas
13712159047fSniklas /* Native-level interface to symbols. */
13722159047fSniklas
13732159047fSniklas /* We read the symbols into a buffer, which is discarded when this
13742159047fSniklas function exits. We read the strings into a buffer large enough to
13752159047fSniklas hold them all plus all the cached symbol entries. */
13762159047fSniklas
13772159047fSniklas static asymbol *
oasys_make_empty_symbol(abfd)13782159047fSniklas oasys_make_empty_symbol (abfd)
13792159047fSniklas bfd *abfd;
13802159047fSniklas {
1381c074d1c9Sdrahn bfd_size_type amt = sizeof (oasys_symbol_type);
1382c074d1c9Sdrahn oasys_symbol_type *new = (oasys_symbol_type *) bfd_zalloc (abfd, amt);
13832159047fSniklas if (!new)
13842159047fSniklas return NULL;
13852159047fSniklas new->symbol.the_bfd = abfd;
13862159047fSniklas return &new->symbol;
13872159047fSniklas }
13882159047fSniklas
13892159047fSniklas
13902159047fSniklas
13912159047fSniklas
13922159047fSniklas /* User should have checked the file flags; perhaps we should return
13932159047fSniklas BFD_NO_MORE_SYMBOLS if there are none? */
13942159047fSniklas
13952159047fSniklas static bfd *
oasys_openr_next_archived_file(arch,prev)13962159047fSniklas oasys_openr_next_archived_file (arch, prev)
13972159047fSniklas bfd *arch;
13982159047fSniklas bfd *prev;
13992159047fSniklas {
14002159047fSniklas oasys_ar_data_type *ar = OASYS_AR_DATA (arch);
14012159047fSniklas oasys_module_info_type *p;
14022159047fSniklas /* take the next one from the arch state, or reset */
14032159047fSniklas if (prev == (bfd *) NULL)
14042159047fSniklas {
14052159047fSniklas /* Reset the index - the first two entries are bogus*/
14062159047fSniklas ar->module_index = 0;
14072159047fSniklas }
14082159047fSniklas
14092159047fSniklas p = ar->module + ar->module_index;
14102159047fSniklas ar->module_index++;
14112159047fSniklas
14122159047fSniklas if (ar->module_index <= ar->module_count)
14132159047fSniklas {
14142159047fSniklas if (p->abfd == (bfd *) NULL)
14152159047fSniklas {
14162159047fSniklas p->abfd = _bfd_create_empty_archive_element_shell (arch);
14172159047fSniklas p->abfd->origin = p->pos;
14182159047fSniklas p->abfd->filename = p->name;
14192159047fSniklas
14202159047fSniklas /* Fixup a pointer to this element for the member */
14212159047fSniklas p->abfd->arelt_data = (PTR) p;
14222159047fSniklas }
14232159047fSniklas return p->abfd;
14242159047fSniklas }
14252159047fSniklas else
14262159047fSniklas {
14272159047fSniklas bfd_set_error (bfd_error_no_more_archived_files);
14282159047fSniklas return (bfd *) NULL;
14292159047fSniklas }
14302159047fSniklas }
14312159047fSniklas
1432c074d1c9Sdrahn static bfd_boolean
oasys_find_nearest_line(abfd,section,symbols,offset,filename_ptr,functionname_ptr,line_ptr)1433c074d1c9Sdrahn oasys_find_nearest_line (abfd, section, symbols, offset,
1434c074d1c9Sdrahn filename_ptr, functionname_ptr, line_ptr)
1435b305b0f1Sespie bfd *abfd ATTRIBUTE_UNUSED;
1436b305b0f1Sespie asection *section ATTRIBUTE_UNUSED;
1437b305b0f1Sespie asymbol **symbols ATTRIBUTE_UNUSED;
1438b305b0f1Sespie bfd_vma offset ATTRIBUTE_UNUSED;
1439c074d1c9Sdrahn const char **filename_ptr ATTRIBUTE_UNUSED;
1440c074d1c9Sdrahn const char **functionname_ptr ATTRIBUTE_UNUSED;
1441b305b0f1Sespie unsigned int *line_ptr ATTRIBUTE_UNUSED;
14422159047fSniklas {
1443c074d1c9Sdrahn return FALSE;
14442159047fSniklas
14452159047fSniklas }
14462159047fSniklas
14472159047fSniklas static int
oasys_generic_stat_arch_elt(abfd,buf)14482159047fSniklas oasys_generic_stat_arch_elt (abfd, buf)
14492159047fSniklas bfd *abfd;
14502159047fSniklas struct stat *buf;
14512159047fSniklas {
14522159047fSniklas oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
14532159047fSniklas if (mod == (oasys_module_info_type *) NULL)
14542159047fSniklas {
14552159047fSniklas bfd_set_error (bfd_error_invalid_operation);
14562159047fSniklas return -1;
14572159047fSniklas }
14582159047fSniklas else
14592159047fSniklas {
14602159047fSniklas buf->st_size = mod->size;
14612159047fSniklas buf->st_mode = 0666;
14622159047fSniklas return 0;
14632159047fSniklas }
14642159047fSniklas }
14652159047fSniklas
14662159047fSniklas static int
oasys_sizeof_headers(abfd,exec)14672159047fSniklas oasys_sizeof_headers (abfd, exec)
1468b305b0f1Sespie bfd *abfd ATTRIBUTE_UNUSED;
1469c074d1c9Sdrahn bfd_boolean exec ATTRIBUTE_UNUSED;
14702159047fSniklas {
14712159047fSniklas return 0;
14722159047fSniklas }
14732159047fSniklas
14742159047fSniklas #define oasys_close_and_cleanup _bfd_generic_close_and_cleanup
14752159047fSniklas #define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
14762159047fSniklas
14772159047fSniklas #define oasys_slurp_armap bfd_true
14782159047fSniklas #define oasys_slurp_extended_name_table bfd_true
14792159047fSniklas #define oasys_construct_extended_name_table \
1480c074d1c9Sdrahn ((bfd_boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
14812159047fSniklas bfd_true)
14822159047fSniklas #define oasys_truncate_arname bfd_dont_truncate_arname
14832159047fSniklas #define oasys_write_armap \
1484c074d1c9Sdrahn ((bfd_boolean (*) \
14852159047fSniklas PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
14862159047fSniklas bfd_true)
14872159047fSniklas #define oasys_read_ar_hdr bfd_nullvoidptr
1488c88b1d6cSniklas #define oasys_get_elt_at_index _bfd_generic_get_elt_at_index
14892159047fSniklas #define oasys_update_armap_timestamp bfd_true
14902159047fSniklas
1491b305b0f1Sespie #define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name
14922159047fSniklas #define oasys_get_lineno _bfd_nosymbols_get_lineno
14932159047fSniklas #define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
14942159047fSniklas #define oasys_read_minisymbols _bfd_generic_read_minisymbols
14952159047fSniklas #define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
14962159047fSniklas
14972159047fSniklas #define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
14982159047fSniklas
14992159047fSniklas #define oasys_set_arch_mach bfd_default_set_arch_mach
15002159047fSniklas
15012159047fSniklas #define oasys_get_section_contents_in_window \
15022159047fSniklas _bfd_generic_get_section_contents_in_window
15032159047fSniklas
15042159047fSniklas #define oasys_bfd_get_relocated_section_contents \
15052159047fSniklas bfd_generic_get_relocated_section_contents
15062159047fSniklas #define oasys_bfd_relax_section bfd_generic_relax_section
1507b305b0f1Sespie #define oasys_bfd_gc_sections bfd_generic_gc_sections
1508c074d1c9Sdrahn #define oasys_bfd_merge_sections bfd_generic_merge_sections
1509c074d1c9Sdrahn #define oasys_bfd_discard_group bfd_generic_discard_group
15102159047fSniklas #define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1511c074d1c9Sdrahn #define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
15122159047fSniklas #define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
1513c074d1c9Sdrahn #define oasys_bfd_link_just_syms _bfd_generic_link_just_syms
15142159047fSniklas #define oasys_bfd_final_link _bfd_generic_final_link
15152159047fSniklas #define oasys_bfd_link_split_section _bfd_generic_link_split_section
15162159047fSniklas
15172159047fSniklas /*SUPPRESS 460 */
15182159047fSniklas const bfd_target oasys_vec =
15192159047fSniklas {
15202159047fSniklas "oasys", /* name */
15212159047fSniklas bfd_target_oasys_flavour,
1522c88b1d6cSniklas BFD_ENDIAN_BIG, /* target byte order */
1523c88b1d6cSniklas BFD_ENDIAN_BIG, /* target headers byte order */
15242159047fSniklas (HAS_RELOC | EXEC_P | /* object flags */
15252159047fSniklas HAS_LINENO | HAS_DEBUG |
15262159047fSniklas HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
15272159047fSniklas (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
15282159047fSniklas | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
15292159047fSniklas 0, /* leading underscore */
15302159047fSniklas ' ', /* ar_pad_char */
15312159047fSniklas 16, /* ar_max_namelen */
15322159047fSniklas bfd_getb64, bfd_getb_signed_64, bfd_putb64,
15332159047fSniklas bfd_getb32, bfd_getb_signed_32, bfd_putb32,
15342159047fSniklas bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
15352159047fSniklas bfd_getb64, bfd_getb_signed_64, bfd_putb64,
15362159047fSniklas bfd_getb32, bfd_getb_signed_32, bfd_putb32,
15372159047fSniklas bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
15382159047fSniklas
15392159047fSniklas {_bfd_dummy_target,
15402159047fSniklas oasys_object_p, /* bfd_check_format */
15412159047fSniklas oasys_archive_p,
15422159047fSniklas _bfd_dummy_target,
15432159047fSniklas },
15442159047fSniklas { /* bfd_set_format */
15452159047fSniklas bfd_false,
15462159047fSniklas oasys_mkobject,
15472159047fSniklas _bfd_generic_mkarchive,
15482159047fSniklas bfd_false
15492159047fSniklas },
15502159047fSniklas { /* bfd_write_contents */
15512159047fSniklas bfd_false,
15522159047fSniklas oasys_write_object_contents,
15532159047fSniklas _bfd_write_archive_contents,
15542159047fSniklas bfd_false,
15552159047fSniklas },
15562159047fSniklas
15572159047fSniklas BFD_JUMP_TABLE_GENERIC (oasys),
15582159047fSniklas BFD_JUMP_TABLE_COPY (_bfd_generic),
15592159047fSniklas BFD_JUMP_TABLE_CORE (_bfd_nocore),
15602159047fSniklas BFD_JUMP_TABLE_ARCHIVE (oasys),
15612159047fSniklas BFD_JUMP_TABLE_SYMBOLS (oasys),
15622159047fSniklas BFD_JUMP_TABLE_RELOCS (oasys),
15632159047fSniklas BFD_JUMP_TABLE_WRITE (oasys),
15642159047fSniklas BFD_JUMP_TABLE_LINK (oasys),
15652159047fSniklas BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
15662159047fSniklas
1567b305b0f1Sespie NULL,
1568b305b0f1Sespie
15692159047fSniklas (PTR) 0
15702159047fSniklas };
1571