+ unsigned long i;
+ /* A buffer used to hold numbers read in from an archive index.
+ These are always 4 bytes long and stored in big-endian format. */
+#define SIZEOF_AR_INDEX_NUMBERS 4
+ unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
+ unsigned char * index_buffer;
+
+ /* Check the size of the archive index. */
+ if (size < SIZEOF_AR_INDEX_NUMBERS)
+ {
+ error (_("%s: the archive index is empty\n"), file_name);
+ return 1;
+ }
+
+ /* Read the numer of entries in the archive index. */
+ got = fread (integer_buffer, 1, sizeof integer_buffer, file);
+ if (got != sizeof (integer_buffer))
+ {
+ error (_("%s: failed to read archive index\n"), file_name);
+ return 1;
+ }
+ index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer);
+ size -= SIZEOF_AR_INDEX_NUMBERS;
+
+ /* Read in the archive index. */
+ if (size < index_num * SIZEOF_AR_INDEX_NUMBERS)
+ {
+ error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
+ file_name, index_num);
+ return 1;
+ }
+ index_buffer = malloc (index_num * SIZEOF_AR_INDEX_NUMBERS);
+ if (index_buffer == NULL)
+ {
+ error (_("Out of memory whilst trying to read archive symbol index\n"));
+ return 1;
+ }
+ got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, index_num, file);
+ if (got != index_num)
+ {
+ free (index_buffer);
+ error (_("%s: failed to read archive index\n"), file_name);
+ ret = 1;
+ goto out;
+ }
+ size -= index_num * SIZEOF_AR_INDEX_NUMBERS;
+
+ /* Convert the index numbers into the host's numeric format. */
+ index_array = malloc (index_num * sizeof (* index_array));
+ if (index_array == NULL)
+ {
+ free (index_buffer);
+ error (_("Out of memory whilst trying to convert the archive symbol index\n"));
+ return 1;
+ }
+
+ for (i = 0; i < index_num; i++)
+ index_array[i] = byte_get_big_endian ((unsigned char *)(index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
+ SIZEOF_AR_INDEX_NUMBERS);
+ free (index_buffer);
+
+ /* The remaining space in the header is taken up by the symbol table. */
+ if (size < 1)
+ {
+ error (_("%s: the archive has an index but no symbols\n"), file_name);
+ ret = 1;
+ goto out;
+ }
+ sym_table = malloc (size);
+ sym_size = size;
+ if (sym_table == NULL)
+ {
+ error (_("Out of memory whilst trying to read archive index symbol table\n"));
+ ret = 1;
+ goto out;
+ }
+ got = fread (sym_table, 1, size, file);
+ if (got != size)
+ {
+ error (_("%s: failed to read archive index symbol table\n"), file_name);
+ ret = 1;
+ goto out;
+ }
+ }
+ else
+ {
+ if (fseek (file, size, SEEK_CUR) != 0)
+ {
+ error (_("%s: failed to skip archive symbol table\n"), file_name);
+ return 1;
+ }