diff options
author | Alan Modra <amodra@gmail.com> | 2012-11-06 05:18:03 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2012-11-06 05:18:03 +0000 |
commit | a38a07e07c75f3d498fb9187a7924d159be6326c (patch) | |
tree | 7aade350a33eb2d73734332cbf7e52d57af4d37e /gas/config | |
parent | 53d8967a8594639334bfd928268e0857b2e72732 (diff) | |
download | gdb-a38a07e07c75f3d498fb9187a7924d159be6326c.zip gdb-a38a07e07c75f3d498fb9187a7924d159be6326c.tar.gz gdb-a38a07e07c75f3d498fb9187a7924d159be6326c.tar.bz2 |
bfd/
* elf64-ppc.c (struct ppc_link_hash_table): Add dot_toc_dot.
(ppc64_elf_size_stubs): Lookup ".TOC.".
(ppc64_elf_relocate_section): Resolve special symbol ".TOC.".
gas/
* config/tc-ppc.c (ppc_elf_adjust_symtab): New function, split out..
(ppc_frob_file_before_adjust): ..from here.
(md_apply_fix): Set BSF_KEEP on .TOC. if not @tocbase.
* config/tc-ppc.h (ppc_elf_adjust_symtab): Declare.
(tc_adjust_symtab): Define.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-ppc.c | 37 | ||||
-rw-r--r-- | gas/config/tc-ppc.h | 3 |
2 files changed, 35 insertions, 5 deletions
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index c72a863..1b12f57 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -2323,11 +2323,28 @@ ppc_frob_file_before_adjust (void) && toc_reloc_types != has_large_toc_reloc && bfd_section_size (stdoutput, toc) > 0x10000) as_warn (_("TOC section size exceeds 64k")); +} + +/* .TOC. used in an opd entry as .TOC.@tocbase doesn't need to be + emitted. Other uses of .TOC. will cause the symbol to be marked + with BSF_KEEP in md_apply_fix. */ - /* Don't emit .TOC. symbol. */ - symp = symbol_find (".TOC."); - if (symp != NULL) - symbol_remove (symp, &symbol_rootP, &symbol_lastP); +void +ppc_elf_adjust_symtab (void) +{ + if (ppc_obj64) + { + symbolS *symp; + symp = symbol_find (".TOC."); + if (symp != NULL) + { + asymbol *bsym = symbol_get_bfdsym (symp); + if ((bsym->flags & BSF_KEEP) == 0) + symbol_remove (symp, &symbol_rootP, &symbol_lastP); + else + S_SET_WEAK (symp); + } + } } #endif /* OBJ_ELF */ @@ -6850,7 +6867,17 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) then the section contents are immaterial, so don't warn if they happen to overflow. Leave such warnings to ld. */ if (!fixP->fx_done) - fixP->fx_no_overflow = 1; + { + fixP->fx_no_overflow = 1; + + /* Arrange to emit .TOC. as a normal symbol if used in anything + but .TOC.@tocbase. */ + if (ppc_obj64 + && fixP->fx_r_type != BFD_RELOC_PPC64_TOC + && fixP->fx_addsy != NULL + && strcmp (S_GET_NAME (fixP->fx_addsy), ".TOC.") == 0) + symbol_get_bfdsym (fixP->fx_addsy)->flags |= BSF_KEEP; + } #else if (fixP->fx_r_type != BFD_RELOC_PPC_TOC16) fixP->fx_addnumber = 0; diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index e053c9c..3dd3f81 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -235,6 +235,9 @@ extern int ppc_fix_adjustable (struct fix *); #define tc_frob_file_before_adjust ppc_frob_file_before_adjust extern void ppc_frob_file_before_adjust (void); +#define tc_adjust_symtab() ppc_elf_adjust_symtab () +extern void ppc_elf_adjust_symtab (void); + #endif /* OBJ_ELF */ #if defined (OBJ_ELF) || defined (OBJ_XCOFF) |