Describe C++ fixes.
[deliverable/binutils-gdb.git] / bfd / archive.c
CommitLineData
9872a49c 1
4a81b561
DHW
2
3/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
4
5This file is part of BFD, the Binary File Diddler.
6
7BFD is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 1, or (at your option)
10any later version.
11
12BFD is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with BFD; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21
6f715d66
SC
22/*doc*
23@setfilename archive-info
24@section Archives
25
26Gumby, you promised to write this bit...
27
28Archives are supported in bfd in @code{archive.c}.
29
30An archive is represented internally just like another bfd, with a
31pointer to a chain of contained bfds. Archives can be created by
32opening bfds, linking them together and attatching them as children to
33another bfd and then closing the parent bfd.
34
35*-*/
36
4a81b561
DHW
37/* Assumes:
38 o - all archive elements start on an even boundary, newline padded;
39 o - all arch headers are char *;
40 o - all arch headers are the same size (across architectures).
41*/
42
fc723380 43/* $Id$ */
4a81b561 44
7ed4093a 45#include <sysdep.h>
4a81b561
DHW
46#include "bfd.h"
47#include "libbfd.h"
48#include "ar.h"
49#include "ranlib.h"
50
9846338e
SC
51#ifdef GNU960
52#define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
53#endif
54
4a81b561
DHW
55/* We keep a cache of archive filepointers to archive elements to
56 speed up searching the archive by filepos. We only add an entry to
57 the cache when we actually read one. We also don't sort the cache;
58 it's short enough to search linearly.
59 Note that the pointers here point to the front of the ar_hdr, not
60 to the front of the contents!
61*/
62struct ar_cache {
63 file_ptr ptr;
64 bfd* arelt;
65 struct ar_cache *next;
66};
67
68#define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
69#define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
70
71#define arch_hdr(bfd) ((struct ar_hdr *) \
72 (((struct areltdata *)((bfd)->arelt_data))->arch_header))
4a81b561 73\f
4a81b561
DHW
74boolean
75_bfd_generic_mkarchive (abfd)
76 bfd *abfd;
77{
fc723380 78 set_tdata (abfd, bfd_zalloc(abfd, sizeof (struct artdata)));
4a81b561 79
fc723380 80 if (bfd_ardata (abfd) == NULL) {
4a81b561
DHW
81 bfd_error = no_memory;
82 return false;
83 }
a37cc0c0 84 bfd_ardata(abfd)->cache = 0;
4a81b561
DHW
85 return true;
86}
87
6f715d66
SC
88/*proto* bfd_get_next_mapent
89What this does
90*; PROTO(symindex, bfd_get_next_mapent, (bfd *, symindex, carsym **));
91*/
4a81b561
DHW
92symindex
93bfd_get_next_mapent (abfd, prev, entry)
94 bfd *abfd;
fc723380 95 symindex prev;
4a81b561
DHW
96 carsym **entry;
97{
98 if (!bfd_has_map (abfd)) {
99 bfd_error = invalid_operation;
100 return BFD_NO_MORE_SYMBOLS;
101 }
102
103 if (prev == BFD_NO_MORE_SYMBOLS) prev = 0;
fc723380 104 else if (++prev >= bfd_ardata (abfd)->symdef_count)
4a81b561
DHW
105 return BFD_NO_MORE_SYMBOLS;
106
107 *entry = (bfd_ardata (abfd)->symdefs + prev);
108 return prev;
109}
110
111
112/* To be called by backends only */
113bfd *
114_bfd_create_empty_archive_element_shell (obfd)
115 bfd *obfd;
116{
117 bfd *nbfd;
118
119 nbfd = new_bfd_contained_in(obfd);
120 if (nbfd == NULL) {
121 bfd_error = no_memory;
122 return NULL;
123 }
124 return nbfd;
125}
126
6f715d66
SC
127/*proto* bfd_set_archive_head
128Used whilst processing archives. Sets the head of the chain of bfds
129contained in an archive to @var{new_head}. (see chapter on archives)
130*; PROTO(boolean, bfd_set_archive_head, (bfd *output, bfd *new_head));
131*/
132
4a81b561 133boolean
6f715d66
SC
134DEFUN(bfd_set_archive_head,(output_archive, new_head),
135 bfd *output_archive AND
136 bfd *new_head)
4a81b561 137{
fc723380 138
4a81b561
DHW
139 output_archive->archive_head = new_head;
140 return true;
141}
142
143bfd *
144look_for_bfd_in_cache (arch_bfd, filepos)
145 bfd *arch_bfd;
146 file_ptr filepos;
147{
148 struct ar_cache *current;
149
150 for (current = bfd_ardata (arch_bfd)->cache; current != NULL;
151 current = current->next)
152 if (current->ptr == filepos) return current->arelt;
153
154 return NULL;
155}
156
157/* Kind of stupid to call cons for each one, but we don't do too many */
158boolean
159add_bfd_to_cache (arch_bfd, filepos, new_elt)
160 bfd *arch_bfd, *new_elt;
161 file_ptr filepos;
162{
fc723380
JG
163 struct ar_cache *new_cache = (struct ar_cache *)
164 bfd_zalloc(arch_bfd, sizeof (struct ar_cache));
4a81b561
DHW
165
166 if (new_cache == NULL) {
167 bfd_error = no_memory;
168 return false;
169 }
170
171 new_cache->ptr = filepos;
172 new_cache->arelt = new_elt;
173 new_cache->next = (struct ar_cache *)NULL;
174 if (bfd_ardata (arch_bfd)->cache == NULL)
175 bfd_ardata (arch_bfd)->cache = new_cache;
176 else {
177 struct ar_cache *current = bfd_ardata (arch_bfd)->cache;
178
179 for (; current->next != NULL; current = current->next);
180 current->next = new_cache;
181 }
182
183 return true;
184}
185
186\f
187
188/* The name begins with space. Hence the rest of the name is an index into
189 the string table. */
190
191char *
192get_extended_arelt_filename (arch, name)
193 bfd *arch;
194 char *name;
195{
7ed4093a
SC
196#ifndef errno
197 extern int errno;
198#endif
4a81b561
DHW
199 unsigned long index = 0;
200
201 /* Should extract string so that I can guarantee not to overflow into
202 the next region, but I"m too lazy. */
203 errno = 0;
204 index = strtol (name, NULL, 10);
205 if (errno != 0) {
206 bfd_error = malformed_archive;
207 return NULL;
208 }
209
210 return bfd_ardata (arch)->extended_names + index;
211}
212
213/* This functions reads an arch header and returns an areltdata pointer, or
214 NULL on error.
215
216 Presumes the file pointer is already in the right place (ie pointing
217 to the ar_hdr in the file). Moves the file pointer; on success it
218 should be pointing to the front of the file contents; on failure it
219 could have been moved arbitrarily.
220*/
221
222struct areltdata *
223snarf_ar_hdr (abfd)
224 bfd *abfd;
225{
7ed4093a
SC
226#ifndef errno
227 extern int errno;
228#endif
229
4a81b561
DHW
230 struct ar_hdr hdr;
231 char *hdrp = (char *) &hdr;
232 unsigned int parsed_size;
233 struct areltdata *ared;
234 char *filename = NULL;
235 unsigned int namelen = 0;
236 unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
237 char *allocptr;
238
9846338e 239 if (bfd_read ((PTR)hdrp, 1, sizeof (struct ar_hdr), abfd)
4a81b561
DHW
240 != sizeof (struct ar_hdr)) {
241 bfd_error = no_more_archived_files;
242 return NULL;
243 }
244 if (strncmp ((hdr.ar_fmag), ARFMAG, 2)) {
245 bfd_error = malformed_archive;
246 return NULL;
247 }
248
249 errno = 0;
250 parsed_size = strtol (hdr.ar_size, NULL, 10);
251 if (errno != 0) {
252 bfd_error = malformed_archive;
253 return NULL;
254 }
255
6f715d66
SC
256 /* extract the filename from the archive - there are two ways to
257 specify an extendend name table, either the first char of the
258 name is a space, or it's a slash */
259 if ((hdr.ar_name[0] == '/' || hdr.ar_name[0] == ' ') && bfd_ardata (abfd)->extended_names != NULL) {
4a81b561
DHW
260 filename = get_extended_arelt_filename (abfd, hdr.ar_name);
261 if (filename == NULL) {
262 bfd_error = malformed_archive;
263 return NULL;
264 }
265 }
266 else
267 {
268 /* We judge the end of the name by looking for a space or a
269 padchar */
270
271 namelen = 0;
272
0452b5aa 273 while (namelen < (unsigned)ar_maxnamelen(abfd) &&
4a81b561
DHW
274 ( hdr.ar_name[namelen] != 0 &&
275 hdr.ar_name[namelen] != ' ' &&
276 hdr.ar_name[namelen] != ar_padchar(abfd))) {
277 namelen++;
278 }
279
280 allocsize += namelen + 1;
281 }
282
a37cc0c0 283 allocptr = bfd_zalloc(abfd, allocsize);
4a81b561
DHW
284 if (allocptr == NULL) {
285 bfd_error = no_memory;
286 return NULL;
287 }
288
289 ared = (struct areltdata *) allocptr;
290
291 ared->arch_header = allocptr + sizeof (struct areltdata);
292 memcpy ((char *) ared->arch_header, &hdr, sizeof (struct ar_hdr));
293 ared->parsed_size = parsed_size;
294
295 if (filename != NULL) ared->filename = filename;
296 else {
297 ared->filename = allocptr + (sizeof (struct areltdata) +
298 sizeof (struct ar_hdr));
299 if (namelen)
300 memcpy (ared->filename, hdr.ar_name, namelen);
301 ared->filename[namelen] = '\0';
302 }
303
304 return ared;
305}
306\f
307bfd *
308get_elt_at_filepos (archive, filepos)
309 bfd *archive;
310 file_ptr filepos;
311{
312 struct areltdata *new_areldata;
313 bfd *n_nfd;
314
315 n_nfd = look_for_bfd_in_cache (archive, filepos);
316 if (n_nfd) return n_nfd;
317
318 if (0 > bfd_seek (archive, filepos, SEEK_SET)) {
319 bfd_error = system_call_error;
320 return NULL;
321 }
322
323 if ((new_areldata = snarf_ar_hdr (archive)) == NULL) return NULL;
324
325 n_nfd = _bfd_create_empty_archive_element_shell (archive);
326 if (n_nfd == NULL) {
fc723380 327 bfd_release (archive, (PTR)new_areldata);
4a81b561
DHW
328 return NULL;
329 }
330 n_nfd->origin = bfd_tell (archive);
9846338e 331 n_nfd->arelt_data = (PTR) new_areldata;
4a81b561
DHW
332 n_nfd->filename = new_areldata->filename;
333
334 if (add_bfd_to_cache (archive, filepos, n_nfd))
335 return n_nfd;
336
337 /* huh? */
fc723380
JG
338 bfd_release (archive, (PTR)n_nfd);
339 bfd_release (archive, (PTR)new_areldata);
4a81b561
DHW
340 return NULL;
341}
342
343bfd *
344bfd_get_elt_at_index (abfd, index)
345 bfd *abfd;
346 int index;
347{
348 bfd *result =
349 get_elt_at_filepos
350 (abfd, (bfd_ardata (abfd)->symdefs + index)->file_offset);
351 return result;
352}
353
6f715d66
SC
354/*proto* bfd_openr_next_archived_file
355Initially provided a bfd containing an archive and NULL, opens a bfd
356on the first contained element and returns that. Subsequent calls to
357bfd_openr_next_archived_file should pass the archive and the previous
358return value to return a created bfd to the next contained element.
359NULL is returned when there are no more.
360
361*; PROTO(bfd*, bfd_openr_next_archived_file,
362 (bfd *archive, bfd *previous));
363
364*/
365
4a81b561 366bfd *
6f715d66
SC
367DEFUN(bfd_openr_next_archived_file,(archive, last_file),
368 bfd *archive AND
369 bfd*last_file)
4a81b561
DHW
370{
371
372 if ((bfd_get_format (archive) != bfd_archive) ||
373 (archive->direction == write_direction)) {
374 bfd_error = invalid_operation;
375 return NULL;
376 }
377
378
379 return BFD_SEND (archive,
380 openr_next_archived_file,
381 (archive,
382 last_file));
383
384}
385
386bfd *bfd_generic_openr_next_archived_file(archive, last_file)
387 bfd *archive;
388 bfd *last_file;
389{
390 file_ptr filestart;
391
392 if (!last_file)
393 filestart = bfd_ardata (archive)->first_file_filepos;
394 else {
fc723380
JG
395 unsigned int size = arelt_size(last_file);
396 /* Pad to an even boundary... */
397 filestart = last_file->origin + size + size%2;
398 }
4a81b561
DHW
399
400 return get_elt_at_filepos (archive, filestart);
401}
402\f
403
404bfd_target *
405bfd_generic_archive_p (abfd)
406 bfd *abfd;
407{
408 char armag[SARMAG+1];
409
9846338e 410 if (bfd_read ((PTR)armag, 1, SARMAG, abfd) != SARMAG) {
4a81b561
DHW
411 bfd_error = wrong_format;
412 return 0;
413 }
414
9846338e
SC
415#ifdef GNU960
416 if (strncmp (armag, BFD_GNU960_ARMAG(abfd), SARMAG)) return 0;
417#else
4a81b561 418 if (strncmp (armag, ARMAG, SARMAG)) return 0;
9846338e 419#endif
4a81b561 420
fc723380
JG
421 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
422 involves a cast, we can't do it as the left operand of assignment. */
423 set_tdata (abfd, bfd_zalloc(abfd,sizeof (struct artdata)));
4a81b561
DHW
424
425 if (bfd_ardata (abfd) == NULL) {
426 bfd_error = no_memory;
427 return 0;
428 }
429
430 bfd_ardata (abfd)->first_file_filepos = SARMAG;
431
432 if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
a37cc0c0 433 bfd_release(abfd, bfd_ardata (abfd));
4a81b561
DHW
434 abfd->tdata = NULL;
435 return 0;
436 }
437
4a81b561 438 if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) {
a37cc0c0 439 bfd_release(abfd, bfd_ardata (abfd));
4a81b561
DHW
440 abfd->tdata = NULL;
441 return 0;
442 }
443
444 return abfd->xvec;
445}
446
447/* Returns false on error, true otherwise */
448boolean
449bfd_slurp_bsd_armap (abfd)
450 bfd *abfd;
451{
6f715d66 452
4a81b561
DHW
453 struct areltdata *mapdata;
454 char nextname[17];
455 unsigned int counter = 0;
456 int *raw_armap, *rbase;
457 struct artdata *ardata = bfd_ardata (abfd);
458 char *stringbase;
459
fc723380
JG
460 /* FIXME, if the read fails, this routine quietly returns "true"!!
461 It should probably do that if the read gives 0 bytes (empty archive),
462 but fail for any other size... */
9846338e 463 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
4a81b561
DHW
464 /* The archive has at least 16 bytes in it */
465 bfd_seek (abfd, -16L, SEEK_CUR);
466
d6a554ae
JG
467 /* This should be using RANLIBMAG, but at least it can be grepped for
468 in this comment. */
4a81b561
DHW
469 if (strncmp (nextname, "__.SYMDEF ", 16)) {
470 bfd_has_map (abfd) = false;
471 return true;
472 }
473
474 mapdata = snarf_ar_hdr (abfd);
475 if (mapdata == NULL) return false;
476
a37cc0c0 477 raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
4a81b561
DHW
478 if (raw_armap == NULL) {
479 bfd_error = no_memory;
480 byebye:
fc723380 481 bfd_release (abfd, (PTR)mapdata);
4a81b561
DHW
482 return false;
483 }
484
9846338e 485 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
4a81b561
DHW
486 mapdata->parsed_size) {
487 bfd_error = malformed_archive;
fc723380 488 bfd_release (abfd, (PTR)raw_armap);
4a81b561
DHW
489 goto byebye;
490 }
491
6f715d66 492 ardata->symdef_count = bfd_h_get_32(abfd, (PTR)raw_armap) / sizeof (struct symdef);
4a81b561
DHW
493 ardata->cache = 0;
494 rbase = raw_armap+1;
495 ardata->symdefs = (carsym *) rbase;
496 stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
497
fc723380 498 for (;counter < ardata->symdef_count; counter++) {
4a81b561 499 struct symdef *sym = ((struct symdef *) rbase) + counter;
6f715d66
SC
500 sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
501 sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
4a81b561
DHW
502 }
503
504 ardata->first_file_filepos = bfd_tell (abfd);
505 /* Pad to an even boundary if you have to */
506 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
fc723380
JG
507 /* FIXME, we should provide some way to free raw_ardata when
508 we are done using the strings from it. For now, it seems
509 to be allocated on an obstack anyway... */
4a81b561
DHW
510 bfd_has_map (abfd) = true;
511 }
512 return true;
513}
514
515/* Returns false on error, true otherwise */
516boolean
517bfd_slurp_coff_armap (abfd)
518 bfd *abfd;
519{
520 struct areltdata *mapdata;
521 char nextname;
522 int *raw_armap, *rawptr;
523 struct artdata *ardata = bfd_ardata (abfd);
524 char *stringbase;
525 unsigned int stringsize;
526 carsym *carsyms;
fc723380 527 int result;
4a81b561 528
fc723380 529 result = bfd_read ((PTR)&nextname, 1, 1, abfd);
b6fc45ca 530 bfd_seek (abfd, -1L, SEEK_CUR);
4a81b561 531
fc723380 532 if (result != 1 || nextname != '/') {
4a81b561
DHW
533 /* Actually I think this is an error for a COFF archive */
534 bfd_has_map (abfd) = false;
535 return true;
536 }
537
4a81b561
DHW
538 mapdata = snarf_ar_hdr (abfd);
539 if (mapdata == NULL) return false;
540
a37cc0c0 541 raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
6f715d66
SC
542
543 if (raw_armap == NULL)
544 {
4a81b561
DHW
545 bfd_error = no_memory;
546 byebye:
fc723380 547 bfd_release (abfd, (PTR)mapdata);
4a81b561
DHW
548 return false;
549 }
550
6f715d66 551 /* read in the raw map */
9846338e 552 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
4a81b561
DHW
553 mapdata->parsed_size) {
554 bfd_error = malformed_archive;
555 oops:
fc723380 556 bfd_release (abfd, (PTR)raw_armap);
4a81b561
DHW
557 goto byebye;
558 }
559
560 /* The coff armap must be read sequentially. So we construct a bsd-style
561 one in core all at once, for simplicity. */
562
563 stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
564
565 {
566 unsigned int nsymz = *raw_armap;
567 unsigned int carsym_size = (nsymz * sizeof (carsym));
568 unsigned int ptrsize = (4 * nsymz);
569 unsigned int i;
a37cc0c0 570 ardata->symdefs = (carsym *) bfd_zalloc(abfd,carsym_size + stringsize + 1);
4a81b561
DHW
571 if (ardata->symdefs == NULL) {
572 bfd_error = no_memory;
573 goto oops;
574 }
575 carsyms = ardata->symdefs;
576
577 stringbase = ((char *) ardata->symdefs) + carsym_size;
578 memcpy (stringbase, (char*)raw_armap + ptrsize + 4, stringsize);
579
580
581 /* OK, build the carsyms */
582 for (i = 0; i < nsymz; i++)
583 {
584 rawptr = raw_armap + i + 1;
585 carsyms->file_offset = *rawptr;
586 carsyms->name = stringbase;
587 for (; *(stringbase++););
588 carsyms++;
589 }
590 *stringbase = 0;
591 }
592 ardata->symdef_count = *raw_armap;
593 ardata->first_file_filepos = bfd_tell (abfd);
594 /* Pad to an even boundary if you have to */
595 ardata->first_file_filepos += (ardata->first_file_filepos) %2;
6f715d66 596
ca18a446
JG
597 /* We'd like to release these allocations, but we have allocated stuff
598 since then (using the same obstack, if bfd_release is obstack based).
599 So they will stick around until the bfd is closed. */
600 /* bfd_release (abfd, (PTR)raw_armap);
601 bfd_release (abfd, (PTR)mapdata); */
4a81b561
DHW
602 bfd_has_map (abfd) = true;
603 return true;
604}
4a81b561
DHW
605\f
606/** Extended name table.
607
6f715d66
SC
608 Normally archives support only 14-character filenames.
609
610 Intel has extended the format: longer names are stored in a special
611 element (the first in the archive, or second if there is an armap);
612 the name in the ar_hdr is replaced by <space><index into filename
613 element>. Index is the P.R. of an int (radix: 8). Data General have
614 extended the format by using the prefix // for the special element */
4a81b561
DHW
615
616/* Returns false on error, true otherwise */
617boolean
618_bfd_slurp_extended_name_table (abfd)
619 bfd *abfd;
620{
621 char nextname[17];
622 struct areltdata *namedata;
623
fc723380
JG
624 /* FIXME: Formatting sucks here, and in case of failure of BFD_READ,
625 we probably don't want to return true. */
9846338e 626 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
4a81b561 627
6f715d66 628 bfd_seek (abfd, -16L, SEEK_CUR);
4a81b561 629
6f715d66
SC
630 if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 &&
631 strncmp (nextname, "// ", 16) != 0)
632 {
633 bfd_ardata (abfd)->extended_names = NULL;
634 return true;
635 }
4a81b561 636
6f715d66
SC
637 namedata = snarf_ar_hdr (abfd);
638 if (namedata == NULL) return false;
4a81b561 639
6f715d66
SC
640 bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
641 if (bfd_ardata (abfd)->extended_names == NULL) {
642 bfd_error = no_memory;
643 byebye:
644 bfd_release (abfd, (PTR)namedata);
645 return false;
646 }
4a81b561 647
6f715d66
SC
648 if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
649 namedata->parsed_size, abfd) != namedata->parsed_size) {
650 bfd_error = malformed_archive;
651 bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
652 bfd_ardata (abfd)->extended_names = NULL;
653 goto byebye;
654 }
4a81b561 655
6f715d66
SC
656 /* Since the archive is supposed to be printable if it contains
657 text, the entries in the list are newline-padded, not null
658 padded. We'll fix that there.. */
659 {
660 char *temp = bfd_ardata (abfd)->extended_names;
661 for (; *temp != '\0'; ++temp)
662 if (*temp == '\n') *temp = '\0';
663 }
9846338e 664
6f715d66
SC
665 /* Pad to an even boundary if you have to */
666 bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
667 bfd_ardata (abfd)->first_file_filepos +=
668 (bfd_ardata (abfd)->first_file_filepos) %2;
669
670 /* FIXME, we can't release namedata here because it was allocated
671 below extended_names on the obstack... */
672 /* bfd_release (abfd, namedata); */
673 }
4a81b561
DHW
674 return true;
675}
676
677static
678char *normalize(file)
679char *file;
680{
681 char * filename = strrchr(file, '/');
682 if (filename != (char *)NULL) {
683 filename ++;
684 }
685 else {
686 filename = file;
687 }
688return filename;
689}
690
691/* Follows archive_head and produces an extended name table if necessary.
692 Returns (in tabloc) a pointer to an extended name table, and in tablen
693 the length of the table. If it makes an entry it clobbers the filename
694 so that the element may be written without further massage.
695 Returns true if it ran successfully, false if something went wrong.
696 A successful return may still involve a zero-length tablen!
697 */
698boolean
699bfd_construct_extended_name_table (abfd, tabloc, tablen)
700 bfd *abfd;
701 char **tabloc;
702 unsigned int *tablen;
703{
9846338e
SC
704 unsigned int maxname = abfd->xvec->ar_max_namelen;
705 unsigned int total_namelen = 0;
706 bfd *current;
707 char *strptr;
4a81b561 708
9846338e 709 *tablen = 0;
4a81b561 710
9846338e
SC
711 /* Figure out how long the table should be */
712 for (current = abfd->archive_head; current != NULL; current = current->next){
713 unsigned int thislen = strlen (normalize(current->filename));
714 if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
715 }
4a81b561 716
9846338e 717 if (total_namelen == 0) return true;
4a81b561 718
a37cc0c0 719 *tabloc = bfd_zalloc (abfd,total_namelen);
9846338e
SC
720 if (*tabloc == NULL) {
721 bfd_error = no_memory;
722 return false;
723 }
4a81b561 724
9846338e
SC
725 *tablen = total_namelen;
726 strptr = *tabloc;
727
728 for (current = abfd->archive_head; current != NULL; current =
729 current->next) {
730 char *normal =normalize( current->filename);
731 unsigned int thislen = strlen (normal);
732 if (thislen > maxname) {
733 /* Works for now; may need to be re-engineered if we encounter an oddball
734 archive format and want to generalise this hack. */
735 struct ar_hdr *hdr = arch_hdr(current);
736 strcpy (strptr, normal);
737 strptr[thislen] = '\n';
738 hdr->ar_name[0] = ' ';
739 /* We know there will always be enough room (one of the few cases
740 where you may safely use sprintf). */
741 sprintf ((hdr->ar_name) + 1, "%-o", (unsigned) (strptr - *tabloc));
742 /* Kinda Kludgy. We should just use the returned value of sprintf
743 but not all implementations get this right */
744 {
745 char *temp = hdr->ar_name +2;
746 for (; temp < hdr->ar_name + maxname; temp++)
747 if (*temp == '\0') *temp = ' ';
4a81b561 748 }
9846338e 749 strptr += thislen + 1;
4a81b561 750 }
9846338e 751 }
4a81b561 752
9846338e 753 return true;
4a81b561
DHW
754}
755\f
756/** A couple of functions for creating ar_hdrs */
757
758/* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
759 The filename must refer to a filename in the filesystem.
760 The filename field of the ar_hdr will NOT be initialized
761*/
762
763struct areltdata *
a37cc0c0
SC
764DEFUN(bfd_ar_hdr_from_filesystem, (abfd,filename),
765 bfd* abfd AND
766 CONST char *filename)
4a81b561
DHW
767{
768 struct stat status;
769 struct areltdata *ared;
770 struct ar_hdr *hdr;
771 char *temp, *temp1;
772
773
774 if (stat (filename, &status) != 0) {
775 bfd_error = system_call_error;
776 return NULL;
777 }
778
a37cc0c0 779 ared = (struct areltdata *) bfd_zalloc(abfd, sizeof (struct ar_hdr) +
4a81b561
DHW
780 sizeof (struct areltdata));
781 if (ared == NULL) {
782 bfd_error = no_memory;
783 return NULL;
784 }
785 hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
786
787 /* ar headers are space padded, not null padded! */
788 temp = (char *) hdr;
789 temp1 = temp + sizeof (struct ar_hdr) - 2;
790 for (; temp < temp1; *(temp++) = ' ');
791 strncpy (hdr->ar_fmag, ARFMAG, 2);
792
793 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
794 sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
795 sprintf ((hdr->ar_uid), "%d", status.st_uid);
796 sprintf ((hdr->ar_gid), "%d", status.st_gid);
797 sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
798 sprintf ((hdr->ar_size), "%-10ld", status.st_size);
799 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
800 understand how these C losers could design such a ramshackle bunch of
801 IO operations */
802 temp = (char *) hdr;
803 temp1 = temp + sizeof (struct ar_hdr) - 2;
804 for (; temp < temp1; temp++) {
805 if (*temp == '\0') *temp = ' ';
806 }
807 strncpy (hdr->ar_fmag, ARFMAG, 2);
808 ared->parsed_size = status.st_size;
809 ared->arch_header = (char *) hdr;
810
811 return ared;
812}
813
814struct ar_hdr *
a37cc0c0
SC
815DEFUN(bfd_special_undocumented_glue, (abfd, filename),
816 bfd *abfd AND
817 char *filename)
4a81b561
DHW
818{
819
a37cc0c0 820 return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (abfd, filename) -> arch_header;
4a81b561
DHW
821}
822
823
824/* Analogous to stat call */
825int
826bfd_generic_stat_arch_elt (abfd, buf)
827 bfd *abfd;
828 struct stat *buf;
829{
830 struct ar_hdr *hdr;
831 char *aloser;
832
833 if (abfd->arelt_data == NULL) {
834 bfd_error = invalid_operation;
835 return -1;
836 }
837
838 hdr = arch_hdr (abfd);
839
840#define foo(arelt, stelt, size) \
841 buf->stelt = strtol (hdr->arelt, &aloser, size); \
842 if (aloser == hdr->arelt) return -1;
843
844 foo (ar_date, st_mtime, 10);
845 foo (ar_uid, st_uid, 10);
846 foo (ar_gid, st_gid, 10);
847 foo (ar_mode, st_mode, 8);
848 foo (ar_size, st_size, 10);
849
850 return 0;
851}
852
4a81b561 853void
9846338e
SC
854bfd_dont_truncate_arname (abfd, pathname, arhdr)
855 bfd *abfd;
8b0328db 856 CONST char *pathname;
9846338e 857 char *arhdr;
4a81b561 858{
fc723380 859 /* FIXME: This interacts unpleasantly with ar's quick-append option.
9846338e
SC
860 Fortunately ic960 users will never use that option. Fixing this
861 is very hard; fortunately I know how to do it and will do so once
862 intel's release is out the door. */
863
864 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
865 int length;
8b0328db 866 CONST char *filename = strrchr (pathname, '/');
9846338e 867 int maxlen = ar_maxnamelen (abfd);
4a81b561 868
9846338e
SC
869 if (filename == NULL)
870 filename = pathname;
871 else
872 ++filename;
873
874 length = strlen (filename);
4a81b561 875
9846338e
SC
876 if (length <= maxlen)
877 memcpy (hdr->ar_name, filename, length);
878
879 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
4a81b561 880 return;
9846338e 881
4a81b561
DHW
882}
883
884void
885bfd_bsd_truncate_arname (abfd, pathname, arhdr)
886 bfd *abfd;
8b0328db 887 CONST char *pathname;
4a81b561
DHW
888 char *arhdr;
889{
890 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
891 int length;
8b0328db 892 CONST char *filename = strrchr (pathname, '/');
4a81b561
DHW
893 int maxlen = ar_maxnamelen (abfd);
894
895
896 if (filename == NULL)
897 filename = pathname;
898 else
899 ++filename;
900
901 length = strlen (filename);
902
903 if (length <= maxlen)
904 memcpy (hdr->ar_name, filename, length);
905 else {
906 /* pathname: meet procrustes */
907 memcpy (hdr->ar_name, filename, maxlen);
908 length = maxlen;
909 }
910
9846338e 911 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
4a81b561
DHW
912}
913
914/* Store name into ar header. Truncates the name to fit.
915 1> strip pathname to be just the basename.
916 2> if it's short enuf to fit, stuff it in.
917 3> If it doesn't end with .o, truncate it to fit
918 4> truncate it before the .o, append .o, stuff THAT in.
919*/
920
921/* This is what gnu ar does. It's better but incompatible with the bsd ar. */
922void
923bfd_gnu_truncate_arname (abfd, pathname, arhdr)
924 bfd *abfd;
8b0328db 925 CONST char *pathname;
4a81b561
DHW
926 char *arhdr;
927{
928 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
929 int length;
8b0328db 930 CONST char *filename = strrchr (pathname, '/');
4a81b561
DHW
931 int maxlen = ar_maxnamelen (abfd);
932
933 if (filename == NULL)
934 filename = pathname;
935 else
936 ++filename;
937
938 length = strlen (filename);
939
940 if (length <= maxlen)
941 memcpy (hdr->ar_name, filename, length);
942 else { /* pathname: meet procrustes */
943 memcpy (hdr->ar_name, filename, maxlen);
944 if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
945 hdr->ar_name[maxlen - 2] = '.';
946 hdr->ar_name[maxlen - 1] = 'o';
947 }
948 length = maxlen;
949 }
950
951 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
952}
953\f
954
955PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
956
957/* The bfd is open for write and has its format set to bfd_archive */
958boolean
959_bfd_write_archive_contents (arch)
960 bfd *arch;
961{
962 bfd *current;
963 char *etable = NULL;
964 unsigned int elength = 0;
965 boolean makemap = bfd_has_map (arch);
966 boolean hasobjects = false; /* if no .o's, don't bother to make a map */
967 unsigned int i;
968
4a81b561
DHW
969 /* Verify the viability of all entries; if any of them live in the
970 filesystem (as opposed to living in an archive open for input)
971 then construct a fresh ar_hdr for them.
972 */
973 for (current = arch->archive_head; current; current = current->next) {
974 if (bfd_write_p (current)) {
975 bfd_error = invalid_operation;
976 return false;
977 }
978 if (!current->arelt_data) {
979 current->arelt_data =
a37cc0c0 980 (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
4a81b561
DHW
981 if (!current->arelt_data) return false;
982
983 /* Put in the file name */
984
985 BFD_SEND (arch, _bfd_truncate_arname,(arch,
986 current->filename,
0452b5aa 987 (char *) arch_hdr(current)));
4a81b561
DHW
988
989
990 }
991
992 if (makemap) { /* don't bother if we won't make a map! */
993 if ((bfd_check_format (current, bfd_object))
994#if 0 /* FIXME -- these are not set correctly */
995 && ((bfd_get_file_flags (current) & HAS_SYMS))
996#endif
997 )
998 hasobjects = true;
999 }
1000 }
1001
1002 if (!bfd_construct_extended_name_table (arch, &etable, &elength))
1003 return false;
1004
1005 bfd_seek (arch, 0, SEEK_SET);
9846338e
SC
1006#ifdef GNU960
1007 bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
1008#else
4a81b561 1009 bfd_write (ARMAG, 1, SARMAG, arch);
9846338e 1010#endif
4a81b561
DHW
1011
1012 if (makemap && hasobjects) {
1013
1014 if (compute_and_write_armap (arch, elength) != true) {
4a81b561
DHW
1015 return false;
1016 }
1017 }
1018
1019 if (elength != 0) {
1020 struct ar_hdr hdr;
1021
1022 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1023 sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
1024 sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
1025 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1026 for (i = 0; i < sizeof (struct ar_hdr); i++)
1027 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
b1847ba9 1028 bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
4a81b561
DHW
1029 bfd_write (etable, 1, elength, arch);
1030 if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
a37cc0c0 1031
4a81b561
DHW
1032 }
1033
1034 for (current = arch->archive_head; current; current = current->next) {
1035 char buffer[DEFAULT_BUFFERSIZE];
1036 unsigned int remaining = arelt_size (current);
1037 struct ar_hdr *hdr = arch_hdr(current);
1038 /* write ar header */
1039
b1847ba9 1040 if (bfd_write ((char *)hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
4a81b561
DHW
1041 syserr:
1042 bfd_error = system_call_error;
1043 return false;
1044 }
1045 if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
0452b5aa
SC
1046 while (remaining)
1047 {
1048 unsigned int amt = DEFAULT_BUFFERSIZE;
1049 if (amt > remaining) {
1050 amt = remaining;
1051 }
1052 if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
1053 if (bfd_write (buffer, amt, 1, arch) != amt) goto syserr;
1054 remaining -= amt;
1055 }
4a81b561
DHW
1056 if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
1057 }
1058return true;
1059}
1060\f
1061/* Note that the namidx for the first symbol is 0 */
1062
4a81b561
DHW
1063boolean
1064compute_and_write_armap (arch, elength)
1065 bfd *arch;
1066 unsigned int elength;
1067{
1068 bfd *current;
1069 file_ptr elt_no = 0;
1070 struct orl *map;
1071 int orl_max = 15000; /* fine initial default */
1072 int orl_count = 0;
1073 int stridx = 0; /* string index */
1074
1075 /* Dunno if this is the best place for this info... */
1076 if (elength != 0) elength += sizeof (struct ar_hdr);
1077 elength += elength %2 ;
1078
a37cc0c0 1079 map = (struct orl *) bfd_zalloc (arch,orl_max * sizeof (struct orl));
4a81b561
DHW
1080 if (map == NULL) {
1081 bfd_error = no_memory;
1082 return false;
1083 }
1084
1085 /* Map over each element */
1086 for (current = arch->archive_head;
1087 current != (bfd *)NULL;
1088 current = current->next, elt_no++)
1089 {
0452b5aa
SC
1090 if ((bfd_check_format (current, bfd_object) == true)
1091 && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1092 asymbol **syms;
1093 unsigned int storage;
1094 unsigned int symcount;
1095 unsigned int src_count;
1096
1097 storage = get_symtab_upper_bound (current);
1098 if (storage != 0) {
1099
a37cc0c0 1100 syms = (asymbol **) bfd_zalloc (arch,storage);
0452b5aa
SC
1101 if (syms == NULL) {
1102 bfd_error = no_memory; /* FIXME -- memory leak */
1103 return false;
1104 }
1105 symcount = bfd_canonicalize_symtab (current, syms);
1106
1107
1108 /* Now map over all the symbols, picking out the ones we want */
1109 for (src_count = 0; src_count <symcount; src_count++) {
1110 flagword flags = (syms[src_count])->flags;
1111 if ((flags & BSF_GLOBAL) ||
1112 (flags & BSF_FORT_COMM)) {
1113
1114 /* This symbol will go into the archive header */
1115 if (orl_count == orl_max)
1116 {
1117 orl_max *= 2;
a37cc0c0 1118 map = (struct orl *) bfd_realloc (arch, (char *) map,
0452b5aa
SC
1119 orl_max * sizeof (struct orl));
1120 }
1121
7ed4093a 1122 (map[orl_count]).name = (char **) &((syms[src_count])->name);
45021fee 1123 (map[orl_count]).pos = (file_ptr) current;
0452b5aa
SC
1124 (map[orl_count]).namidx = stridx;
1125
1126 stridx += strlen ((syms[src_count])->name) + 1;
1127 ++orl_count;
1128 }
1129 }
4a81b561 1130 }
4a81b561
DHW
1131 }
1132 }
4a81b561
DHW
1133 /* OK, now we have collected all the data, let's write them out */
1134 if (!BFD_SEND (arch, write_armap,
1135 (arch, elength, map, orl_count, stridx))) {
a37cc0c0 1136
4a81b561
DHW
1137 return false;
1138 }
1139
a37cc0c0 1140
4a81b561
DHW
1141 return true;
1142}
1143
4a81b561
DHW
1144boolean
1145bsd_write_armap (arch, elength, map, orl_count, stridx)
1146 bfd *arch;
1147 unsigned int elength;
1148 struct orl *map;
1149 int orl_count;
1150 int stridx;
1151{
1152 unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1153 unsigned int stringsize = stridx + 4;
1154 unsigned int mapsize = stringsize + ranlibsize;
1155 file_ptr firstreal;
1156 bfd *current = arch->archive_head;
45021fee 1157 bfd *last_elt = current; /* last element arch seen */
4a81b561
DHW
1158 int temp;
1159 int count;
1160 struct ar_hdr hdr;
1161 struct stat statbuf;
1162 unsigned int i;
1163 int padit = mapsize & 1;
1164
1165 if (padit) mapsize ++;
1166
1167 firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1168
2a525d0c 1169 stat (arch->filename, &statbuf);
4a81b561 1170 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
d6a554ae 1171 sprintf (hdr.ar_name, RANLIBMAG);
4a81b561 1172 sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);
45021fee
RP
1173 sprintf (hdr.ar_uid, "%d", getuid());
1174 sprintf (hdr.ar_gid, "%d", getgid());
1175 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
4a81b561
DHW
1176 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1177 for (i = 0; i < sizeof (struct ar_hdr); i++)
1178 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
b1847ba9 1179 bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
6f715d66 1180 bfd_h_put_32(arch, ranlibsize, (PTR)&temp);
4a81b561
DHW
1181 bfd_write (&temp, 1, sizeof (temp), arch);
1182
1183 for (count = 0; count < orl_count; count++) {
1184 struct symdef outs;
1185 struct symdef *outp = &outs;
1186
45021fee
RP
1187 if (((bfd *)(map[count]).pos) != last_elt) {
1188 do {
1189 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1190 firstreal += firstreal % 2;
1191 current = current->next;
1192 } while (current != (bfd *)(map[count]).pos);
1193 } /* if new archive element */
1194
1195 last_elt = current;
6f715d66
SC
1196 bfd_h_put_32(arch, ((map[count]).namidx),(PTR) &outs.s.string_offset);
1197 bfd_h_put_32(arch, firstreal,(PTR) &outs.file_offset);
4a81b561
DHW
1198 bfd_write ((char *)outp, 1, sizeof (outs), arch);
1199 }
1200
1201 /* now write the strings themselves */
6f715d66 1202 bfd_h_put_32(arch, stridx, (PTR)&temp);
d0ec7a8e 1203 bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
4a81b561
DHW
1204 for (count = 0; count < orl_count; count++)
1205 bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1206
1207 /* The spec sez this should be a newline. But in order to be
1208 bug-compatible for sun's ar we use a null. */
1209 if (padit)
1210 bfd_write("\0",1,1,arch);
1211
1212 return true;
1213}
1214\f
1215
1216/* A coff armap looks like :
1217 ARMAG
1218 struct ar_hdr with name = '/'
1219 number of symbols
1220 offset of file for symbol 0
1221 offset of file for symbol 1
1222 ..
1223 offset of file for symbol n-1
1224 symbol name 0
1225 symbol name 1
1226 ..
1227 symbol name n-1
1228
1229*/
1230
1231boolean
1232coff_write_armap (arch, elength, map, orl_count, stridx)
1233 bfd *arch;
1234 unsigned int elength;
1235 struct orl *map;
1236 int orl_count;
1237 int stridx;
1238{
1239 unsigned int ranlibsize = (orl_count * 4) + 4;
1240 unsigned int stringsize = stridx;
1241 unsigned int mapsize = stringsize + ranlibsize;
1242 file_ptr archive_member_file_ptr;
1243 bfd *current = arch->archive_head;
1244 int last_eltno = 0; /* last element arch seen */
1245 int count;
1246 struct ar_hdr hdr;
4a81b561
DHW
1247 unsigned int i;
1248 int padit = mapsize & 1;
1249
1250 if (padit) mapsize ++;
1251
1252 archive_member_file_ptr =
1253 mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1254
4a81b561
DHW
1255 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1256 hdr.ar_name[0] = '/';
1257 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
9846338e 1258 sprintf (hdr.ar_date, "%ld", (long)time (NULL));
37a1fd96
DHW
1259 /* This, at least, is what Intel coff sets the values to.: */
1260 sprintf ((hdr.ar_uid), "%d", 0);
1261 sprintf ((hdr.ar_gid), "%d", 0);
9846338e 1262 sprintf ((hdr.ar_mode), "%-7o",(unsigned ) 0);
4a81b561
DHW
1263 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1264
1265 for (i = 0; i < sizeof (struct ar_hdr); i++)
1266 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1267
1268 /* Write the ar header for this item and the number of symbols */
1269
d0ec7a8e 1270 bfd_write ((PTR)&hdr, 1, sizeof (struct ar_hdr), arch);
b1847ba9 1271 /* FIXME, this needs to be byte-swapped */
d0ec7a8e 1272 bfd_write ((PTR)&orl_count, 1, sizeof (orl_count), arch);
4a81b561
DHW
1273
1274 /* Two passes, first write the file offsets for each symbol -
1275 remembering that each offset is on a two byte boundary
1276 */
1277
1278 for (count = 0; count < orl_count; count++) {
1279 while ((map[count]).pos != last_eltno) {
1280 /* If this is the first time we've seen a ref to this archive
1281 then remember it's size */
1282 archive_member_file_ptr +=
1283 arelt_size (current) + sizeof (struct ar_hdr);
1284 archive_member_file_ptr += archive_member_file_ptr % 2;
1285 current = current->next;
1286 last_eltno++;
1287 }
b1847ba9 1288 /* FIXME, this needs to be byte-swapped */
d0ec7a8e 1289 bfd_write ((PTR)&archive_member_file_ptr,
4a81b561
DHW
1290 1,
1291 sizeof (archive_member_file_ptr),
1292 arch);
1293 }
1294
1295 /* now write the strings themselves */
1296 for (count = 0; count < orl_count; count++) {
d0ec7a8e 1297 bfd_write ((PTR)*((map[count]).name),
4a81b561
DHW
1298 1,
1299 strlen (*((map[count]).name))+1, arch);
1300
1301 }
1302 /* The spec sez this should be a newline. But in order to be
1303 bug-compatible for arc960 we use a null. */
1304 if (padit)
1305 bfd_write("\0",1,1,arch);
1306
1307 return true;
1308}
This page took 0.152457 seconds and 4 git commands to generate.