get rid of rcs crud
[deliverable/binutils-gdb.git] / bfd / coff-rs6000.c
1 /* BFD back-end for IBM RS/6000 "XCOFF" files.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3 FIXME: Can someone provide a transliteration of this name into ASCII?
4 Using the following chars caused a compiler warning on HIUX (so I replaced
5 them with octal escapes), and isn't useful without an understanding of what
6 character set it is.
7 Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
8 and John Gilmore.
9 Archive support from Damon A. Permezel.
10 Contributed by IBM Corporation and Cygnus Support.
11
12 This file is part of BFD, the Binary File Descriptor library.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
27
28 /* This port currently only handles reading object files, except when
29 compiled on an RS/6000 host. -- no archive support, no core files.
30 In all cases, it does not support writing.
31
32 FIXMEmgo comments are left from Metin Ozisik's original port. */
33
34 /* Internalcoff.h and coffcode.h modify themselves based on this flag. */
35 #define RS6000COFF_C 1
36
37 #include "bfd.h"
38 #include "sysdep.h"
39 #include "libbfd.h"
40 #include "obstack.h"
41 #include "coff/internal.h"
42 #include "coff/rs6000.h"
43 #include "libcoff.h"
44
45 /* The main body of code is in coffcode.h. */
46
47 /* Can't read rs6000 relocs */
48 static reloc_howto_type dummy_reloc =
49 HOWTO (0, /* type */
50 0, /* rightshift */
51 0, /* size (0 = byte, 1 = short, 2 = long) */
52 8, /* bitsize */
53 false, /* pc_relative */
54 0, /* bitpos */
55 complain_overflow_dont, /* complain_on_overflow */
56 0, /* special_function */
57 "UNKNOWN", /* name */
58 false, /* partial_inplace */
59 0, /* src_mask */
60 0, /* dst_mask */
61 false); /* pcrel_offset */
62
63 #define RTYPE2HOWTO(cache_ptr, dst) cache_ptr->howto = &dummy_reloc;
64
65 #include "coffcode.h"
66
67 #define coff_archive_p bfd_generic_archive_p
68 #define coff_mkarchive _bfd_generic_mkarchive
69
70 #ifdef ARCHIVES_PLEASE
71
72 /* ------------------------------------------------------------------------ */
73 /* Support for archive file stuff.. */
74 /* Stolen from Damon A. Permezel's `bfd' portation. */
75 /* ------------------------------------------------------------------------ */
76
77 #undef coff_openr_next_archived_file
78 #define coff_openr_next_archived_file rs6000coff_openr_next_archived_file
79
80 #undef coff_write_armap
81 #define coff_write_armap rs6000coff_write_armap
82
83 #undef coff_stat_arch_elt
84 #define coff_stat_arch_elt rs6000coff_stat_arch_elt
85
86 #undef coff_snarf_ar_hdr
87 #define coff_snarf_ar_hdr rs6000coff_snarf_ar_hdr
88
89 #undef coff_mkarchive
90 #define coff_mkarchive rs6000coff_mkarchive
91
92 #undef coff_archive_p
93 #define coff_archive_p rs6000coff_archive_p
94
95 #include "/usr/include/ar.h" /* <ar.h> doesn't do it. */
96
97
98 #define arch_hdr(bfd) \
99 ((struct ar_hdr *) \
100 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
101
102
103 static boolean
104 rs6000coff_mkarchive (abfd)
105 bfd *abfd;
106 {
107 bfd_error = invalid_operation; /* write not supported */
108 }
109
110
111 /* This functions reads an arch header and returns an areltdata pointer, or
112 NULL on error.
113
114 Presumes the file pointer is already in the right place (ie pointing
115 to the ar_hdr in the file). Moves the file pointer; on success it
116 should be pointing to the front of the file contents; on failure it
117 could have been moved arbitrarily.
118 */
119
120 struct areltdata *
121 rs6000coff_snarf_ar_hdr (abfd)
122 bfd *abfd;
123 {
124 extern int errno;
125
126 struct {
127 struct ar_hdr hdr;
128 char namebuf[256];
129 } h;
130 int size;
131 struct areltdata *ared;
132 unsigned int namelen = 0;
133 char *allocptr;
134
135 size = sizeof (h.hdr);
136 if (bfd_read(&h.hdr, 1, size, abfd) != size) {
137 bfd_error = no_more_archived_files;
138 return NULL;
139 }
140 size = atoi(h.hdr.ar_namlen); /* ar_name[] length */
141 size += size & 1;
142
143 if (bfd_read(&h.hdr._ar_name.ar_name[2], 1, size, abfd) != size) {
144 bfd_error = no_more_archived_files;
145 return NULL;
146 }
147
148 if (strncmp(h.hdr._ar_name.ar_fmag + size, AIAFMAG, 2)) {
149 bfd_error = malformed_archive;
150 return NULL;
151 }
152
153 h.hdr._ar_name.ar_name[size] = 0; /* terminate filename */
154
155 /*
156 * if the filename is NULL, we're (probably) at the end.
157 */
158 if (size == 0) {
159 bfd_error = no_more_archived_files;
160 return NULL;
161 }
162
163 size += sizeof (h.hdr);
164 allocptr = bfd_zalloc(abfd, sizeof (*ared) + size);
165
166 if (allocptr == NULL) {
167 bfd_error = no_memory;
168 return NULL;
169 }
170
171 ared = (struct areltdata *) allocptr;
172
173 ared->arch_header = (void *) (allocptr + sizeof (struct areltdata));
174 memcpy ((char *) ared->arch_header, &h.hdr, size);
175 ared->parsed_size = atoi(h.hdr.ar_size);
176 ared->filename = ((AR_HDR*) ared->arch_header)->_ar_name.ar_name;
177
178 return ared;
179 }
180
181 /* Stolen directly from archive.c, except it calls rs6000coff_snarf_ar_hdr.
182 Why wasn't this part of the transfer vector? */
183
184 bfd *
185 rs6000coff_get_elt_at_filepos (archive, filepos)
186 bfd *archive;
187 file_ptr filepos;
188 {
189 struct areltdata *new_areldata;
190 bfd *n_nfd;
191
192 n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos);
193 if (n_nfd) return n_nfd;
194
195 if (0 != bfd_seek (archive, filepos, SEEK_SET)) {
196 bfd_error = system_call_error;
197 return NULL;
198 }
199
200 if ((new_areldata = rs6000coff_snarf_ar_hdr (archive)) == NULL) return NULL;
201
202 n_nfd = _bfd_create_empty_archive_element_shell (archive);
203 if (n_nfd == NULL) {
204 bfd_release (archive, (PTR)new_areldata);
205 return NULL;
206 }
207 n_nfd->origin = bfd_tell (archive);
208 n_nfd->arelt_data = (PTR) new_areldata;
209 n_nfd->filename = new_areldata->filename;
210
211 if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd))
212 return n_nfd;
213
214 /* huh? */
215 bfd_release (archive, (PTR)n_nfd);
216 bfd_release (archive, (PTR)new_areldata);
217 return NULL;
218 }
219
220 /*
221 * xcoff_openr_next_archived_file - xcoff has nxt/prv seek addrs.
222 */
223 static bfd *
224 rs6000coff_openr_next_archived_file(archive, last_file)
225 bfd *archive, *last_file;
226 {
227 file_ptr filestart;
228
229 if (!last_file)
230 filestart = bfd_ardata(archive)->first_file_filepos;
231 else
232 filestart = atol(arch_hdr(last_file)->ar_nxtmem);
233
234 return rs6000coff_get_elt_at_filepos (archive, filestart);
235 }
236
237
238 static bfd_target *
239 rs6000coff_archive_p (abfd)
240 bfd *abfd;
241 {
242 struct fl_hdr hdr;
243 register struct artdata *art;
244
245 if (bfd_read (&hdr, sizeof (hdr), 1, abfd) != sizeof (hdr)) {
246 bfd_error = wrong_format;
247 return 0;
248 }
249
250 if (strncmp(hdr.fl_magic, AIAMAG, SAIAMAG)) {
251 bfd_error = wrong_format;
252 return 0;
253 }
254
255 /*
256 * bfd_ardata() accesses the bfd->tdata field.
257 */
258 abfd->tdata.aout_ar_data =
259 (void *) bfd_zalloc(abfd, sizeof (*art) + sizeof (hdr));
260 if ((art = bfd_ardata (abfd)) == NULL) {
261 bfd_error = no_memory;
262 return 0;
263 }
264
265 art->first_file_filepos = atoi(hdr.fl_fstmoff);
266 *(struct fl_hdr *) (1 + art) = hdr;
267
268 /* Someday...
269 * slurp in the member table, which I think is the armap equivalent.
270 xcoff_slurp_armap(abfd);
271 */
272
273 return abfd->xvec;
274 }
275
276
277 static int
278 rs6000coff_stat_arch_elt(abfd, buf)
279 bfd *abfd;
280 struct stat *buf;
281 {
282 struct ar_hdr *hdr;
283 char *aloser;
284
285 if (abfd->arelt_data == NULL) {
286 bfd_error = invalid_operation;
287 return -1;
288 }
289
290 hdr = arch_hdr (abfd);
291
292 #define foo(arelt, stelt, size) \
293 buf->stelt = strtol (hdr->arelt, &aloser, size); \
294 if (aloser == hdr->arelt) return -1;
295
296 foo (ar_date, st_mtime, 10);
297 foo (ar_uid, st_uid, 10);
298 foo (ar_gid, st_gid, 10);
299 foo (ar_mode, st_mode, 8);
300 foo (ar_size, st_size, 10);
301 #undef foo
302
303 return 0;
304 }
305
306 static boolean
307 rs6000coff_write_armap (arch, elength, map, orl_count, stridx)
308 bfd *arch;
309 unsigned int elength;
310 struct orl *map;
311 {
312 bfd_error = invalid_operation;
313 return false;
314 }
315 #endif /* ARCHIVES_PLEASE */
316
317 \f
318 #ifdef COREFILES_PLEASE
319 extern bfd_target * rs6000coff_core_p ();
320 extern boolean rs6000coff_get_section_contents ();
321 extern boolean rs6000coff_core_file_matches_executable_p ();
322
323 #undef coff_core_file_matches_executable_p
324 #define coff_core_file_matches_executable_p \
325 rs6000coff_core_file_matches_executable_p
326
327 #undef coff_get_section_contents
328 #define coff_get_section_contents rs6000coff_get_section_contents
329 #endif
330
331 /* The transfer vector that leads the outside world to all of the above. */
332
333 bfd_target rs6000coff_vec =
334 {
335 "aixcoff-rs6000", /* name */
336 bfd_target_coff_flavour,
337 true, /* data byte order is big */
338 true, /* header byte order is big */
339
340 (HAS_RELOC | EXEC_P | /* object flags */
341 HAS_LINENO | HAS_DEBUG |
342 HAS_SYMS | HAS_LOCALS | WP_TEXT),
343
344 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
345 0, /* leading char */
346 '/', /* ar_pad_char */
347 15, /* ar_max_namelen??? FIXMEmgo */
348 3, /* default alignment power */
349
350 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
351 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
352 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
353 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
354 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
355 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
356
357 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
358 coff_archive_p,
359 #ifdef COREFILES_PLEASE
360 rs6000coff_core_p
361 #else
362 _bfd_dummy_target
363 #endif
364 },
365 {bfd_false, coff_mkobject, coff_mkarchive, /* bfd_set_format */
366 bfd_false},
367 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
368 _bfd_write_archive_contents, bfd_false},
369
370 JUMP_TABLE(coff),
371 COFF_SWAP_TABLE,
372 };
This page took 0.036245 seconds and 4 git commands to generate.