Add support to GDB for the Renesas rl78 architecture.
[external/binutils.git] / gas / config / obj-macho.c
index 61e6771..f4706ab 100644 (file)
@@ -45,6 +45,8 @@
 #include "mach-o/loader.h"
 #include "obj-macho.h"
 
+#include <string.h>
+
 /* Forward decls.  */
 static segT obj_mach_o_segT_from_bfd_name (const char *, int);
 
@@ -432,7 +434,7 @@ obj_mach_o_zerofill (int ignore ATTRIBUTE_UNUSED)
   symbolS *sym = NULL;
   unsigned int align = 0;
   unsigned int specified_mask = 0;
-  offsetT size;
+  offsetT size = 0;
 
 #ifdef md_flush_pending_output
   md_flush_pending_output ();
@@ -1471,6 +1473,89 @@ obj_macho_frob_symbol (struct symbol *sp)
   return 0;
 }
 
+/* Zerofill and GB Zerofill sections must be sorted to follow all other
+   sections in their segments.
+
+   The native 'as' leaves the sections physically in the order they appear in
+   the source, and adjusts the section VMAs to meet the constraint.
+   
+   We follow this for now - if nothing else, it makes comparison easier.
+
+   An alternative implementation would be to sort the sections as ld requires.
+   It might be advantageous to implement such a scheme in the future (or even
+   to make the style of section ordering user-selectable).  */
+
+typedef struct obj_mach_o_set_vma_data
+{
+  bfd_vma vma;
+  unsigned vma_pass;
+  unsigned zerofill_seen;
+  unsigned gb_zerofill_seen;
+} obj_mach_o_set_vma_data;
+
+/* We do (possibly) three passes through to set the vma, so that:
+
+   zerofill sections get VMAs after all others in their segment
+   GB zerofill get VMAs last.
+   
+   As we go, we notice if we see any Zerofill or GB Zerofill sections, so that
+   we can skip the additional passes if there's nothing to do.  */
+
+static void
+obj_mach_o_set_section_vma (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *v_p)
+{
+  bfd_mach_o_section *ms = bfd_mach_o_get_mach_o_section (sec);
+  unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
+  obj_mach_o_set_vma_data *p = (struct obj_mach_o_set_vma_data *)v_p;
+  unsigned sectype = (ms->flags & BFD_MACH_O_SECTION_TYPE_MASK);
+  unsigned zf;
+
+  zf = 0;
+  if (sectype == BFD_MACH_O_S_ZEROFILL)
+    {
+      zf = 1;
+      p->zerofill_seen = zf;
+    }
+  else if (sectype == BFD_MACH_O_S_GB_ZEROFILL)
+    {
+      zf = 2;
+      p->gb_zerofill_seen = zf;
+    }
+
+  if (p->vma_pass != zf)
+    return;
+
+  /* We know the section size now - so make a vma for the section just
+     based on order.  */
+  ms->size = bfd_get_section_size (sec);
+  
+  /* Make sure that the align agrees, and set to the largest value chosen.  */
+  ms->align = ms->align > bfd_align ? ms->align : bfd_align;
+  bfd_set_section_alignment (abfd, sec, ms->align);
+  
+  p->vma += (1 << ms->align) - 1;
+  p->vma &= ~((1 << ms->align) - 1);
+  ms->addr = p->vma;
+  bfd_set_section_vma (abfd, sec, p->vma);
+  p->vma += ms->size;
+}
+
+/* (potentially) three passes over the sections, setting VMA.  We skip the 
+  {gb}zerofill passes if we didn't see any of the relevant sections.  */
+
+void obj_mach_o_post_relax_hook (void)
+{
+  obj_mach_o_set_vma_data d;
+
+  memset (&d, 0, sizeof (d));
+  
+  bfd_map_over_sections (stdoutput, obj_mach_o_set_section_vma, (char *) &d);
+  if ((d.vma_pass = d.zerofill_seen) != 0)
+    bfd_map_over_sections (stdoutput, obj_mach_o_set_section_vma, (char *) &d);
+  if ((d.vma_pass = d.gb_zerofill_seen) != 0)
+    bfd_map_over_sections (stdoutput, obj_mach_o_set_section_vma, (char *) &d);
+}
+
 static void
 obj_mach_o_set_indirect_symbols (bfd *abfd, asection *sec,
                                 void *xxx ATTRIBUTE_UNUSED)
@@ -1545,14 +1630,18 @@ obj_mach_o_set_indirect_symbols (bfd *abfd, asection *sec,
              
              for (isym = list, n = 0; isym != NULL; isym = isym->next, n++)
                {
+                 sym = (bfd_mach_o_asymbol *)symbol_get_bfdsym (isym->sym);
                  /* Array is init to NULL & NULL signals a local symbol
                     If the section is lazy-bound, we need to keep the
-                    reference to the symbol, since dyld can override.  */
-                 if (S_IS_LOCAL (isym->sym) && ! lazy)
+                    reference to the symbol, since dyld can override.
+                    
+                    Absolute symbols are handled specially.  */
+                 if (sym->symbol.section == bfd_abs_section_ptr)
+                   ms->indirect_syms[n] = sym;
+                 else if (S_IS_LOCAL (isym->sym) && ! lazy)
                    ;
                  else
                    {
-                     sym = (bfd_mach_o_asymbol *)symbol_get_bfdsym (isym->sym);
                      if (sym == NULL)
                        ;
                      /* If the symbols is external ...  */
@@ -1590,6 +1679,23 @@ obj_mach_o_frob_file_after_relocs (void)
   bfd_map_over_sections (stdoutput, obj_mach_o_set_indirect_symbols, (char *) 0);
 }
 
+/* Reverse relocations order to make ld happy.  */
+
+void
+obj_mach_o_reorder_section_relocs (asection *sec, arelent **rels, unsigned int n)
+{
+  unsigned int i;
+  unsigned int max = n / 2;
+
+  for (i = 0; i < max; i++)
+    {
+      arelent *r = rels[i];
+      rels[i] = rels[n - i - 1];
+      rels[n - i - 1] = r;
+    }
+  bfd_set_reloc (stdoutput, sec, rels, n);
+}
+
 /* Support stabs for mach-o.  */
 
 void