+
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (mapdata == NULL)
+ return false;
+
+ amt = mapdata->parsed_size;
+ raw_armap = (bfd_byte *) bfd_zalloc (abfd, amt);
+ if (raw_armap == NULL)
+ {
+ byebye:
+ bfd_release (abfd, (PTR) mapdata);
+ return false;
+ }
+
+ if (bfd_bread ((PTR) raw_armap, amt, abfd) != amt)
+ {
+ 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 = 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 = 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;
+ amt = (bfd_size_type) ardata->symdef_count * BSD_SYMDEF_SIZE;
+ ardata->symdefs = (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.
+
+ 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;
+ bfd_size_type amt;
+
+ /* 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_bread ((PTR) nextname, (bfd_size_type) 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;
+
+ amt = namedata->parsed_size;
+ bfd_ardata (abfd)->extended_names = bfd_zalloc (abfd, amt);
+ if (bfd_ardata (abfd)->extended_names == NULL)
+ {
+ byebye:
+ bfd_release (abfd, (PTR) namedata);
+ return false;
+ }
+
+ if (bfd_bread ((PTR) bfd_ardata (abfd)->extended_names, amt, abfd) != amt)
+ {
+ 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.. */
+ {
+ char *temp = bfd_ardata (abfd)->extended_names;
+ char *limit = temp + namedata->parsed_size;
+ for (; temp < limit; ++temp)
+ {
+ if (*temp == '\012')
+ temp[temp[-1] == '/' ? -1 : 0] = '\0';
+ if (*temp == '\\')
+ *temp = '/';
+ }
+ }
+
+ /* Pad to an even boundary if you have to. */
+ bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
+ bfd_ardata (abfd)->first_file_filepos +=
+ (bfd_ardata (abfd)->first_file_filepos) % 2;
+
+ /* FIXME, we can't release namedata here because it was allocated
+ below extended_names on the objalloc... */
+#if 0
+ bfd_release (abfd, namedata);
+#endif