summaryrefslogtreecommitdiff
path: root/bfd/archive.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/archive.c')
-rw-r--r--bfd/archive.c92
1 files changed, 81 insertions, 11 deletions
diff --git a/bfd/archive.c b/bfd/archive.c
index 53e295eb26c..6fc5f1d80f9 100644
--- a/bfd/archive.c
+++ b/bfd/archive.c
@@ -1144,10 +1144,9 @@ bfd_slurp_armap (bfd *abfd)
return do_slurp_coff_armap (abfd);
else if (CONST_STRNEQ (nextname, "/SYM64/ "))
{
- /* 64bit ELF (Irix 6) archive. */
+ /* 64bit (Irix 6) archive. */
#ifdef BFD64
- extern bfd_boolean bfd_elf64_archive_slurp_armap (bfd *);
- return bfd_elf64_archive_slurp_armap (abfd);
+ return _bfd_archive_64_bit_slurp_armap (abfd);
#else
bfd_set_error (bfd_error_wrong_format);
return FALSE;
@@ -2466,15 +2465,49 @@ bsd_write_armap (bfd *arch,
unsigned int stringsize = stridx + padit;
/* Include 8 bytes to store ranlibsize and stringsize in output. */
unsigned int mapsize = ranlibsize + stringsize + 8;
- file_ptr firstreal;
- bfd *current = arch->archive_head;
- bfd *last_elt = current; /* Last element arch seen. */
+ file_ptr firstreal, first;
+ bfd *current;
+ bfd *last_elt;
bfd_byte temp[4];
unsigned int count;
struct ar_hdr hdr;
long uid, gid;
- firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
+ first = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
+
+#ifdef BFD64
+ firstreal = first;
+ current = arch->archive_head;
+ last_elt = current; /* Last element arch seen. */
+ for (count = 0; count < orl_count; count++)
+ {
+ unsigned int offset;
+
+ if (map[count].u.abfd != last_elt)
+ {
+ do
+ {
+ struct areltdata *ared = arch_eltdata (current);
+
+ firstreal += (ared->parsed_size + ared->extra_size
+ + sizeof (struct ar_hdr));
+ firstreal += firstreal % 2;
+ current = current->archive_next;
+ }
+ while (current != map[count].u.abfd);
+ }
+
+ /* The archive file format only has 4 bytes to store the offset
+ of the member. Generate 64-bit archive if an archive is past
+ its 4Gb limit. */
+ offset = (unsigned int) firstreal;
+ if (firstreal != (file_ptr) offset)
+ return _bfd_archive_64_bit_write_armap (arch, elength, map,
+ orl_count, stridx);
+
+ last_elt = current;
+ }
+#endif
/* If deterministic, we use 0 as the timestamp in the map.
Some linkers may require that the archive filesystem modification
@@ -2513,6 +2546,9 @@ bsd_write_armap (bfd *arch,
if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp))
return FALSE;
+ firstreal = first;
+ current = arch->archive_head;
+ last_elt = current; /* Last element arch seen. */
for (count = 0; count < orl_count; count++)
{
unsigned int offset;
@@ -2654,6 +2690,7 @@ coff_write_armap (bfd *arch,
unsigned int stringsize = stridx;
unsigned int mapsize = stringsize + ranlibsize;
file_ptr archive_member_file_ptr;
+ file_ptr first_archive_member_file_ptr;
bfd *current = arch->archive_head;
unsigned int count;
struct ar_hdr hdr;
@@ -2663,10 +2700,42 @@ coff_write_armap (bfd *arch,
mapsize++;
/* Work out where the first object file will go in the archive. */
- archive_member_file_ptr = (mapsize
- + elength
- + sizeof (struct ar_hdr)
- + SARMAG);
+ first_archive_member_file_ptr = (mapsize
+ + elength
+ + sizeof (struct ar_hdr)
+ + SARMAG);
+
+#ifdef BFD64
+ current = arch->archive_head;
+ count = 0;
+ archive_member_file_ptr = first_archive_member_file_ptr;
+ while (current != NULL && count < symbol_count)
+ {
+ /* For each symbol which is used defined in this object, write
+ out the object file's address in the archive. */
+
+ while (count < symbol_count && map[count].u.abfd == current)
+ {
+ unsigned int offset = (unsigned int) archive_member_file_ptr;
+
+ /* Generate 64-bit archive if an archive is past its 4Gb
+ limit. */
+ if (archive_member_file_ptr != (file_ptr) offset)
+ return _bfd_archive_64_bit_write_armap (arch, elength, map,
+ symbol_count, stridx);
+ count++;
+ }
+ archive_member_file_ptr += sizeof (struct ar_hdr);
+ if (! bfd_is_thin_archive (arch))
+ {
+ /* Add size of this archive entry. */
+ archive_member_file_ptr += arelt_size (current);
+ /* Remember about the even alignment. */
+ archive_member_file_ptr += archive_member_file_ptr % 2;
+ }
+ current = current->archive_next;
+ }
+#endif
memset (&hdr, ' ', sizeof (struct ar_hdr));
hdr.ar_name[0] = '/';
@@ -2697,6 +2766,7 @@ coff_write_armap (bfd *arch,
current = arch->archive_head;
count = 0;
+ archive_member_file_ptr = first_archive_member_file_ptr;
while (current != NULL && count < symbol_count)
{
/* For each symbol which is used defined in this object, write