/* BFD back-end for archive files (libraries).
- Copyright (C) 1990-2016 Free Software Foundation, Inc.
+ Copyright (C) 1990-2019 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.
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 *
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)
{
bfd_is_thin_archive (abfd) = (strncmp (armag, ARMAGT, SARMAG) == 0);
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);
+ return NULL;
+ }
tdata_hold = bfd_ardata (abfd);
int *raw_armap, *rawptr;
struct artdata *ardata = bfd_ardata (abfd);
char *stringbase;
+ char *stringend;
bfd_size_type stringsize;
bfd_size_type parsed_size;
carsym *carsyms;
nsymz = bfd_getb32 (int_buf);
stringsize = parsed_size - (4 * nsymz) - 4;
- /* ... except that some archive formats are broken, and it may be our
- fault - the i960 little endian coff sometimes has big and sometimes
- little, because our tools changed. Here's a horrible hack to clean
- up the crap. */
-
- 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 (int_buf);
- stringsize = parsed_size - (4 * nsymz) - 4;
- swap = bfd_getl32;
- }
-
/* The coff armap must be read sequentially. So we construct a
bsd-style one in core all at once, for simplicity. */
}
/* OK, build the carsyms. */
- for (i = 0; i < nsymz && stringsize > 0; i++)
+ stringend = stringbase + stringsize;
+ *stringend = 0;
+ for (i = 0; i < nsymz; i++)
{
- bfd_size_type len;
-
rawptr = raw_armap + i;
carsyms->file_offset = swap ((bfd_byte *) rawptr);
carsyms->name = stringbase;
- /* PR 17512: file: 4a1d50c1. */
- len = strnlen (stringbase, stringsize);
- if (len < stringsize)
- len ++;
- stringbase += len;
- stringsize -= len;
+ stringbase += strlen (stringbase);
+ if (stringbase != stringend)
+ ++stringbase;
carsyms++;
}
- *stringbase = 0;
ardata->symdef_count = nsymz;
ardata->first_file_filepos = bfd_tell (abfd);
return TRUE;
}
\f
-/* Returns FALSE on error, TRUE otherwise. */
-/* Flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the
- header is in a slightly different order and the map name is '/'.
- This flavour is used by hp300hpux. */
-
-#define HPUX_SYMDEF_COUNT_SIZE 2
-
-bfd_boolean
-bfd_slurp_bsd_armap_f2 (bfd *abfd)
-{
- struct areltdata *mapdata;
- char nextname[17];
- unsigned int counter;
- bfd_byte *raw_armap, *rbase;
- struct artdata *ardata = bfd_ardata (abfd);
- char *stringbase;
- unsigned int stringsize;
- unsigned int left;
- bfd_size_type amt;
- carsym *set;
- int i = bfd_bread (nextname, 16, abfd);
-
- if (i == 0)
- return TRUE;
- if (i != 16)
- return FALSE;
-
- /* The archive has at least 16 bytes in it. */
- if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
- return FALSE;
-
- if (CONST_STRNEQ (nextname, "__.SYMDEF ")
- || CONST_STRNEQ (nextname, "__.SYMDEF/ ")) /* Old Linux archives. */
- return do_slurp_bsd_armap (abfd);
-
- if (! CONST_STRNEQ (nextname, "/ "))
- {
- bfd_has_map (abfd) = FALSE;
- return TRUE;
- }
-
- mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
- if (mapdata == NULL)
- return FALSE;
-
- if (mapdata->parsed_size < HPUX_SYMDEF_COUNT_SIZE + BSD_STRING_COUNT_SIZE)
- {
- free (mapdata);
- wrong_format:
- bfd_set_error (bfd_error_wrong_format);
- byebye:
- return FALSE;
- }
- left = mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE - BSD_STRING_COUNT_SIZE;
-
- amt = mapdata->parsed_size;
- free (mapdata);
-
- raw_armap = (bfd_byte *) bfd_zalloc (abfd, amt);
- if (raw_armap == NULL)
- goto byebye;
-
- if (bfd_bread (raw_armap, amt, abfd) != amt)
- {
- if (bfd_get_error () != bfd_error_system_call)
- bfd_set_error (bfd_error_malformed_archive);
- goto byebye;
- }
-
- ardata->symdef_count = H_GET_16 (abfd, raw_armap);
-
- ardata->cache = 0;
-
- stringsize = H_GET_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE);
- if (stringsize > left)
- goto wrong_format;
- left -= stringsize;
-
- /* Skip sym count and string sz. */
- stringbase = ((char *) raw_armap
- + HPUX_SYMDEF_COUNT_SIZE
- + BSD_STRING_COUNT_SIZE);
- rbase = (bfd_byte *) stringbase + stringsize;
- amt = ardata->symdef_count * BSD_SYMDEF_SIZE;
- if (amt > left)
- goto wrong_format;
-
- ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt);
- if (!ardata->symdefs)
- return FALSE;
-
- for (counter = 0, set = ardata->symdefs;
- counter < ardata->symdef_count;
- counter++, set++, rbase += BSD_SYMDEF_SIZE)
- {
- set->name = H_GET_32 (abfd, rbase) + stringbase;
- set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE);
- }
-
- 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;
- /* 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 objalloc anyway... */
- bfd_has_map (abfd) = TRUE;
- return TRUE;
-}
-\f
/** Extended name table.
Normally archives support only 14-character filenames.
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"));
+ (_("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)
+ 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
- (_("%s: plugin needed to handle lto object"),
- bfd_get_filename (current));
+ (_("%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;
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. */
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)
{
return 1;
}
+void
+_bfd_unlink_from_archive_parent (bfd *abfd)
+{
+ if (arch_eltdata (abfd) != NULL)
+ {
+ struct areltdata *ared = arch_eltdata (abfd);
+ htab_t htab = (htab_t) ared->parent_cache;
+
+ if (htab)
+ {
+ struct ar_cache ent;
+ void **slot;
+
+ ent.ptr = ared->key;
+ slot = htab_find_slot (htab, &ent, NO_INSERT);
+ if (slot != NULL)
+ {
+ BFD_ASSERT (((struct ar_cache *) *slot)->arbfd == abfd);
+ htab_clear_slot (htab, slot);
+ }
+ }
+ }
+}
+
bfd_boolean
_bfd_archive_close_and_cleanup (bfd *abfd)
{
bfd_ardata (abfd)->cache = NULL;
}
}
- if (arch_eltdata (abfd) != NULL)
- {
- struct areltdata *ared = arch_eltdata (abfd);
- htab_t htab = (htab_t) ared->parent_cache;
- if (htab)
- {
- struct ar_cache ent;
- void **slot;
+ _bfd_unlink_from_archive_parent (abfd);
- ent.ptr = ared->key;
- slot = htab_find_slot (htab, &ent, NO_INSERT);
- if (slot != NULL)
- {
- BFD_ASSERT (((struct ar_cache *) *slot)->arbfd == abfd);
- htab_clear_slot (htab, slot);
- }
- }
- }
if (abfd->is_linker_output)
(*abfd->link.hash->hash_table_free) (abfd);