This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch gas/mach-o] pre-output error check hook.


For mach-o there are a couple of errors that we can't really diagnose until we finish parsing (i.e. ones that depend on whether symbols are defined or not).

It would be nicer if these errors could be enumerated before the object file is output - so that they could appear in the summary and the output aborted at that point (otherwise they will just hit when we try to validate relocs).

In a way, I'm surprised that no-one else wants to do this - which makes me wonder if I've missed an alternate implementation?

Anyway, the implementation here adds a hook which is activated right before the final error count tally in write_object_file()

This is used, initially, to bail out if we have certain invalid relocs.
OK?
Iain

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/config/obj-macho.c | 66 +++++++++++++++++++++++++++++++++++++++ +++++++++
gas/config/obj-macho.h | 3 ++
gas/write.c | 4 +++
3 files changed, 73 insertions(+), 0 deletions(-)


diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c
index 632eafa..f1b4e70 100644
--- a/gas/config/obj-macho.c
+++ b/gas/config/obj-macho.c
@@ -1541,6 +1541,72 @@ obj_mach_o_process_stab (int what, const char *string,
+
+/* 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 b49038c..f76b66d 100644
--- a/gas/config/obj-macho.h
+++ b/gas/config/obj-macho.h
@@ -84,6 +84,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);

diff --git a/gas/write.c b/gas/write.c
index f640c61..23d4334 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]