diff options
-rw-r--r-- | gas/ChangeLog | 7 | ||||
-rw-r--r-- | gas/config/tc-ppc.c | 48 | ||||
-rw-r--r-- | gas/config/tc-ppc.h | 5 |
3 files changed, 47 insertions, 13 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index e8b9b01..1771741 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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. diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index b73d30c..68f8764 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -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 */ diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index f05f8e7..b6dd640 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -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 */ |