+ bfd_has_map (abfd) = false;
+ 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
+
+boolean
+bfd_slurp_bsd_armap_f2 (abfd)
+ 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;
+ carsym *set;
+ int i = bfd_read ((PTR) nextname, 1, 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, -16L, SEEK_CUR) != 0)
+ return false;
+
+ if (!strncmp (nextname, "__.SYMDEF ", 16)
+ || !strncmp (nextname, "__.SYMDEF/ ", 16)) /* old Linux archives */
+ return do_slurp_bsd_armap (abfd);
+
+ if (strncmp (nextname, "/ ", 16))
+ {
+ bfd_has_map (abfd) = false;
+ return true;
+ }
+
+ 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)
+ {
+ byebye:
+ bfd_release (abfd, (PTR) mapdata);
+ return false;
+ }
+
+ if (bfd_read ((PTR) raw_armap, 1, mapdata->parsed_size, abfd) !=
+ mapdata->parsed_size)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ byebyebye:
+ bfd_release (abfd, (PTR) raw_armap);
+ goto byebye;
+ }
+
+ ardata->symdef_count = bfd_h_get_16 (abfd, (PTR) raw_armap);
+
+ if (ardata->symdef_count * BSD_SYMDEF_SIZE
+ > mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE)
+ {
+ /* Probably we're using the wrong byte ordering. */
+ bfd_set_error (bfd_error_wrong_format);
+ goto byebyebye;
+ }
+
+ ardata->cache = 0;
+
+ stringsize = bfd_h_get_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE);
+ /* skip sym count and string sz */
+ stringbase = ((char *) raw_armap
+ + HPUX_SYMDEF_COUNT_SIZE
+ + BSD_STRING_COUNT_SIZE);
+ rbase = (bfd_byte *) stringbase + stringsize;
+ ardata->symdefs = (carsym *) bfd_alloc (abfd,
+ (ardata->symdef_count
+ * BSD_SYMDEF_SIZE));
+ if (!ardata->symdefs)
+ return false;
+
+ for (counter = 0, set = ardata->symdefs;
+ counter < ardata->symdef_count;
+ counter++, set++, rbase += BSD_SYMDEF_SIZE)
+ {
+ set->name = bfd_h_get_32 (abfd, rbase) + stringbase;
+ set->file_offset = bfd_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.
+
+ 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 (decimal). Data General have
+ extended the format by using the prefix // for the special element */
+
+/* Returns false on error, true otherwise */
+boolean
+_bfd_slurp_extended_name_table (abfd)
+ bfd *abfd;
+{
+ char nextname[17];
+ struct areltdata *namedata;
+
+ /* FIXME: Formatting sucks here, and in case of failure of BFD_READ,
+ we probably don't want to return true. */
+ bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET);
+ if (bfd_read ((PTR) nextname, 1, 16, abfd) == 16)
+ {
+ if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
+ return false;
+
+ if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 &&
+ strncmp (nextname, "// ", 16) != 0)
+ {
+ bfd_ardata (abfd)->extended_names = NULL;
+ return true;
+ }
+
+ namedata = (struct areltdata *) _bfd_read_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)
+ {
+ 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)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ bfd_release (abfd, (PTR) (bfd_ardata (abfd)->extended_names));
+ bfd_ardata (abfd)->extended_names = NULL;
+ goto byebye;
+ }
+
+ /* Since the archive is supposed to be printable if it contains
+ text, the entries in the list are newline-padded, not null
+ padded. In SVR4-style archives, the names also have a
+ trailing '/'. DOS/NT created archive often have \ in them
+ We'll fix all problems here.. */
+ {