1 /* IBM RS/6000 "XCOFF" back-end for BFD.
2 Copyright (C) 1990, 1991 Free Software Foundation, Inc.
3 Written by Metin G. Ozisik, Mimi Phûông-Thåo Võ, and John Gilmore.
4 Archive support from Damon A. Permezel.
5 Contributed by IBM Corporation and Cygnus Support.
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23 /* This port currently only handles reading object files, except when
24 compiled on an RS/6000 host. -- no archive support, no core files.
25 In all cases, it does not support writing.
27 FIXMEmgo comments are left from Metin Ozisik's original port. */
29 /* Internalcoff.h and coffcode.h modify themselves based on this flag. */
30 #define RS6000COFF_C 1
36 #include "coff/internal.h"
37 #include "coff/rs6000.h"
40 /* The main body of code is in coffcode.h. */
42 /* Can't read rs6000 relocs */
43 #define RTYPE2HOWTO(a,b)
46 #define coff_archive_p bfd_generic_archive_p
47 #define coff_mkarchive _bfd_generic_mkarchive
49 #ifdef ARCHIVES_PLEASE
51 /* ------------------------------------------------------------------------ */
52 /* Support for archive file stuff.. */
53 /* Stolen from Damon A. Permezel's `bfd' portation. */
54 /* ------------------------------------------------------------------------ */
56 #undef coff_openr_next_archived_file
57 #define coff_openr_next_archived_file rs6000coff_openr_next_archived_file
59 #undef coff_write_armap
60 #define coff_write_armap rs6000coff_write_armap
62 #undef coff_stat_arch_elt
63 #define coff_stat_arch_elt rs6000coff_stat_arch_elt
65 #undef coff_snarf_ar_hdr
66 #define coff_snarf_ar_hdr rs6000coff_snarf_ar_hdr
69 #define coff_mkarchive rs6000coff_mkarchive
72 #define coff_archive_p rs6000coff_archive_p
74 #include "/usr/include/ar.h" /* <ar.h> doesn't do it. */
77 #define arch_hdr(bfd) \
79 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
83 rs6000coff_mkarchive (abfd)
86 bfd_error = invalid_operation; /* write not supported */
90 /* This functions reads an arch header and returns an areltdata pointer, or
93 Presumes the file pointer is already in the right place (ie pointing
94 to the ar_hdr in the file). Moves the file pointer; on success it
95 should be pointing to the front of the file contents; on failure it
96 could have been moved arbitrarily.
100 rs6000coff_snarf_ar_hdr (abfd)
110 struct areltdata *ared;
111 unsigned int namelen = 0;
114 size = sizeof (h.hdr);
115 if (bfd_read(&h.hdr, 1, size, abfd) != size) {
116 bfd_error = no_more_archived_files;
119 size = atoi(h.hdr.ar_namlen); /* ar_name[] length */
122 if (bfd_read(&h.hdr._ar_name.ar_name[2], 1, size, abfd) != size) {
123 bfd_error = no_more_archived_files;
127 if (strncmp(h.hdr._ar_name.ar_fmag + size, AIAFMAG, 2)) {
128 bfd_error = malformed_archive;
132 h.hdr._ar_name.ar_name[size] = 0; /* terminate filename */
135 * if the filename is NULL, we're (probably) at the end.
138 bfd_error = no_more_archived_files;
142 size += sizeof (h.hdr);
143 allocptr = bfd_zalloc(abfd, sizeof (*ared) + size);
145 if (allocptr == NULL) {
146 bfd_error = no_memory;
150 ared = (struct areltdata *) allocptr;
152 ared->arch_header = (void *) (allocptr + sizeof (struct areltdata));
153 memcpy ((char *) ared->arch_header, &h.hdr, size);
154 ared->parsed_size = atoi(h.hdr.ar_size);
155 ared->filename = ((AR_HDR*) ared->arch_header)->_ar_name.ar_name;
160 /* Stolen directly from archive.c, except it calls rs6000coff_snarf_ar_hdr.
161 Why wasn't this part of the transfer vector? */
164 rs6000coff_get_elt_at_filepos (archive, filepos)
168 struct areltdata *new_areldata;
171 n_nfd = look_for_bfd_in_cache (archive, filepos);
172 if (n_nfd) return n_nfd;
174 if (0 != bfd_seek (archive, filepos, SEEK_SET)) {
175 bfd_error = system_call_error;
179 if ((new_areldata = rs6000coff_snarf_ar_hdr (archive)) == NULL) return NULL;
181 n_nfd = _bfd_create_empty_archive_element_shell (archive);
183 bfd_release (archive, (PTR)new_areldata);
186 n_nfd->origin = bfd_tell (archive);
187 n_nfd->arelt_data = (PTR) new_areldata;
188 n_nfd->filename = new_areldata->filename;
190 if (add_bfd_to_cache (archive, filepos, n_nfd))
194 bfd_release (archive, (PTR)n_nfd);
195 bfd_release (archive, (PTR)new_areldata);
200 * xcoff_openr_next_archived_file - xcoff has nxt/prv seek addrs.
203 rs6000coff_openr_next_archived_file(archive, last_file)
204 bfd *archive, *last_file;
209 filestart = bfd_ardata(archive)->first_file_filepos;
211 filestart = atol(arch_hdr(last_file)->ar_nxtmem);
213 return rs6000coff_get_elt_at_filepos (archive, filestart);
218 rs6000coff_archive_p (abfd)
222 register struct artdata *art;
224 if (bfd_read (&hdr, sizeof (hdr), 1, abfd) != sizeof (hdr)) {
225 bfd_error = wrong_format;
229 if (strncmp(hdr.fl_magic, AIAMAG, SAIAMAG)) {
230 bfd_error = wrong_format;
235 * bfd_ardata() accesses the bfd->tdata field.
237 abfd->tdata.aout_ar_data =
238 (void *) bfd_zalloc(abfd, sizeof (*art) + sizeof (hdr));
239 if ((art = bfd_ardata (abfd)) == NULL) {
240 bfd_error = no_memory;
244 art->first_file_filepos = atoi(hdr.fl_fstmoff);
245 *(struct fl_hdr *) (1 + art) = hdr;
248 * slurp in the member table, which I think is the armap equivalent.
249 xcoff_slurp_armap(abfd);
257 rs6000coff_stat_arch_elt(abfd, buf)
264 if (abfd->arelt_data == NULL) {
265 bfd_error = invalid_operation;
269 hdr = arch_hdr (abfd);
271 #define foo(arelt, stelt, size) \
272 buf->stelt = strtol (hdr->arelt, &aloser, size); \
273 if (aloser == hdr->arelt) return -1;
275 foo (ar_date, st_mtime, 10);
276 foo (ar_uid, st_uid, 10);
277 foo (ar_gid, st_gid, 10);
278 foo (ar_mode, st_mode, 8);
279 foo (ar_size, st_size, 10);
286 rs6000coff_write_armap (arch, elength, map, orl_count, stridx)
288 unsigned int elength;
291 bfd_error = invalid_operation;
294 #endif /* ARCHIVES_PLEASE */
297 #ifdef COREFILES_PLEASE
298 extern bfd_target * rs6000coff_core_p ();
299 extern boolean rs6000coff_get_section_contents ();
300 extern boolean rs6000coff_core_file_matches_executable_p ();
302 #undef coff_core_file_matches_executable_p
303 #define coff_core_file_matches_executable_p \
304 rs6000coff_core_file_matches_executable_p
306 #undef coff_get_section_contents
307 #define coff_get_section_contents rs6000coff_get_section_contents
310 /* The transfer vector that leads the outside world to all of the above. */
312 bfd_target rs6000coff_vec =
314 "aixcoff-rs6000", /* name */
315 bfd_target_coff_flavour,
316 true, /* data byte order is big */
317 true, /* header byte order is big */
319 (HAS_RELOC | EXEC_P | /* object flags */
320 HAS_LINENO | HAS_DEBUG |
321 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
323 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
324 0, /* leading char */
325 '/', /* ar_pad_char */
326 15, /* ar_max_namelen??? FIXMEmgo */
327 3, /* default alignment power */
329 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
330 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
332 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
334 #ifdef COREFILES_PLEASE
340 {bfd_false, coff_mkobject, coff_mkarchive, /* bfd_set_format */
342 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
343 _bfd_write_archive_contents, bfd_false},