summaryrefslogtreecommitdiff
path: root/bfd/coff-rs6000.c
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@nildram.co.uk>2009-04-01 20:04:28 +0000
committerRichard Sandiford <rsandifo@nildram.co.uk>2009-04-01 20:04:28 +0000
commit26196d14596ff1854b1ffc84cbc4b1828d512d66 (patch)
tree557319d08f7ec0d9a8db6a4aa7e8b7544463cab4 /bfd/coff-rs6000.c
parent82150465b2e362456e66d00636461a3b29cc0a14 (diff)
downloadbinutils-redhat-26196d14596ff1854b1ffc84cbc4b1828d512d66.tar.gz
bfd/
* coff-rs6000.c (member_layout): New structure. (archive_iterator): Likewise. (member_layout_init): New function. (archive_iterator_begin): Likewise. (archive_iterator_next): Likewise. (xcoff_write_armap_old): Use the new iterator functions. (do_shared_object_padding): Delete. (xcoff_write_armap_big): Use the new iterator functions. Simplify handling of arch_info. (xcoff_write_archive_contents_old): Allocate arelt_data in the first loop rather than the second. Allocate a member header if there isn't one, then work out the stat information and length in the first loop too. Use the new iterators for the second loop. (xcoff_write_archive_contents_big): Likewise.
Diffstat (limited to 'bfd/coff-rs6000.c')
-rw-r--r--bfd/coff-rs6000.c504
1 files changed, 242 insertions, 262 deletions
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 334353056f..c5a486bab6 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -180,8 +180,6 @@ static bfd_boolean do_pad
PARAMS ((bfd *, unsigned int));
static bfd_boolean do_copy
PARAMS ((bfd *, bfd *));
-static bfd_boolean do_shared_object_padding
- PARAMS ((bfd *, bfd *, file_ptr *, int));
/* Relocation functions */
static bfd_boolean xcoff_reloc_type_br
@@ -238,6 +236,119 @@ bfd_boolean (*xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW])
xcoff_complain_overflow_unsigned_func,
};
+/* Information about one member of an archive. */
+struct member_layout {
+ /* The archive member that this structure describes. */
+ bfd *member;
+
+ /* The number of bytes of padding that must be inserted before the
+ start of the member in order to ensure that the section contents
+ are correctly aligned. */
+ unsigned int leading_padding;
+
+ /* The offset of MEMBER from the start of the archive (i.e. the end
+ of the leading padding). */
+ file_ptr offset;
+
+ /* The normalized name of MEMBER. */
+ const char *name;
+
+ /* The length of NAME, without padding. */
+ bfd_size_type namlen;
+
+ /* The length of NAME, with padding. */
+ bfd_size_type padded_namlen;
+
+ /* The size of MEMBER's header, including the name and magic sequence. */
+ bfd_size_type header_size;
+
+ /* The size of the MEMBER's contents. */
+ bfd_size_type contents_size;
+
+ /* The number of bytes of padding that must be inserted after MEMBER
+ in order to preserve even alignment. */
+ bfd_size_type trailing_padding;
+};
+
+/* A structure used for iterating over the members of an archive. */
+struct archive_iterator {
+ /* The archive itself. */
+ bfd *archive;
+
+ /* Information about the current archive member. */
+ struct member_layout current;
+
+ /* Information about the next archive member. MEMBER is null if there
+ are no more archive members, in which case OFFSET is the offset of
+ the first unused byte. */
+ struct member_layout next;
+};
+
+/* Initialize INFO so that it describes member MEMBER of archive ARCHIVE.
+ OFFSET is the even-padded offset of MEMBER, not including any leading
+ padding needed for section alignment. */
+
+static void
+member_layout_init (struct member_layout *info, bfd *archive,
+ bfd *member, file_ptr offset)
+{
+ info->member = member;
+ info->leading_padding = 0;
+ if (member)
+ {
+ info->name = normalize_filename (member);
+ info->namlen = strlen (info->name);
+ info->padded_namlen = info->namlen + (info->namlen & 1);
+ if (xcoff_big_format_p (archive))
+ info->header_size = SIZEOF_AR_HDR_BIG;
+ else
+ info->header_size = SIZEOF_AR_HDR;
+ info->header_size += info->padded_namlen + SXCOFFARFMAG;
+ info->contents_size = arelt_size (member);
+ info->trailing_padding = info->contents_size & 1;
+
+ if (bfd_check_format (member, bfd_object)
+ && bfd_get_flavour (member) == bfd_target_xcoff_flavour
+ && (member->flags & DYNAMIC) != 0)
+ info->leading_padding
+ = (-(offset + info->header_size)
+ & ((1 << bfd_xcoff_text_align_power (member)) - 1));
+ }
+ info->offset = offset + info->leading_padding;
+}
+
+/* Set up ITERATOR to iterate through archive ARCHIVE. */
+
+static void
+archive_iterator_begin (struct archive_iterator *iterator,
+ bfd *archive)
+{
+ iterator->archive = archive;
+ member_layout_init (&iterator->next, archive, archive->archive_head,
+ xcoff_big_format_p (archive)
+ ? SIZEOF_AR_FILE_HDR_BIG
+ : SIZEOF_AR_FILE_HDR);
+}
+
+/* Make ITERATOR visit the first unvisited archive member. Return true
+ on success; return false if all members have been visited. */
+
+static bfd_boolean
+archive_iterator_next (struct archive_iterator *iterator)
+{
+ if (!iterator->next.member)
+ return FALSE;
+
+ iterator->current = iterator->next;
+ member_layout_init (&iterator->next, iterator->archive,
+ iterator->current.member->archive_next,
+ iterator->current.offset
+ + iterator->current.header_size
+ + iterator->current.contents_size
+ + iterator->current.trailing_padding);
+ return TRUE;
+}
+
/* We use our own tdata type. Its first field is the COFF tdata type,
so the COFF routines are compatible. */
@@ -1603,11 +1714,10 @@ xcoff_write_armap_old (abfd, elength, map, orl_count, stridx)
unsigned int orl_count;
int stridx;
{
+ struct archive_iterator iterator;
struct xcoff_ar_hdr hdr;
char *p;
unsigned char buf[4];
- bfd *sub;
- file_ptr fileoff;
unsigned int i;
memset (&hdr, 0, sizeof hdr);
@@ -1635,29 +1745,16 @@ xcoff_write_armap_old (abfd, elength, map, orl_count, stridx)
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
return FALSE;
- sub = abfd->archive_head;
- fileoff = SIZEOF_AR_FILE_HDR;
i = 0;
- while (sub != NULL && i < orl_count)
- {
- size_t namlen;
-
- while (map[i].u.abfd == sub)
- {
- H_PUT_32 (abfd, fileoff, buf);
- if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
- return FALSE;
- ++i;
- }
- namlen = strlen (normalize_filename (sub));
- namlen = (namlen + 1) &~ (size_t) 1;
- fileoff += (SIZEOF_AR_HDR
- + namlen
- + SXCOFFARFMAG
- + arelt_size (sub));
- fileoff = (fileoff + 1) &~ 1;
- sub = sub->archive_next;
- }
+ archive_iterator_begin (&iterator, abfd);
+ while (i < orl_count && archive_iterator_next (&iterator))
+ while (map[i].u.abfd == iterator.current.member)
+ {
+ H_PUT_32 (abfd, iterator.current.offset, buf);
+ if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
+ return FALSE;
+ ++i;
+ }
for (i = 0; i < orl_count; i++)
{
@@ -1759,34 +1856,6 @@ do_copy (out_bfd, in_bfd)
}
static bfd_boolean
-do_shared_object_padding (out_bfd, in_bfd, offset, ar_header_size)
- bfd *out_bfd;
- bfd *in_bfd;
- file_ptr *offset;
- int ar_header_size;
-{
- if (bfd_check_format (in_bfd, bfd_object)
- && bfd_get_flavour (in_bfd) == bfd_target_xcoff_flavour
- && (in_bfd->flags & DYNAMIC) != 0)
- {
- bfd_size_type pad = 0;
- int text_align_power;
-
- text_align_power = bfd_xcoff_text_align_power (in_bfd);
-
- pad = 1 << text_align_power;
- pad -= (*offset + ar_header_size) & (pad - 1);
-
- if (! do_pad (out_bfd, pad))
- return FALSE;
-
- *offset += pad;
- }
-
- return TRUE;
-}
-
-static bfd_boolean
xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
bfd *abfd;
unsigned int elength ATTRIBUTE_UNUSED;
@@ -1794,9 +1863,10 @@ xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
unsigned int orl_count;
int stridx;
{
+ struct archive_iterator iterator;
struct xcoff_ar_file_hdr_big *fhdr;
bfd_vma i, sym_32, sym_64, str_32, str_64;
- const bfd_arch_info_type *arch_info = NULL;
+ const bfd_arch_info_type *arch_info;
bfd *current_bfd;
size_t string_length;
file_ptr nextoff, prevoff;
@@ -1805,16 +1875,15 @@ xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
from 32-bit objects and which from 64-bit ones. */
sym_32 = sym_64 = str_32 = str_64 = 0;
- current_bfd = abfd->archive_head;
- if (current_bfd != NULL)
- arch_info = bfd_get_arch_info (current_bfd);
- i = 0;
- while (current_bfd != NULL && i < orl_count)
+ i = 0;
+ for (current_bfd = abfd->archive_head;
+ current_bfd != NULL && i < orl_count;
+ current_bfd = current_bfd->archive_next)
{
+ arch_info = bfd_get_arch_info (current_bfd);
while (map[i].u.abfd == current_bfd)
{
string_length = strlen (*map[i].name) + 1;
-
if (arch_info->bits_per_address == 64)
{
sym_64++;
@@ -1827,9 +1896,6 @@ xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
}
i++;
}
- current_bfd = current_bfd->archive_next;
- if (current_bfd != NULL)
- arch_info = bfd_get_arch_info (current_bfd);
}
/* A quick sanity check... */
@@ -1871,7 +1937,6 @@ xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
struct xcoff_ar_hdr_big *hdr;
char *symbol_table;
char *st;
- file_ptr fileoff;
bfd_vma symbol_table_size =
SIZEOF_AR_HDR_BIG
@@ -1908,41 +1973,29 @@ xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
st += 8;
/* loop over the 32 bit offsets */
- current_bfd = abfd->archive_head;
- if (current_bfd != NULL)
- arch_info = bfd_get_arch_info (current_bfd);
- fileoff = SIZEOF_AR_FILE_HDR_BIG;
i = 0;
- while (current_bfd != NULL && i < orl_count)
+ archive_iterator_begin (&iterator, abfd);
+ while (i < orl_count && archive_iterator_next (&iterator))
{
- while (map[i].u.abfd == current_bfd)
+ arch_info = bfd_get_arch_info (iterator.current.member);
+ while (map[i].u.abfd == iterator.current.member)
{
if (arch_info->bits_per_address == 32)
{
- bfd_h_put_64 (abfd, fileoff, st);
+ bfd_h_put_64 (abfd, iterator.current.offset, st);
st += 8;
}
i++;
}
- string_length = strlen (normalize_filename (current_bfd));
- string_length += string_length & 1;
- fileoff += (SIZEOF_AR_HDR_BIG
- + string_length
- + SXCOFFARFMAG
- + arelt_size (current_bfd));
- fileoff += fileoff & 1;
- current_bfd = current_bfd->archive_next;
- if (current_bfd != NULL)
- arch_info = bfd_get_arch_info (current_bfd);
}
/* loop over the 32 bit symbol names */
- current_bfd = abfd->archive_head;
- if (current_bfd != NULL)
- arch_info = bfd_get_arch_info (current_bfd);
i = 0;
- while (current_bfd != NULL && i < orl_count)
+ for (current_bfd = abfd->archive_head;
+ current_bfd != NULL && i < orl_count;
+ current_bfd = current_bfd->archive_next)
{
+ arch_info = bfd_get_arch_info (current_bfd);
while (map[i].u.abfd == current_bfd)
{
if (arch_info->bits_per_address == 32)
@@ -1952,9 +2005,6 @@ xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
}
i++;
}
- current_bfd = current_bfd->archive_next;
- if (current_bfd != NULL)
- arch_info = bfd_get_arch_info (current_bfd);
}
bfd_bwrite (symbol_table, symbol_table_size, abfd);
@@ -1972,7 +2022,6 @@ xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
struct xcoff_ar_hdr_big *hdr;
char *symbol_table;
char *st;
- file_ptr fileoff;
bfd_vma symbol_table_size =
SIZEOF_AR_HDR_BIG
@@ -2004,41 +2053,29 @@ xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
st += 8;
/* loop over the 64 bit offsets */
- current_bfd = abfd->archive_head;
- if (current_bfd != NULL)
- arch_info = bfd_get_arch_info (current_bfd);
- fileoff = SIZEOF_AR_FILE_HDR_BIG;
i = 0;
- while (current_bfd != NULL && i < orl_count)
+ archive_iterator_begin (&iterator, abfd);
+ while (i < orl_count && archive_iterator_next (&iterator))
{
- while (map[i].u.abfd == current_bfd)
+ arch_info = bfd_get_arch_info (iterator.current.member);
+ while (map[i].u.abfd == iterator.current.member)
{
if (arch_info->bits_per_address == 64)
{
- bfd_h_put_64 (abfd, fileoff, st);
+ bfd_h_put_64 (abfd, iterator.current.offset, st);
st += 8;
}
i++;
}
- string_length = strlen (normalize_filename (current_bfd));
- string_length += string_length & 1;
- fileoff += (SIZEOF_AR_HDR_BIG
- + string_length
- + SXCOFFARFMAG
- + arelt_size (current_bfd));
- fileoff += fileoff & 1;
- current_bfd = current_bfd->archive_next;
- if (current_bfd != NULL)
- arch_info = bfd_get_arch_info (current_bfd);
}
/* loop over the 64 bit symbol names */
- current_bfd = abfd->archive_head;
- if (current_bfd != NULL)
- arch_info = bfd_get_arch_info (current_bfd);
i = 0;
- while (current_bfd != NULL && i < orl_count)
+ for (current_bfd = abfd->archive_head;
+ current_bfd != NULL && i < orl_count;
+ current_bfd = current_bfd->archive_next)
{
+ arch_info = bfd_get_arch_info (current_bfd);
while (map[i].u.abfd == current_bfd)
{
if (arch_info->bits_per_address == 64)
@@ -2048,9 +2085,6 @@ xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
}
i++;
}
- current_bfd = current_bfd->archive_next;
- if (current_bfd != NULL)
- arch_info = bfd_get_arch_info (current_bfd);
}
bfd_bwrite (symbol_table, symbol_table_size, abfd);
@@ -2086,6 +2120,7 @@ static bfd_boolean
xcoff_write_archive_contents_old (abfd)
bfd *abfd;
{
+ struct archive_iterator iterator;
struct xcoff_ar_file_hdr fhdr;
bfd_size_type count;
bfd_size_type total_namlen;
@@ -2111,118 +2146,92 @@ xcoff_write_archive_contents_old (abfd)
{
++count;
total_namlen += strlen (normalize_filename (sub)) + 1;
- }
- offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
- if (offsets == NULL)
- return FALSE;
-
- if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
- return FALSE;
-
- makemap = bfd_has_map (abfd);
- hasobjects = FALSE;
- prevoff = 0;
- nextoff = SIZEOF_AR_FILE_HDR;
- for (sub = abfd->archive_head, i = 0;
- sub != NULL;
- sub = sub->archive_next, i++)
- {
- const char *name;
- bfd_size_type namlen;
- struct xcoff_ar_hdr *ahdrp;
- bfd_size_type remaining;
-
- if (makemap && ! hasobjects)
+ if (sub->arelt_data == NULL)
{
- if (bfd_check_format (sub, bfd_object))
- hasobjects = TRUE;
+ sub->arelt_data = bfd_zalloc (sub, sizeof (struct areltdata));
+ if (sub->arelt_data == NULL)
+ return FALSE;
}
-
- name = normalize_filename (sub);
- namlen = strlen (name);
-
- if (sub->arelt_data != NULL)
- ahdrp = arch_xhdr (sub);
- else
- ahdrp = NULL;
-
- if (ahdrp == NULL)
+ if (arch_xhdr (sub) == NULL)
{
+ struct xcoff_ar_hdr *ahdrp;
struct stat s;
- memset (&ahdr, 0, sizeof ahdr);
- ahdrp = &ahdr;
if (stat (bfd_get_filename (sub), &s) != 0)
{
bfd_set_error (bfd_error_system_call);
return FALSE;
}
+ ahdrp = bfd_zalloc (sub, sizeof (*ahdrp));
+ if (ahdrp == NULL)
+ return FALSE;
+
sprintf (ahdrp->size, "%ld", (long) s.st_size);
sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
- if (sub->arelt_data == NULL)
- {
- size = sizeof (struct areltdata);
- sub->arelt_data = bfd_alloc (sub, size);
- if (sub->arelt_data == NULL)
- return FALSE;
- }
-
+ arch_eltdata (sub)->arch_header = (char *) ahdrp;
arch_eltdata (sub)->parsed_size = s.st_size;
}
+ }
+ offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
+ if (offsets == NULL)
+ return FALSE;
- sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
- sprintf (ahdrp->namlen, "%ld", (long) namlen);
-
- /* If the length of the name is odd, we write out the null byte
- after the name as well. */
- namlen = (namlen + 1) &~ (bfd_size_type) 1;
-
- remaining = arelt_size (sub);
- size = (SIZEOF_AR_HDR
- + namlen
- + SXCOFFARFMAG
- + remaining);
-
- BFD_ASSERT (nextoff == bfd_tell (abfd));
+ if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
+ return FALSE;
- offsets[i] = nextoff;
+ makemap = bfd_has_map (abfd);
+ hasobjects = FALSE;
+ prevoff = 0;
+ for (archive_iterator_begin (&iterator, abfd), i = 0;
+ archive_iterator_next (&iterator);
+ i++)
+ {
+ bfd_size_type namlen;
+ struct xcoff_ar_hdr *ahdrp;
- prevoff = nextoff;
- nextoff += size + (size & 1);
+ if (makemap && ! hasobjects)
+ {
+ if (bfd_check_format (iterator.current.member, bfd_object))
+ hasobjects = TRUE;
+ }
- sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
+ ahdrp = arch_xhdr (iterator.current.member);
+ sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
+ sprintf (ahdrp->namlen, "%ld", (long) iterator.current.namlen);
+ sprintf (ahdrp->nextoff, "%ld", (long) iterator.next.offset);
/* We need spaces, not null bytes, in the header. */
for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
if (*p == '\0')
*p = ' ';
- if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR, abfd)
- != SIZEOF_AR_HDR)
- || bfd_bwrite ((PTR) name, namlen, abfd) != namlen
- || bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
- abfd) != SXCOFFARFMAG)
- return FALSE;
-
- if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
+ if (!do_pad (abfd, iterator.current.leading_padding))
return FALSE;
- if (! do_copy (abfd, sub))
+ BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
+ namlen = iterator.current.padded_namlen;
+ if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
+ || bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
+ || bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
+ || bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
+ || !do_copy (abfd, iterator.current.member)
+ || !do_pad (abfd, iterator.current.trailing_padding))
return FALSE;
- if (! do_pad (abfd, size & 1))
- return FALSE;
+ offsets[i] = iterator.current.offset;
+ prevoff = iterator.current.offset;
}
sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
/* Write out the member table. */
+ nextoff = iterator.next.offset;
BFD_ASSERT (nextoff == bfd_tell (abfd));
sprintf (fhdr.memoff, "%ld", (long) nextoff);
@@ -2327,10 +2336,11 @@ xcoff_write_archive_contents_big (abfd)
file_ptr prevoff, nextoff;
bfd *current_bfd;
size_t i;
- struct xcoff_ar_hdr_big *hdr, ahdr;
+ struct xcoff_ar_hdr_big *hdr;
bfd_size_type size;
char *member_table, *mt;
bfd_vma member_table_size;
+ struct archive_iterator iterator;
memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
@@ -2351,40 +2361,20 @@ xcoff_write_archive_contents_big (abfd)
&& ! hasobjects
&& bfd_check_format (current_bfd, bfd_object))
hasobjects = TRUE;
- }
- offsets = NULL;
- if (count)
- {
- offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
- if (offsets == NULL)
- return FALSE;
- }
-
- prevoff = 0;
- nextoff = SIZEOF_AR_FILE_HDR_BIG;
- for (current_bfd = abfd->archive_head, i = 0;
- current_bfd != NULL;
- current_bfd = current_bfd->archive_next, i++)
- {
- const char *name;
- bfd_size_type namlen;
- struct xcoff_ar_hdr_big *ahdrp;
- bfd_size_type remaining;
-
- name = normalize_filename (current_bfd);
- namlen = strlen (name);
-
- if (current_bfd->arelt_data != NULL)
- ahdrp = arch_xhdr_big (current_bfd);
- else
- ahdrp = NULL;
+ if (current_bfd->arelt_data == NULL)
+ {
+ size = sizeof (struct areltdata);
+ current_bfd->arelt_data = bfd_zalloc (current_bfd, size);
+ if (current_bfd->arelt_data == NULL)
+ return FALSE;
+ }
- if (ahdrp == NULL)
+ if (arch_xhdr_big (current_bfd) == NULL)
{
+ struct xcoff_ar_hdr_big *ahdrp;
struct stat s;
- ahdrp = &ahdr;
/* XXX This should actually be a call to stat64 (at least on
32-bit machines).
XXX This call will fail if the original object is not found. */
@@ -2394,68 +2384,57 @@ xcoff_write_archive_contents_big (abfd)
return FALSE;
}
+ ahdrp = bfd_zalloc (current_bfd, sizeof (*ahdrp));
+ if (ahdrp == NULL)
+ return FALSE;
+
PRINT20 (ahdrp->size, s.st_size);
PRINT12 (ahdrp->date, s.st_mtime);
PRINT12 (ahdrp->uid, s.st_uid);
PRINT12 (ahdrp->gid, s.st_gid);
PRINT12_OCTAL (ahdrp->mode, s.st_mode);
- if (current_bfd->arelt_data == NULL)
- {
- size = sizeof (struct areltdata);
- current_bfd->arelt_data = bfd_alloc (current_bfd, size);
- if (current_bfd->arelt_data == NULL)
- return FALSE;
- }
-
+ arch_eltdata (current_bfd)->arch_header = (char *) ahdrp;
arch_eltdata (current_bfd)->parsed_size = s.st_size;
}
+ }
- PRINT20 (ahdrp->prevoff, prevoff);
- PRINT4 (ahdrp->namlen, namlen);
-
- /* If the length of the name is odd, we write out the null byte
- after the name as well. */
- namlen = (namlen + 1) &~ (bfd_size_type) 1;
-
- remaining = arelt_size (current_bfd);
- size = (SIZEOF_AR_HDR_BIG
- + namlen
- + SXCOFFARFMAG
- + remaining);
-
- BFD_ASSERT (nextoff == bfd_tell (abfd));
-
- /* Check for xcoff shared objects.
- Their text section needs to be aligned wrt the archive file position.
- This requires extra padding before the archive header. */
- if (! do_shared_object_padding (abfd, current_bfd, & nextoff,
- SIZEOF_AR_HDR_BIG + namlen
- + SXCOFFARFMAG))
+ offsets = NULL;
+ if (count)
+ {
+ offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
+ if (offsets == NULL)
return FALSE;
+ }
- offsets[i] = nextoff;
-
- prevoff = nextoff;
- nextoff += size + (size & 1);
-
- PRINT20 (ahdrp->nextoff, nextoff);
+ prevoff = 0;
+ for (archive_iterator_begin (&iterator, abfd), i = 0;
+ archive_iterator_next (&iterator);
+ i++)
+ {
+ bfd_size_type namlen;
+ struct xcoff_ar_hdr_big *ahdrp;
- if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
- != SIZEOF_AR_HDR_BIG)
- || bfd_bwrite ((PTR) name, (bfd_size_type) namlen, abfd) != namlen
- || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
- abfd) != SXCOFFARFMAG))
- return FALSE;
+ ahdrp = arch_xhdr_big (iterator.current.member);
+ PRINT20 (ahdrp->prevoff, prevoff);
+ PRINT4 (ahdrp->namlen, iterator.current.namlen);
+ PRINT20 (ahdrp->nextoff, iterator.next.offset);
- if (bfd_seek (current_bfd, (file_ptr) 0, SEEK_SET) != 0)
+ if (!do_pad (abfd, iterator.current.leading_padding))
return FALSE;
- if (! do_copy (abfd, current_bfd))
+ BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
+ namlen = iterator.current.padded_namlen;
+ if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR_BIG, abfd) != SIZEOF_AR_HDR_BIG
+ || bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
+ || bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
+ || bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
+ || !do_copy (abfd, iterator.current.member)
+ || !do_pad (abfd, iterator.current.trailing_padding))
return FALSE;
- if (! do_pad (abfd, size & 1))
- return FALSE;
+ offsets[i] = iterator.current.offset;
+ prevoff = iterator.current.offset;
}
if (count)
@@ -2485,6 +2464,7 @@ xcoff_write_archive_contents_big (abfd)
?? pad to even bytes.
*/
+ nextoff = iterator.next.offset;
BFD_ASSERT (nextoff == bfd_tell (abfd));
member_table_size = (SIZEOF_AR_HDR_BIG