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