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