provide a hook to allow checking errors just before we output the file.
authorIain Sandoe <iain@codesourcery.com>
Tue, 21 Feb 2012 13:39:37 +0000 (13:39 +0000)
committerIain Sandoe <iain@codesourcery.com>
Tue, 21 Feb 2012 13:39:37 +0000 (13:39 +0000)
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.

gas/ChangeLog
gas/config/obj-macho.c
gas/config/obj-macho.h
gas/write.c

index 7a8fcb59f7b88b6baa86753fffec275186453624..63f341e935a8852a091407ea33a63fdf66d16e12 100644 (file)
@@ -1,3 +1,11 @@
+2012-02-21  Iain Sandoe  <idsandoe@googlemail.com>
+
+       * 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.
+
 2012-02-21  Tristan Gingold  <gingold@adacore.com>
 
        * config/tc-i386.h (OBJ_MACH_O): New section.
index 376e620d428effc049a141cdb9e7861c6ac70b60..21281a0ef13627889d43258d6712a5b21f10b63f 100644 (file)
@@ -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
index 0ac8df4174a8e4d2083f64db8772c95b7951331f..92cb8ef87891e743cfd305dd15acef909a31e70b 100644 (file)
@@ -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);
 
index f640c6103d13553c0565094a4b6f1ac15a64e000..23d4334289fc2c515f49104ce7f4e710b57c0e1b 100644 (file)
@@ -1767,6 +1767,10 @@ write_object_file (void)
   fragS *fragP;                        /* Track along all frags.  */
 #endif
 
+#ifdef md_pre_output_hook
+  md_pre_output_hook;
+#endif
+
   /* Do we really want to write it?  */
   {
     int n_warns, n_errs;