aboutsummaryrefslogtreecommitdiff
path: root/bfd/archive.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/archive.c')
-rw-r--r--bfd/archive.c171
1 files changed, 109 insertions, 62 deletions
diff --git a/bfd/archive.c b/bfd/archive.c
index a4431cc..fd7fc3c 100644
--- a/bfd/archive.c
+++ b/bfd/archive.c
@@ -1,6 +1,4 @@
-/*** archive.c -- an attempt at combining the machine-independent parts of
- archives */
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
@@ -21,6 +19,21 @@ along with BFD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+/*doc*
+@setfilename archive-info
+@section Archives
+
+Gumby, you promised to write this bit...
+
+Archives are supported in bfd in @code{archive.c}.
+
+An archive is represented internally just like another bfd, with a
+pointer to a chain of contained bfds. Archives can be created by
+opening bfds, linking them together and attatching them as children to
+another bfd and then closing the parent bfd.
+
+*-*/
+
/* Assumes:
o - all archive elements start on an even boundary, newline padded;
o - all arch headers are char *;
@@ -72,6 +85,10 @@ _bfd_generic_mkarchive (abfd)
return true;
}
+/*proto* bfd_get_next_mapent
+What this does
+*; PROTO(symindex, bfd_get_next_mapent, (bfd *, symindex, carsym **));
+*/
symindex
bfd_get_next_mapent (abfd, prev, entry)
bfd *abfd;
@@ -107,9 +124,16 @@ _bfd_create_empty_archive_element_shell (obfd)
return nbfd;
}
+/*proto* bfd_set_archive_head
+Used whilst processing archives. Sets the head of the chain of bfds
+contained in an archive to @var{new_head}. (see chapter on archives)
+*; PROTO(boolean, bfd_set_archive_head, (bfd *output, bfd *new_head));
+*/
+
boolean
-bfd_set_archive_head (output_archive, new_head)
- bfd *output_archive, *new_head;
+DEFUN(bfd_set_archive_head,(output_archive, new_head),
+ bfd *output_archive AND
+ bfd *new_head)
{
output_archive->archive_head = new_head;
@@ -229,8 +253,10 @@ snarf_ar_hdr (abfd)
return NULL;
}
- /* extract the filename from the archive */
- if (hdr.ar_name[0] == ' ' && bfd_ardata (abfd)->extended_names != NULL) {
+ /* extract the filename from the archive - there are two ways to
+ specify an extendend name table, either the first char of the
+ name is a space, or it's a slash */
+ if ((hdr.ar_name[0] == '/' || hdr.ar_name[0] == ' ') && bfd_ardata (abfd)->extended_names != NULL) {
filename = get_extended_arelt_filename (abfd, hdr.ar_name);
if (filename == NULL) {
bfd_error = malformed_archive;
@@ -325,10 +351,22 @@ bfd_get_elt_at_index (abfd, index)
return result;
}
-/* If you've got an archive, call this to read each subfile. */
+/*proto* bfd_openr_next_archived_file
+Initially provided a bfd containing an archive and NULL, opens a bfd
+on the first contained element and returns that. Subsequent calls to
+bfd_openr_next_archived_file should pass the archive and the previous
+return value to return a created bfd to the next contained element.
+NULL is returned when there are no more.
+
+*; PROTO(bfd*, bfd_openr_next_archived_file,
+ (bfd *archive, bfd *previous));
+
+*/
+
bfd *
-bfd_openr_next_archived_file (archive, last_file)
- bfd *archive, *last_file;
+DEFUN(bfd_openr_next_archived_file,(archive, last_file),
+ bfd *archive AND
+ bfd*last_file)
{
if ((bfd_get_format (archive) != bfd_archive) ||
@@ -411,7 +449,7 @@ boolean
bfd_slurp_bsd_armap (abfd)
bfd *abfd;
{
- int i;
+
struct areltdata *mapdata;
char nextname[17];
unsigned int counter = 0;
@@ -451,7 +489,7 @@ bfd_slurp_bsd_armap (abfd)
goto byebye;
}
- ardata->symdef_count = bfd_h_get_32(abfd, raw_armap) / sizeof (struct symdef);
+ ardata->symdef_count = bfd_h_get_32(abfd, (PTR)raw_armap) / sizeof (struct symdef);
ardata->cache = 0;
rbase = raw_armap+1;
ardata->symdefs = (carsym *) rbase;
@@ -459,8 +497,8 @@ bfd_slurp_bsd_armap (abfd)
for (;counter < ardata->symdef_count; counter++) {
struct symdef *sym = ((struct symdef *) rbase) + counter;
- sym->s.name = bfd_h_get_32(abfd, &(sym->s.string_offset)) + stringbase;
- sym->file_offset = bfd_h_get_32(abfd, &(sym->file_offset));
+ sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
+ sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
}
ardata->first_file_filepos = bfd_tell (abfd);
@@ -501,13 +539,16 @@ bfd_slurp_coff_armap (abfd)
if (mapdata == NULL) return false;
raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
- if (raw_armap == NULL) {
+
+ if (raw_armap == NULL)
+ {
bfd_error = no_memory;
byebye:
bfd_release (abfd, (PTR)mapdata);
return false;
}
+ /* read in the raw map */
if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
mapdata->parsed_size) {
bfd_error = malformed_archive;
@@ -552,19 +593,22 @@ bfd_slurp_coff_armap (abfd)
ardata->first_file_filepos = bfd_tell (abfd);
/* Pad to an even boundary if you have to */
ardata->first_file_filepos += (ardata->first_file_filepos) %2;
- bfd_release (abfd, (PTR)raw_armap);
- bfd_release (abfd, (PTR)mapdata);
+
+/* bfd_release (abfd, (PTR)raw_armap);
+ bfd_release (abfd, (PTR)mapdata);*/
bfd_has_map (abfd) = true;
return true;
}
/** Extended name table.
- Normally archives support only 14-character filenames. Intel has extended
- the format: longer names are stored in a special element (the first in the
- archive, or second if there is an armap); the name in the ar_hdr is replaced
- by <space><index into filename element>. Index is the P.R. of an int (radix:
- 8). */
+ Normally archives support only 14-character filenames.
+
+ Intel has extended the format: longer names are stored in a special
+ element (the first in the archive, or second if there is an armap);
+ the name in the ar_hdr is replaced by <space><index into filename
+ element>. Index is the P.R. of an int (radix: 8). Data General have
+ extended the format by using the prefix // for the special element */
/* Returns false on error, true otherwise */
boolean
@@ -578,49 +622,52 @@ _bfd_slurp_extended_name_table (abfd)
we probably don't want to return true. */
if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
- bfd_seek (abfd, -16L, SEEK_CUR);
+ bfd_seek (abfd, -16L, SEEK_CUR);
- if (strncmp (nextname, "ARFILENAMES/ ", 16)) {
- bfd_ardata (abfd)->extended_names = NULL;
- return true;
- }
+ if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 &&
+ strncmp (nextname, "// ", 16) != 0)
+ {
+ bfd_ardata (abfd)->extended_names = NULL;
+ return true;
+ }
- namedata = snarf_ar_hdr (abfd);
- if (namedata == NULL) return false;
+ namedata = snarf_ar_hdr (abfd);
+ if (namedata == NULL) return false;
- bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
- if (bfd_ardata (abfd)->extended_names == NULL) {
- bfd_error = no_memory;
- byebye:
- bfd_release (abfd, (PTR)namedata);
- return false;
- }
+ bfd_ardata (abfd)->extended_names = bfd_zalloc(abfd,namedata->parsed_size);
+ if (bfd_ardata (abfd)->extended_names == NULL) {
+ bfd_error = no_memory;
+ byebye:
+ bfd_release (abfd, (PTR)namedata);
+ return false;
+ }
- if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
- namedata->parsed_size, abfd) != namedata->parsed_size) {
- bfd_error = malformed_archive;
- bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
- bfd_ardata (abfd)->extended_names = NULL;
- goto byebye;
- }
+ if (bfd_read ((PTR)bfd_ardata (abfd)->extended_names, 1,
+ namedata->parsed_size, abfd) != namedata->parsed_size) {
+ bfd_error = malformed_archive;
+ bfd_release (abfd, (PTR)(bfd_ardata (abfd)->extended_names));
+ bfd_ardata (abfd)->extended_names = NULL;
+ goto byebye;
+ }
- /* It appears that the extended names are newline-padded, not null padded.
- */
- {
- char *temp = bfd_ardata (abfd)->extended_names;
- for (; *temp != '\0'; ++temp)
- if (*temp == '\n') *temp = '\0';
- }
+ /* Since the archive is supposed to be printable if it contains
+ text, the entries in the list are newline-padded, not null
+ padded. We'll fix that there.. */
+ {
+ char *temp = bfd_ardata (abfd)->extended_names;
+ for (; *temp != '\0'; ++temp)
+ if (*temp == '\n') *temp = '\0';
+ }
- /* Pad to an even boundary if you have to */
- bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
- bfd_ardata (abfd)->first_file_filepos +=
- (bfd_ardata (abfd)->first_file_filepos) %2;
-
- /* FIXME, we can't release namedata here because it was allocated
- below extended_names on the obstack... */
- /* bfd_release (abfd, namedata); */
-}
+ /* Pad to an even boundary if you have to */
+ bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
+ bfd_ardata (abfd)->first_file_filepos +=
+ (bfd_ardata (abfd)->first_file_filepos) %2;
+
+ /* FIXME, we can't release namedata here because it was allocated
+ below extended_names on the obstack... */
+ /* bfd_release (abfd, namedata); */
+ }
return true;
}
@@ -1127,7 +1174,7 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
for (i = 0; i < sizeof (struct ar_hdr); i++)
if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
bfd_write ((char *)&hdr, 1, sizeof (struct ar_hdr), arch);
- bfd_h_put_32(arch, ranlibsize, &temp);
+ bfd_h_put_32(arch, ranlibsize, (PTR)&temp);
bfd_write (&temp, 1, sizeof (temp), arch);
for (count = 0; count < orl_count; count++) {
@@ -1143,13 +1190,13 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
} /* if new archive element */
last_elt = current;
- bfd_h_put_32(arch, ((map[count]).namidx), &outs.s.string_offset);
- bfd_h_put_32(arch, firstreal, &outs.file_offset);
+ bfd_h_put_32(arch, ((map[count]).namidx),(PTR) &outs.s.string_offset);
+ bfd_h_put_32(arch, firstreal,(PTR) &outs.file_offset);
bfd_write ((char *)outp, 1, sizeof (outs), arch);
}
/* now write the strings themselves */
- bfd_h_put_32(arch, stridx, &temp);
+ bfd_h_put_32(arch, stridx, (PTR)&temp);
bfd_write ((PTR)&temp, 1, sizeof (temp), arch);
for (count = 0; count < orl_count; count++)
bfd_write (*((map[count]).name), 1, strlen (*((map[count]).name))+1, arch);