add indirect_symbol to mach-o port.
[deliverable/binutils-gdb.git] / bfd / mach-o.c
index 307a8ebd762f7ad700fb5c73fad8ce4996297853..c5196631c4a90ea7f0637dd8c7192662c41ada3c 100644 (file)
@@ -2023,6 +2023,7 @@ bfd_mach_o_build_seg_command (const char *segment,
 
   /* TODO: fix this up for non-MH_OBJECT cases.  */
   seg->vmaddr = 0;
+  seg->vmsize = 0;
 
   seg->fileoff = mdata->filelen;
   seg->filesize = 0;
@@ -2048,9 +2049,21 @@ bfd_mach_o_build_seg_command (const char *segment,
 
       bfd_mach_o_append_section_to_segment (seg, sec);
 
-      if (s->size == 0)
-         s->offset = 0;
-      else
+      s->offset = 0;
+      if (s->size > 0)
+       {
+          seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
+         seg->vmsize += s->size;
+        }
+      
+      /* Zerofill sections have zero file size & offset, 
+        and are not written.  */
+      if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) == BFD_MACH_O_S_ZEROFILL
+          || (s->flags & BFD_MACH_O_SECTION_TYPE_MASK) 
+             == BFD_MACH_O_S_GB_ZEROFILL)
+        continue;
+
+      if (s->size > 0)
        {
           mdata->filelen = FILE_ALIGN (mdata->filelen, s->align);
           s->offset = mdata->filelen;
@@ -2062,11 +2075,37 @@ bfd_mach_o_build_seg_command (const char *segment,
     }
 
   seg->filesize = mdata->filelen - seg->fileoff;
-  seg->vmsize = seg->filesize;
 
   return TRUE;
 }
 
+/* Count the number of indirect symbols in the image.
+   Requires that the sections are in their final order.  */
+
+static unsigned int
+bfd_mach_o_count_indirect_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
+{
+  unsigned int i;
+  unsigned int nisyms = 0;
+
+  for (i = 0; i < mdata->nsects; ++i)
+    {
+      bfd_mach_o_section *sec = mdata->sections[i];
+
+      switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+       {
+         case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
+         case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
+         case BFD_MACH_O_S_SYMBOL_STUBS:
+           nisyms += bfd_mach_o_section_get_nbr_indirect (abfd, sec);
+           break;
+         default:
+           break;
+       }
+    }
+  return nisyms;
+}
+
 static bfd_boolean
 bfd_mach_o_build_dysymtab_command (bfd *abfd,
                                   bfd_mach_o_data_struct *mdata,
@@ -2123,9 +2162,11 @@ bfd_mach_o_build_dysymtab_command (bfd *abfd,
       dsym->nundefsym = 0;
     }
 
+  dsym->nindirectsyms = bfd_mach_o_count_indirect_symbols (abfd, mdata);
   if (dsym->nindirectsyms > 0)
     {
       unsigned i;
+      unsigned n;
 
       mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
       dsym->indirectsymoff = mdata->filelen;
@@ -2134,11 +2175,38 @@ bfd_mach_o_build_dysymtab_command (bfd *abfd,
       dsym->indirect_syms = bfd_zalloc (abfd, dsym->nindirectsyms * 4);
       if (dsym->indirect_syms == NULL)
         return FALSE;
-      
-      /* So fill in the indices.  */
-      for (i = 0; i < dsym->nindirectsyms; ++i)
+                 
+      n = 0;
+      for (i = 0; i < mdata->nsects; ++i)
        {
-         /* TODO: fill in the table.  */
+         bfd_mach_o_section *sec = mdata->sections[i];
+
+         switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+           {
+             case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
+             case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
+             case BFD_MACH_O_S_SYMBOL_STUBS:
+               {
+                 unsigned j, num;
+                 bfd_mach_o_asymbol **isyms = sec->indirect_syms;
+                 
+                 num = bfd_mach_o_section_get_nbr_indirect (abfd, sec);
+                 if (isyms == NULL || num == 0)
+                   break;
+                 /* Record the starting index in the reserved1 field.  */
+                 sec->reserved1 = n;
+                 for (j = 0; j < num; j++, n++)
+                   {
+                     if (isyms[j] == NULL)
+                       dsym->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL;
+                     else
+                       dsym->indirect_syms[n] = isyms[j]->symbol.udata.i;
+                   }
+               }
+               break;
+             default:
+               break;
+           }
        }
     }
 
This page took 0.024554 seconds and 4 git commands to generate.