aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorIain Sandoe <iain@codesourcery.com>2012-02-21 13:39:37 +0000
committerIain Sandoe <iain@codesourcery.com>2012-02-21 13:39:37 +0000
commit16a87420985f256b5cde070586ebcdfda2225b01 (patch)
tree8d56cb791213e8329675be59b24b693bfbb4aea6 /gas/config
parent025682772a5d4ce0877e3bcbb63086c1883c7211 (diff)
downloadgdb-16a87420985f256b5cde070586ebcdfda2225b01.zip
gdb-16a87420985f256b5cde070586ebcdfda2225b01.tar.gz
gdb-16a87420985f256b5cde070586ebcdfda2225b01.tar.bz2
provide a hook to allow checking errors just before we output the file.
gas: * write.c (write_object_file): Add md_pre_output_hook. * config/obj-macho.c (obj_mach_o_check_before_writing): New. (obj_mach_o_pre_output_hook): New. * config/obj-macho.h (md_pre_output_hook): Define. (obj_mach_o_pre_output_hook): Declare.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/obj-macho.c66
-rw-r--r--gas/config/obj-macho.h3
2 files changed, 69 insertions, 0 deletions
diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c
index 376e620..21281a0 100644
--- a/gas/config/obj-macho.c
+++ b/gas/config/obj-macho.c
@@ -1554,6 +1554,72 @@ obj_mach_o_process_stab (int what, const char *string,
/* It's a debug symbol. */
s->symbol.flags |= BSF_DEBUGGING;
+
+ /* We've set it - so check it, if you can, but don't try to create the
+ flags. */
+ s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED;
+}
+
+/* This is a place to check for any errors that we can't detect until we know
+ what remains undefined at the end of assembly. */
+
+static void
+obj_mach_o_check_before_writing (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ void *unused ATTRIBUTE_UNUSED)
+{
+ fixS *fixP;
+ struct frchain *frchp;
+ segment_info_type *seginfo = seg_info (sec);
+
+ if (seginfo == NULL)
+ return;
+
+ /* We are not allowed subtractions where either of the operands is
+ undefined. So look through the frags for any fixes to check. */
+ for (frchp = seginfo->frchainP; frchp != NULL; frchp = frchp->frch_next)
+ for (fixP = frchp->fix_root; fixP != NULL; fixP = fixP->fx_next)
+ {
+ if (fixP->fx_addsy != NULL
+ && fixP->fx_subsy != NULL
+ && (! S_IS_DEFINED (fixP->fx_addsy)
+ || ! S_IS_DEFINED (fixP->fx_subsy)))
+ {
+ segT add_symbol_segment = S_GET_SEGMENT (fixP->fx_addsy);
+ segT sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy);
+
+ if (! S_IS_DEFINED (fixP->fx_addsy)
+ && S_IS_DEFINED (fixP->fx_subsy))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("`%s' can't be undefined in `%s' - `%s' {%s section}"),
+ S_GET_NAME (fixP->fx_addsy), S_GET_NAME (fixP->fx_addsy),
+ S_GET_NAME (fixP->fx_subsy), segment_name (sub_symbol_segment));
+ }
+ else if (! S_IS_DEFINED (fixP->fx_subsy)
+ && S_IS_DEFINED (fixP->fx_addsy))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("`%s' can't be undefined in `%s' {%s section} - `%s'"),
+ S_GET_NAME (fixP->fx_subsy), S_GET_NAME (fixP->fx_addsy),
+ segment_name (add_symbol_segment), S_GET_NAME (fixP->fx_subsy));
+ }
+ else
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("`%s' and `%s' can't be undefined in `%s' - `%s'"),
+ S_GET_NAME (fixP->fx_addsy), S_GET_NAME (fixP->fx_subsy),
+ S_GET_NAME (fixP->fx_addsy), S_GET_NAME (fixP->fx_subsy));
+ }
+ }
+ }
+}
+
+/* Do any checks that we can't complete without knowing what's undefined. */
+void
+obj_mach_o_pre_output_hook (void)
+{
+ bfd_map_over_sections (stdoutput, obj_mach_o_check_before_writing, (char *) 0);
}
/* Here we count up frags in each subsection (where a sub-section is defined
diff --git a/gas/config/obj-macho.h b/gas/config/obj-macho.h
index 0ac8df4..92cb8ef 100644
--- a/gas/config/obj-macho.h
+++ b/gas/config/obj-macho.h
@@ -87,6 +87,9 @@ struct obj_mach_o_frag_data
#define OBJ_FRAG_TYPE struct obj_mach_o_frag_data
+#define md_pre_output_hook obj_mach_o_pre_output_hook()
+extern void obj_mach_o_pre_output_hook(void);
+
#define md_pre_relax_hook obj_mach_o_pre_relax_hook()
extern void obj_mach_o_pre_relax_hook (void);