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