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