gas:
authorIain Sandoe <iain@codesourcery.com>
Mon, 20 Feb 2012 20:11:32 +0000 (20:11 +0000)
committerIain Sandoe <iain@codesourcery.com>
Mon, 20 Feb 2012 20:11:32 +0000 (20:11 +0000)
* config/obj-macho.c (obj_mach_o_is_frame_section): New.
(obj_mach_o_allow_local_subtract): New.
* config/obj-macho.h (md_allow_local_subtract): Define.
(obj_mach_o_allow_local_subtract): Declare.

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

index d6d30c1..2f9d09a 100644 (file)
@@ -1,5 +1,12 @@
 2012-02-20  Iain Sandoe  <idsandoe@googlemail.com>
 
+       * config/obj-macho.c (obj_mach_o_is_frame_section): New.
+       (obj_mach_o_allow_local_subtract): New.
+       * config/obj-macho.h (md_allow_local_subtract): Define.
+       (obj_mach_o_allow_local_subtract): Declare.
+
+2012-02-20  Iain Sandoe  <idsandoe@googlemail.com>
+
        * config/obj-macho.c (obj_mach_o_make_or_get_sect): In the absence of
        canonical information, try to determine CODE and DEBUG section flags
        from the mach-o section data.
index b0ef741..4623384 100644 (file)
@@ -1495,6 +1495,19 @@ obj_macho_frob_symbol (struct symbol *sp)
   return 0;
 }
 
+/* Relocation rules are different in frame sections.  */
+
+static int
+obj_mach_o_is_frame_section (segT sec)
+{
+  int l;
+  l = strlen (segment_name (sec));
+  if ((l == 9 && strncmp (".eh_frame", segment_name (sec), 9) == 0)
+       || (l == 12 && strncmp (".debug_frame", segment_name (sec), 12) == 0))
+    return 1;
+  return 0;
+}
+
 /* Zerofill and GB Zerofill sections must be sorted to follow all other
    sections in their segments.
 
@@ -1757,3 +1770,21 @@ obj_mach_o_process_stab (int what, const char *string,
   /* It's a debug symbol.  */
   s->symbol.flags |= BSF_DEBUGGING;
 }
+
+/* Unless we're in a frame section, we need to force relocs to be generated for
+   local subtractions.  We might eliminate them later (if they are within the
+   same sub-section) but we don't know that at the point that this decision is
+   being made.  */
+
+int
+obj_mach_o_allow_local_subtract (expressionS * left ATTRIBUTE_UNUSED, 
+                                expressionS * right ATTRIBUTE_UNUSED,
+                                segT seg)
+{
+  /* Don't interfere if it's one of the GAS internal sections.  */
+  if (! SEG_NORMAL (seg))
+    return 1;
+
+  /* Allow in frame sections, otherwise emit a reloc.  */
+  return obj_mach_o_is_frame_section (seg);
+}
index bb8daf9..e081ba0 100644 (file)
@@ -73,6 +73,12 @@ void obj_mach_o_reorder_section_relocs (asection *, arelent **, unsigned int);
 #define SET_SECTION_RELOCS(sec, relocs, n) \
   obj_mach_o_reorder_section_relocs (sec, relocs, n)
 
+/* Emit relocs for local subtracts, to cater for subsections-via-symbols.  */
+#define md_allow_local_subtract(LEFT, RIGHT, SECTION) \
+ obj_mach_o_allow_local_subtract (LEFT, RIGHT, SECTION)
+extern int obj_mach_o_allow_local_subtract (expressionS *, expressionS *,
+                                           segT);
+
 #define EMIT_SECTION_SYMBOLS           0
 
 #define OBJ_PROCESS_STAB(SEG,W,S,T,O,D)        obj_mach_o_process_stab(W,S,T,O,D)