From 16a87420985f256b5cde070586ebcdfda2225b01 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Tue, 21 Feb 2012 13:39:37 +0000 Subject: [PATCH] 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. --- gas/ChangeLog | 8 +++++ gas/config/obj-macho.c | 66 ++++++++++++++++++++++++++++++++++++++++++ gas/config/obj-macho.h | 3 ++ gas/write.c | 4 +++ 4 files changed, 81 insertions(+) diff --git a/gas/ChangeLog b/gas/ChangeLog index 7a8fcb59f7..63f341e935 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2012-02-21 Iain Sandoe + + * 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 * config/tc-i386.h (OBJ_MACH_O): New section. diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c index 376e620d42..21281a0ef1 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 0ac8df4174..92cb8ef878 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); diff --git a/gas/write.c b/gas/write.c index f640c6103d..23d4334289 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;