diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c
index 6de2410e1a7..bf6f2758bc7 100644
--- a/gas/config/obj-macho.c
+++ b/gas/config/obj-macho.c
@@ -1864,7 +1864,8 @@ obj_mach_o_allow_local_subtract (expressionS * left ATTRIBUTE_UNUSED,
 }
 
 static bool
-obj_mach_o_in_different_subsection (symbolS *a, symbolS *b)
+obj_mach_o_in_different_subsection (symbolS *a, segT aseg, valueT offset,
+				    symbolS *b)
 {
   fragS *fa;
   fragS *fb;
@@ -1877,7 +1878,10 @@ obj_mach_o_in_different_subsection (symbolS *a, symbolS *b)
       return true;
     }
 
-  fa = symbol_get_frag (a);
+  if (symbol_section_p (a) && aseg != NULL)
+    fa = get_frag_for_address (NULL, seg_info (aseg), offset);
+  else
+    fa = symbol_get_frag (a);
   fb = symbol_get_frag (b);
   if (fa == NULL || fb == NULL)
     {
@@ -1893,7 +1897,8 @@ obj_mach_o_force_reloc_sub_same (fixS *fix, segT seg)
 {
   if (! SEG_NORMAL (seg))
     return true;
-  return obj_mach_o_in_different_subsection (fix->fx_addsy, fix->fx_subsy);
+  return obj_mach_o_in_different_subsection (fix->fx_addsy, seg,
+					     fix->fx_offset, fix->fx_subsy);
 }
 
 bool
@@ -1902,7 +1907,7 @@ obj_mach_o_force_reloc_sub_local (fixS *fix, segT seg ATTRIBUTE_UNUSED)
   symbolS *fragsym = fix->fx_frag->obj_frag_data.subsection;
   if (fragsym == NULL)
     return false;
-  return obj_mach_o_in_different_subsection (fix->fx_subsy, fragsym);
+  return obj_mach_o_in_different_subsection (fix->fx_subsy, NULL, 0, fragsym);
 }
 
 bool
@@ -1916,16 +1921,18 @@ obj_mach_o_force_reloc (fixS *fix)
   if (fix->fx_addsy != NULL)
     {
       symbolS *subsec = fix->fx_frag->obj_frag_data.subsection;
-      symbolS *targ = fix->fx_addsy;
 
       /* There might be no subsections at all.  */
       if (subsec == NULL)
 	return false;
 
-      if (S_GET_SEGMENT (targ) == absolute_section)
+      symbolS *targ = fix->fx_addsy;
+      segT targseg = S_GET_SEGMENT (targ);
+      if (targseg == absolute_section)
 	return false;
 
-      return obj_mach_o_in_different_subsection (targ, subsec);
+      return obj_mach_o_in_different_subsection (targ, targseg,
+						 fix->fx_offset, subsec);
     }
   return false;
 }
diff --git a/gas/testsuite/gas/i386/insn-32.d b/gas/testsuite/gas/i386/insn-32.d
index c2d8202bd2e..2649fdcf94e 100644
--- a/gas/testsuite/gas/i386/insn-32.d
+++ b/gas/testsuite/gas/i386/insn-32.d
@@ -1,7 +1,6 @@
 #as: --divide
 #objdump: -dw
 #name: .insn (32-bit code)
-#xfail: *-*-darwin*
 
 .*: +file format .*
 
diff --git a/gas/write.c b/gas/write.c
index 9bb47857936..9514c3df42e 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -1228,33 +1228,41 @@ install_reloc (asection *sec, arelent *reloc, fragS *fragp,
     }
 }
 
-static fragS *
-get_frag_for_reloc (fragS *last_frag,
-		    const segment_info_type *seginfo,
-		    const struct reloc_list *r)
+fragS *
+get_frag_for_address (fragS *last_frag,
+		      const segment_info_type *seginfo,
+		      addressT addr)
 {
   fragS *f;
 
   for (f = last_frag; f != NULL; f = f->fr_next)
-    if (f->fr_address <= r->u.b.r.address
-	&& r->u.b.r.address < f->fr_address + f->fr_fix)
+    if (f->fr_address <= addr && addr < f->fr_address + f->fr_fix)
       return f;
 
   for (f = seginfo->frchainP->frch_root; f != NULL; f = f->fr_next)
-    if (f->fr_address <= r->u.b.r.address
-	&& r->u.b.r.address < f->fr_address + f->fr_fix)
+    if (f->fr_address <= addr && addr < f->fr_address + f->fr_fix)
       return f;
 
   for (f = seginfo->frchainP->frch_root; f != NULL; f = f->fr_next)
-    if (f->fr_address <= r->u.b.r.address
-	&& r->u.b.r.address <= f->fr_address + f->fr_fix)
+    if (f->fr_address <= addr && addr <= f->fr_address + f->fr_fix)
       return f;
 
-  as_bad_where (r->file, r->line,
-		_("reloc not within (fixed part of) section"));
   return NULL;
 }
 
+static fragS *
+get_frag_for_reloc (fragS *last_frag,
+		    const segment_info_type *seginfo,
+		    const struct reloc_list *r)
+{
+  fragS *f = get_frag_for_address (last_frag, seginfo, r->u.b.r.address);
+
+  if (f == NULL)
+    as_bad_where (r->file, r->line,
+		  _("reloc not within (fixed part of) section"));
+  return f;
+}
+
 static void
 write_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
 	      void *xxx ATTRIBUTE_UNUSED)
diff --git a/gas/write.h b/gas/write.h
index 7281930c2d6..bc5260a2efd 100644
--- a/gas/write.h
+++ b/gas/write.h
@@ -188,5 +188,8 @@ extern fixS *fix_new_exp (fragS *, unsigned long, unsigned long,
 			  const expressionS *, int, bfd_reloc_code_real_type);
 extern void write_print_statistics (FILE *);
 extern void as_bad_subtract (fixS *);
+struct segment_info_struct;
+extern fragS *get_frag_for_address (fragS *, const struct segment_info_struct *,
+				    addressT);
 
 #endif /* __write_h__ */
