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