* asranlib/asranlib.c, link/lkar.h, link/lkar.c:
authorborutr <borutr@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 5 Feb 2009 19:10:08 +0000 (19:10 +0000)
committerborutr <borutr@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 5 Feb 2009 19:10:08 +0000 (19:10 +0000)
  added support for BSD (Mac OS X) ar format

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5354 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
as/asranlib/asranlib.c
as/link/lkar.c
as/link/lkar.h

index dc2d8322a0d09c5c8b5ac31dbeb060f5375823b8..5891d3c4c00070ce5553b653797482ea96eab992 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-02-05 Borut Razem <borut.razem AT siol.net>
+
+       * asranlib/asranlib.c, link/lkar.h, link/lkar.c:
+         added support for BSD (Mac OS X) ar format
+
 2009-02-02 Borut Razem <borut.razem AT siol.net>
 
        * device/lib/gbz80/Makefile.in, device/lib/hc08/Makefile.in,
 2009-02-02 Borut Razem <borut.razem AT siol.net>
 
        * device/lib/gbz80/Makefile.in, device/lib/hc08/Makefile.in,
index e5449cfdf7490cb8c2e68b4b68b2169d6f57e3ce..ba92f7e17b4842d7bf663be3945df859ea148299 100644 (file)
@@ -5,7 +5,7 @@
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
 later version.
 
 This program is distributed in the hope that it will be useful,
 later version.
 
 This program is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -33,6 +32,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 #define NELEM(x)  (sizeof (x) / sizeof (*x))
 
 
 #define NELEM(x)  (sizeof (x) / sizeof (*x))
 
 
+int verbose = 0;
+int list = 0;
+int print_index = 0;
+
 int
 is_ar (FILE * libfp)
 {
 int
 is_ar (FILE * libfp)
 {
@@ -45,17 +48,139 @@ is_ar (FILE * libfp)
   return ret;
 }
 
   return ret;
 }
 
-static struct ar_hdr *
-ar_get_header (struct ar_hdr *hdr, FILE * libfp)
+static char *sym_tab;
+static int sym_tab_size;
+
+char *
+get_member_name (char *name, size_t *p_size, int allocate, FILE * libfp)
+{
+  *p_size = 0;
+
+  if (0 == memcmp (name, "#1/", 3))
+    {
+      char *p;
+      size_t len = strtoul (&name [3], &p, 10);
+      if (p > &name [3])
+        {
+          /* BSD appends real file name to the file header */
+          if (p_size != NULL)
+            *p_size = len;
+
+          if (allocate)
+            {
+              char *n = (char *) malloc (len);
+              if (fread (n, 1, len, libfp) != len)
+                {
+                  /* not an ar archive or broken ar archive */
+                  return NULL;
+                }
+              else
+                return n;
+            }
+          else
+            {
+              /* just advance the file pointer */
+              fseek (libfp, len, SEEK_CUR);
+              return NULL;
+            }
+        }
+      else
+        {
+          /* not an ar archive or broken ar archive */
+          return NULL;
+        }
+    }
+  else if (allocate)
+    {
+      if (name[0] == '/')
+        {
+          if (NULL != sym_tab)
+            {
+              char *p;
+
+              int name_offset = strtol (++name, &p, 0);
+              if (p != name && name_offset < sym_tab_size)
+                {
+                  int len = p - name + 1;
+                  while (len < AR_NAME_LEN && name[len++] == ' ')
+                    ;
+                  if (len == AR_NAME_LEN)
+                    {
+                      char *n;
+
+                      /* long name: get it from the symbol table */
+                      name = &sym_tab[name_offset];
+                      for (p = name; *p != '/' && *p != '\n'; ++p)
+                        assert (p < &sym_tab[sym_tab_size]);
+
+                      if (p[0] != '/' || p[1] != '\n')
+                        while (*++p != '\n')
+                          assert (p < &sym_tab[sym_tab_size]);
+
+                      n = (char *) malloc (p - name + 1);
+                      memcpy (n, name, p - name);
+                      n[p - name] = '\0';
+                      return n;
+                    }
+                }
+            }
+        }
+      else
+        {
+          char *p = strrchr (name, '/');
+
+          if (NULL != p)
+            {
+              int len = p - name;
+              while (name[++len] == ' ')
+                ;
+              if (len == AR_NAME_LEN)
+                {
+                  char *n = (char *) malloc (p - name + 1);
+                  memcpy (n, name, p - name);
+                  n[p - name] = '\0';
+                  return n;
+                }
+            }
+          else
+            {
+              /* BSD formed member name:
+                 trim trailing spaces */
+              char *n;
+
+              p = name + AR_NAME_LEN;
+              while (*--p == ' ' && p >= name)
+                ;
+              ++p;
+              n = (char *) malloc (p - name + 1);
+              memcpy (n, name, p - name);
+              n[p - name] = '\0';
+              return n;
+            }
+        }
+
+      /* bad formed member name:
+       just return it */
+
+      return strdup (name);
+    }
+  else
+    return NULL;
+}
+
+size_t
+ar_get_header (struct ar_hdr *hdr, FILE * libfp, char **p_obj_name)
 {
   char header[ARHDR_LEN];
   char buf[AR_DATE_LEN + 1];
 {
   char header[ARHDR_LEN];
   char buf[AR_DATE_LEN + 1];
+  char *obj_name;
+  size_t size;
 
 
-  if (fread (header, 1, sizeof (header), libfp) != sizeof (header) ||
-      memcmp (header + AR_FMAG_OFFSET, ARFMAG, AR_FMAG_LEN) != 0)
+  if (fread (header, 1, sizeof (header), libfp) != sizeof (header)
+      || memcmp (header + AR_FMAG_OFFSET, ARFMAG, AR_FMAG_LEN) != 0)
     {
       /* not an ar archive */
     {
       /* not an ar archive */
-      return NULL;
+      return 0;
     }
 
   memcpy (hdr->ar_name, &header[AR_NAME_OFFSET], AR_NAME_LEN);
     }
 
   memcpy (hdr->ar_name, &header[AR_NAME_OFFSET], AR_NAME_LEN);
@@ -81,9 +206,26 @@ ar_get_header (struct ar_hdr *hdr, FILE * libfp)
   buf[AR_SIZE_LEN] = '\0';
   hdr->ar_size = strtol (buf, NULL, 0);
 
   buf[AR_SIZE_LEN] = '\0';
   hdr->ar_size = strtol (buf, NULL, 0);
 
-  return hdr;
+  obj_name = get_member_name (hdr->ar_name, &size, p_obj_name != NULL, libfp);
+
+  if (p_obj_name != NULL)
+    *p_obj_name = obj_name;
+
+  /* treat BSD appended real file name as a part of the header */
+  hdr->ar_size -= size;
+
+  return size + ARHDR_LEN;
 }
 
 }
 
+static char *
+get_member_name_by_offset (FILE * fp, long offset)
+{
+  struct ar_hdr hdr;
+  char *name;
+
+  fseek (fp, offset, SEEK_SET);
+  return (ar_get_header (&hdr, fp, &name) != 0) ? name : NULL;
+}
 
 struct symbol_s
   {
 
 struct symbol_s
   {
@@ -103,6 +245,9 @@ add_symbol (const char *sym, void *param)
   if ((s = (struct symbol_s *) malloc (sizeof (struct symbol_s))) == NULL)
     return 0;
 
   if ((s = (struct symbol_s *) malloc (sizeof (struct symbol_s))) == NULL)
     return 0;
 
+  if (verbose)
+    printf ("%s\n", sym);
+
   s->name = strdup (sym);
   s->offset = offset - first_member_offset;
   s->next = NULL;
   s->name = strdup (sym);
   s->offset = offset - first_member_offset;
   s->next = NULL;
@@ -212,21 +357,152 @@ enum_symbols (FILE * fp, long size, int (*func) (const char *sym, void *param),
   return 0;
 }
 
   return 0;
 }
 
+
+static int
+process_symbol_table (struct ar_hdr *hdr, FILE *fp)
+{
+  if (print_index)
+    {
+      char *buf, *po, *ps;
+      int i;
+      long nsym;
+      long pos;
+
+      printf ("Archive index:\n");
+
+      buf = (char *) malloc (hdr->ar_size);
+
+      if (fread (buf, 1, hdr->ar_size, fp) != hdr->ar_size)
+        {
+          free (buf);
+          return 0;
+        }
+
+      pos = ftell (fp);
+
+      nsym = sgetl (buf);
+
+      po = buf + 4;
+      ps = po + nsym * 4;
+
+      for (i = 0; i < nsym; ++i)
+        {
+          char *obj;
+
+          offset = sgetl (po);
+          po += 4;
+
+          printf ("%s in ", ps);
+          ps += strlen(ps) + 1;
+
+          obj = get_member_name_by_offset (fp, offset);  /* member name */
+          printf ("%s\n", obj);
+          free (obj);
+
+        }
+      free (buf);
+
+      fseek (fp, pos, SEEK_SET);
+
+      putchar ('\n');
+    }
+  else
+    {
+      /* skip the symbol table */
+      fseek (fp, hdr->ar_size + (hdr->ar_size & 1), SEEK_CUR);
+    }
+
+  return 1;
+}
+
+static int
+process_bsd_symbol_table (struct ar_hdr *hdr, FILE *fp)
+{
+  if (print_index)
+    {
+      char *buf, *po, *ps;
+      int i;
+      long tablesize;
+      long nsym;
+      long pos;
+
+      printf ("Archive index:\n");
+
+      buf = (char *) malloc (hdr->ar_size);
+
+      if (fread (buf, 1, hdr->ar_size, fp) != hdr->ar_size)
+        {
+          free (buf);
+          return 0;
+        }
+
+      pos = ftell (fp);
+
+      tablesize = sgetl (buf);
+      nsym = tablesize / 8;
+
+      po = buf + 4;
+
+      ps = po + tablesize + 4;
+
+      for (i = 0; i < nsym; ++i)
+        {
+          char *obj;
+          long sym;
+
+          sym = sgetl (po);
+          po += 4;
+          offset = sgetl (po);
+          po += 4;
+
+          printf ("%s in ", ps + sym);
+
+          obj = get_member_name_by_offset (fp, offset);  /* member name */
+          printf ("%s\n", obj);
+          free (obj);
+        }
+      free (buf);
+
+      fseek (fp, pos, SEEK_SET);
+
+      putchar ('\n');
+    }
+  else
+    {
+      /* skip the symbol table */
+      fseek (fp, hdr->ar_size + (hdr->ar_size & 1), SEEK_CUR);
+    }
+
+  return 1;
+}
+
 int
 get_symbols (FILE * fp, const char *archive)
 {
   struct ar_hdr hdr;
 int
 get_symbols (FILE * fp, const char *archive)
 {
   struct ar_hdr hdr;
+  char *name;
 
 
-  if (!is_ar (fp) || !ar_get_header (&hdr, fp))
+  if (!is_ar (fp) || !ar_get_header (&hdr, fp, &name))
     {
       fprintf (stderr, "asranlib: %s: File format not recognized\n", archive);
       exit (1);
     }
 
     {
       fprintf (stderr, "asranlib: %s: File format not recognized\n", archive);
       exit (1);
     }
 
-  if (AR_IS_SYMBOL_TABLE (hdr))
+  if (AR_IS_SYMBOL_TABLE (name))
     {
     {
-      /* skip the symbol table */
-      fseek (fp, hdr.ar_size + (hdr.ar_size & 1), SEEK_CUR);
+      free (name);
+
+      process_symbol_table (&hdr, fp);
+      if (!ar_get_header (&hdr, fp, (verbose || list) ? &name : NULL))
+        return 1;
+    }
+  else if (AR_IS_BSD_SYMBOL_TABLE (name))
+    {
+      free (name);
+
+      process_bsd_symbol_table (&hdr, fp);
+      if (!ar_get_header (&hdr, fp, (verbose || list) ? &name : NULL))
+        return 1;
     }
 
   first_member_offset = ftell (fp) - ARHDR_LEN;
     }
 
   first_member_offset = ftell (fp) - ARHDR_LEN;
@@ -236,32 +512,49 @@ get_symbols (FILE * fp, const char *archive)
     {
       if (is_rel (fp))
         {
     {
       if (is_rel (fp))
         {
-          long mdule_offset = ftell (fp);
+          if (verbose || list)
+            {
+              printf ("%s%s\n", name, verbose ? ":" : "");
+              free (name);
+            }
 
 
-          offset = mdule_offset - ARHDR_LEN;
+          if (!list)
+            {
+              long mdule_offset = ftell (fp);
 
 
-          enum_symbols (fp, hdr.ar_size, add_symbol, NULL);
+              offset = mdule_offset - ARHDR_LEN;
 
 
-          fseek (fp, mdule_offset + hdr.ar_size, SEEK_SET);
+              enum_symbols (fp, hdr.ar_size, add_symbol, NULL);
 
 
-          if (hdr.ar_size & 1)
-            {
-              int c = getc (fp);
-              assert (c == EOF || c == '\n');
+              fseek (fp, mdule_offset + hdr.ar_size, SEEK_SET);
+
+              if (hdr.ar_size & 1)
+                {
+                  int c = getc (fp);
+                  assert (c == EOF || c == '\n');
+                }
             }
             }
+
+          if (verbose)
+            putchar ('\n');
         }
       else
         {
         }
       else
         {
+          if (verbose || list)
+            {
+              fprintf (stderr, "asranlib: %s: File format not recognized\n", name);
+              free (name);
+            }
+
           /* skip if the member is not a .REL format */
           fseek (fp, hdr.ar_size + (hdr.ar_size & 1), SEEK_CUR);
         }
     }
           /* skip if the member is not a .REL format */
           fseek (fp, hdr.ar_size + (hdr.ar_size & 1), SEEK_CUR);
         }
     }
-  while (ar_get_header (&hdr, fp));
+  while (ar_get_header (&hdr, fp, (verbose || list) ? &name : NULL));
 
   return 1;
 }
 
 
   return 1;
 }
 
-
 void
 do_ranlib (const char *archive)
 {
 void
 do_ranlib (const char *archive)
 {
@@ -276,25 +569,43 @@ do_ranlib (const char *archive)
 
   if (get_symbols (infp, archive))
     {
 
   if (get_symbols (infp, archive))
     {
-      FILE *outfp = NULL;
+      FILE *outfp;
       struct symbol_s *symp;
       char buf[4];
       struct symbol_s *symp;
       char buf[4];
-      int str_length = 0;
-      int pad = 0;
+      int str_length;
+      int pad;
       int nsym;
       int symtab_size;
       char tmpfile[] = "arXXXXXX";
 
       int nsym;
       int symtab_size;
       char tmpfile[] = "arXXXXXX";
 
-      if (NULL == mktemp (tmpfile) || NULL == (outfp = fopen (tmpfile, "wb")))
+#ifdef _WIN32
+      if (NULL == _mktemp (tmpfile) || NULL == (outfp = fopen (tmpfile, "wb")))
         {
           fclose (infp);
           fprintf (stderr, "asranlib: %s: ", tmpfile);
           perror (NULL);
           exit (1);
         }
         {
           fclose (infp);
           fprintf (stderr, "asranlib: %s: ", tmpfile);
           perror (NULL);
           exit (1);
         }
+#else
+      if ((pad = mkstemp (tmpfile)) < 0)
+        {
+          fclose (infp);
+          fprintf (stderr, "asranlib: %s: ", tmpfile);
+          perror (NULL);
+          exit (1);
+        }
+
+      if (NULL == (outfp = fdopen (pad, "wb")))
+        {
+          close (pad);
+          fclose (infp);
+          perror ("asranlib");
+          exit (1);
+        }
+#endif
 
       /* calculate the size of symbol table */
 
       /* calculate the size of symbol table */
-      for (nsym = 0, symp = symlist; symp; ++nsym, symp = symp->next)
+      for (str_length = 0, nsym = 0, symp = symlist; symp; ++nsym, symp = symp->next)
         {
           str_length += strlen (symp->name) + 1;
         }
         {
           str_length += strlen (symp->name) + 1;
         }
@@ -355,6 +666,11 @@ do_ranlib (const char *archive)
     fclose (infp);
 }
 
     fclose (infp);
 }
 
+void
+do_verbose (void)
+{
+  verbose = 1;
+}
 
 void
 print_version (void)
 
 void
 print_version (void)
@@ -363,35 +679,64 @@ print_version (void)
   exit (0);
 }
 
   exit (0);
 }
 
-
 void
 void
-usage (void)
+do_list (void)
 {
 {
-  printf ("Usage: asranlib [options] archive\n"
-    " Generate an index to speed access to archives\n"
-    " The options are:\n"
-    "  -h --help                    Print this help message\n"
-    "  -V --version                 Print version information\n"
-    "asranlib: supported targets: asxxxx\n");
+  list = 1;
+}
 
 
-  exit (1);
+void
+print_armap (void)
+{
+  print_index = 1;
 }
 
 }
 
+void usage (void);
 
 struct opt_s
   {
 
 struct opt_s
   {
-    const char *opt;
+    const char *short_opt;
+    const char *long_opt;
     void (*optfnc) (void);
     void (*optfnc) (void);
+    const char *comment;
   }
 opts[] =
   {
   }
 opts[] =
   {
-    { "-v", &print_version, },
-    { "-V", &print_version, },
-    { "--version", &print_version, },
-    { "-h", &usage, },
-    { "--help", &usage, },
+    { "-v", "--verbose", &do_verbose, "Be more verbose about the operation" },
+    { "-V", "--version", &print_version, "Print this help message" },
+    { "-h", "--help", &usage, "Print version information" },
+    { "-t", "--list", &do_list, "List the contents of an archive" },
+    { "-s", "--print-armap", &print_armap, "Print the archive index" },
   };
 
   };
 
+void
+usage (void)
+{
+  int i;
+
+  printf ("Usage: asranlib [options] archive\n"
+    " Generate an index to speed access to archives\n"
+    " The options are:\n");
+
+  for (i = 0; i < NELEM (opts); ++i)
+    {
+      int len = 3;
+      printf ("  %s ", (NULL != opts[i].short_opt) ? opts[i].short_opt : "  ");
+      if (NULL != opts[i].long_opt)
+        {
+          printf ("%s ", opts[i].long_opt);
+          len += strlen (opts[i].long_opt);
+        }
+
+      while (len++ < 32)
+        putchar (' ');
+      printf ("%s\n", opts[i].comment);
+    }
+
+  printf ("asranlib: supported targets: asxxxx\n");
+
+  exit (1);
+}
 
 void
 process_options (int argc, char *argv[])
 
 void
 process_options (int argc, char *argv[])
@@ -413,26 +758,28 @@ process_options (int argc, char *argv[])
 
           for (i = 0; i < NELEM (opts); ++i)
             {
 
           for (i = 0; i < NELEM (opts); ++i)
             {
-              if (0 == strcmp (*argp, opts[i].opt))
+              if (0 == strcmp (*argp, opts[i].short_opt) || 0 == strcmp (*argp, opts[i].long_opt))
                 {
                   if (NULL != opts[i].optfnc)
                     {
                       (*opts[i].optfnc) ();
                 {
                   if (NULL != opts[i].optfnc)
                     {
                       (*opts[i].optfnc) ();
-                      continue;
+                      break;
                     }
                 }
             }
         }
 
                     }
                 }
             }
         }
 
-      do_ranlib (*argp);
-      ++narch;
+      else
+        {
+          do_ranlib (*argp);
+          ++narch;
+        }
     }
 
   if (!narch)
     usage ();
 }
 
     }
 
   if (!narch)
     usage ();
 }
 
-
 int
 main (int argc, char *argv[])
 {
 int
 main (int argc, char *argv[])
 {
index b137ffde58a45394a69d9411f4418daf3f9abdc4..3334b29dcfe17c857d3d9c88dc63d4e0a2782151 100644 (file)
@@ -6,7 +6,7 @@
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
 later version.
 
 This program is distributed in the hope that it will be useful,
 later version.
 
 This program is distributed in the hope that it will be useful,
@@ -15,8 +15,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 /*
  * With contributions for the
 
 /*
  * With contributions for the
@@ -62,17 +61,139 @@ is_ar (FILE * libfp)
   return ret;
 }
 
   return ret;
 }
 
-static struct ar_hdr *
-ar_get_header (struct ar_hdr *hdr, FILE * libfp)
+static char *sym_tab;
+static int sym_tab_size;
+
+char *
+get_member_name (char *name, size_t *p_size, int allocate, FILE * libfp)
+{
+  *p_size = 0;
+
+  if (0 == memcmp (name, "#1/", 3))
+    {
+      char *p;
+      size_t len = strtoul (&name [3], &p, 10);
+      if (p > &name [3])
+        {
+          /* BSD appends real file name to the file header */
+          if (p_size != NULL)
+            *p_size = len;
+
+          if (allocate)
+            {
+              char *n = (char *) malloc (len);
+              if (fread (n, 1, len, libfp) != len)
+                {
+                  /* not an ar archive or broken ar archive */
+                  return NULL;
+                }
+              else
+                return n;
+            }
+          else
+            {
+              /* just advance the file pointer */
+              fseek (libfp, len, SEEK_CUR);
+              return NULL;
+            }
+        }
+      else
+        {
+          /* not an ar archive or broken ar archive */
+          return NULL;
+        }
+    }
+  else if (allocate)
+    {
+      if (name[0] == '/')
+        {
+          if (NULL != sym_tab)
+            {
+              char *p;
+
+              int name_offset = strtol (++name, &p, 0);
+              if (p != name && name_offset < sym_tab_size)
+                {
+                  int len = p - name + 1;
+                  while (len < AR_NAME_LEN && name[len++] == ' ')
+                    ;
+                  if (len == AR_NAME_LEN)
+                    {
+                      char *n;
+
+                      /* long name: get it from the symbol table */
+                      name = &sym_tab[name_offset];
+                      for (p = name; *p != '/' && *p != '\n'; ++p)
+                        assert (p < &sym_tab[sym_tab_size]);
+
+                      if (p[0] != '/' || p[1] != '\n')
+                        while (*++p != '\n')
+                          assert (p < &sym_tab[sym_tab_size]);
+
+                      n = (char *) malloc (p - name + 1);
+                      memcpy (n, name, p - name);
+                      n[p - name] = '\0';
+                      return n;
+                    }
+                }
+            }
+        }
+      else
+        {
+          char *p = strrchr (name, '/');
+
+          if (NULL != p)
+            {
+              int len = p - name;
+              while (name[++len] == ' ')
+                ;
+              if (len == AR_NAME_LEN)
+                {
+                  char *n = (char *) malloc (p - name + 1);
+                  memcpy (n, name, p - name);
+                  n[p - name] = '\0';
+                  return n;
+                }
+            }
+          else
+            {
+              /* BSD formed member name:
+                 trim trailing spaces */
+              char *n;
+
+              p = name + AR_NAME_LEN;
+              while (*--p == ' ' && p >= name)
+                ;
+              ++p;
+              n = (char *) malloc (p - name + 1);
+              memcpy (n, name, p - name);
+              n[p - name] = '\0';
+              return n;
+            }
+        }
+
+      /* bad formed member name:
+       just return it */
+
+      return strdup (name);
+    }
+  else
+    return NULL;
+}
+
+size_t
+ar_get_header (struct ar_hdr *hdr, FILE * libfp, char **p_obj_name)
 {
   char header[ARHDR_LEN];
   char buf[AR_DATE_LEN + 1];
 {
   char header[ARHDR_LEN];
   char buf[AR_DATE_LEN + 1];
+  char *obj_name;
+  size_t size;
 
   if (fread (header, 1, sizeof (header), libfp) != sizeof (header)
       || memcmp (header + AR_FMAG_OFFSET, ARFMAG, AR_FMAG_LEN) != 0)
     {
       /* not an ar archive */
 
   if (fread (header, 1, sizeof (header), libfp) != sizeof (header)
       || memcmp (header + AR_FMAG_OFFSET, ARFMAG, AR_FMAG_LEN) != 0)
     {
       /* not an ar archive */
-      return NULL;
+      return 0;
     }
 
   memcpy (hdr->ar_name, &header[AR_NAME_OFFSET], AR_NAME_LEN);
     }
 
   memcpy (hdr->ar_name, &header[AR_NAME_OFFSET], AR_NAME_LEN);
@@ -98,122 +219,26 @@ ar_get_header (struct ar_hdr *hdr, FILE * libfp)
   buf[AR_SIZE_LEN] = '\0';
   hdr->ar_size = strtol (buf, NULL, 0);
 
   buf[AR_SIZE_LEN] = '\0';
   hdr->ar_size = strtol (buf, NULL, 0);
 
-  return hdr;
-}
+  obj_name = get_member_name (hdr->ar_name, &size, p_obj_name != NULL, libfp);
 
 
-static char *sym_tab;
-static int sym_tab_size;
+  if (p_obj_name != NULL)
+    *p_obj_name = obj_name;
 
 
-static void
-loadfile_ar (struct lbfile *lbfh)
-{
-  FILE *fp;
+  /* treat BSD appended real file name as a part of the header */
+  hdr->ar_size -= size;
 
 
-#ifdef __CYGWIN__
-  char posix_path[PATH_MAX];
-  void cygwin_conv_to_full_posix_path (char *win_path, char *posix_path);
-  cygwin_conv_to_full_posix_path (lbfh->libspc, posix_path);
-  fp = fopen (posix_path, "rb");
-#else
-  fp = fopen (lbfh->libspc, "rb");
-#endif
-
-  if (fp != NULL)
-    {
-      struct ar_hdr hdr;
-
-      fseek (fp, lbfh->offset, SEEK_SET);
-      if (ar_get_header (&hdr, fp))
-        {
-          D ("Loading module %s from file %s.\n", hdr.ar_name, lbfh->libspc);
-          load_rel (fp, hdr.ar_size);
-          fclose (fp);
-        }
-      else
-        {
-          fprintf (stderr, "?ASlink-Error-Bad offset in library file %s(%s)\n", lbfh->libspc, lbfh->relfil);
-          fclose (fp);
-          lkexit (1);
-        }
-    }
-  else
-    {
-      fprintf (stderr, "?ASlink-Error-Opening library '%s'\n", lbfh->libspc);
-      lkexit (1);
-    }
+  return size + ARHDR_LEN;
 }
 
 #if INDEXLIB
 }
 
 #if INDEXLIB
-char *
-get_member_name (char *name)
-{
-  if (name[0] == '/')
-    {
-      if (NULL != sym_tab)
-        {
-          char *p;
-
-          int name_offset = strtol (++name, &p, 0);
-          if (p != name && name_offset < sym_tab_size)
-            {
-              int len = p - name + 1;
-              while (len < AR_NAME_LEN && name[len++] == ' ')
-                ;
-              if (len == AR_NAME_LEN)
-                {
-                  char *n;
-
-                  /* long name: get it from the symbol table */
-                  name = &sym_tab[name_offset];
-                  for (p = name; *p != '/' && *p != '\n'; ++p)
-                    assert (p < &sym_tab[sym_tab_size]);
-
-                  if (p[0] != '/' || p[1] != '\n')
-                    while (*++p != '\n')
-                      assert (p < &sym_tab[sym_tab_size]);
-
-                  n = (char *) malloc (p - name + 1);
-                  memcpy (n, name, p - name);
-                  n[p - name] = '\0';
-                  return n;
-                }
-            }
-        }
-    }
-  else
-    {
-      char *p = strrchr (name, '/');
-
-      if (NULL != p)
-        {
-          int len = p - name;
-          while (name[++len] == ' ')
-            ;
-          if (len == AR_NAME_LEN)
-            {
-              char *n = (char *) malloc (p - name + 1);
-              memcpy (n, name, p - name);
-              n[p - name] = '\0';
-              return n;
-            }
-        }
-    }
-
-  /* bad formed member name:
-     just return it */
-
-  return strdup (name);
-}
-
 static char *
 get_member_name_by_offset (FILE * fp, long offset)
 {
   struct ar_hdr hdr;
 static char *
 get_member_name_by_offset (FILE * fp, long offset)
 {
   struct ar_hdr hdr;
+  char *name;
 
   fseek (fp, offset, SEEK_SET);
 
   fseek (fp, offset, SEEK_SET);
-
-  /* walk trough all archive members */
-  return (NULL != ar_get_header (&hdr, fp)) ? get_member_name (hdr.ar_name) : NULL;
+  return (ar_get_header (&hdr, fp, &name) != 0) ? name : NULL;
 }
 
 static pmlibraryfile
 }
 
 static pmlibraryfile
@@ -221,6 +246,7 @@ find_member_by_offset (const char *libspc, long offset)
 {
   pmlibraryfile p;
 
 {
   pmlibraryfile p;
 
+  /* walk trough all archive members */
   for (p = libr; p; p = p->next)
     {
       if (0 == strcmp (libspc, p->libspc) && p->offset == offset)
   for (p = libr; p; p = p->next)
     {
       if (0 == strcmp (libspc, p->libspc) && p->offset == offset)
@@ -234,24 +260,31 @@ static pmlibraryfile
 buildlibraryindex_ar (struct lbname *lbnh, FILE * libfp, pmlibraryfile This, int type)
 {
   struct ar_hdr hdr;
 buildlibraryindex_ar (struct lbname *lbnh, FILE * libfp, pmlibraryfile This, int type)
 {
   struct ar_hdr hdr;
+  char *obj_name;
+  size_t hdr_size;
 
   /* walk trough all archive members */
 
   /* walk trough all archive members */
-  while (ar_get_header (&hdr, libfp))
+  while ((hdr_size = ar_get_header (&hdr, libfp, &obj_name)) != 0)
     {
     {
-      if (AR_IS_SYMBOL_TABLE (hdr))
+      if (AR_IS_SYMBOL_TABLE (obj_name))
         {
           char *buf, *po, *ps;
           int i;
           long nsym;
         {
           char *buf, *po, *ps;
           int i;
           long nsym;
+          long pos;
+
+          free (obj_name);
 
           buf = (char *) new (hdr.ar_size);
 
 
           buf = (char *) new (hdr.ar_size);
 
-          if ((off_t) fread (buf, 1, hdr.ar_size, libfp) != hdr.ar_size)
+          if (fread (buf, 1, hdr.ar_size, libfp) != hdr.ar_size)
             {
               free (buf);
               return This;
             }
 
             {
               free (buf);
               return This;
             }
 
+          pos = ftell (libfp);
+
           nsym = sgetl (buf);
 
           po = buf + 4;
           nsym = sgetl (buf);
 
           po = buf + 4;
@@ -268,8 +301,92 @@ buildlibraryindex_ar (struct lbname *lbnh, FILE * libfp, pmlibraryfile This, int
               po += 4;
 
               sym = strdup (ps);
               po += 4;
 
               sym = strdup (ps);
-              while (*ps++ != '\0')
-                ;
+              ps += strlen (ps) + 1;
+
+              if ((entry = find_member_by_offset (lbnh->libspc, offset)) != NULL)
+                {
+                  for (ThisSym = entry->symbols; ThisSym->next != NULL; ThisSym = ThisSym->next)
+                    ;
+                }
+              else
+                {
+                  /* Opened OK - create a new libraryfile object for it */
+                  if (This == NULL)
+                    {
+                      assert (libr == NULL);
+                      libr = This = (pmlibraryfile) new (sizeof (mlibraryfile));
+                    }
+                  else
+                    {
+                      This->next = (pmlibraryfile) new (sizeof (mlibraryfile));
+                      This = This->next;
+                    }
+                  This->next = NULL;
+                  This->loaded = 0;
+                  This->libspc = lbnh->libspc;
+                  This->offset = offset;
+                  This->relfil = get_member_name_by_offset (libfp, offset);     /* member name */
+                  This->filspc = strdup (This->relfil); /* member file name */
+                  This->type = type;
+
+                  /* start a new linked list of symbols for this module. */
+                  This->symbols = ThisSym = NULL;
+                }
+
+              if (ThisSym == NULL)
+                ThisSym = This->symbols = (pmlibrarysymbol) new (sizeof (mlibrarysymbol));
+              else
+                {
+                  ThisSym->next = (pmlibrarysymbol) new (sizeof (mlibrarysymbol));
+                  ThisSym = ThisSym->next;
+                }
+              ThisSym->next = NULL;
+              ThisSym->name = sym;
+            }
+          free (buf);
+
+          fseek (libfp, pos, SEEK_SET);
+          break;
+        }
+      else if (AR_IS_BSD_SYMBOL_TABLE (obj_name))
+        {
+          char *buf, *po, *ps;
+          int i;
+          long nsym, tablesize;
+          long pos;
+
+          free (obj_name);
+
+          buf = (char *) new (hdr.ar_size);
+
+          if (fread (buf, 1, hdr.ar_size, libfp) != hdr.ar_size)
+            {
+              free (buf);
+              return This;
+            }
+
+          pos = ftell (libfp);
+
+          tablesize = sgetl (buf);
+          nsym = tablesize / 8;
+
+          po = buf + 4;
+
+          ps = po + tablesize + 4;
+
+          for (i = 0; i < nsym; ++i)
+            {
+              pmlibrarysymbol ThisSym;
+              char *sym;
+              long offset;
+              pmlibraryfile entry;
+
+              sym = ps + sgetl (po);
+              po += 4;
+              offset = sgetl (po);
+              po += 4;
+
+              sym = strdup (ps);
 
               if ((entry = find_member_by_offset (lbnh->libspc, offset)) != NULL)
                 {
 
               if ((entry = find_member_by_offset (lbnh->libspc, offset)) != NULL)
                 {
@@ -313,16 +430,19 @@ buildlibraryindex_ar (struct lbname *lbnh, FILE * libfp, pmlibraryfile This, int
             }
           free (buf);
 
             }
           free (buf);
 
+          fseek (libfp, pos, SEEK_SET);
           break;
         }
           break;
         }
-      else if (AR_IS_STRING_TABLE (hdr))
+      else if (AR_IS_STRING_TABLE (obj_name))
         {
         {
+          free (obj_name);
+
           if (sym_tab)
             free (sym_tab);
 
           sym_tab = (char *) new (hdr.ar_size);
 
           if (sym_tab)
             free (sym_tab);
 
           sym_tab = (char *) new (hdr.ar_size);
 
-          if ((off_t) fread (sym_tab, 1, hdr.ar_size, libfp) != hdr.ar_size)
+          if (fread (sym_tab, 1, hdr.ar_size, libfp) != hdr.ar_size)
             {
               free (sym_tab);
               sym_tab_size = 0;
             {
               free (sym_tab);
               sym_tab_size = 0;
@@ -348,9 +468,9 @@ buildlibraryindex_ar (struct lbname *lbnh, FILE * libfp, pmlibraryfile This, int
           This->next = NULL;
           This->loaded = -1;
           This->libspc = lbnh->libspc;
           This->next = NULL;
           This->loaded = -1;
           This->libspc = lbnh->libspc;
-          This->offset = moduleOffset - ARHDR_LEN;
+          This->offset = moduleOffset - hdr_size;
 
 
-          This->relfil = get_member_name (hdr.ar_name); /* member name */
+          This->relfil = obj_name;              /* member name */
           This->filspc = strdup (This->relfil); /* member file name */
 
           D ("  Indexing module: %s\n", This->relfil);
           This->filspc = strdup (This->relfil); /* member file name */
 
           D ("  Indexing module: %s\n", This->relfil);
@@ -390,6 +510,8 @@ load_adb (FILE * libfp, struct lbfile *lbfh)
 {
   struct ar_hdr hdr;
   char *adb_name;
 {
   struct ar_hdr hdr;
   char *adb_name;
+  char *obj_name;
+  size_t hdr_size;
 
   /* check if it is a .rel file */
   if (0 != stricmp (&lbfh->relfil[strlen (lbfh->relfil) - 4], ".rel"))
 
   /* check if it is a .rel file */
   if (0 != stricmp (&lbfh->relfil[strlen (lbfh->relfil) - 4], ".rel"))
@@ -409,10 +531,12 @@ load_adb (FILE * libfp, struct lbfile *lbfh)
 
 
   /* walk trough all archive members */
 
 
   /* walk trough all archive members */
-  while (ar_get_header (&hdr, libfp))
+  while ((hdr_size = ar_get_header (&hdr, libfp, &obj_name)) != 0)
     {
     {
-      if (AR_IS_STRING_TABLE (hdr))
+      if (AR_IS_STRING_TABLE (obj_name))
         {
         {
+          free (obj_name);
+
           if (sym_tab)
             free (sym_tab);
 
           if (sym_tab)
             free (sym_tab);
 
@@ -426,8 +550,10 @@ load_adb (FILE * libfp, struct lbfile *lbfh)
             }
           sym_tab_size = hdr.ar_size;
         }
             }
           sym_tab_size = hdr.ar_size;
         }
-      if (AR_IS_SYMBOL_TABLE (hdr) || 0 != stricmp (get_member_name (hdr.ar_name), adb_name))
+      if (AR_IS_SYMBOL_TABLE (obj_name) || 0 != stricmp (obj_name, adb_name))
         {
         {
+          free (obj_name);
+
           /* skip the mamber */
           fseek (libfp, hdr.ar_size + (hdr.ar_size & 1), SEEK_CUR);
         }
           /* skip the mamber */
           fseek (libfp, hdr.ar_size + (hdr.ar_size & 1), SEEK_CUR);
         }
@@ -436,6 +562,8 @@ load_adb (FILE * libfp, struct lbfile *lbfh)
           long left = hdr.ar_size;
           char buf[4096];
 
           long left = hdr.ar_size;
           char buf[4096];
 
+          free (obj_name);
+
           while (left)
             {
               size_t n = min (left, sizeof buf);
           while (left)
             {
               size_t n = min (left, sizeof buf);
@@ -471,9 +599,10 @@ fndsym_ar (const char *name, struct lbname *lbnh, FILE * libfp, int type)
 {
   struct ar_hdr hdr;
   int ret = 0;
 {
   struct ar_hdr hdr;
   int ret = 0;
+  size_t hdr_size;
 
   /* walk trough all archive members */
 
   /* walk trough all archive members */
-  while (ar_get_header (&hdr, libfp))
+  while ((hdr_size = ar_get_header (&hdr, libfp, NULL)) != 0)
     {
       char filspc[PATH_MAX];
 
     {
       char filspc[PATH_MAX];
 
@@ -488,12 +617,14 @@ fndsym_ar (const char *name, struct lbname *lbnh, FILE * libfp, int type)
 #endif
         }
 
 #endif
         }
 
-      if (AR_IS_SYMBOL_TABLE (hdr))
+      if (AR_IS_SYMBOL_TABLE (obj_name))
         {
           char *buf, *po, *ps;
           int i;
           long nsym;
 
         {
           char *buf, *po, *ps;
           int i;
           long nsym;
 
+          free (obj_name);
+
           buf = (char *) new (hdr.ar_size);
 
           if ((off_t) fread (buf, 1, hdr.ar_size, libfp) != hdr.ar_size)
           buf = (char *) new (hdr.ar_size);
 
           if ((off_t) fread (buf, 1, hdr.ar_size, libfp) != hdr.ar_size)
@@ -574,7 +705,95 @@ fndsym_ar (const char *name, struct lbname *lbnh, FILE * libfp, int type)
 
           break;
         }
 
           break;
         }
-      else if (AR_IS_STRING_TABLE (hdr))
+      else if (AR_IS_BSD_SYMBOL_TABLE (obj_name))
+        {
+          char *buf, *po, *ps;
+          int i;
+          long nsym, tablesize;
+
+          free (obj_name);
+
+          buf = (char *) new (hdr.ar_size);
+
+          if ((off_t) fread (buf, 1, hdr.ar_size, libfp) != hdr.ar_size)
+            {
+              free (buf);
+              return 0;
+            }
+
+          tablesize = sgetl (buf);
+          nsym = tablesize / 8;
+
+          po = buf + 4;
+
+          ps = po + tablesize + 4;
+
+          for (i = 0; i < nsym; ++i)
+            {
+              char *sym;
+              long offset;
+
+              sym = ps + sgetl (po);
+              po += 4;
+              offset = sgetl (po);
+              po += 4;
+
+              if (0 == strcmp (name, sym))
+                {
+                  fseek (libfp, offset, SEEK_SET);
+                  if (ar_get_header (&hdr, libfp))
+                    {
+                      sprintf (&filspc[strlen (filspc)], "%s", hdr.ar_name);
+
+                      /* If this module has been loaded already don't load it again. */
+                      if (!is_module_loaded (filspc))
+                        {
+                          struct lbfile *lbfh, *lbf;
+
+                          lbfh = (struct lbfile *) new (sizeof (struct lbfile));
+                          lbfh->libspc = strdup (lbnh->libspc);
+                          lbfh->relfil = strdup (hdr.ar_name);
+                          lbfh->filspc = strdup (filspc);
+                          lbfh->offset = offset;
+                          lbfh->type = type;
+
+                          if (lbfhead == NULL)
+                            {
+                              lbfhead = lbfh;
+                            }
+                          else
+                            {
+                              for (lbf = lbfhead; lbf->next != NULL; lbf = lbf->next)
+                                ;
+
+                              lbf->next = lbfh;
+                            }
+
+                          D ("Loading module %s from file %s.\n", hdr.ar_name, lbfh->libspc);
+                          load_rel (libfp, hdr.ar_size);
+                          ///* if cdb information required & .adb file present */
+                          //if (dflag && dfp)
+                          //  {
+                          //    if (load_adb(FILE *libfp, struct lbfile *lbfh))
+                          //      SaveLinkedFilePath (filspc);
+                          //  }
+                          ret = 1;
+                          break;
+                        }
+                    }
+                  else
+                    {
+                      fprintf (stderr, "?ASlink-Error-Bad offset in library file %s(%s)\n", lbnh->libspc, name);
+                      fclose (libfp);
+                      lkexit (1);
+                    }
+                }
+            }
+          free (buf);
+
+          break;
+        }
+      else if (AR_IS_STRING_TABLE (obj_name))
         {
           if (sym_tab)
             free (sym_tab);
         {
           if (sym_tab)
             free (sym_tab);
@@ -599,7 +818,7 @@ fndsym_ar (const char *name, struct lbname *lbnh, FILE * libfp, int type)
           sprintf (&filspc[strlen (filspc)], "%s", hdr.ar_name);
 
           /* Opened OK - create a new libraryfile object for it */
           sprintf (&filspc[strlen (filspc)], "%s", hdr.ar_name);
 
           /* Opened OK - create a new libraryfile object for it */
-          ret = add_rel_file (name, lbnh, hdr.ar_name, filspc, moduleOffset - ARHDR_LEN, libfp, hdr.ar_size, type);
+          ret = add_rel_file (name, lbnh, hdr.ar_name, filspc, moduleOffset - hdr_size, libfp, hdr.ar_size, type);
           ///* if cdb information required & .adb file present */
           //if (dflag && dfp)
           //  {
           ///* if cdb information required & .adb file present */
           //if (dflag && dfp)
           //  {
@@ -630,6 +849,45 @@ fndsym_ar (const char *name, struct lbname *lbnh, FILE * libfp, int type)
 }
 #endif
 
 }
 #endif
 
+static void
+loadfile_ar (struct lbfile *lbfh)
+{
+  FILE *fp;
+
+#ifdef __CYGWIN__
+  char posix_path[PATH_MAX];
+  void cygwin_conv_to_full_posix_path (char *win_path, char *posix_path);
+  cygwin_conv_to_full_posix_path (lbfh->libspc, posix_path);
+  fp = fopen (posix_path, "rb");
+#else
+  fp = fopen (lbfh->libspc, "rb");
+#endif
+
+  if (fp != NULL)
+    {
+      struct ar_hdr hdr;
+
+      fseek (fp, lbfh->offset, SEEK_SET);
+      if (ar_get_header (&hdr, fp, NULL) != 0)
+        {
+          D ("Loading module %s from file %s.\n", hdr.ar_name, lbfh->libspc);
+          load_rel (fp, hdr.ar_size);
+          fclose (fp);
+        }
+      else
+        {
+          fprintf (stderr, "?ASlink-Error-Bad offset in library file %s(%s)\n", lbfh->libspc, lbfh->relfil);
+          fclose (fp);
+          lkexit (1);
+        }
+    }
+  else
+    {
+      fprintf (stderr, "?ASlink-Error-Opening library '%s'\n", lbfh->libspc);
+      lkexit (1);
+    }
+}
+
 struct aslib_target aslib_target_ar = {
   &is_ar,
 #ifdef INDEXLIB
 struct aslib_target aslib_target_ar = {
   &is_ar,
 #ifdef INDEXLIB
index 748c7f44a79e76b4e5a38d4d9dceb7015337b51b..af77754bfd2a66cc0bf07a6e20b776769abe679a 100644 (file)
@@ -4,7 +4,7 @@
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
 later version.
 
 This program is distributed in the hope that it will be useful,
 later version.
 
 This program is distributed in the hope that it will be useful,
@@ -13,8 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #ifndef __LKAR_H
 #define __LKAR_H
 
 #ifndef __LKAR_H
 #define __LKAR_H
@@ -61,11 +60,16 @@ typedef _off_t off_t;
 
 #define ARHDR_LEN (AR_NAME_LEN + AR_DATE_LEN + AR_UID_LEN + AR_GID_LEN + AR_MODE_LEN + AR_SIZE_LEN + AR_FMAG_LEN)
 
 
 #define ARHDR_LEN (AR_NAME_LEN + AR_DATE_LEN + AR_UID_LEN + AR_GID_LEN + AR_MODE_LEN + AR_SIZE_LEN + AR_FMAG_LEN)
 
-#define AR_SYMBOL_TABLE_NAME "/               "
-#define AR_STRING_TABLE_NAME "//              "
+#define AR_SYMBOL_TABLE_NAME            "/               "
+#define AR_STRING_TABLE_NAME            "//              "
 
 
-#define AR_IS_SYMBOL_TABLE(hdr) (0 == strcmp((hdr).ar_name, AR_SYMBOL_TABLE_NAME))
-#define AR_IS_STRING_TABLE(hdr) (0 == strcmp((hdr).ar_name, AR_STRING_TABLE_NAME))
+#define AR_BSD_SYMBOL_TABLE_NAME        "__.SYMDEF       "
+#define AR_BSD_SORTED_SYMBOL_TABLE_NAME "__.SYMDEF SORTED"
+
+#define AR_IS_SYMBOL_TABLE(name) (0 == strcmp((name), AR_SYMBOL_TABLE_NAME))
+#define AR_IS_STRING_TABLE(name) (0 == strcmp((name), AR_STRING_TABLE_NAME))
+
+#define AR_IS_BSD_SYMBOL_TABLE(name) (0 == strcmp((name), AR_BSD_SYMBOL_TABLE_NAME) || 0 == strcmp((name), AR_BSD_SORTED_SYMBOL_TABLE_NAME))
 
 
 struct ar_hdr                     /* archive member header */
 
 
 struct ar_hdr                     /* archive member header */