aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2012-11-06 05:18:03 +0000
committerAlan Modra <amodra@gmail.com>2012-11-06 05:18:03 +0000
commita38a07e07c75f3d498fb9187a7924d159be6326c (patch)
tree7aade350a33eb2d73734332cbf7e52d57af4d37e /gas/config
parent53d8967a8594639334bfd928268e0857b2e72732 (diff)
downloadgdb-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.c37
-rw-r--r--gas/config/tc-ppc.h3
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)