Fix import symbols for AIX.
authorTom Rix <trix@redhat.com>
Thu, 6 Sep 2001 15:20:01 +0000 (15:20 +0000)
committerTom Rix <trix@redhat.com>
Thu, 6 Sep 2001 15:20:01 +0000 (15:20 +0000)
bfd/ChangeLog
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/libxcoff.h
bfd/xcofflink.c
include/coff/ChangeLog
include/coff/xcoff.h
ld/ChangeLog
ld/emultempl/aix.em

index ffc81da2cbcd22d2292f4e6a23454e10730e6524..8e056f938134693ef99bb76b97d68bc8f8b2847f 100644 (file)
@@ -1,3 +1,14 @@
+2001-09-05  Tom Rix <trix@redhat.com> 
+
+       * xcofflink.c (bfd_xcoff_import_symbol): Handle import file XMC_XO 
+       and syscall symbols.
+       (write_global_symbol) : Same.   
+       (bfd_xcoff_export_symbol): Remove unused syscall param.
+       * libxcoff.h: Change prototype of bfd_xcoff_export symbol and 
+       bfd_xcoff_import_symbol.
+       * bfd-in.h: Same.
+       * bfd-in2.h : Regenerate.
+
 2001-09-04  Richard Henderson  <rth@redhat.com>
 
        * elf64-alpha.c (SKIP_HOWTO): New.
index 6d4293ee982179c5ede1b20b35ee5c8abbb73a22..079761fc2795856978f1dab5b58d516e306b22a9 100644 (file)
@@ -722,10 +722,9 @@ extern boolean bfd_xcoff_link_record_set
           bfd_size_type));
 extern boolean bfd_xcoff_import_symbol
   PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
-          bfd_vma, const char *, const char *, const char *));
+          bfd_vma, const char *, const char *, const char *, unsigned int));
 extern boolean bfd_xcoff_export_symbol
-  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
-          boolean));
+  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *));
 extern boolean bfd_xcoff_link_count_reloc
   PARAMS ((bfd *, struct bfd_link_info *, const char *));
 extern boolean bfd_xcoff_record_link_assignment
index 148fcaa272f4d6c14d0989ab187b58c1f11ac5c5..b725dd42adba13e5c5ae789f68a585cdf813d802 100644 (file)
@@ -722,10 +722,9 @@ extern boolean bfd_xcoff_link_record_set
           bfd_size_type));
 extern boolean bfd_xcoff_import_symbol
   PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
-          bfd_vma, const char *, const char *, const char *));
+          bfd_vma, const char *, const char *, const char *, unsigned int));
 extern boolean bfd_xcoff_export_symbol
-  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
-          boolean));
+  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *));
 extern boolean bfd_xcoff_link_count_reloc
   PARAMS ((bfd *, struct bfd_link_info *, const char *));
 extern boolean bfd_xcoff_record_link_assignment
index 83a65924c64b2cb48c37080018fba58e6b087d35..cbc0bfca948025fad18ea2c988167e586c1dc4fe 100644 (file)
@@ -248,10 +248,9 @@ extern boolean bfd_xcoff_link_record_set
           bfd_size_type));
 extern boolean bfd_xcoff_import_symbol
   PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
-          bfd_vma, const char *, const char *, const char *));
+          bfd_vma, const char *, const char *, const char *, unsigned int));
 extern boolean bfd_xcoff_export_symbol
-  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
-          boolean));
+  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *));
 extern boolean bfd_xcoff_link_count_reloc
   PARAMS ((bfd *, struct bfd_link_info *, const char *));
 extern boolean bfd_xcoff_record_link_assignment
index ec4257c91b5ff0b702311d3a1b9638592b9c3106..6f70a32bd628d9fc9d01122b73d5e204654df2aa 100644 (file)
@@ -2514,7 +2514,7 @@ bfd_xcoff_link_record_set (output_bfd, info, harg, size)
 
 boolean
 bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile,
-                        impmember)
+                        impmember, syscall_flag)
      bfd *output_bfd;
      struct bfd_link_info *info;
      struct bfd_link_hash_entry *harg;
@@ -2522,6 +2522,7 @@ bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile,
      const char *imppath;
      const char *impfile;
      const char *impmember;
+     unsigned int syscall_flag;
 {
   struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
 
@@ -2564,7 +2565,7 @@ bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile,
        h = hds;
     }
 
-  h->flags |= XCOFF_IMPORT;
+  h->flags |= (XCOFF_IMPORT | syscall_flag);
 
   if (val != (bfd_vma) -1)
     {
@@ -2631,11 +2632,10 @@ bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile,
 /* Export a symbol.  */
 
 boolean
-bfd_xcoff_export_symbol (output_bfd, info, harg, syscall)
+bfd_xcoff_export_symbol (output_bfd, info, harg)
      bfd *output_bfd;
      struct bfd_link_info *info;
      struct bfd_link_hash_entry *harg;
-     boolean syscall ATTRIBUTE_UNUSED;
 {
   struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
 
@@ -5334,7 +5334,10 @@ xcoff_write_global_symbol (h, p)
     if (((h->flags & XCOFF_DEF_REGULAR) == 0 && 
         (h->flags & XCOFF_DEF_DYNAMIC) != 0) || 
        (h->flags & XCOFF_IMPORT) != 0) {
-      ldsym->l_smtype |= L_IMPORT;
+      /* Clear l_smtype 
+        Import symbols are defined so the check above will make the l_smtype
+        XTY_SD.  But this is not correct, it should be cleared. */
+      ldsym->l_smtype = L_IMPORT;
     }
 
     if (((h->flags & XCOFF_DEF_REGULAR) != 0 && 
@@ -5353,6 +5356,29 @@ xcoff_write_global_symbol (h, p)
 
     ldsym->l_smclas = h->smclas;
 
+    if (ldsym->l_smtype & L_IMPORT)
+      {
+       if ((h->root.type == bfd_link_hash_defined ||
+            h->root.type == bfd_link_hash_defweak) &&
+           (h->root.u.def.value != 0))
+         {
+           ldsym->l_smclas = XMC_XO;
+         }
+       else if ((h->flags & (XCOFF_SYSCALL32 | XCOFF_SYSCALL64)) ==
+                (XCOFF_SYSCALL32 | XCOFF_SYSCALL64))
+         {
+           ldsym->l_smclas = XMC_SV3264;
+         }
+       else if (h->flags & XCOFF_SYSCALL32) 
+         {
+           ldsym->l_smclas = XMC_SV;
+         }
+       else if (h->flags & XCOFF_SYSCALL64) 
+         {
+           ldsym->l_smclas = XMC_SV64;
+         }
+      }
+       
     if (ldsym->l_ifile == (bfd_size_type) -1) {
       ldsym->l_ifile = 0;
 
index 498cb265b81362789793396a539331d6c8898a20..6577b5b6798662be1a60d24730c7b4be70681362 100644 (file)
@@ -1,3 +1,7 @@
+2001-09-05  Tom Rix <trix@redhat.com>
+
+       * xcoff.h : Add XCOFF_SYSCALL32 and XCOFF_SYSCALL64 hash table flags.
+       
 2001-08-27  Andreas Jaeger  <aj@suse.de>
 
        * xcoff.h (struct __rtinit): Make proper prototype for rtl.
index 508ddfaa2146ac7b938aed7805ecf2aa47ff709a..b25c2945c5b26d7e277fd47e6bd95a7589e52c07 100644 (file)
 /*             14      ??? */
 #define        XMC_TC0 15              /* Read-write TOC anchor */
 #define XMC_TD 16              /* Read-write data in TOC */
+#define        XMC_SV64   17           /* Read-only 64 bit supervisor call */
+#define        XMC_SV3264 18           /* Read-only 32 or 64 bit supervisor call */
 
 /* The ldhdr structure.  This appears at the start of the .loader
    section.  */
@@ -305,6 +307,11 @@ struct xcoff_link_hash_entry
  * XCOFF_RTINIT 
  * Symbol is the __rtinit symbol 
  *
+ * XCOFF_SYSCALL32 
+ * Symbol is an imported 32 bit syscall
+ * 
+ * XCOFF_SYSCALL64 
+ * Symbol is an imported 64 bit syscall
  */
 
 #define XCOFF_REF_REGULAR      0x00000001
@@ -322,7 +329,8 @@ struct xcoff_link_hash_entry
 #define XCOFF_DESCRIPTOR       0x00001000
 #define XCOFF_MULTIPLY_DEFINED 0x00002000
 #define XCOFF_RTINIT           0x00004000
-
+#define XCOFF_SYSCALL32        0x00008000
+#define XCOFF_SYSCALL64        0x00010000 
 
 /* The XCOFF linker hash table.  */
 
index 0c25d4dab6ac38d2b2f0604c533a0847d98571d4..78e4ec0771a0561bc6bc00c9c500156a33dff8e8 100644 (file)
@@ -3,6 +3,10 @@
        * ld.texinfo (Options, --stack): Correct default value for stack
        reserve.
 
+2001-09-05  Tom Rix <trix@redhat.com>
+
+       * emultempl/aix.em : Handle import file XMC_XO and syscall symbols.
+       
 2001-09-03  Andreas Jaeger  <aj@suse.de>
 
        * emultempl/beos.em: Declare prototypes for comparions functions,
index 3d1c018658060b04dc3078947a79cf3d1965f257..775a678a4b30a4b2a7d4ee49939dbd181d1f969e 100644 (file)
@@ -108,7 +108,6 @@ struct export_symbol_list
 {
   struct export_symbol_list *next;
   const char *name;
-  boolean syscall;
 };
 
 static struct export_symbol_list *export_symbols;
@@ -642,7 +641,7 @@ gld${EMULATION_NAME}_before_allocation ()
       h = bfd_link_hash_lookup (link_info.hash, el->name, false, false, false);
       if (h == NULL)
        einfo ("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n");
-      if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h, el->syscall))
+      if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h))
        einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n");
     }
 
@@ -842,8 +841,7 @@ static int change_symbol_mode (char *input)
   return 0;
 }
 
-
-static int is_syscall (char *input)
+static int is_syscall(char *input, unsigned int *flag)
 {
   /*
    * 1 : yes
@@ -852,45 +850,44 @@ static int is_syscall (char *input)
    */
   unsigned int bit;
   char *string;
-
-  char *syscall_string[] = {
-    "svc",          /* 0x01 */
-    "svc32",        /* 0x02 */
-    "svc3264",      /* 0x04 */
-    "svc64",        /* 0x08 */
-    "syscall",      /* 0x10 */
-    "syscall32",     /* 0x20 */
-    "syscall3264",   /* 0x40 */
-    "syscall64",     /* 0x80 */
-    NULL
+  
+  struct sc {
+    char *syscall_string;
+    unsigned int flag;
+  } s [] = {
+    { "svc"        /* 0x01 */, XCOFF_SYSCALL32 },
+    { "svc32"      /* 0x02 */, XCOFF_SYSCALL32 },
+    { "svc3264"     /* 0x04 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
+    { "svc64"      /* 0x08 */, XCOFF_SYSCALL64 },
+    { "syscall"     /* 0x10 */, XCOFF_SYSCALL32 },
+    { "syscall32"   /* 0x20 */, XCOFF_SYSCALL32 },
+    { "syscall3264" /* 0x40 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 },
+    { "syscall64"   /* 0x80 */, XCOFF_SYSCALL64 },
+    { NULL, 0 },
   };
 
-  for (bit = 0; ;bit++)
-    {
+  *flag = 0;
 
-      string = syscall_string[bit];
-      if (NULL == string)
-       {
-         return -1;
-       }
+  for (bit = 0; ;bit++) {
+    
+    string = s[bit].syscall_string;
+    if (NULL == string) {
+      return -1;
+    }
 
-      if (0 == strcmp (input, string))
-       {
-         if (1 << bit & ${SYSCALL_MASK})
-           {
-             return 1;
-           }
-         else
-           {
-             return 0;
-           }
-       }
+    if (0 == strcmp(input, string)) {
+      if (1 << bit & ${SYSCALL_MASK}) {
+       *flag = s[bit].flag;
+       return 1;
+      } else {
+       return 0;
+      }
     }
+  }
   /* should not be here */
   return -1;
 }
 
-
 /* Read an import or export file.  For an import file, this is called
    by the before_allocation emulation routine.  For an export file,
    this is called by the parse_args emulation routine.  */
@@ -939,7 +936,7 @@ gld${EMULATION_NAME}_read_file (filename, import)
     {
       char *s;
       char *symname;
-      boolean syscall;
+      unsigned int syscall_flag = 0;
       bfd_vma address;
       struct bfd_link_hash_entry *h;
 
@@ -1042,7 +1039,7 @@ gld${EMULATION_NAME}_read_file (filename, import)
        {
          /* This is a symbol to be imported or exported.  */
          symname = s;
-         syscall = false;
+         syscall_flag = 0;
          address = (bfd_vma) -1;
 
          while (! isspace ((unsigned char) *s) && *s != '\0')
@@ -1074,29 +1071,21 @@ gld${EMULATION_NAME}_read_file (filename, import)
                  int status;
                  char *end;
 
-                 status = is_syscall (s);
-
-                 switch (status)
-                   {
-                   case 1:
-                     /* this is a system call */
-                     syscall = true;
-                     break;
-
-                   case 0:
-                     /* ignore this system call */
-                     break;
-
-                   default:
-                     /* not a system call, check for address */
-                     address = strtoul (s, &end, 0);
-                     if (*end != '\0')
-                       {
-                         einfo ("%s:%d: warning: syntax error in import/export file\n",
-                                filename, lineno);
-
-                       }
-                   }
+                 status = is_syscall(s, &syscall_flag);
+             
+                 if (0 > status) {
+                   /* not a system call, check for address */
+                   address = strtoul (s, &end, 0);
+
+                   /* not a system call, check for address */
+                   address = strtoul (s, &end, 0);
+                   if (*end != '\0')
+                     {
+                       einfo ("%s:%d: warning: syntax error in import/export file\n",
+                              filename, lineno);
+                       
+                     }
+                 }
                }
            }
 
@@ -1109,7 +1098,6 @@ gld${EMULATION_NAME}_read_file (filename, import)
                   xmalloc (sizeof (struct export_symbol_list)));
              n->next = export_symbols;
              n->name = xstrdup (symname);
-             n->syscall = syscall;
              export_symbols = n;
            }
          else
@@ -1125,7 +1113,7 @@ gld${EMULATION_NAME}_read_file (filename, import)
                {
                  if (! bfd_xcoff_import_symbol (output_bfd, &link_info, h,
                                                 address, imppath, impfile,
-                                                impmember))
+                                                impmember, syscall_flag))
                    einfo ("%X%s:%d: failed to import symbol %s: %E\n",
                           filename, lineno, symname);
                }