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