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