Allow symbols in MEMORY region specification
[deliverable/binutils-gdb.git] / gas / config / obj-macho.c
index 376e620d428effc049a141cdb9e7861c6ac70b60..63c0b7e4e09c42376f58578ff0ffa60a0036055f 100644 (file)
@@ -1,5 +1,5 @@
 /* Mach-O object file format
-   Copyright 2009, 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 2009-2015 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -1013,7 +1013,6 @@ obj_mach_o_set_symbol_qualifier (symbolS *sym, int type)
   bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (sym);
   bfd_mach_o_section *sec;
   int sectype = -1;
-  int err = 0;
 
   /* If the symbol is defined, then we can do more rigorous checking on
      the validity of the qualifiers.  Otherwise, we are stuck with waiting 
@@ -1041,7 +1040,8 @@ obj_mach_o_set_symbol_qualifier (symbolS *sym, int type)
            as_bad (_("'%s' previously declared as '%s'."), s->symbol.name,
                      (s->n_type & BFD_MACH_O_N_PEXT) ? "private extern"
                                                      : "global" );
-           err = 1;
+           s->symbol.udata.i = SYM_MACHO_FIELDS_UNSET;
+           return 1;
          }
        else
          {
@@ -1092,7 +1092,8 @@ obj_mach_o_set_symbol_qualifier (symbolS *sym, int type)
            as_bad (_("'%s' can't be a weak_definition (currently only"
                      " supported in sections of type coalesced)"),
                      s->symbol.name);
-           err = 1;
+           s->symbol.udata.i = SYM_MACHO_FIELDS_UNSET;
+           return 1;
          }
        else
          s->n_desc |= BFD_MACH_O_N_WEAK_DEF;
@@ -1111,7 +1112,7 @@ obj_mach_o_set_symbol_qualifier (symbolS *sym, int type)
     /* We've seen some kind of qualifier - check validity if or when the entity
      is defined.  */
   s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED;
-  return err;
+  return 0;
 }
 
 /* Respond to symbol qualifiers.
@@ -1409,8 +1410,12 @@ void obj_mach_o_frob_label (struct symbol *sp)
     {
       if ((s->n_desc & BFD_MACH_O_N_WEAK_DEF)
          && sectype != BFD_MACH_O_S_COALESCED)
-       as_bad (_("'%s' can't be a weak_definition (currently only supported"
-                 " in sections of type coalesced)"), s->symbol.name);
+       {
+         as_bad (_("'%s' can't be a weak_definition (currently only supported"
+                   " in sections of type coalesced)"), s->symbol.name);
+         /* Don't cascade errors.  */
+         s->symbol.udata.i = SYM_MACHO_FIELDS_UNSET;
+       }
 
       /* Have we changed from an undefined to defined ref? */
       s->n_desc &= ~(REFE | LAZY);
@@ -1480,7 +1485,6 @@ obj_mach_o_frob_symbol (struct symbol *sp)
     {
       /* Anything here that should be added that is non-standard.  */
       s->n_desc &= ~BFD_MACH_O_REFERENCE_MASK;
-      s->symbol.udata.i = SYM_MACHO_FIELDS_NOT_VALIDATED;
     }    
   else if (s->symbol.udata.i == SYM_MACHO_FIELDS_NOT_VALIDATED)
     {
@@ -1554,6 +1558,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
This page took 0.02475 seconds and 4 git commands to generate.