ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG;
}
+ /* Size occupied by the header above that covered in the fixed
+ SIZEOF_AR_HDR or SIZEOF_AR_HDR_BIG. */
+ ret->extra_size = namlen + (namlen & 1) + SXCOFFARFMAG;
+
/* Skip over the XCOFFARFMAG at the end of the file name. */
if (bfd_seek (abfd, (file_ptr) ((namlen & 1) + SXCOFFARFMAG), SEEK_CUR) != 0)
return NULL;
_bfd_xcoff_openr_next_archived_file (bfd *archive, bfd *last_file)
{
file_ptr filestart;
+ file_ptr laststart, lastend;
if (xcoff_ardata (archive) == NULL)
{
if (! xcoff_big_format_p (archive))
{
if (last_file == NULL)
- filestart = bfd_ardata (archive)->first_file_filepos;
+ {
+ filestart = bfd_ardata (archive)->first_file_filepos;
+ laststart = 0;
+ lastend = SIZEOF_AR_FILE_HDR;
+ }
else
- GET_VALUE_IN_FIELD (filestart, arch_xhdr (last_file)->nextoff, 10);
+ {
+ struct areltdata *arel = arch_eltdata (last_file);
+
+ GET_VALUE_IN_FIELD (filestart, arch_xhdr (last_file)->nextoff, 10);
+ laststart = last_file->proxy_origin;
+ lastend = laststart + arel->parsed_size;
+ laststart -= SIZEOF_AR_HDR + arel->extra_size;
+ }
+
+ /* Sanity check that we aren't pointing into the previous element. */
+ if (filestart != 0 && filestart >= laststart && filestart < lastend)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
if (filestart == 0
|| EQ_VALUE_IN_FIELD (filestart, xcoff_ardata (archive)->memoff, 10)
else
{
if (last_file == NULL)
- filestart = bfd_ardata (archive)->first_file_filepos;
+ {
+ filestart = bfd_ardata (archive)->first_file_filepos;
+ laststart = 0;
+ lastend = SIZEOF_AR_FILE_HDR_BIG;
+ }
else
- GET_VALUE_IN_FIELD (filestart, arch_xhdr_big (last_file)->nextoff, 10);
+ {
+ struct areltdata *arel = arch_eltdata (last_file);
+
+ GET_VALUE_IN_FIELD (filestart, arch_xhdr_big (last_file)->nextoff, 10);
+ laststart = last_file->proxy_origin;
+ lastend = laststart + arel->parsed_size;
+ laststart -= SIZEOF_AR_HDR_BIG + arel->extra_size;
+ }
+
+ /* Sanity check that we aren't pointing into the previous element. */
+ if (filestart != 0 && filestart >= laststart && filestart < lastend)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
if (filestart == 0
|| EQ_VALUE_IN_FIELD (filestart, xcoff_ardata_big (archive)->memoff, 10)
static bfd *
xcoff64_openr_next_archived_file (bfd *archive, bfd *last_file)
{
- bfd_vma filestart;
-
if ((xcoff_ardata (archive) == NULL)
|| ! xcoff_big_format_p (archive))
{
return NULL;
}
- if (last_file == NULL)
- {
- filestart = bfd_ardata (archive)->first_file_filepos;
- }
- else
- {
- filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
- (const char **) NULL, 10);
- }
-
- if (filestart == 0
- || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
- (const char **) NULL, 10)
- || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
- (const char **) NULL, 10))
- {
- bfd_set_error (bfd_error_no_more_archived_files);
- return NULL;
- }
-
- return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
+ return _bfd_xcoff_openr_next_archived_file (archive, last_file);
}
/* We can't use the usual coff_sizeof_headers routine, because AIX