/* BFD back-end for archive files (libraries).
- Copyright (C) 1990-2015 Free Software Foundation, Inc.
+ Copyright (C) 1990-2018 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.
{
n_bfd->lto_output = archive->lto_output;
n_bfd->no_export = archive->no_export;
+ n_bfd->my_archive = archive;
}
return n_bfd;
}
return _bfd_get_elt_at_filepos (abfd, entry->file_offset);
}
+bfd *
+_bfd_noarchive_get_elt_at_index (bfd *abfd,
+ symindex sym_index ATTRIBUTE_UNUSED)
+{
+ return (bfd *) _bfd_ptr_bfd_null_error (abfd);
+}
+
/*
FUNCTION
bfd_openr_next_archived_file
DESCRIPTION
Provided a BFD, @var{archive}, containing an archive and NULL, open
an input BFD on the first contained element and returns that.
- Subsequent calls 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.
+ Subsequent calls 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.
+ Note - if you want to process the bfd returned by this call be
+ sure to call bfd_check_format() on it first.
*/
bfd *
Note that last_file->origin can be odd in the case of
BSD-4.4-style element with a long odd size. */
filestart += filestart % 2;
- if (filestart <= last_file->proxy_origin)
+ if (filestart < last_file->proxy_origin)
{
/* Prevent looping. See PR19256. */
bfd_set_error (bfd_error_malformed_archive);
return _bfd_get_elt_at_filepos (archive, filestart);
}
+bfd *
+_bfd_noarchive_openr_next_archived_file (bfd *archive,
+ bfd *last_file ATTRIBUTE_UNUSED)
+{
+ return (bfd *) _bfd_ptr_bfd_null_error (archive);
+}
+
const bfd_target *
bfd_generic_archive_p (bfd *abfd)
{
if (strncmp (armag, ARMAG, SARMAG) != 0
&& strncmp (armag, ARMAGB, SARMAG) != 0
&& ! bfd_is_thin_archive (abfd))
- return NULL;
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ if (abfd->format == bfd_archive)
+ abfd->format = bfd_unknown;
+ return NULL;
+ }
tdata_hold = bfd_ardata (abfd);
return do_slurp_coff_armap (abfd);
else if (CONST_STRNEQ (nextname, "/SYM64/ "))
{
- /* 64bit ELF (Irix 6) archive. */
+ /* 64bit (Irix 6) archive. */
#ifdef BFD64
- extern bfd_boolean bfd_elf64_archive_slurp_armap (bfd *);
- return bfd_elf64_archive_slurp_armap (abfd);
+ return _bfd_archive_64_bit_slurp_armap (abfd);
#else
bfd_set_error (bfd_error_wrong_format);
return FALSE;
Relative path Reference path Result
------------- -------------- ------
- bar.o lib.a bar.o
- foo/bar.o lib.a foo/bar.o
- bar.o foo/lib.a ../bar.o
- foo/bar.o baz/lib.a ../foo/bar.o
- bar.o ../lib.a <parent of current dir>/bar.o
- ; ../bar.o ../lib.a bar.o
- ; ../bar.o lib.a ../bar.o
- foo/bar.o ../lib.a <parent of current dir>/foo/bar.o
- bar.o ../../lib.a <grandparent>/<parent>/bar.o
- bar.o foo/baz/lib.a ../../bar.o
+ bar.o lib.a bar.o
+ foo/bar.o lib.a foo/bar.o
+ bar.o foo/lib.a ../bar.o
+ foo/bar.o baz/lib.a ../foo/bar.o
+ bar.o ../lib.a <parent of current dir>/bar.o
+ ; ../bar.o ../lib.a bar.o
+ ; ../bar.o lib.a ../bar.o
+ foo/bar.o ../lib.a <parent of current dir>/foo/bar.o
+ bar.o ../../lib.a <grandparent>/<parent>/bar.o
+ bar.o foo/baz/lib.a ../../bar.o
Note - the semicolons above are there to prevent the BFD chew
utility from interpreting those lines as prototypes to put into
return _bfd_construct_extended_name_table (abfd, TRUE, tabloc, tablen);
}
+bfd_boolean
+_bfd_noarchive_construct_extended_name_table (bfd *abfd ATTRIBUTE_UNUSED,
+ char **tabloc ATTRIBUTE_UNUSED,
+ bfd_size_type *len ATTRIBUTE_UNUSED,
+ const char **name ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
/* Follows archive_head and produces an extended name table if
necessary. Returns (in tabloc) a pointer to an extended name
table, and in tablen the length of the table. If it makes an entry
}
return TRUE;
}
+
+bfd_boolean
+_bfd_noarchive_write_ar_hdr (bfd *archive, bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return _bfd_bool_bfd_false_error (archive);
+}
\f
/* A couple of functions for creating ar_hdrs. */
status.st_gid);
_bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo",
status.st_mode);
+ if (status.st_size - (bfd_size_type) status.st_size != 0)
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ free (ared);
+ return NULL;
+ }
if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size), status.st_size))
{
free (ared);
return -1;
#define foo(arelt, stelt, size) \
buf->stelt = strtol (hdr->arelt, &aloser, size); \
- if (aloser == hdr->arelt) \
+ if (aloser == hdr->arelt) \
return -1;
/* Some platforms support special notations for large IDs. */
if (length < 16)
(hdr->ar_name)[length] = ar_padchar (abfd);
}
+
+void
+_bfd_noarchive_truncate_arname (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *pathname ATTRIBUTE_UNUSED,
+ char *arhdr ATTRIBUTE_UNUSED)
+{
+}
\f
/* The BFD is open for write and has its format set to bfd_archive. */
{
if (bfd_update_armap_timestamp (arch))
break;
- (*_bfd_error_handler)
- (_("Warning: writing archive was slow: rewriting timestamp\n"));
+ _bfd_error_handler
+ (_("warning: writing archive was slow: rewriting timestamp"));
}
while (++tries < 6);
}
return TRUE;
input_err:
- bfd_set_error (bfd_error_on_input, current, bfd_get_error ());
+ bfd_set_input_error (current, bfd_get_error ());
return FALSE;
}
\f
map = new_map;
}
- if (strcmp (syms[src_count]->name, "__gnu_lto_slim") == 0)
- (*_bfd_error_handler)
- (_("%s: plugin needed to handle lto object"),
- bfd_get_filename (current));
+ if (syms[src_count]->name[0] == '_'
+ && syms[src_count]->name[1] == '_'
+ && strcmp (syms[src_count]->name
+ + (syms[src_count]->name[2] == '_'),
+ "__gnu_lto_slim") == 0)
+ _bfd_error_handler
+ (_("%pB: plugin needed to handle lto object"),
+ current);
namelen = strlen (syms[src_count]->name);
amt = sizeof (char *);
map[orl_count].name = (char **) bfd_alloc (arch, amt);
}
bfd_boolean
-bsd_write_armap (bfd *arch,
- unsigned int elength,
- struct orl *map,
- unsigned int orl_count,
- int stridx)
+_bfd_bsd_write_armap (bfd *arch,
+ unsigned int elength,
+ struct orl *map,
+ unsigned int orl_count,
+ int stridx)
{
int padit = stridx & 1;
unsigned int ranlibsize = orl_count * BSD_SYMDEF_SIZE;
unsigned int stringsize = stridx + padit;
/* Include 8 bytes to store ranlibsize and stringsize in output. */
unsigned int mapsize = ranlibsize + stringsize + 8;
- file_ptr firstreal;
- bfd *current = arch->archive_head;
- bfd *last_elt = current; /* Last element arch seen. */
+ file_ptr firstreal, first;
+ bfd *current;
+ bfd *last_elt;
bfd_byte temp[4];
unsigned int count;
struct ar_hdr hdr;
long uid, gid;
- firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
+ first = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
+
+#ifdef BFD64
+ firstreal = first;
+ current = arch->archive_head;
+ last_elt = current; /* Last element arch seen. */
+ for (count = 0; count < orl_count; count++)
+ {
+ unsigned int offset;
+
+ if (map[count].u.abfd != last_elt)
+ {
+ do
+ {
+ struct areltdata *ared = arch_eltdata (current);
+
+ firstreal += (ared->parsed_size + ared->extra_size
+ + sizeof (struct ar_hdr));
+ firstreal += firstreal % 2;
+ current = current->archive_next;
+ }
+ while (current != map[count].u.abfd);
+ }
+
+ /* The archive file format only has 4 bytes to store the offset
+ of the member. Generate 64-bit archive if an archive is past
+ its 4Gb limit. */
+ offset = (unsigned int) firstreal;
+ if (firstreal != (file_ptr) offset)
+ return _bfd_archive_64_bit_write_armap (arch, elength, map,
+ orl_count, stridx);
+
+ last_elt = current;
+ }
+#endif
/* If deterministic, we use 0 as the timestamp in the map.
Some linkers may require that the archive filesystem modification
if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp))
return FALSE;
+ firstreal = first;
+ current = arch->archive_head;
+ last_elt = current; /* Last element arch seen. */
for (count = 0; count < orl_count; count++)
{
unsigned int offset;
symbol name n-1 */
bfd_boolean
-coff_write_armap (bfd *arch,
- unsigned int elength,
- struct orl *map,
- unsigned int symbol_count,
- int stridx)
+_bfd_coff_write_armap (bfd *arch,
+ unsigned int elength,
+ struct orl *map,
+ unsigned int symbol_count,
+ int stridx)
{
/* The size of the ranlib is the number of exported symbols in the
archive * the number of bytes in an int, + an int for the count. */
unsigned int stringsize = stridx;
unsigned int mapsize = stringsize + ranlibsize;
file_ptr archive_member_file_ptr;
+ file_ptr first_archive_member_file_ptr;
bfd *current = arch->archive_head;
unsigned int count;
struct ar_hdr hdr;
mapsize++;
/* Work out where the first object file will go in the archive. */
- archive_member_file_ptr = (mapsize
- + elength
- + sizeof (struct ar_hdr)
- + SARMAG);
+ first_archive_member_file_ptr = (mapsize
+ + elength
+ + sizeof (struct ar_hdr)
+ + SARMAG);
+
+#ifdef BFD64
+ current = arch->archive_head;
+ count = 0;
+ archive_member_file_ptr = first_archive_member_file_ptr;
+ while (current != NULL && count < symbol_count)
+ {
+ /* For each symbol which is used defined in this object, write
+ out the object file's address in the archive. */
+
+ while (count < symbol_count && map[count].u.abfd == current)
+ {
+ unsigned int offset = (unsigned int) archive_member_file_ptr;
+
+ /* Generate 64-bit archive if an archive is past its 4Gb
+ limit. */
+ if (archive_member_file_ptr != (file_ptr) offset)
+ return _bfd_archive_64_bit_write_armap (arch, elength, map,
+ symbol_count, stridx);
+ count++;
+ }
+ archive_member_file_ptr += sizeof (struct ar_hdr);
+ if (! bfd_is_thin_archive (arch))
+ {
+ /* Add size of this archive entry. */
+ archive_member_file_ptr += arelt_size (current);
+ /* Remember about the even alignment. */
+ archive_member_file_ptr += archive_member_file_ptr % 2;
+ }
+ current = current->archive_next;
+ }
+#endif
memset (&hdr, ' ', sizeof (struct ar_hdr));
hdr.ar_name[0] = '/';
current = arch->archive_head;
count = 0;
+ archive_member_file_ptr = first_archive_member_file_ptr;
while (current != NULL && count < symbol_count)
{
/* For each symbol which is used defined in this object, write
return TRUE;
}
+bfd_boolean
+_bfd_noarchive_write_armap
+ (bfd *arch ATTRIBUTE_UNUSED,
+ unsigned int elength ATTRIBUTE_UNUSED,
+ struct orl *map ATTRIBUTE_UNUSED,
+ unsigned int orl_count ATTRIBUTE_UNUSED,
+ int stridx ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
static int
archive_close_worker (void **slot, void *inf ATTRIBUTE_UNUSED)
{