/* BFD back-end for archive files (libraries).
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
{
bfd_size_type amt = sizeof (struct artdata);
- abfd->tdata.aout_ar_data = bfd_zalloc (abfd, amt);
+ abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt);
if (bfd_ardata (abfd) == NULL)
return FALSE;
}
/* Insert new_elt into the hash table by filepos. */
- cache = bfd_zalloc (arch_bfd, sizeof (struct ar_cache));
+ cache = (struct ar_cache *) bfd_zalloc (arch_bfd, sizeof (struct ar_cache));
cache->ptr = filepos;
cache->arbfd = new_elt;
*htab_find_slot (hash_table, (const void *) cache, INSERT) = cache;
{
file_ptr origin = strtol (endp + 1, NULL, 10);
- if (errno != 0 || index >= bfd_ardata (arch)->extended_names_size)
+ if (errno != 0)
{
bfd_set_error (bfd_error_malformed_archive);
return NULL;
allocsize += namelen + 1;
parsed_size -= namelen;
- allocptr = bfd_zalloc (abfd, allocsize);
+ allocptr = (char *) bfd_zalloc (abfd, allocsize);
if (allocptr == NULL)
return NULL;
filename = (allocptr
spaces, so only look for ' ' if we don't find '/'. */
char *e;
- e = memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd));
+ e = (char *) memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd));
if (e == NULL)
{
- e = memchr (hdr.ar_name, '/', ar_maxnamelen (abfd));
+ e = (char *) memchr (hdr.ar_name, '/', ar_maxnamelen (abfd));
if (e == NULL)
- e = memchr (hdr.ar_name, ' ', ar_maxnamelen (abfd));
+ e = (char *) memchr (hdr.ar_name, ' ', ar_maxnamelen (abfd));
}
if (e != NULL)
if (!allocptr)
{
- allocptr = bfd_zalloc (abfd, allocsize);
+ allocptr = (char *) bfd_zalloc (abfd, allocsize);
if (allocptr == NULL)
return NULL;
}
return elt_name;
prefix_len = base_name - arch_name;
- filename = bfd_alloc (arch, prefix_len + strlen (elt_name) + 1);
+ filename = (char *) bfd_alloc (arch, prefix_len + strlen (elt_name) + 1);
if (filename == NULL)
return NULL;
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;
filename = new_areldata->filename;
tdata_hold = bfd_ardata (abfd);
amt = sizeof (struct artdata);
- bfd_ardata (abfd) = bfd_zalloc (abfd, amt);
+ bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
if (bfd_ardata (abfd) == NULL)
{
bfd_ardata (abfd) = tdata_hold;
bfd_size_type parsed_size, amt;
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;
bfd_release (abfd, mapdata); /* Don't need it any more. */
- raw_armap = bfd_zalloc (abfd, parsed_size);
+ raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);
if (raw_armap == NULL)
return FALSE;
+ ardata->symdef_count * BSD_SYMDEF_SIZE
+ BSD_STRING_COUNT_SIZE);
amt = ardata->symdef_count * sizeof (carsym);
- ardata->symdefs = bfd_alloc (abfd, amt);
+ ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt);
if (!ardata->symdefs)
return FALSE;
bfd_size_type carsym_size, ptrsize;
unsigned int 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;
if (carsym_size + stringsize + 1 <= carsym_size)
return FALSE;
- ardata->symdefs = bfd_zalloc (abfd, carsym_size + stringsize + 1);
+ ardata->symdefs = (struct carsym *) bfd_zalloc (abfd,
+ carsym_size + stringsize + 1);
if (ardata->symdefs == NULL)
return FALSE;
carsyms = ardata->symdefs;
stringbase = ((char *) ardata->symdefs) + carsym_size;
/* Allocate and read in the raw offsets. */
- raw_armap = bfd_alloc (abfd, ptrsize);
+ raw_armap = (int *) bfd_alloc (abfd, ptrsize);
if (raw_armap == NULL)
goto release_symdefs;
if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize
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 TRUE;
}
- mapdata = _bfd_read_ar_hdr (abfd);
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
if (mapdata == NULL)
return FALSE;
amt = mapdata->parsed_size;
- raw_armap = bfd_zalloc (abfd, amt);
+ raw_armap = (bfd_byte *) bfd_zalloc (abfd, amt);
if (raw_armap == NULL)
{
byebye:
+ BSD_STRING_COUNT_SIZE);
rbase = (bfd_byte *) stringbase + stringsize;
amt = ardata->symdef_count * BSD_SYMDEF_SIZE;
- ardata->symdefs = bfd_alloc (abfd, amt);
+ ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt);
if (!ardata->symdefs)
return FALSE;
return TRUE;
}
- namedata = _bfd_read_ar_hdr (abfd);
+ namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
if (namedata == NULL)
return FALSE;
goto byebye;
bfd_ardata (abfd)->extended_names_size = amt;
- bfd_ardata (abfd)->extended_names = bfd_zalloc (abfd, amt + 1);
+ bfd_ardata (abfd)->extended_names = (char *) bfd_zalloc (abfd, amt + 1);
if (bfd_ardata (abfd)->extended_names == NULL)
{
byebye:
char *limit = temp + namedata->parsed_size;
for (; temp < limit; ++temp)
{
- if (*temp == ARFMAG[0])
+ if (*temp == ARFMAG[1])
temp[temp > ext_names && temp[-1] == '/' ? -1 : 0] = '\0';
if (*temp == '\\')
*temp = '/';
if (pathbuf != NULL)
free (pathbuf);
pathbuf_len = 0;
- pathbuf = bfd_malloc (len);
+ pathbuf = (char *) bfd_malloc (len);
if (pathbuf == NULL)
return path;
pathbuf_len = len;
if (total_namelen == 0)
return TRUE;
- *tabloc = bfd_zalloc (abfd, total_namelen);
+ *tabloc = (char *) bfd_zalloc (abfd, total_namelen);
if (*tabloc == NULL)
return FALSE;
{
strcpy (strptr, normal);
if (! trailing_slash)
- strptr[thislen] = ARFMAG[0];
+ strptr[thislen] = ARFMAG[1];
else
{
strptr[thislen] = '/';
- strptr[thislen + 1] = ARFMAG[0];
+ strptr[thislen + 1] = ARFMAG[1];
}
stroff = strptr - *tabloc;
last_stroff = stroff;
if (member && (member->flags & BFD_IN_MEMORY) != 0)
{
/* Assume we just "made" the member, and fake it. */
- struct bfd_in_memory *bim = member->iostream;
+ struct bfd_in_memory *bim = (struct bfd_in_memory *) member->iostream;
time (&status.st_mtime);
status.st_uid = getuid ();
status.st_gid = getgid ();
return NULL;
}
+ /* If the caller requested that the BFD generate deterministic output,
+ fake values for modification time, UID, GID, and file mode. */
+ if ((abfd->flags & BFD_DETERMINISTIC_OUTPUT) != 0)
+ {
+ status.st_mtime = 0;
+ status.st_uid = 0;
+ status.st_gid = 0;
+ status.st_mode = 0644;
+ }
+
amt = sizeof (struct ar_hdr) + sizeof (struct areltdata);
- ared = bfd_zalloc (abfd, amt);
+ ared = (struct areltdata *) bfd_zalloc (abfd, amt);
if (ared == NULL)
return NULL;
hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
return FALSE;
if ((elength % 2) == 1)
{
- if (bfd_bwrite (ARFMAG, 1, arch) != 1)
+ if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1)
return FALSE;
}
}
if ((arelt_size (current) % 2) == 1)
{
- if (bfd_bwrite (ARFMAG, 1, arch) != 1)
+ if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1)
return FALSE;
}
}
elength += elength % 2;
amt = orl_max * sizeof (struct orl);
- map = bfd_malloc (amt);
+ map = (struct orl *) bfd_malloc (amt);
if (map == NULL)
goto error_return;
/* We put the symbol names on the arch objalloc, and then discard
them when done. */
- first_name = bfd_alloc (arch, 1);
+ first_name = (char *) bfd_alloc (arch, 1);
if (first_name == NULL)
goto error_return;
if (syms_max > 0)
free (syms);
syms_max = storage;
- syms = bfd_malloc (syms_max);
+ syms = (asymbol **) bfd_malloc (syms_max);
if (syms == NULL)
goto error_return;
}
{
orl_max *= 2;
amt = orl_max * sizeof (struct orl);
- new_map = bfd_realloc (map, amt);
+ new_map = (struct orl *) bfd_realloc (map, amt);
if (new_map == NULL)
goto error_return;
namelen = strlen (syms[src_count]->name);
amt = sizeof (char *);
- map[orl_count].name = bfd_alloc (arch, amt);
+ map[orl_count].name = (char **) bfd_alloc (arch, amt);
if (map[orl_count].name == NULL)
goto error_return;
- *(map[orl_count].name) = bfd_alloc (arch, namelen + 1);
+ *(map[orl_count].name) = (char *) bfd_alloc (arch,
+ namelen + 1);
if (*(map[orl_count].name) == NULL)
goto error_return;
strcpy (*(map[orl_count].name), syms[src_count]->name);
unsigned int count;
struct ar_hdr hdr;
struct stat statbuf;
+ long uid, gid;
firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
stat (arch->filename, &statbuf);
+ if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0)
+ {
+ /* Remember the timestamp, to keep it holy. But fudge it a little. */
+ bfd_ardata (arch)->armap_timestamp = (statbuf.st_mtime
+ + ARMAP_TIME_OFFSET);
+ uid = getuid();
+ gid = getgid();
+ }
+ else
+ {
+ /* If deterministic, we use 0 as the timestamp in the map.
+ Some linkers may require that the archive filesystem modification
+ time is less than (or near to) the archive map timestamp. Those
+ linkers should not be used with deterministic mode. (GNU ld and
+ Gold do not have this restriction.) */
+ bfd_ardata (arch)->armap_timestamp = 0;
+ uid = 0;
+ gid = 0;
+ }
+
memset (&hdr, ' ', sizeof (struct ar_hdr));
memcpy (hdr.ar_name, RANLIBMAG, strlen (RANLIBMAG));
- /* Remember the timestamp, to keep it holy. But fudge it a little. */
- bfd_ardata (arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET;
bfd_ardata (arch)->armap_datepos = (SARMAG
+ offsetof (struct ar_hdr, ar_date[0]));
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
bfd_ardata (arch)->armap_timestamp);
- _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", getuid ());
- _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", getgid ());
+ _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", uid);
+ _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", gid);
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize);
memcpy (hdr.ar_fmag, ARFMAG, 2);
if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
struct stat archstat;
struct ar_hdr hdr;
+ /* If creating deterministic archives, just leave the timestamp as-is. */
+ if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) != 0)
+ return TRUE;
+
/* Flush writes, get last-write timestamp from file, and compare it
to the timestamp IN the file. */
bfd_flush (arch);
/* Can't read mod time for some reason. */
return TRUE;
}
- if (archstat.st_mtime <= bfd_ardata (arch)->armap_timestamp)
+ if (((long) archstat.st_mtime) <= bfd_ardata (arch)->armap_timestamp)
/* OK by the linker's rules. */
return TRUE;
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
mapsize);
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
- time (NULL));
+ ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0
+ ? time (NULL) : 0));
/* This, at least, is what Intel coff sets the values to. */
_bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
_bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);