This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

ar, ranlib support for aix 4.3.3 & 64-bit objects



This patch adds support to BFD for writing the 64-bit symbol table for
aix 4.3.3.  AIX puts two symbol tables in its archive files, one for
symbols of 32-bit objects and one for 64-bit.

Although it's possible to not write one of the symbol tables if it
would be empty, we always write both.

-- 
- Geoffrey Keating <geoffk@cygnus.com>

===File ~/patches/cygnus/rs6000-binu-wrsymtab.patch=========
2000-07-13  Geoffrey Keating  <geoffk@cygnus.com>

	* coff-rs6000.c (xcoff_write_one_armap_big): New procedure.
	(xcoff_write_armap_big): Write both 32-bit and 64-bit armaps.
	(xcoff_write_archive_contents_big): Don't update the offset
	of the symbol table, xcoff_write_armap will do it.

Index: coff-rs6000.c
===================================================================
RCS file: /cvs/cvsfiles/devo/bfd/coff-rs6000.c,v
retrieving revision 1.65.16.5
retrieving revision 1.65.16.6
diff -u -p -r1.65.16.5 -r1.65.16.6
--- coff-rs6000.c	2000/05/16 16:18:57	1.65.16.5
+++ coff-rs6000.c	2000/07/13 09:50:08	1.65.16.6
@@ -1553,29 +1553,39 @@ xcoff_write_armap_old (abfd, elength, ma
   return true;
 }
 
-/*ARGSUSED*/
+/* Write a single armap in the big format.  */
 static boolean
-xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
+xcoff_write_one_armap_big (abfd, map, orl_count, orl_ccount, stridx, bits64,
+			   prevoff, nextoff)
      bfd *abfd;
-     unsigned int elength ATTRIBUTE_UNUSED;
      struct orl *map;
      unsigned int orl_count;
-     int stridx;
+     unsigned int orl_ccount;
+     unsigned int stridx;
+     int bits64;
+     const char *prevoff;
+     char *nextoff;
 {
   struct xcoff_ar_hdr_big hdr;
   char *p;
   unsigned char buf[4];
   bfd *sub;
   file_ptr fileoff;
+  const bfd_arch_info_type *arch_info;
+  bfd *object_bfd;
   unsigned int i;
 
   memset (&hdr, 0, sizeof hdr);
   /* XXX This call actually should use %lld (at least on 32-bit
      machines) since the fields's width is 20 and there numbers with
      more than 32 bits can be represented.  */
-  sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
-  sprintf (hdr.nextoff, "%d", 0);
-  memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, 12);
+  sprintf (hdr.size, "%ld", (long) (4 + orl_ccount * 4 + stridx));
+  if (bits64)
+    sprintf (hdr.nextoff, "%d", 0);
+  else
+    sprintf (hdr.nextoff, "%d", (strtol (prevoff, (char **) NULL, 10)
+				 + 4 + orl_ccount * 4 + stridx));
+  memcpy (hdr.prevoff, prevoff, sizeof (hdr.prevoff));
   sprintf (hdr.date, "%d", 0);
   sprintf (hdr.uid, "%d", 0);
   sprintf (hdr.gid, "%d", 0);
@@ -1587,11 +1597,13 @@ xcoff_write_armap_big (abfd, elength, ma
     if (*p == '\0')
       *p = ' ';
 
+  memcpy (nextoff, hdr.nextoff, sizeof (hdr.nextoff));
+
   if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR_BIG, 1, abfd) != SIZEOF_AR_HDR_BIG
       || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG)
     return false;
 
-  bfd_h_put_32 (abfd, orl_count, buf);
+  bfd_h_put_32 (abfd, orl_ccount, buf);
   if (bfd_write (buf, 1, 4, abfd) != 4)
     return false;
 
@@ -1602,13 +1614,18 @@ xcoff_write_armap_big (abfd, elength, ma
     {
       size_t namlen;
 
-      while (((bfd *) (map[i]).pos) == sub)
-	{
-	  bfd_h_put_32 (abfd, fileoff, buf);
-	  if (bfd_write (buf, 1, 4, abfd) != 4)
-	    return false;
-	  ++i;
-	}
+      if ((bfd_arch_bits_per_address ((bfd *) map[i].pos) == 64) == bits64)
+	while (((bfd *) (map[i]).pos) == sub)
+	  {
+	    bfd_h_put_32 (abfd, fileoff, buf);
+	    if (bfd_write (buf, 1, 4, abfd) != 4)
+	      return false;
+	    i++;
+	  }
+      else
+	while (((bfd *) (map[i]).pos) == sub)
+	  i++;
+
       namlen = strlen (normalize_filename (sub));
       namlen = (namlen + 1) &~ 1;
       fileoff += (SIZEOF_AR_HDR_BIG
@@ -1619,11 +1636,18 @@ xcoff_write_armap_big (abfd, elength, ma
       sub = sub->next;
     }
 
+  object_bfd = NULL;
   for (i = 0; i < orl_count; i++)
     {
       const char *name;
       size_t namlen;
+      bfd *ob = (bfd *)map[i].pos;
 
+      if (ob != object_bfd)
+	arch_info = bfd_get_arch_info (ob);
+      if ((arch_info->bits_per_address == 64) != bits64)
+	continue;
+
       name = *map[i].name;
       namlen = strlen (name);
       if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1)
@@ -1643,6 +1667,66 @@ xcoff_write_armap_big (abfd, elength, ma
 }
 
 /*ARGSUSED*/
+static boolean
+xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
+     bfd *abfd;
+     unsigned int elength ATTRIBUTE_UNUSED;
+     struct orl *map;
+     unsigned int orl_count;
+     int stridx;
+{
+  unsigned int i;
+  unsigned int orl_count_32, orl_count_64;
+  unsigned int stridx_32, stridx_64;
+  const bfd_arch_info_type *arch_info;
+  bfd *object_bfd;
+
+  /* First, we look through the symbols and work out which are
+     from 32-bit objects and which from 64-bit ones.  */
+  orl_count_32 = 0;
+  orl_count_64 = 0;
+  stridx_32 = 0;
+  stridx_64 = 0;
+  object_bfd = NULL;
+  for (i = 0; i < orl_count; i++)
+    {
+      bfd *ob = (bfd *)map[i].pos;
+      unsigned int len;
+      if (ob != object_bfd)
+	arch_info = bfd_get_arch_info (ob);
+      len = strlen (*map[i].name) + 1;
+      if (arch_info->bits_per_address == 64)
+	{
+	  orl_count_64++;
+	  stridx_64 += len;
+	}
+      else
+	{
+	  orl_count_32++;
+	  stridx_32 += len;
+	}
+      object_bfd = ob;
+    }
+  /* A quick sanity check... */
+  BFD_ASSERT (orl_count_64 + orl_count_32 == orl_count);
+  BFD_ASSERT (stridx_64 + stridx_32 == stridx);
+
+  /* Now write out each map.  */
+  if (! xcoff_write_one_armap_big (abfd, map, orl_count, orl_count_32,
+				   stridx_32, false, 
+				   xcoff_ardata_big (abfd)->memoff,
+				   xcoff_ardata_big (abfd)->symoff))
+    return false;
+  if (! xcoff_write_one_armap_big (abfd, map, orl_count, orl_count_64,
+				   stridx_64, true,
+				   xcoff_ardata_big (abfd)->symoff,
+				   xcoff_ardata_big (abfd)->symoff64))
+    return false;
+    
+  return true;
+}
+
+/*ARGSUSED*/
 boolean
 _bfd_xcoff_write_armap (abfd, elength, map, orl_count, stridx)
      bfd *abfd;
@@ -2153,7 +2237,6 @@ xcoff_write_archive_contents_big (abfd)
       /* XXX This call actually should use %lld (at least on 32-bit
 	 machines) since the fields's width is 20 and there numbers with
 	 more than 32 bits can be represented.  */
-      sprintf (fhdr.symoff, "%ld", (long) nextoff);
       bfd_ardata (abfd)->tdata = (PTR) &fhdr;
       if (! _bfd_compute_and_write_armap (abfd, 0))
 	return false;
============================================================

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]