Merge intel-deliver and amd-deliver "include" directories, and the
[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
420 if (strncmp (nextname, "__.SYMDEF ", 16)) {
421 bfd_has_map (abfd) = false;
422 return true;
423 }
424
425 mapdata = snarf_ar_hdr (abfd);
426 if (mapdata == NULL) return false;
427
a37cc0c0 428 raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
4a81b561
DHW
429 if (raw_armap == NULL) {
430 bfd_error = no_memory;
431 byebye:
4a81b561
DHW
432 return false;
433 }
434
9846338e 435 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
4a81b561
DHW
436 mapdata->parsed_size) {
437 bfd_error = malformed_archive;
4a81b561
DHW
438 goto byebye;
439 }
440
441 ardata->symdef_count = *(raw_armap) / sizeof (struct symdef);
442 ardata->cache = 0;
443 rbase = raw_armap+1;
444 ardata->symdefs = (carsym *) rbase;
445 stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
446
447 for (;counter < (unsigned)( ardata->symdef_count); counter++) {
448 struct symdef *sym = ((struct symdef *) rbase) + counter;
449 sym->s.name = sym->s.string_offset + stringbase;
450 }
451
452 ardata->first_file_filepos = bfd_tell (abfd);
453 /* Pad to an even boundary if you have to */
454 ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
4a81b561
DHW
455 bfd_has_map (abfd) = true;
456 }
457 return true;
458}
459
460/* Returns false on error, true otherwise */
461boolean
462bfd_slurp_coff_armap (abfd)
463 bfd *abfd;
464{
465 struct areltdata *mapdata;
466 char nextname;
467 int *raw_armap, *rawptr;
468 struct artdata *ardata = bfd_ardata (abfd);
469 char *stringbase;
470 unsigned int stringsize;
471 carsym *carsyms;
472
9846338e 473 if (bfd_read ((PTR)&nextname, 1, 1, abfd) != 1) {
b6fc45ca 474 bfd_seek (abfd, -1L, SEEK_CUR);
4a81b561
DHW
475 bfd_has_map(abfd) = false;
476 return true;
477 }
b6fc45ca 478 bfd_seek (abfd, -1L, SEEK_CUR);
4a81b561
DHW
479
480 if (nextname != '/') {
481 /* Actually I think this is an error for a COFF archive */
482 bfd_has_map (abfd) = false;
483 return true;
484 }
485
4a81b561
DHW
486 mapdata = snarf_ar_hdr (abfd);
487 if (mapdata == NULL) return false;
488
a37cc0c0 489 raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
4a81b561
DHW
490 if (raw_armap == NULL) {
491 bfd_error = no_memory;
492 byebye:
a37cc0c0 493
4a81b561
DHW
494 return false;
495 }
496
9846338e 497 if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
4a81b561
DHW
498 mapdata->parsed_size) {
499 bfd_error = malformed_archive;
500 oops:
a37cc0c0 501
4a81b561
DHW
502 goto byebye;
503 }
504
505 /* The coff armap must be read sequentially. So we construct a bsd-style
506 one in core all at once, for simplicity. */
507
508 stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4;
509
510 {
511 unsigned int nsymz = *raw_armap;
512 unsigned int carsym_size = (nsymz * sizeof (carsym));
513 unsigned int ptrsize = (4 * nsymz);
514 unsigned int i;
a37cc0c0 515 ardata->symdefs = (carsym *) bfd_zalloc(abfd,carsym_size + stringsize + 1);
4a81b561
DHW
516 if (ardata->symdefs == NULL) {
517 bfd_error = no_memory;
518 goto oops;
519 }
520 carsyms = ardata->symdefs;
521
522 stringbase = ((char *) ardata->symdefs) + carsym_size;
523 memcpy (stringbase, (char*)raw_armap + ptrsize + 4, stringsize);
524
525
526 /* OK, build the carsyms */
527 for (i = 0; i < nsymz; i++)
528 {
529 rawptr = raw_armap + i + 1;
530 carsyms->file_offset = *rawptr;
531 carsyms->name = stringbase;
532 for (; *(stringbase++););
533 carsyms++;
534 }
535 *stringbase = 0;
536 }
537 ardata->symdef_count = *raw_armap;
538 ardata->first_file_filepos = bfd_tell (abfd);
539 /* Pad to an even boundary if you have to */
540 ardata->first_file_filepos += (ardata->first_file_filepos) %2;
a37cc0c0 541
4a81b561
DHW
542 bfd_has_map (abfd) = true;
543 return true;
544}
545
546\f
547/** Extended name table.
548
549 Normally archives support only 14-character filenames. Intel has extended
550 the format: longer names are stored in a special element (the first in the
551 archive, or second if there is an armap); the name in the ar_hdr is replaced
552 by <space><index into filename element>. Index is the P.R. of an int (radix:
553 8). */
554
555/* Returns false on error, true otherwise */
556boolean
557_bfd_slurp_extended_name_table (abfd)
558 bfd *abfd;
559{
560 char nextname[17];
561 struct areltdata *namedata;
562
9846338e 563 if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
4a81b561
DHW
564
565 bfd_seek (abfd, -16L, SEEK_CUR);
566
567 if (strncmp (nextname, "ARFILENAMES/ ", 16)) {
568 bfd_ardata (abfd)->extended_names = NULL;
569 return true;
570 }
571
572 namedata = snarf_ar_hdr (abfd);
573 if (namedata == NULL) return false;
574
575
a37cc0c0 576 bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
4a81b561
DHW
577 if (bfd_ardata (abfd)->extended_names == NULL) {
578 bfd_error = no_memory;
579 byebye:
a37cc0c0 580
4a81b561
DHW
581 return false;
582 }
583
9846338e 584 if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
4a81b561
DHW
585 namedata->parsed_size, abfd) != namedata->parsed_size) {
586 bfd_error = malformed_archive;
a37cc0c0 587
4a81b561
DHW
588 bfd_ardata (abfd)->extended_names = NULL;
589 goto byebye;
590 }
591
9846338e
SC
592 /* It appears that the extended names are newline-padded, not null padded.
593 */
594 {
595 char *temp = bfd_ardata (abfd)->extended_names;
596 for (; *temp != '\0'; ++temp)
597 if (*temp == '\n') *temp = '\0';
598 }
599
4a81b561
DHW
600 /* Pad to an even boundary if you have to */
601 bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
602 bfd_ardata (abfd)->first_file_filepos +=
603 (bfd_ardata (abfd)->first_file_filepos) %2;
604
a37cc0c0 605
4a81b561
DHW
606}
607 return true;
608}
609
610static
611char *normalize(file)
612char *file;
613{
614 char * filename = strrchr(file, '/');
615 if (filename != (char *)NULL) {
616 filename ++;
617 }
618 else {
619 filename = file;
620 }
621return filename;
622}
623
624/* Follows archive_head and produces an extended name table if necessary.
625 Returns (in tabloc) a pointer to an extended name table, and in tablen
626 the length of the table. If it makes an entry it clobbers the filename
627 so that the element may be written without further massage.
628 Returns true if it ran successfully, false if something went wrong.
629 A successful return may still involve a zero-length tablen!
630 */
631boolean
632bfd_construct_extended_name_table (abfd, tabloc, tablen)
633 bfd *abfd;
634 char **tabloc;
635 unsigned int *tablen;
636{
9846338e
SC
637 unsigned int maxname = abfd->xvec->ar_max_namelen;
638 unsigned int total_namelen = 0;
639 bfd *current;
640 char *strptr;
4a81b561 641
9846338e 642 *tablen = 0;
4a81b561 643
9846338e
SC
644 /* Figure out how long the table should be */
645 for (current = abfd->archive_head; current != NULL; current = current->next){
646 unsigned int thislen = strlen (normalize(current->filename));
647 if (thislen > maxname) total_namelen += thislen + 1; /* leave room for \n */
648 }
4a81b561 649
9846338e 650 if (total_namelen == 0) return true;
4a81b561 651
a37cc0c0 652 *tabloc = bfd_zalloc (abfd,total_namelen);
9846338e
SC
653 if (*tabloc == NULL) {
654 bfd_error = no_memory;
655 return false;
656 }
4a81b561 657
9846338e
SC
658 *tablen = total_namelen;
659 strptr = *tabloc;
660
661 for (current = abfd->archive_head; current != NULL; current =
662 current->next) {
663 char *normal =normalize( current->filename);
664 unsigned int thislen = strlen (normal);
665 if (thislen > maxname) {
666 /* Works for now; may need to be re-engineered if we encounter an oddball
667 archive format and want to generalise this hack. */
668 struct ar_hdr *hdr = arch_hdr(current);
669 strcpy (strptr, normal);
670 strptr[thislen] = '\n';
671 hdr->ar_name[0] = ' ';
672 /* We know there will always be enough room (one of the few cases
673 where you may safely use sprintf). */
674 sprintf ((hdr->ar_name) + 1, "%-o", (unsigned) (strptr - *tabloc));
675 /* Kinda Kludgy. We should just use the returned value of sprintf
676 but not all implementations get this right */
677 {
678 char *temp = hdr->ar_name +2;
679 for (; temp < hdr->ar_name + maxname; temp++)
680 if (*temp == '\0') *temp = ' ';
4a81b561 681 }
9846338e 682 strptr += thislen + 1;
4a81b561 683 }
9846338e 684 }
4a81b561 685
9846338e 686 return true;
4a81b561
DHW
687}
688\f
689/** A couple of functions for creating ar_hdrs */
690
691/* Takes a filename, returns an arelt_data for it, or NULL if it can't make one.
692 The filename must refer to a filename in the filesystem.
693 The filename field of the ar_hdr will NOT be initialized
694*/
695
696struct areltdata *
a37cc0c0
SC
697DEFUN(bfd_ar_hdr_from_filesystem, (abfd,filename),
698 bfd* abfd AND
699 CONST char *filename)
4a81b561
DHW
700{
701 struct stat status;
702 struct areltdata *ared;
703 struct ar_hdr *hdr;
704 char *temp, *temp1;
705
706
707 if (stat (filename, &status) != 0) {
708 bfd_error = system_call_error;
709 return NULL;
710 }
711
a37cc0c0 712 ared = (struct areltdata *) bfd_zalloc(abfd, sizeof (struct ar_hdr) +
4a81b561
DHW
713 sizeof (struct areltdata));
714 if (ared == NULL) {
715 bfd_error = no_memory;
716 return NULL;
717 }
718 hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
719
720 /* ar headers are space padded, not null padded! */
721 temp = (char *) hdr;
722 temp1 = temp + sizeof (struct ar_hdr) - 2;
723 for (; temp < temp1; *(temp++) = ' ');
724 strncpy (hdr->ar_fmag, ARFMAG, 2);
725
726 /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
727 sprintf ((hdr->ar_date), "%-12ld", status.st_mtime);
728 sprintf ((hdr->ar_uid), "%d", status.st_uid);
729 sprintf ((hdr->ar_gid), "%d", status.st_gid);
730 sprintf ((hdr->ar_mode), "%-8o", (unsigned) status.st_mode);
731 sprintf ((hdr->ar_size), "%-10ld", status.st_size);
732 /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
733 understand how these C losers could design such a ramshackle bunch of
734 IO operations */
735 temp = (char *) hdr;
736 temp1 = temp + sizeof (struct ar_hdr) - 2;
737 for (; temp < temp1; temp++) {
738 if (*temp == '\0') *temp = ' ';
739 }
740 strncpy (hdr->ar_fmag, ARFMAG, 2);
741 ared->parsed_size = status.st_size;
742 ared->arch_header = (char *) hdr;
743
744 return ared;
745}
746
747struct ar_hdr *
a37cc0c0
SC
748DEFUN(bfd_special_undocumented_glue, (abfd, filename),
749 bfd *abfd AND
750 char *filename)
4a81b561
DHW
751{
752
a37cc0c0 753 return (struct ar_hdr *) bfd_ar_hdr_from_filesystem (abfd, filename) -> arch_header;
4a81b561
DHW
754}
755
756
757/* Analogous to stat call */
758int
759bfd_generic_stat_arch_elt (abfd, buf)
760 bfd *abfd;
761 struct stat *buf;
762{
763 struct ar_hdr *hdr;
764 char *aloser;
765
766 if (abfd->arelt_data == NULL) {
767 bfd_error = invalid_operation;
768 return -1;
769 }
770
771 hdr = arch_hdr (abfd);
772
773#define foo(arelt, stelt, size) \
774 buf->stelt = strtol (hdr->arelt, &aloser, size); \
775 if (aloser == hdr->arelt) return -1;
776
777 foo (ar_date, st_mtime, 10);
778 foo (ar_uid, st_uid, 10);
779 foo (ar_gid, st_gid, 10);
780 foo (ar_mode, st_mode, 8);
781 foo (ar_size, st_size, 10);
782
783 return 0;
784}
785
4a81b561 786void
9846338e
SC
787bfd_dont_truncate_arname (abfd, pathname, arhdr)
788 bfd *abfd;
789 char *pathname;
790 char *arhdr;
4a81b561 791{
9846338e
SC
792 /* This interacts unpleasantly with ar's quick-append option.
793 Fortunately ic960 users will never use that option. Fixing this
794 is very hard; fortunately I know how to do it and will do so once
795 intel's release is out the door. */
796
797 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
798 int length;
799 char *filename = strrchr (pathname, '/');
800 int maxlen = ar_maxnamelen (abfd);
4a81b561 801
9846338e
SC
802 if (filename == NULL)
803 filename = pathname;
804 else
805 ++filename;
806
807 length = strlen (filename);
4a81b561 808
9846338e
SC
809 if (length <= maxlen)
810 memcpy (hdr->ar_name, filename, length);
811
812 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
4a81b561 813 return;
9846338e 814
4a81b561
DHW
815}
816
817void
818bfd_bsd_truncate_arname (abfd, pathname, arhdr)
819 bfd *abfd;
820 char *pathname;
821 char *arhdr;
822{
823 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
824 int length;
825 char *filename = strrchr (pathname, '/');
826 int maxlen = ar_maxnamelen (abfd);
827
828
829 if (filename == NULL)
830 filename = pathname;
831 else
832 ++filename;
833
834 length = strlen (filename);
835
836 if (length <= maxlen)
837 memcpy (hdr->ar_name, filename, length);
838 else {
839 /* pathname: meet procrustes */
840 memcpy (hdr->ar_name, filename, maxlen);
841 length = maxlen;
842 }
843
9846338e 844 if (length < maxlen) (hdr->ar_name)[length] = ar_padchar (abfd);
4a81b561
DHW
845}
846
847/* Store name into ar header. Truncates the name to fit.
848 1> strip pathname to be just the basename.
849 2> if it's short enuf to fit, stuff it in.
850 3> If it doesn't end with .o, truncate it to fit
851 4> truncate it before the .o, append .o, stuff THAT in.
852*/
853
854/* This is what gnu ar does. It's better but incompatible with the bsd ar. */
855void
856bfd_gnu_truncate_arname (abfd, pathname, arhdr)
857 bfd *abfd;
858 char *pathname;
859 char *arhdr;
860{
861 struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
862 int length;
863 char *filename = strrchr (pathname, '/');
864 int maxlen = ar_maxnamelen (abfd);
865
866 if (filename == NULL)
867 filename = pathname;
868 else
869 ++filename;
870
871 length = strlen (filename);
872
873 if (length <= maxlen)
874 memcpy (hdr->ar_name, filename, length);
875 else { /* pathname: meet procrustes */
876 memcpy (hdr->ar_name, filename, maxlen);
877 if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) {
878 hdr->ar_name[maxlen - 2] = '.';
879 hdr->ar_name[maxlen - 1] = 'o';
880 }
881 length = maxlen;
882 }
883
884 if (length < 16) (hdr->ar_name)[length] = ar_padchar (abfd);
885}
886\f
887
888PROTO (boolean, compute_and_write_armap, (bfd *arch, unsigned int elength));
889
890/* The bfd is open for write and has its format set to bfd_archive */
891boolean
892_bfd_write_archive_contents (arch)
893 bfd *arch;
894{
895 bfd *current;
896 char *etable = NULL;
897 unsigned int elength = 0;
898 boolean makemap = bfd_has_map (arch);
899 boolean hasobjects = false; /* if no .o's, don't bother to make a map */
900 unsigned int i;
901
902
903 /* Verify the viability of all entries; if any of them live in the
904 filesystem (as opposed to living in an archive open for input)
905 then construct a fresh ar_hdr for them.
906 */
907 for (current = arch->archive_head; current; current = current->next) {
908 if (bfd_write_p (current)) {
909 bfd_error = invalid_operation;
910 return false;
911 }
912 if (!current->arelt_data) {
913 current->arelt_data =
a37cc0c0 914 (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
4a81b561
DHW
915 if (!current->arelt_data) return false;
916
917 /* Put in the file name */
918
919 BFD_SEND (arch, _bfd_truncate_arname,(arch,
920 current->filename,
0452b5aa 921 (char *) arch_hdr(current)));
4a81b561
DHW
922
923
924 }
925
926 if (makemap) { /* don't bother if we won't make a map! */
927 if ((bfd_check_format (current, bfd_object))
928#if 0 /* FIXME -- these are not set correctly */
929 && ((bfd_get_file_flags (current) & HAS_SYMS))
930#endif
931 )
932 hasobjects = true;
933 }
934 }
935
936 if (!bfd_construct_extended_name_table (arch, &etable, &elength))
937 return false;
938
939 bfd_seek (arch, 0, SEEK_SET);
9846338e
SC
940#ifdef GNU960
941 bfd_write (BFD_GNU960_ARMAG(arch), 1, SARMAG, arch);
942#else
4a81b561 943 bfd_write (ARMAG, 1, SARMAG, arch);
9846338e 944#endif
4a81b561
DHW
945
946 if (makemap && hasobjects) {
947
948 if (compute_and_write_armap (arch, elength) != true) {
4a81b561
DHW
949 return false;
950 }
951 }
952
953 if (elength != 0) {
954 struct ar_hdr hdr;
955
956 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
957 sprintf (&(hdr.ar_name[0]), "ARFILENAMES/");
958 sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength);
959 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
960 for (i = 0; i < sizeof (struct ar_hdr); i++)
961 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
962 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
963 bfd_write (etable, 1, elength, arch);
964 if ((elength % 2) == 1) bfd_write ("\n", 1, 1, arch);
a37cc0c0 965
4a81b561
DHW
966 }
967
968 for (current = arch->archive_head; current; current = current->next) {
969 char buffer[DEFAULT_BUFFERSIZE];
970 unsigned int remaining = arelt_size (current);
971 struct ar_hdr *hdr = arch_hdr(current);
972 /* write ar header */
973
974 if (bfd_write (hdr, 1, sizeof(*hdr), arch) != sizeof(*hdr)) {
975 syserr:
976 bfd_error = system_call_error;
977 return false;
978 }
979 if (bfd_seek (current, 0L, SEEK_SET) != 0L) goto syserr;
0452b5aa
SC
980 while (remaining)
981 {
982 unsigned int amt = DEFAULT_BUFFERSIZE;
983 if (amt > remaining) {
984 amt = remaining;
985 }
986 if (bfd_read (buffer, amt, 1, current) != amt) goto syserr;
987 if (bfd_write (buffer, amt, 1, arch) != amt) goto syserr;
988 remaining -= amt;
989 }
4a81b561
DHW
990 if ((arelt_size (current) % 2) == 1) bfd_write ("\n", 1, 1, arch);
991 }
992return true;
993}
994\f
995/* Note that the namidx for the first symbol is 0 */
996
997
998
999boolean
1000compute_and_write_armap (arch, elength)
1001 bfd *arch;
1002 unsigned int elength;
1003{
1004 bfd *current;
1005 file_ptr elt_no = 0;
1006 struct orl *map;
1007 int orl_max = 15000; /* fine initial default */
1008 int orl_count = 0;
1009 int stridx = 0; /* string index */
1010
1011 /* Dunno if this is the best place for this info... */
1012 if (elength != 0) elength += sizeof (struct ar_hdr);
1013 elength += elength %2 ;
1014
a37cc0c0 1015 map = (struct orl *) bfd_zalloc (arch,orl_max * sizeof (struct orl));
4a81b561
DHW
1016 if (map == NULL) {
1017 bfd_error = no_memory;
1018 return false;
1019 }
1020
1021 /* Map over each element */
1022 for (current = arch->archive_head;
1023 current != (bfd *)NULL;
1024 current = current->next, elt_no++)
1025 {
0452b5aa
SC
1026 if ((bfd_check_format (current, bfd_object) == true)
1027 && ((bfd_get_file_flags (current) & HAS_SYMS))) {
1028 asymbol **syms;
1029 unsigned int storage;
1030 unsigned int symcount;
1031 unsigned int src_count;
1032
1033 storage = get_symtab_upper_bound (current);
1034 if (storage != 0) {
1035
a37cc0c0 1036 syms = (asymbol **) bfd_zalloc (arch,storage);
0452b5aa
SC
1037 if (syms == NULL) {
1038 bfd_error = no_memory; /* FIXME -- memory leak */
1039 return false;
1040 }
1041 symcount = bfd_canonicalize_symtab (current, syms);
1042
1043
1044 /* Now map over all the symbols, picking out the ones we want */
1045 for (src_count = 0; src_count <symcount; src_count++) {
1046 flagword flags = (syms[src_count])->flags;
1047 if ((flags & BSF_GLOBAL) ||
1048 (flags & BSF_FORT_COMM)) {
1049
1050 /* This symbol will go into the archive header */
1051 if (orl_count == orl_max)
1052 {
1053 orl_max *= 2;
a37cc0c0 1054 map = (struct orl *) bfd_realloc (arch, (char *) map,
0452b5aa
SC
1055 orl_max * sizeof (struct orl));
1056 }
1057
1058 (map[orl_count]).name = &((syms[src_count])->name);
1059 (map[orl_count]).pos = elt_no;
1060 (map[orl_count]).namidx = stridx;
1061
1062 stridx += strlen ((syms[src_count])->name) + 1;
1063 ++orl_count;
1064 }
1065 }
4a81b561 1066 }
4a81b561
DHW
1067 }
1068 }
4a81b561
DHW
1069 /* OK, now we have collected all the data, let's write them out */
1070 if (!BFD_SEND (arch, write_armap,
1071 (arch, elength, map, orl_count, stridx))) {
a37cc0c0 1072
4a81b561
DHW
1073 return false;
1074 }
1075
a37cc0c0 1076
4a81b561
DHW
1077 return true;
1078}
1079
1080\f
1081 /* FIXME -- have to byte-swap this */
1082
1083boolean
1084bsd_write_armap (arch, elength, map, orl_count, stridx)
1085 bfd *arch;
1086 unsigned int elength;
1087 struct orl *map;
1088 int orl_count;
1089 int stridx;
1090{
1091 unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4;
1092 unsigned int stringsize = stridx + 4;
1093 unsigned int mapsize = stringsize + ranlibsize;
1094 file_ptr firstreal;
1095 bfd *current = arch->archive_head;
1096 int last_eltno = 0; /* last element arch seen */
1097 int temp;
1098 int count;
1099 struct ar_hdr hdr;
1100 struct stat statbuf;
1101 unsigned int i;
1102 int padit = mapsize & 1;
1103
1104 if (padit) mapsize ++;
1105
1106 firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1107
2a525d0c 1108 stat (arch->filename, &statbuf);
4a81b561
DHW
1109 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1110 sprintf (hdr.ar_name, "__.SYMDEF");
1111 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1112 sprintf (hdr.ar_date, "%ld", statbuf.st_mtime);
1113 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1114 for (i = 0; i < sizeof (struct ar_hdr); i++)
1115 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1116 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1117
1118 temp = orl_count /* + 4 */;
1119 bfd_write (&temp, 1, sizeof (temp), arch);
1120
1121 for (count = 0; count < orl_count; count++) {
1122 struct symdef outs;
1123 struct symdef *outp = &outs;
1124
1125 if ((map[count]).pos != last_eltno) {
1126 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
1127 firstreal += firstreal % 2;
1128 last_eltno = (map[count]).pos;
1129 current = current->next;
1130 }
1131
1132 outs.s.string_offset = ((map[count]).namidx) +4;
1133 outs.file_offset = firstreal;
1134 bfd_write ((char *)outp, 1, sizeof (outs), arch);
1135 }
1136
1137 /* now write the strings themselves */
1138 temp = stridx + 4;
1139 bfd_write (&temp, 1, sizeof (temp), arch);
1140 for (count = 0; count < orl_count; count++)
1141 bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);
1142
1143 /* The spec sez this should be a newline. But in order to be
1144 bug-compatible for sun's ar we use a null. */
1145 if (padit)
1146 bfd_write("\0",1,1,arch);
1147
1148 return true;
1149}
1150\f
1151
1152/* A coff armap looks like :
1153 ARMAG
1154 struct ar_hdr with name = '/'
1155 number of symbols
1156 offset of file for symbol 0
1157 offset of file for symbol 1
1158 ..
1159 offset of file for symbol n-1
1160 symbol name 0
1161 symbol name 1
1162 ..
1163 symbol name n-1
1164
1165*/
1166
1167boolean
1168coff_write_armap (arch, elength, map, orl_count, stridx)
1169 bfd *arch;
1170 unsigned int elength;
1171 struct orl *map;
1172 int orl_count;
1173 int stridx;
1174{
1175 unsigned int ranlibsize = (orl_count * 4) + 4;
1176 unsigned int stringsize = stridx;
1177 unsigned int mapsize = stringsize + ranlibsize;
1178 file_ptr archive_member_file_ptr;
1179 bfd *current = arch->archive_head;
1180 int last_eltno = 0; /* last element arch seen */
1181 int count;
1182 struct ar_hdr hdr;
4a81b561
DHW
1183 unsigned int i;
1184 int padit = mapsize & 1;
1185
1186 if (padit) mapsize ++;
1187
1188 archive_member_file_ptr =
1189 mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
1190
4a81b561
DHW
1191 memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
1192 hdr.ar_name[0] = '/';
1193 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
9846338e 1194 sprintf (hdr.ar_date, "%ld", (long)time (NULL));
37a1fd96
DHW
1195 /* This, at least, is what Intel coff sets the values to.: */
1196 sprintf ((hdr.ar_uid), "%d", 0);
1197 sprintf ((hdr.ar_gid), "%d", 0);
9846338e 1198 sprintf ((hdr.ar_mode), "%-7o",(unsigned ) 0);
4a81b561
DHW
1199 hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
1200
1201 for (i = 0; i < sizeof (struct ar_hdr); i++)
1202 if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
1203
1204 /* Write the ar header for this item and the number of symbols */
1205
1206 bfd_write (&hdr, 1, sizeof (struct ar_hdr), arch);
1207 bfd_write (&orl_count, 1, sizeof (orl_count), arch);
1208
1209 /* Two passes, first write the file offsets for each symbol -
1210 remembering that each offset is on a two byte boundary
1211 */
1212
1213 for (count = 0; count < orl_count; count++) {
1214 while ((map[count]).pos != last_eltno) {
1215 /* If this is the first time we've seen a ref to this archive
1216 then remember it's size */
1217 archive_member_file_ptr +=
1218 arelt_size (current) + sizeof (struct ar_hdr);
1219 archive_member_file_ptr += archive_member_file_ptr % 2;
1220 current = current->next;
1221 last_eltno++;
1222 }
1223 bfd_write (&archive_member_file_ptr,
1224 1,
1225 sizeof (archive_member_file_ptr),
1226 arch);
1227 }
1228
1229 /* now write the strings themselves */
1230 for (count = 0; count < orl_count; count++) {
1231 bfd_write (*((map[count]).name),
1232 1,
1233 strlen (*((map[count]).name))+1, arch);
1234
1235 }
1236 /* The spec sez this should be a newline. But in order to be
1237 bug-compatible for arc960 we use a null. */
1238 if (padit)
1239 bfd_write("\0",1,1,arch);
1240
1241 return true;
1242}
This page took 0.074214 seconds and 4 git commands to generate.