* config/tc-ppc.c (ppc_elf_frob_symbol): Delete.
authorAlan Modra <amodra@gmail.com>
Thu, 11 Jul 2002 01:07:49 +0000 (01:07 +0000)
committerAlan Modra <amodra@gmail.com>
Thu, 11 Jul 2002 01:07:49 +0000 (01:07 +0000)
(ppc_frob_file_before_adjust): New function.
* config/tc-ppc.h (tc_frob_symbol): Don't define.
(ppc_elf_frob_symbol): Don't declare.
(tc_frob_file_before_adjust): Define.
(ppc_frob_file_before_adjust): Declare.

gas/ChangeLog
gas/config/tc-ppc.c
gas/config/tc-ppc.h

index e8b9b01b8388bd84d39f433e3ce24bf2c148da84..17717417b13ba21fcab9e15b84efc5b54eaeaa6f 100644 (file)
@@ -1,5 +1,12 @@
 2002-07-11  Alan Modra  <amodra@bigpond.net.au>
 
+       * config/tc-ppc.c (ppc_elf_frob_symbol): Delete.
+       (ppc_frob_file_before_adjust): New function.
+       * config/tc-ppc.h (tc_frob_symbol): Don't define.
+       (ppc_elf_frob_symbol): Don't declare.
+       (tc_frob_file_before_adjust): Define.
+       (ppc_frob_file_before_adjust): Declare.
+
        * config/tc-ppc.c (md_pseudo_table): Warning fix.
        (ppc_cpu): Make it unsigned long to agree with struct powerpc_opcode
        flags.
index b73d30cff51209371c9f6a43ccaef579c7b1c150..68f8764bf5fe1d820bbfbbc7faefcb6edd089c63 100644 (file)
@@ -1688,21 +1688,49 @@ ppc_elf_validate_fix (fixp, seg)
     }
 }
 
-/* Don't emit .TOC. symbol.  */
-int
-ppc_elf_frob_symbol (sym)
-     symbolS *sym;
+/* Prevent elf_frob_file_before_adjust removing a weak undefined
+   function descriptor sym if the corresponding code sym is used.  */
+
+void
+ppc_frob_file_before_adjust ()
 {
-  const char *name;
+  symbolS *symp;
+
+  if (!ppc_obj64)
+    return;
 
-  name = S_GET_NAME (sym);
-  if (name != NULL && strcmp (name, ".TOC.") == 0)
+  for (symp = symbol_rootP; symp; symp = symbol_next (symp))
     {
-      S_CLEAR_EXTERNAL (sym);
-      return 1;
+      const char *name;
+      char *dotname;
+      symbolS *dotsym;
+      size_t len;
+
+      name = S_GET_NAME (symp);
+      if (name[0] == '.')
+       continue;
+
+      if (! S_IS_WEAK (symp)
+         || S_IS_DEFINED (symp))
+       continue;
+
+      len = strlen (name) + 1;
+      dotname = xmalloc (len + 1);
+      dotname[0] = '.';
+      memcpy (dotname + 1, name, len);
+      dotsym = symbol_find (dotname);
+      free (dotname);
+      if (dotsym != NULL && (symbol_used_p (dotsym)
+                            || symbol_used_in_reloc_p (dotsym)))
+       {
+         symbol_mark_used (symp);
+       }
     }
 
-  return 0;
+  /* Don't emit .TOC. symbol.  */
+  symp = symbol_find (".TOC.");
+  if (symp != NULL)
+    symbol_remove (symp, &symbol_rootP, &symbol_lastP);
 }
 #endif /* OBJ_ELF */
 \f
index f05f8e7a08eb79fe871e3ea004b4e5303d7d661e..b6dd64065f1e5805b4f689e67bbf8deb138cd52a 100644 (file)
@@ -271,9 +271,8 @@ extern int ppc_fix_adjustable PARAMS ((struct fix *));
        && S_IS_DEFINED ((FIX)->fx_addsy) \
        && ! S_IS_COMMON ((FIX)->fx_addsy)))
 
-/* Finish up the symbol.  */
-#define tc_frob_symbol(sym, punt) punt = ppc_elf_frob_symbol (sym)
-extern int ppc_elf_frob_symbol PARAMS ((symbolS *));
+#define tc_frob_file_before_adjust ppc_frob_file_before_adjust
+extern void ppc_frob_file_before_adjust PARAMS ((void));
 
 #define DWARF2_LINE_MIN_INSN_LENGTH 4
 #endif /* OBJ_ELF */