/* BFD back-end for archive files (libraries).
- Copyright 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
This file is part of BFD, the Binary File Descriptor library.
#define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
#endif
-/* Can't define this in hosts/foo.h, because (e.g. in gprof) the hosts file
- is included, then obstack.h, which thinks if offsetof is defined, it
- doesn't need to include stddef.h. */
/* Define offsetof for those systems which lack it */
-#if !defined (offsetof)
+#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif
bfd_zalloc (abfd, sizeof (struct artdata)));
if (bfd_ardata (abfd) == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
bfd_ardata (abfd)->cache = NULL;
bfd_ardata (abfd)->archive_head = NULL;
_bfd_create_empty_archive_element_shell (obfd)
bfd *obfd;
{
- bfd *nbfd;
-
- nbfd = _bfd_new_bfd_contained_in (obfd);
- if (nbfd == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
- return nbfd;
+ return _bfd_new_bfd_contained_in (obfd);
}
/*
sizeof (struct ar_cache)));
if (new_cache == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
new_cache->ptr = filepos;
new_cache->arelt = new_elt;
_bfd_generic_read_ar_hdr (abfd)
bfd *abfd;
{
-#ifndef errno
- extern int errno;
-#endif
+ return _bfd_generic_read_ar_hdr_mag (abfd, (const char *) NULL);
+}
+
+/* Alpha ECOFF uses an optional different ARFMAG value, so we have a
+ variant of _bfd_generic_read_ar_hdr which accepts a magic string. */
+PTR
+_bfd_generic_read_ar_hdr_mag (abfd, mag)
+ bfd *abfd;
+ const char *mag;
+{
struct ar_hdr hdr;
char *hdrp = (char *) &hdr;
unsigned int parsed_size;
bfd_set_error (bfd_error_no_more_archived_files);
return NULL;
}
- if (strncmp (hdr.ar_fmag, ARFMAG, 2))
+ if (strncmp (hdr.ar_fmag, ARFMAG, 2) != 0
+ && (mag == NULL
+ || strncmp (hdr.ar_fmag, mag, 2) != 0))
{
bfd_set_error (bfd_error_malformed_archive);
return NULL;
}
/* BSD4.4-style long filename.
Only implemented for reading, so far! */
- else if (hdr.ar_name[0] == '#' && hdr.ar_name[1] == '1'
- && hdr.ar_name[2] == '/' && isdigit (hdr.ar_name[3]))
+ else if (hdr.ar_name[0] == '#'
+ && hdr.ar_name[1] == '1'
+ && hdr.ar_name[2] == '/'
+ && isdigit ((unsigned char) hdr.ar_name[3]))
{
/* BSD-4.4 extended name */
namelen = atoi (&hdr.ar_name[3]);
allocptr = bfd_zalloc (abfd, allocsize);
if (allocptr == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
+ return NULL;
filename = (allocptr
+ sizeof (struct areltdata)
+ sizeof (struct ar_hdr));
Note: The SYSV format (terminated by '/') allows embedded
spaces, so only look for ' ' if we don't find '/'. */
- namelen = 0;
- while (hdr.ar_name[namelen] != '\0' &&
- hdr.ar_name[namelen] != '/')
+ char *e;
+ e = memchr(hdr.ar_name, '\0', ar_maxnamelen (abfd));
+ if (e == NULL)
{
- namelen++;
- if (namelen == (unsigned) ar_maxnamelen (abfd))
- {
- namelen = 0;
- while (hdr.ar_name[namelen] != ' '
- && namelen < (unsigned) ar_maxnamelen (abfd))
- namelen++;
- break;
- }
+ e = memchr(hdr.ar_name, '/', ar_maxnamelen (abfd));
+ if (e == NULL)
+ e = memchr(hdr.ar_name, ' ', ar_maxnamelen (abfd));
+ }
+ if (e == NULL)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
}
+ namelen = e - hdr.ar_name;
allocsize += namelen + 1;
}
{
allocptr = bfd_zalloc (abfd, allocsize);
if (allocptr == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
+ return NULL;
}
ared = (struct areltdata *) allocptr;
if (0 > bfd_seek (archive, filepos, SEEK_SET))
return NULL;
- if ((new_areldata = _bfd_read_ar_hdr (archive)) == NULL)
+ if ((new_areldata = (struct areltdata *) _bfd_read_ar_hdr (archive)) == NULL)
return NULL;
n_nfd = _bfd_create_empty_archive_element_shell (archive);
return NULL;
}
-/*
-FUNCTION
- bfd_get_elt_at_index
-
-SYNOPSIS
- bfd *bfd_get_elt_at_index(bfd *archive, int index);
-
-DESCRIPTION
- Return the BFD which is referenced by the symbol in @var{archive}
- indexed by @var{index}. @var{index} should have been returned by
- <<bfd_get_next_mapent>> (q.v.).
+/* Return the BFD which is referenced by the symbol in ABFD indexed by
+ INDEX. INDEX should have been returned by bfd_get_next_mapent. */
-*/
bfd *
-bfd_get_elt_at_index (abfd, index)
+_bfd_generic_get_elt_at_index (abfd, index)
bfd *abfd;
- int index;
+ symindex index;
{
carsym *entry;
bfd_generic_archive_p (abfd)
bfd *abfd;
{
+ struct artdata *tdata_hold;
char armag[SARMAG + 1];
+ tdata_hold = abfd->tdata.aout_ar_data;
+
if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG)
{
if (bfd_get_error () != bfd_error_system_call)
bfd_zalloc (abfd, sizeof (struct artdata)));
if (bfd_ardata (abfd) == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
+ return NULL;
bfd_ardata (abfd)->first_file_filepos = SARMAG;
bfd_ardata (abfd)->cache = NULL;
if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd)))
{
bfd_release (abfd, bfd_ardata (abfd));
- abfd->tdata.aout_ar_data = NULL;
+ abfd->tdata.aout_ar_data = tdata_hold;
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
return NULL;
}
if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd)))
{
bfd_release (abfd, bfd_ardata (abfd));
- abfd->tdata.aout_ar_data = NULL;
+ abfd->tdata.aout_ar_data = tdata_hold;
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
return NULL;
}
- if (bfd_has_map (abfd) && abfd->target_defaulted)
+ if (bfd_has_map (abfd))
{
bfd *first;
/* This archive has a map, so we may presume that the contents
- are object files. Make sure that the first file in the
- archive can be recognized as an object file for this target.
- If not, assume that this is the wrong format.
+ are object files. Make sure that if the first file in the
+ archive can be recognized as an object file, it is for this
+ target. If not, assume that this is the wrong format. If
+ the first file is not an object file, somebody is doing
+ something weird, and we permit it so that ar -t will work.
This is done because any normal format will recognize any
normal archive, regardless of the format of the object files.
first = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
if (first != NULL)
{
+ boolean fail;
+
first->target_defaulted = false;
- if (! bfd_check_format (first, bfd_object))
+ fail = false;
+ if (bfd_check_format (first, bfd_object)
+ && first->xvec != abfd->xvec)
{
- bfd_error_type err;
-
- err = bfd_get_error ();
(void) bfd_close (first);
bfd_release (abfd, bfd_ardata (abfd));
- abfd->tdata.aout_ar_data = NULL;
- bfd_set_error (err);
+ abfd->tdata.aout_ar_data = tdata_hold;
+ bfd_set_error (bfd_error_wrong_format);
return NULL;
}
unsigned int parsed_size;
carsym *set;
- mapdata = _bfd_read_ar_hdr (abfd);
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
if (mapdata == NULL)
return false;
parsed_size = mapdata->parsed_size;
raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);
if (raw_armap == (bfd_byte *) NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
if (bfd_read ((PTR) raw_armap, 1, parsed_size, abfd) != parsed_size)
{
(ardata->symdef_count
* sizeof (carsym)));
if (!ardata->symdefs)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
for (counter = 0, set = ardata->symdefs;
counter < ardata->symdef_count;
ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
/* FIXME, we should provide some way to free raw_ardata when
we are done using the strings from it. For now, it seems
- to be allocated on an obstack anyway... */
+ to be allocated on an objalloc anyway... */
bfd_has_map (abfd) = true;
return true;
}
char int_buf[sizeof (long)];
unsigned int carsym_size, ptrsize, i;
- mapdata = _bfd_read_ar_hdr (abfd);
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
if (mapdata == NULL)
return false;
parsed_size = mapdata->parsed_size;
little, because our tools changed. Here's a horrible hack to clean
up the crap. */
- if (stringsize > 0xfffff)
+ if (stringsize > 0xfffff
+ && bfd_get_arch (abfd) == bfd_arch_i960
+ && bfd_get_flavour (abfd) == bfd_target_coff_flavour)
{
/* This looks dangerous, let's do it the other way around */
nsymz = bfd_getl32 ((PTR) int_buf);
ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1);
if (ardata->symdefs == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
carsyms = ardata->symdefs;
stringbase = ((char *) ardata->symdefs) + carsym_size;
/* Allocate and read in the raw offsets. */
raw_armap = (int *) bfd_alloc (abfd, ptrsize);
if (raw_armap == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- goto release_symdefs;
- }
+ goto release_symdefs;
if (bfd_read ((PTR) raw_armap, 1, ptrsize, abfd) != ptrsize
|| bfd_read ((PTR) stringbase, 1, stringsize, abfd) != stringsize)
{
struct areltdata *tmp;
bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET);
- tmp = _bfd_read_ar_hdr (abfd);
+ tmp = (struct areltdata *) _bfd_read_ar_hdr (abfd);
if (tmp != NULL)
{
if (tmp->arch_header[0] == '/'
return do_slurp_bsd_armap (abfd);
else if (!strncmp (nextname, "/ ", 16))
return do_slurp_coff_armap (abfd);
+ else if (!strncmp (nextname, "/SYM64/ ", 16))
+ {
+ /* Irix 6 archive--must be recognized by code in elf64-mips.c. */
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
bfd_has_map (abfd) = false;
return true;
return true;
}
- mapdata = _bfd_read_ar_hdr (abfd);
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
if (mapdata == NULL)
return false;
raw_armap = (bfd_byte *) bfd_zalloc (abfd, mapdata->parsed_size);
if (raw_armap == NULL)
{
- bfd_set_error (bfd_error_no_memory);
byebye:
bfd_release (abfd, (PTR) mapdata);
return false;
(ardata->symdef_count
* BSD_SYMDEF_SIZE));
if (!ardata->symdefs)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
for (counter = 0, set = ardata->symdefs;
counter < ardata->symdef_count;
ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
/* FIXME, we should provide some way to free raw_ardata when
we are done using the strings from it. For now, it seems
- to be allocated on an obstack anyway... */
+ to be allocated on an objalloc anyway... */
bfd_has_map (abfd) = true;
return true;
}
return true;
}
- namedata = _bfd_read_ar_hdr (abfd);
+ namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
if (namedata == NULL)
return false;
bfd_zalloc (abfd, namedata->parsed_size);
if (bfd_ardata (abfd)->extended_names == NULL)
{
- bfd_set_error (bfd_error_no_memory);
byebye:
bfd_release (abfd, (PTR) namedata);
return false;
(bfd_ardata (abfd)->first_file_filepos) % 2;
/* FIXME, we can't release namedata here because it was allocated
- below extended_names on the obstack... */
+ below extended_names on the objalloc... */
/* bfd_release (abfd, namedata); */
}
return true;
copy = (char *) bfd_alloc (abfd, last - first + 1);
if (copy == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
+ return NULL;
memcpy (copy, first, last - first);
copy[last - first] = 0;
*tabloc = bfd_zalloc (abfd, total_namelen);
if (*tabloc == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
*tablen = total_namelen;
strptr = *tabloc;
ared = (struct areltdata *) bfd_zalloc (abfd, sizeof (struct ar_hdr) +
sizeof (struct areltdata));
if (ared == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
+ return NULL;
hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
/* ar headers are space padded, not null padded! */
a strong stomach to write this, and it does, but it takes even a
stronger stomach to try to code around such a thing! */
+struct ar_hdr *bfd_special_undocumented_glue PARAMS ((bfd *, const char *));
+
struct ar_hdr *
bfd_special_undocumented_glue (abfd, filename)
bfd *abfd;
- char *filename;
+ const char *filename;
{
struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename);
if (ar_elt == NULL)
if (bfd_update_armap_timestamp (arch))
break;
(*_bfd_error_handler)
- ("Warning: writing archive was slow: rewriting timestamp\n");
+ (_("Warning: writing archive was slow: rewriting timestamp\n"));
}
while (++tries < 6);
}
elength += sizeof (struct ar_hdr);
elength += elength % 2;
- map = (struct orl *) malloc (orl_max * sizeof (struct orl));
+ map = (struct orl *) bfd_malloc (orl_max * sizeof (struct orl));
if (map == NULL)
- goto no_memory_return;
+ goto error_return;
- /* We put the symbol names on the arch obstack, and then discard
+ /* We put the symbol names on the arch objalloc, and then discard
them when done. */
first_name = bfd_alloc (arch, 1);
if (first_name == NULL)
- goto no_memory_return;
+ goto error_return;
/* Drop all the files called __.SYMDEF, we're going to make our
own */
if (syms_max > 0)
free (syms);
syms_max = storage;
- syms = (asymbol **) malloc ((size_t) syms_max);
+ syms = (asymbol **) bfd_malloc ((size_t) syms_max);
if (syms == NULL)
- goto no_memory_return;
+ goto error_return;
}
symcount = bfd_canonicalize_symtab (current, syms);
if (symcount < 0)
if (orl_count == orl_max)
{
orl_max *= 2;
- new_map = ((struct orl *)
- realloc ((PTR) map,
- orl_max * sizeof (struct orl)));
+ new_map =
+ ((struct orl *)
+ bfd_realloc (map, orl_max * sizeof (struct orl)));
if (new_map == (struct orl *) NULL)
- goto no_memory_return;
+ goto error_return;
map = new_map;
}
bfd_alloc (arch,
sizeof (char *)));
if (map[orl_count].name == NULL)
- goto no_memory_return;
+ goto error_return;
*(map[orl_count].name) = bfd_alloc (arch, namelen + 1);
if (*(map[orl_count].name) == NULL)
- goto no_memory_return;
+ goto error_return;
strcpy (*(map[orl_count].name), syms[src_count]->name);
(map[orl_count]).pos = (file_ptr) current;
(map[orl_count]).namidx = stridx;
return ret;
- no_memory_return:
- bfd_set_error (bfd_error_no_memory);
-
error_return:
if (syms_max > 0)
free (syms);
bfd_ardata (arch)->armap_datepos = (SARMAG
+ offsetof (struct ar_hdr, ar_date[0]));
sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp);
+#ifndef _WIN32
sprintf (hdr.ar_uid, "%ld", (long) getuid ());
sprintf (hdr.ar_gid, "%ld", (long) getgid ());
+#else
+ sprintf (hdr.ar_uid, "%ld", (long) 666);
+ sprintf (hdr.ar_gid, "%ld", (long) 42);
+#endif
sprintf (hdr.ar_size, "%-10d", (int) mapsize);
strncpy (hdr.ar_fmag, ARFMAG, 2);
for (i = 0; i < sizeof (struct ar_hdr); i++)
bfd_flush (arch);
if (bfd_stat (arch, &archstat) == -1)
{
- perror ("Reading archive file mod timestamp");
+ perror (_("Reading archive file mod timestamp"));
return true; /* Can't read mod time for some reason */
}
if (archstat.st_mtime <= bfd_ardata (arch)->armap_timestamp)
!= sizeof (hdr.ar_date)))
{
/* FIXME: bfd can't call perror. */
- perror ("Writing updated armap timestamp");
+ perror (_("Writing updated armap timestamp"));
return true; /* Some error while writing */
}