*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / mach-o.c
index abfd7c1b4d78a95e78f68ffe1fc1a57508df429d..efc58f59a65eabed43e486f89c225c83141ff3a8 100644 (file)
@@ -1,5 +1,6 @@
 /* Mach-O support for BFD.
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+   2009, 2010, 2011
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -25,6 +26,8 @@
 #include "libbfd.h"
 #include "libiberty.h"
 #include "aout/stab_gnu.h"
+#include "mach-o/reloc.h"
+#include "mach-o/external.h"
 #include <ctype.h>
 
 #define bfd_mach_o_object_p bfd_mach_o_gen_object_p
@@ -131,63 +134,76 @@ static const struct mach_o_section_name_xlat data_section_names_xlat[] =
 
 struct mach_o_segment_name_xlat
 {
+  /* Segment name.  */
   const char *segname;
+
+  /* List of known sections for the segment.  */
   const struct mach_o_section_name_xlat *sections;
 };
 
+/* List of known segment names.  */
+
 static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
   {
-    { "__DWARF", dwarf_section_names_xlat },
     { "__TEXT", text_section_names_xlat },
     { "__DATA", data_section_names_xlat },
+    { "__DWARF", dwarf_section_names_xlat },
     { NULL, NULL }
   };
 
-
 /* Mach-O to bfd names.  */
 
-static void
-bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section,
-                                        char **name, flagword *flags)
+void
+bfd_mach_o_normalize_section_name (const char *segname, const char *sectname,
+                                   const char **name, flagword *flags)
 {
   const struct mach_o_segment_name_xlat *seg;
-  char *res;
-  unsigned int len;
-  const char *pfx = "";
 
   *name = NULL;
   *flags = SEC_NO_FLAGS;
 
   for (seg = segsec_names_xlat; seg->segname; seg++)
     {
-      if (strcmp (seg->segname, section->segname) == 0)
+      if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
         {
           const struct mach_o_section_name_xlat *sec;
 
           for (sec = seg->sections; sec->mach_o_name; sec++)
             {
-              if (strcmp (sec->mach_o_name, section->sectname) == 0)
+              if (strncmp (sec->mach_o_name, sectname,
+                           BFD_MACH_O_SECTNAME_SIZE) == 0)
                 {
-                  len = strlen (sec->bfd_name);
-                  res = bfd_alloc (abfd, len + 1);
-
-                  if (res == NULL)
-                    return;
-                  strcpy (res, sec->bfd_name);
-                  *name = res;
+                  *name = sec->bfd_name;
                   *flags = sec->flags;
                   return;
                 }
             }
+          return;
         }
     }
+}
 
-  len = strlen (section->segname) + 1
-    + strlen (section->sectname) + 1;
+static void
+bfd_mach_o_convert_section_name_to_bfd
+  (bfd *abfd, const char *segname, const char *sectname,
+   const char **name, flagword *flags)
+{
+  char *res;
+  unsigned int len;
+  const char *pfx = "";
+
+  /* First search for a canonical name.  */
+  bfd_mach_o_normalize_section_name (segname, sectname, name, flags);
+
+  /* Return now if found.  */
+  if (*name)
+    return;
+
+  len = strlen (segname) + 1 + strlen (sectname) + 1;
 
   /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
      with an underscore.  */
-  if (section->segname[0] != '_')
+  if (segname[0] != '_')
     {
       static const char seg_pfx[] = "LC_SEGMENT.";
 
@@ -198,8 +214,9 @@ bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section,
   res = bfd_alloc (abfd, len);
   if (res == NULL)
     return;
-  snprintf (res, len, "%s%s.%s", pfx, section->segname, section->sectname);
+  snprintf (res, len, "%s%s.%s", pfx, segname, sectname);
   *name = res;
+  *flags = SEC_NO_FLAGS;
 }
 
 /* Convert a bfd section name to a Mach-O segment + section name.  */
@@ -375,10 +392,16 @@ bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
   if (nsyms < 0)
     return nsyms;
 
+  if (nsyms == 0)
+    {
+      /* Do not try to read symbols if there are none.  */
+      alocation[0] = NULL;
+      return 0;
+    }
+
   if (bfd_mach_o_read_symtab_symbols (abfd) != 0)
     {
-      fprintf (stderr,
-               "bfd_mach_o_canonicalize_symtab: unable to load symbols\n");
+      (*_bfd_error_handler) (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
       return 0;
     }
 
@@ -598,25 +621,25 @@ bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
 static bfd_boolean
 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
 {
-  unsigned char buf[32];
+  struct mach_o_header_external raw;
   unsigned int size;
 
   size = mach_o_wide_p (header) ?
     BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
 
-  bfd_h_put_32 (abfd, header->magic, buf + 0);
-  bfd_h_put_32 (abfd, header->cputype, buf + 4);
-  bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
-  bfd_h_put_32 (abfd, header->filetype, buf + 12);
-  bfd_h_put_32 (abfd, header->ncmds, buf + 16);
-  bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
-  bfd_h_put_32 (abfd, header->flags, buf + 24);
+  bfd_h_put_32 (abfd, header->magic, raw.magic);
+  bfd_h_put_32 (abfd, header->cputype, raw.cputype);
+  bfd_h_put_32 (abfd, header->cpusubtype, raw.cpusubtype);
+  bfd_h_put_32 (abfd, header->filetype, raw.filetype);
+  bfd_h_put_32 (abfd, header->ncmds, raw.ncmds);
+  bfd_h_put_32 (abfd, header->sizeofcmds, raw.sizeofcmds);
+  bfd_h_put_32 (abfd, header->flags, raw.flags);
 
   if (mach_o_wide_p (header))
-    bfd_h_put_32 (abfd, header->reserved, buf + 28);
+    bfd_h_put_32 (abfd, header->reserved, raw.reserved);
 
   if (bfd_seek (abfd, 0, SEEK_SET) != 0
-      || bfd_bwrite ((void *) buf, size, abfd) != size)
+      || bfd_bwrite (&raw, size, abfd) != size)
     return FALSE;
 
   return TRUE;
@@ -627,28 +650,27 @@ bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
 {
   bfd_mach_o_thread_command *cmd = &command->command.thread;
   unsigned int i;
-  unsigned char buf[8];
+  struct mach_o_thread_command_external raw;
   unsigned int offset;
-  unsigned int nflavours;
 
   BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
              || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
 
   offset = 8;
-  nflavours = 0;
   for (i = 0; i < cmd->nflavours; i++)
     {
       BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
-      BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
+      BFD_ASSERT (cmd->flavours[i].offset ==
+                  (command->offset + offset + BFD_MACH_O_LC_SIZE));
 
-      bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
-      bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
+      bfd_h_put_32 (abfd, cmd->flavours[i].flavour, raw.flavour);
+      bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count);
 
       if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
-          || bfd_bwrite ((void *) buf, 8, abfd) != 8)
+          || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
        return -1;
 
-      offset += cmd->flavours[i].size + 8;
+      offset += cmd->flavours[i].size + sizeof (raw);
     }
 
   return 0;
@@ -662,7 +684,8 @@ bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
 }
 
 static int
-bfd_mach_o_canonicalize_one_reloc (bfd *abfd, char *buf,
+bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
+                                   struct mach_o_reloc_info_external *raw,
                                    arelent *res, asymbol **syms)
 {
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
@@ -672,8 +695,8 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd, char *buf,
   bfd_vma symnum;
   asymbol **sym;
 
-  addr = bfd_get_32 (abfd, buf + 0);
-  symnum = bfd_get_32 (abfd, buf + 4);
+  addr = bfd_get_32 (abfd, raw->r_address);
+  symnum = bfd_get_32 (abfd, raw->r_symbolnum);
   
   if (addr & BFD_MACH_O_SR_SCATTERED)
     {
@@ -705,12 +728,22 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd, char *buf,
       res->addend = 0;
       res->address = addr;
       if (symnum & BFD_MACH_O_R_EXTERN)
-        sym = syms + num;
+        {
+          sym = syms + num;
+          reloc.r_extern = 1;
+        }
       else
         {
           BFD_ASSERT (num != 0);
           BFD_ASSERT (num <= mdata->nsects);
           sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
+          /* For a symbol defined in section S, the addend (stored in the
+             binary) contains the address of the section.  To comply with
+             bfd conventio, substract the section address.
+             Use the address from the header, so that the user can modify
+             the vma of the section.  */
+          res->addend = -mdata->sections[num - 1]->addr;
+          reloc.r_extern = 0;
         }
       res->sym_ptr_ptr = sym;
       reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
@@ -730,12 +763,13 @@ bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
                                 arelent *res, asymbol **syms)
 {
   unsigned long i;
-  char *native_relocs;
+  struct mach_o_reloc_info_external *native_relocs;
   bfd_size_type native_size;
 
   /* Allocate and read relocs.  */
   native_size = count * BFD_MACH_O_RELENT_SIZE;
-  native_relocs = bfd_malloc (native_size);
+  native_relocs =
+    (struct mach_o_reloc_info_external *) bfd_malloc (native_size);
   if (native_relocs == NULL)
     return -1;
 
@@ -745,9 +779,8 @@ bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
 
   for (i = 0; i < count; i++)
     {
-      char *buf = native_relocs + BFD_MACH_O_RELENT_SIZE * i;
-
-      if (bfd_mach_o_canonicalize_one_reloc (abfd, buf, &res[i], syms) < 0)
+      if (bfd_mach_o_canonicalize_one_reloc (abfd, &native_relocs[i],
+                                             &res[i], syms) < 0)
         goto err;
     }
   free (native_relocs);
@@ -877,7 +910,7 @@ bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
   for (i = 0; i < section->nreloc; i++)
     {
       arelent *rel = entries[i];
-      char buf[8];
+      struct mach_o_reloc_info_external raw;
       bfd_mach_o_reloc_info info, *pinfo = &info;
 
       /* Convert relocation to an intermediate representation.  */
@@ -894,23 +927,24 @@ bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
             | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
             | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
             | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
-          bfd_put_32 (abfd, v, buf);
-          bfd_put_32 (abfd, pinfo->r_value, buf + 4);
+          /* Note: scattered relocs have field in reverse order...  */
+          bfd_put_32 (abfd, v, raw.r_address);
+          bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
         }
       else
         {
           unsigned long v;
 
-          bfd_put_32 (abfd, pinfo->r_address, buf);
+          bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
           v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
             | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
             | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
             | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
             | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
-          bfd_put_32 (abfd, v, buf + 4);
+          bfd_put_32 (abfd, v, raw.r_symbolnum);
         }
 
-      if (bfd_bwrite ((void *) buf, BFD_MACH_O_RELENT_SIZE, abfd)
+      if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
           != BFD_MACH_O_RELENT_SIZE)
         return FALSE;
     }
@@ -920,21 +954,21 @@ bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
 static int
 bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
 {
-  unsigned char buf[BFD_MACH_O_SECTION_SIZE];
-
-  memcpy (buf, section->sectname, 16);
-  memcpy (buf + 16, section->segname, 16);
-  bfd_h_put_32 (abfd, section->addr, buf + 32);
-  bfd_h_put_32 (abfd, section->size, buf + 36);
-  bfd_h_put_32 (abfd, section->offset, buf + 40);
-  bfd_h_put_32 (abfd, section->align, buf + 44);
-  bfd_h_put_32 (abfd, section->reloff, buf + 48);
-  bfd_h_put_32 (abfd, section->nreloc, buf + 52);
-  bfd_h_put_32 (abfd, section->flags, buf + 56);
-  bfd_h_put_32 (abfd, section->reserved1, buf + 60);
-  bfd_h_put_32 (abfd, section->reserved2, buf + 64);
-
-  if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
+  struct mach_o_section_32_external raw;
+
+  memcpy (raw.sectname, section->sectname, 16);
+  memcpy (raw.segname, section->segname, 16);
+  bfd_h_put_32 (abfd, section->addr, raw.addr);
+  bfd_h_put_32 (abfd, section->size, raw.size);
+  bfd_h_put_32 (abfd, section->offset, raw.offset);
+  bfd_h_put_32 (abfd, section->align, raw.align);
+  bfd_h_put_32 (abfd, section->reloff, raw.reloff);
+  bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
+  bfd_h_put_32 (abfd, section->flags, raw.flags);
+  bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
+  bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
+
+  if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
       != BFD_MACH_O_SECTION_SIZE)
     return -1;
 
@@ -944,22 +978,22 @@ bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
 static int
 bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
 {
-  unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
-
-  memcpy (buf, section->sectname, 16);
-  memcpy (buf + 16, section->segname, 16);
-  bfd_h_put_64 (abfd, section->addr, buf + 32);
-  bfd_h_put_64 (abfd, section->size, buf + 40);
-  bfd_h_put_32 (abfd, section->offset, buf + 48);
-  bfd_h_put_32 (abfd, section->align, buf + 52);
-  bfd_h_put_32 (abfd, section->reloff, buf + 56);
-  bfd_h_put_32 (abfd, section->nreloc, buf + 60);
-  bfd_h_put_32 (abfd, section->flags, buf + 64);
-  bfd_h_put_32 (abfd, section->reserved1, buf + 68);
-  bfd_h_put_32 (abfd, section->reserved2, buf + 72);
-  bfd_h_put_32 (abfd, section->reserved3, buf + 76);
-
-  if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
+  struct mach_o_section_64_external raw;
+
+  memcpy (raw.sectname, section->sectname, 16);
+  memcpy (raw.segname, section->segname, 16);
+  bfd_h_put_64 (abfd, section->addr, raw.addr);
+  bfd_h_put_64 (abfd, section->size, raw.size);
+  bfd_h_put_32 (abfd, section->offset, raw.offset);
+  bfd_h_put_32 (abfd, section->align, raw.align);
+  bfd_h_put_32 (abfd, section->reloff, raw.reloff);
+  bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
+  bfd_h_put_32 (abfd, section->flags, raw.flags);
+  bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
+  bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
+  bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
+
+  if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
       != BFD_MACH_O_SECTION_64_SIZE)
     return -1;
 
@@ -969,33 +1003,32 @@ bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
 static int
 bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
 {
-  unsigned char buf[BFD_MACH_O_LC_SEGMENT_SIZE];
+  struct mach_o_segment_command_32_external raw;
   bfd_mach_o_segment_command *seg = &command->command.segment;
-  unsigned long i;
+  bfd_mach_o_section *sec;
 
   BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
 
-  for (i = 0; i < seg->nsects; i++)
-    if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
+  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+    if (!bfd_mach_o_write_relocs (abfd, sec))
       return -1;
 
-  memcpy (buf, seg->segname, 16);
-  bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
-  bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
-  bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
-  bfd_h_put_32 (abfd, seg->filesize, buf + 28);
-  bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
-  bfd_h_put_32 (abfd, seg->initprot, buf + 36);
-  bfd_h_put_32 (abfd, seg->nsects, buf + 40);
-  bfd_h_put_32 (abfd, seg->flags, buf + 44);
+  memcpy (raw.segname, seg->segname, 16);
+  bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
+  bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
+  bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
+  bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
+  bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
+  bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
+  bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
+  bfd_h_put_32 (abfd, seg->flags, raw.flags);
   
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_SIZE - 8, abfd) 
-          != BFD_MACH_O_LC_SEGMENT_SIZE - 8))
+  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+      || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
     return -1;
 
-  for (i = 0; i < seg->nsects; i++)
-    if (bfd_mach_o_write_section_32 (abfd, &seg->sections[i]))
+  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+    if (bfd_mach_o_write_section_32 (abfd, sec))
       return -1;
 
   return 0;
@@ -1004,33 +1037,32 @@ bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
 static int
 bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
 {
-  unsigned char buf[BFD_MACH_O_LC_SEGMENT_64_SIZE];
+  struct mach_o_segment_command_64_external raw;
   bfd_mach_o_segment_command *seg = &command->command.segment;
-  unsigned long i;
+  bfd_mach_o_section *sec;
 
   BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
 
-  for (i = 0; i < seg->nsects; i++)
-    if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
+  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+    if (!bfd_mach_o_write_relocs (abfd, sec))
       return -1;
 
-  memcpy (buf, seg->segname, 16);
-  bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
-  bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
-  bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
-  bfd_h_put_64 (abfd, seg->filesize, buf + 40);
-  bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
-  bfd_h_put_32 (abfd, seg->initprot, buf + 52);
-  bfd_h_put_32 (abfd, seg->nsects, buf + 56);
-  bfd_h_put_32 (abfd, seg->flags, buf + 60);
-
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_64_SIZE - 8, abfd)
-          != BFD_MACH_O_LC_SEGMENT_64_SIZE - 8))
+  memcpy (raw.segname, seg->segname, 16);
+  bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
+  bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
+  bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
+  bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
+  bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
+  bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
+  bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
+  bfd_h_put_32 (abfd, seg->flags, raw.flags);
+
+  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+      || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
     return -1;
 
-  for (i = 0; i < seg->nsects; i++)
-    if (bfd_mach_o_write_section_64 (abfd, &seg->sections[i]))
+  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+    if (bfd_mach_o_write_section_64 (abfd, sec))
       return -1;
 
   return 0;
@@ -1041,7 +1073,6 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
 {
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
   bfd_mach_o_symtab_command *sym = &command->command.symtab;
-  unsigned char buf[16];
   unsigned long i;
   unsigned int wide = bfd_mach_o_wide_p (abfd);
   unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
@@ -1078,17 +1109,35 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
           if (str_index == (bfd_size_type) -1)
             goto err;
         }
-      bfd_h_put_32 (abfd, str_index, buf);
-      bfd_h_put_8 (abfd, s->n_type, buf + 4);
-      bfd_h_put_8 (abfd, s->n_sect, buf + 5);
-      bfd_h_put_16 (abfd, s->n_desc, buf + 6);
+
       if (wide)
-        bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
+        {
+          struct mach_o_nlist_64_external raw;
+
+          bfd_h_put_32 (abfd, str_index, raw.n_strx);
+          bfd_h_put_8 (abfd, s->n_type, raw.n_type);
+          bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
+          bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
+          bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
+                        raw.n_value);
+
+          if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+            goto err;
+        }
       else
-        bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
+        {
+          struct mach_o_nlist_external raw;
 
-      if (bfd_bwrite ((void *) buf, symlen, abfd) != symlen)
-        goto err;
+          bfd_h_put_32 (abfd, str_index, raw.n_strx);
+          bfd_h_put_8 (abfd, s->n_type, raw.n_type);
+          bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
+          bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
+          bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
+                        raw.n_value);
+
+          if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+            goto err;
+        }
     }
   sym->strsize = _bfd_stringtab_size (strtab);
   sym->stroff = mdata->filelen;
@@ -1099,14 +1148,18 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
   _bfd_stringtab_free (strtab);
 
   /* The command.  */
-  bfd_h_put_32 (abfd, sym->symoff, buf);
-  bfd_h_put_32 (abfd, sym->nsyms, buf + 4);
-  bfd_h_put_32 (abfd, sym->stroff, buf + 8);
-  bfd_h_put_32 (abfd, sym->strsize, buf + 12);
+  {
+    struct mach_o_symtab_command_external raw;
 
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || bfd_bwrite ((void *) buf, 16, abfd) != 16)
-    return FALSE;
+    bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
+    bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
+    bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
+    bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
+
+    if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+        || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+      return FALSE;
+  }
 
   return TRUE;
 
@@ -1191,17 +1244,17 @@ bfd_mach_o_write_contents (bfd *abfd)
 
   for (i = 0; i < mdata->header.ncmds; i++)
     {
-      unsigned char buf[8];
+      struct mach_o_load_command_external raw;
       bfd_mach_o_load_command *cur = &mdata->commands[i];
       unsigned long typeflag;
 
       typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
 
-      bfd_h_put_32 (abfd, typeflag, buf);
-      bfd_h_put_32 (abfd, cur->len, buf + 4);
+      bfd_h_put_32 (abfd, typeflag, raw.cmd);
+      bfd_h_put_32 (abfd, cur->len, raw.cmdsize);
 
       if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
-          || bfd_bwrite ((void *) buf, 8, abfd) != 8)
+          || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
        return FALSE;
 
       switch (cur->type)
@@ -1242,9 +1295,8 @@ bfd_mach_o_write_contents (bfd *abfd)
        case BFD_MACH_O_LC_SUB_FRAMEWORK:
          break;
        default:
-         fprintf (stderr,
-                  "unable to write unknown load command 0x%lx\n",
-                  (unsigned long) cur->type);
+         (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
+                                (unsigned long) cur->type);
          return FALSE;
        }
     }
@@ -1252,6 +1304,40 @@ bfd_mach_o_write_contents (bfd *abfd)
   return TRUE;
 }
 
+static void
+bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
+                                      asection *sec)
+{
+  bfd_mach_o_section *s = (bfd_mach_o_section *)sec->used_by_bfd;
+  if (seg->sect_head == NULL)
+    seg->sect_head = s;
+  else
+    seg->sect_tail->next = s;
+  seg->sect_tail = s;
+}
+
+/* Create section Mach-O flags from BFD flags.  */
+
+static void
+bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+{
+  flagword bfd_flags;
+  bfd_mach_o_section *s = bfd_mach_o_get_mach_o_section (sec);
+
+  /* Create default flags.  */
+  bfd_flags = bfd_get_section_flags (abfd, sec);
+  if ((bfd_flags & SEC_CODE) == SEC_CODE)
+    s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
+      | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
+      | BFD_MACH_O_S_REGULAR;
+  else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
+    s->flags = BFD_MACH_O_S_ZEROFILL;
+  else if (bfd_flags & SEC_DEBUGGING)
+    s->flags = BFD_MACH_O_S_REGULAR |  BFD_MACH_O_S_ATTR_DEBUG;
+  else
+    s->flags = BFD_MACH_O_S_REGULAR;
+}
+
 /* Build Mach-O load commands from the sections.  */
 
 bfd_boolean
@@ -1260,7 +1346,6 @@ bfd_mach_o_build_commands (bfd *abfd)
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
   unsigned int wide = mach_o_wide_p (&mdata->header);
   bfd_mach_o_segment_command *seg;
-  bfd_mach_o_section *sections;
   asection *sec;
   bfd_mach_o_load_command *cmd;
   bfd_mach_o_load_command *symtab_cmd;
@@ -1270,7 +1355,8 @@ bfd_mach_o_build_commands (bfd *abfd)
   if (mdata->header.ncmds)
     return FALSE;
 
-  /* Very simple version: 1 command (segment) containing all sections.  */
+  /* Very simple version: a command (segment) to contain all the sections and
+     a command for the symbol table.  */
   mdata->header.ncmds = 2;
   mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
                                * sizeof (bfd_mach_o_load_command));
@@ -1280,10 +1366,6 @@ bfd_mach_o_build_commands (bfd *abfd)
   seg = &cmd->command.segment;
 
   seg->nsects = bfd_count_sections (abfd);
-  sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
-  if (sections == NULL)
-    return FALSE;
-  seg->sections = sections;
 
   /* Set segment command.  */
   if (wide)
@@ -1329,30 +1411,31 @@ bfd_mach_o_build_commands (bfd *abfd)
   target_index = 0;
   for (sec = abfd->sections; sec; sec = sec->next)
     {
-      sections->bfdsection = sec;
-      bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
-      sections->addr = bfd_get_section_vma (abfd, sec);
-      sections->size = bfd_get_section_size (sec);
-      sections->align = bfd_get_section_alignment (abfd, sec);
+      bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
+
+      bfd_mach_o_append_section_to_segment (seg, sec);
 
-      if (sections->size != 0)
+      if (msect->flags == 0)
         {
-          mdata->filelen = FILE_ALIGN (mdata->filelen, sections->align);
-          sections->offset = mdata->filelen;
+          /* We suppose it hasn't been set.  Convert from BFD flags.  */
+          bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
+        }
+      msect->addr = bfd_get_section_vma (abfd, sec);
+      msect->size = bfd_get_section_size (sec);
+      msect->align = bfd_get_section_alignment (abfd, sec);
+
+      if (msect->size != 0)
+        {
+          mdata->filelen = FILE_ALIGN (mdata->filelen, msect->align);
+          msect->offset = mdata->filelen;
         }
       else
-        sections->offset = 0;
-      sections->reloff = 0;
-      sections->nreloc = 0;
-      sections->reserved1 = 0;
-      sections->reserved2 = 0;
-      sections->reserved3 = 0;
-
-      sec->filepos = sections->offset;
+        msect->offset = 0;
+
+      sec->filepos = msect->offset;
       sec->target_index = ++target_index;
 
-      mdata->filelen += sections->size;
-      sections++;
+      mdata->filelen += msect->size;
     }
   seg->filesize = mdata->filelen - seg->fileoff;
   seg->vmsize = seg->filesize;
@@ -1413,37 +1496,37 @@ bfd_mach_o_make_empty_symbol (bfd *abfd)
 static bfd_boolean
 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
 {
-  unsigned char buf[32];
+  struct mach_o_header_external raw;
   unsigned int size;
   bfd_vma (*get32) (const void *) = NULL;
 
   /* Just read the magic number.  */
   if (bfd_seek (abfd, 0, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, 4, abfd) != 4)
+      || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
     return FALSE;
 
-  if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC)
+  if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
     {
       header->byteorder = BFD_ENDIAN_BIG;
       header->magic = BFD_MACH_O_MH_MAGIC;
       header->version = 1;
       get32 = bfd_getb32;
     }
-  else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC)
+  else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
     {
       header->byteorder = BFD_ENDIAN_LITTLE;
       header->magic = BFD_MACH_O_MH_MAGIC;
       header->version = 1;
       get32 = bfd_getl32;
     }
-  else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64)
+  else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
     {
       header->byteorder = BFD_ENDIAN_BIG;
       header->magic = BFD_MACH_O_MH_MAGIC_64;
       header->version = 2;
       get32 = bfd_getb32;
     }
-  else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64)
+  else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
     {
       header->byteorder = BFD_ENDIAN_LITTLE;
       header->magic = BFD_MACH_O_MH_MAGIC_64;
@@ -1461,33 +1544,67 @@ bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
     BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
 
   if (bfd_seek (abfd, 0, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, size, abfd) != size)
+      || bfd_bread (&raw, size, abfd) != size)
     return FALSE;
 
-  header->cputype = (*get32) (buf + 4);
-  header->cpusubtype = (*get32) (buf + 8);
-  header->filetype = (*get32) (buf + 12);
-  header->ncmds = (*get32) (buf + 16);
-  header->sizeofcmds = (*get32) (buf + 20);
-  header->flags = (*get32) (buf + 24);
+  header->cputype = (*get32) (raw.cputype);
+  header->cpusubtype = (*get32) (raw.cpusubtype);
+  header->filetype = (*get32) (raw.filetype);
+  header->ncmds = (*get32) (raw.ncmds);
+  header->sizeofcmds = (*get32) (raw.sizeofcmds);
+  header->flags = (*get32) (raw.flags);
 
   if (mach_o_wide_p (header))
-    header->reserved = (*get32) (buf + 28);
+    header->reserved = (*get32) (raw.reserved);
 
   return TRUE;
 }
 
-static asection *
-bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
-                            unsigned long prot)
+bfd_boolean
+bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
+{
+  bfd_mach_o_section *s;
+
+  s = bfd_mach_o_get_mach_o_section (sec);
+  if (s == NULL)
+    {
+      flagword bfd_flags;
+
+      s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
+      if (s == NULL)
+       return FALSE;
+      sec->used_by_bfd = s;
+      s->bfdsection = sec;
+
+      /* Create default name.  */
+      bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
+
+      /* Create default flags.  */
+      bfd_flags = bfd_get_section_flags (abfd, sec);
+      if ((bfd_flags & SEC_CODE) == SEC_CODE)
+        s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
+          | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
+          | BFD_MACH_O_S_REGULAR;
+      else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
+        s->flags = BFD_MACH_O_S_ZEROFILL;
+      else if (bfd_flags & SEC_DEBUGGING)
+        s->flags = BFD_MACH_O_S_REGULAR |  BFD_MACH_O_S_ATTR_DEBUG;
+      else
+        s->flags = BFD_MACH_O_S_REGULAR;
+    }
+
+  return _bfd_generic_new_section_hook (abfd, sec);
+}
+
+static void
+bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
+                                     unsigned long prot)
 {
-  asection *bfdsec;
-  char *sname;
   flagword flags;
+  bfd_mach_o_section *section;
 
-  bfd_mach_o_convert_section_name_to_bfd (abfd, section, &sname, &flags);
-  if (sname == NULL)
-    return NULL;
+  flags = bfd_get_section_flags (abfd, sec);
+  section = bfd_mach_o_get_mach_o_section (sec);
 
   if (flags == SEC_NO_FLAGS)
     {
@@ -1521,103 +1638,122 @@ bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
   if (section->nreloc != 0)
     flags |= SEC_RELOC;
 
-  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
-  if (bfdsec == NULL)
-    return NULL;
+  bfd_set_section_flags (abfd, sec, flags);
 
-  bfdsec->vma = section->addr;
-  bfdsec->lma = section->addr;
-  bfdsec->size = section->size;
-  bfdsec->filepos = section->offset;
-  bfdsec->alignment_power = section->align;
-  bfdsec->segment_mark = 0;
-  bfdsec->reloc_count = section->nreloc;
-  bfdsec->rel_filepos = section->reloff;
+  sec->vma = section->addr;
+  sec->lma = section->addr;
+  sec->size = section->size;
+  sec->filepos = section->offset;
+  sec->alignment_power = section->align;
+  sec->segment_mark = 0;
+  sec->reloc_count = section->nreloc;
+  sec->rel_filepos = section->reloff;
+}
 
-  return bfdsec;
+static asection *
+bfd_mach_o_make_bfd_section (bfd *abfd,
+                             const unsigned char *segname,
+                             const unsigned char *sectname)
+{
+  const char *sname;
+  flagword flags;
+
+  bfd_mach_o_convert_section_name_to_bfd
+    (abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
+  if (sname == NULL)
+    return NULL;
+
+  return bfd_make_section_anyway_with_flags (abfd, sname, flags);
 }
 
-static int
+static asection *
 bfd_mach_o_read_section_32 (bfd *abfd,
-                            bfd_mach_o_section *section,
                             unsigned int offset,
                             unsigned long prot)
 {
-  unsigned char buf[BFD_MACH_O_SECTION_SIZE];
+  struct mach_o_section_32_external raw;
+  asection *sec;
+  bfd_mach_o_section *section;
 
   if (bfd_seek (abfd, offset, SEEK_SET) != 0
-      || (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
+      || (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
           != BFD_MACH_O_SECTION_SIZE))
-    return -1;
+    return NULL;
 
-  memcpy (section->sectname, buf, 16);
-  section->sectname[16] = '\0';
-  memcpy (section->segname, buf + 16, 16);
-  section->segname[16] = '\0';
-  section->addr = bfd_h_get_32 (abfd, buf + 32);
-  section->size = bfd_h_get_32 (abfd, buf + 36);
-  section->offset = bfd_h_get_32 (abfd, buf + 40);
-  section->align = bfd_h_get_32 (abfd, buf + 44);
-  section->reloff = bfd_h_get_32 (abfd, buf + 48);
-  section->nreloc = bfd_h_get_32 (abfd, buf + 52);
-  section->flags = bfd_h_get_32 (abfd, buf + 56);
-  section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
-  section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
+  sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
+  if (sec == NULL)
+    return NULL;
+
+  section = bfd_mach_o_get_mach_o_section (sec);
+  memcpy (section->segname, raw.segname, sizeof (raw.segname));
+  section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
+  memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
+  section->segname[BFD_MACH_O_SECTNAME_SIZE] = 0;
+  section->addr = bfd_h_get_32 (abfd, raw.addr);
+  section->size = bfd_h_get_32 (abfd, raw.size);
+  section->offset = bfd_h_get_32 (abfd, raw.offset);
+  section->align = bfd_h_get_32 (abfd, raw.align);
+  section->reloff = bfd_h_get_32 (abfd, raw.reloff);
+  section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
+  section->flags = bfd_h_get_32 (abfd, raw.flags);
+  section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
+  section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
   section->reserved3 = 0;
-  section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
 
-  if (section->bfdsection == NULL)
-    return -1;
+  bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
 
-  return 0;
+  return sec;
 }
 
-static int
+static asection *
 bfd_mach_o_read_section_64 (bfd *abfd,
-                            bfd_mach_o_section *section,
                             unsigned int offset,
                             unsigned long prot)
 {
-  unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
+  struct mach_o_section_64_external raw;
+  asection *sec;
+  bfd_mach_o_section *section;
 
   if (bfd_seek (abfd, offset, SEEK_SET) != 0
-      || (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
+      || (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
           != BFD_MACH_O_SECTION_64_SIZE))
-    return -1;
+    return NULL;
 
-  memcpy (section->sectname, buf, 16);
-  section->sectname[16] = '\0';
-  memcpy (section->segname, buf + 16, 16);
-  section->segname[16] = '\0';
-  section->addr = bfd_h_get_64 (abfd, buf + 32);
-  section->size = bfd_h_get_64 (abfd, buf + 40);
-  section->offset = bfd_h_get_32 (abfd, buf + 48);
-  section->align = bfd_h_get_32 (abfd, buf + 52);
-  section->reloff = bfd_h_get_32 (abfd, buf + 56);
-  section->nreloc = bfd_h_get_32 (abfd, buf + 60);
-  section->flags = bfd_h_get_32 (abfd, buf + 64);
-  section->reserved1 = bfd_h_get_32 (abfd, buf + 68);
-  section->reserved2 = bfd_h_get_32 (abfd, buf + 72);
-  section->reserved3 = bfd_h_get_32 (abfd, buf + 76);
-  section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
-
-  if (section->bfdsection == NULL)
-    return -1;
+  sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
+  if (sec == NULL)
+    return NULL;
 
-  return 0;
+  section = bfd_mach_o_get_mach_o_section (sec);
+  memcpy (section->segname, raw.segname, sizeof (raw.segname));
+  section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
+  memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
+  section->segname[BFD_MACH_O_SECTNAME_SIZE] = 0;
+  section->addr = bfd_h_get_64 (abfd, raw.addr);
+  section->size = bfd_h_get_64 (abfd, raw.size);
+  section->offset = bfd_h_get_32 (abfd, raw.offset);
+  section->align = bfd_h_get_32 (abfd, raw.align);
+  section->reloff = bfd_h_get_32 (abfd, raw.reloff);
+  section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
+  section->flags = bfd_h_get_32 (abfd, raw.flags);
+  section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
+  section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
+  section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
+
+  bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
+
+  return sec;
 }
 
-static int
+static asection *
 bfd_mach_o_read_section (bfd *abfd,
-                         bfd_mach_o_section *section,
                          unsigned int offset,
                          unsigned long prot,
                          unsigned int wide)
 {
   if (wide)
-    return bfd_mach_o_read_section_64 (abfd, section, offset, prot);
+    return bfd_mach_o_read_section_64 (abfd, offset, prot);
   else
-    return bfd_mach_o_read_section_32 (abfd, section, offset, prot);
+    return bfd_mach_o_read_section_32 (abfd, offset, prot);
 }
 
 static int
@@ -1631,7 +1767,7 @@ bfd_mach_o_read_symtab_symbol (bfd *abfd,
   unsigned int symwidth =
     wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
   unsigned int symoff = sym->symoff + (i * symwidth);
-  unsigned char buf[16];
+  struct mach_o_nlist_64_external raw;
   unsigned char type = -1;
   unsigned char section = -1;
   short desc = -1;
@@ -1642,27 +1778,30 @@ bfd_mach_o_read_symtab_symbol (bfd *abfd,
   BFD_ASSERT (sym->strtab != NULL);
 
   if (bfd_seek (abfd, symoff, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, symwidth, abfd) != symwidth)
+      || bfd_bread (&raw, symwidth, abfd) != symwidth)
     {
-      fprintf (stderr, "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu\n",
-              symwidth, (unsigned long) symoff);
+      (*_bfd_error_handler)
+        (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
+         symwidth, (unsigned long) symoff);
       return -1;
     }
 
-  stroff = bfd_h_get_32 (abfd, buf);
-  type = bfd_h_get_8 (abfd, buf + 4);
+  stroff = bfd_h_get_32 (abfd, raw.n_strx);
+  type = bfd_h_get_8 (abfd, raw.n_type);
   symtype = type & BFD_MACH_O_N_TYPE;
-  section = bfd_h_get_8 (abfd, buf + 5);
-  desc = bfd_h_get_16 (abfd, buf + 6);
+  section = bfd_h_get_8 (abfd, raw.n_sect);
+  desc = bfd_h_get_16 (abfd, raw.n_desc);
   if (wide)
-    value = bfd_h_get_64 (abfd, buf + 8);
+    value = bfd_h_get_64 (abfd, raw.n_value);
   else
-    value = bfd_h_get_32 (abfd, buf + 8);
+    value = bfd_h_get_32 (abfd, raw.n_value);
 
   if (stroff >= sym->strsize)
     {
-      fprintf (stderr, "bfd_mach_o_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
-              (unsigned long) stroff, (unsigned long) sym->strsize);
+      (*_bfd_error_handler)
+        (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
+         (unsigned long) stroff,
+         (unsigned long) sym->strsize);
       return -1;
     }
 
@@ -1745,23 +1884,23 @@ bfd_mach_o_read_symtab_symbol (bfd *abfd,
              /* Mach-O uses 0 to mean "no section"; not an error.  */
              if (section != 0)
                {
-                 fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
-                          "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
-                          s->symbol.name, section, mdata->nsects);
+                 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
+                                          "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
+                                        s->symbol.name, section, mdata->nsects);
                }
              s->symbol.section = bfd_und_section_ptr;
            }
          break;
        case BFD_MACH_O_N_INDR:
-         fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
-                  "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
-                  s->symbol.name);
+         (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
+                                  "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"),
+                                s->symbol.name);
          s->symbol.section = bfd_und_section_ptr;
          break;
        default:
-         fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
-                  "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
-                  s->symbol.name, symtype);
+         (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
+                                  "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
+                                s->symbol.name, symtype);
          s->symbol.section = bfd_und_section_ptr;
          break;
        }
@@ -1822,14 +1961,17 @@ bfd_mach_o_read_symtab_symbols (bfd *abfd)
   unsigned long i;
   int ret;
 
-  if (sym->symbols)
-    return 0;
+  if (sym == NULL || sym->symbols)
+    {
+      /* Return now if there are no symbols or if already loaded.  */
+      return 0;
+    }
 
   sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
 
   if (sym->symbols == NULL)
     {
-      fprintf (stderr, "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols\n");
+      (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
       return -1;
     }
 
@@ -1856,18 +1998,19 @@ bfd_mach_o_read_dysymtab_symbol (bfd *abfd,
 {
   unsigned long isymoff = dysym->indirectsymoff + (i * 4);
   unsigned long sym_index;
-  unsigned char buf[4];
+  unsigned char raw[4];
 
   BFD_ASSERT (i < dysym->nindirectsyms);
 
   if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, 4, abfd) != 4)
+      || bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
     {
-      fprintf (stderr, "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
-              (unsigned long) 4, isymoff);
+      (*_bfd_error_handler)
+        (_("bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"),
+         (unsigned long) sizeof (raw), isymoff);
       return -1;
     }
-  sym_index = bfd_h_get_32 (abfd, buf);
+  sym_index = bfd_h_get_32 (abfd, raw);
 
   return bfd_mach_o_read_symtab_symbol (abfd, sym, s, sym_index);
 }
@@ -1913,17 +2056,17 @@ static int
 bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
 {
   bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
-  unsigned char buf[4];
+  struct mach_o_str_command_external raw;
   unsigned int nameoff;
 
   BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
              || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
 
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, 4, abfd) != 4)
+  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
     return -1;
 
-  nameoff = bfd_h_get_32 (abfd, buf + 0);
+  nameoff = bfd_h_get_32 (abfd, raw.str);
 
   cmd->name_offset = command->offset + nameoff;
   cmd->name_len = command->len - nameoff;
@@ -1940,7 +2083,7 @@ static int
 bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
 {
   bfd_mach_o_dylib_command *cmd = &command->command.dylib;
-  unsigned char buf[16];
+  struct mach_o_dylib_command_external raw;
   unsigned int nameoff;
 
   switch (command->type)
@@ -1955,14 +2098,14 @@ bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
       return -1;
     }
 
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, 16, abfd) != 16)
+  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
     return -1;
 
-  nameoff = bfd_h_get_32 (abfd, buf + 0);
-  cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
-  cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
-  cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
+  nameoff = bfd_h_get_32 (abfd, raw.name);
+  cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
+  cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
+  cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
 
   cmd->name_offset = command->offset + nameoff;
   cmd->name_len = command->len - nameoff;
@@ -1990,7 +2133,6 @@ bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
 {
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
   bfd_mach_o_thread_command *cmd = &command->command.thread;
-  unsigned char buf[8];
   unsigned int offset;
   unsigned int nflavours;
   unsigned int i;
@@ -2003,14 +2145,16 @@ bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
   nflavours = 0;
   while (offset != command->len)
     {
+      struct mach_o_thread_command_external raw;
+
       if (offset >= command->len)
        return -1;
 
       if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
-          || bfd_bread ((void *) buf, 8, abfd) != 8)
+          || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
        return -1;
 
-      offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
+      offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
       nflavours++;
     }
 
@@ -2025,6 +2169,8 @@ bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
   nflavours = 0;
   while (offset != command->len)
     {
+      struct mach_o_thread_command_external raw;
+
       if (offset >= command->len)
        return -1;
 
@@ -2032,13 +2178,13 @@ bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
        return -1;
 
       if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
-          || bfd_bread ((void *) buf, 8, abfd) != 8)
+          || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
        return -1;
 
-      cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
-      cmd->flavours[nflavours].offset = command->offset + offset + 8;
-      cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
-      offset += cmd->flavours[nflavours].size + 8;
+      cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
+      cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
+      cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
+      offset += cmd->flavours[nflavours].size + sizeof (raw);
       nflavours++;
     }
 
@@ -2098,32 +2244,35 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
 {
   bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
-  unsigned char buf[72];
 
   BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
 
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, 72, abfd) != 72)
-    return -1;
+  {
+    struct mach_o_dysymtab_command_external raw;
+
+    if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+        || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+      return -1;
 
-  cmd->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
-  cmd->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
-  cmd->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
-  cmd->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
-  cmd->iundefsym = bfd_h_get_32 (abfd, buf + 16);
-  cmd->nundefsym = bfd_h_get_32 (abfd, buf + 20);
-  cmd->tocoff = bfd_h_get_32 (abfd, buf + 24);
-  cmd->ntoc = bfd_h_get_32 (abfd, buf + 28);
-  cmd->modtaboff = bfd_h_get_32 (abfd, buf + 32);
-  cmd->nmodtab = bfd_h_get_32 (abfd, buf + 36);
-  cmd->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
-  cmd->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
-  cmd->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
-  cmd->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
-  cmd->extreloff = bfd_h_get_32 (abfd, buf + 56);
-  cmd->nextrel = bfd_h_get_32 (abfd, buf + 60);
-  cmd->locreloff = bfd_h_get_32 (abfd, buf + 64);
-  cmd->nlocrel = bfd_h_get_32 (abfd, buf + 68);
+    cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
+    cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
+    cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
+    cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
+    cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
+    cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
+    cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
+    cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
+    cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
+    cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
+    cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
+    cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
+    cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
+    cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
+    cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
+    cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
+    cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
+    cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
+  }
 
   if (cmd->nmodtab != 0)
     {
@@ -2143,6 +2292,7 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
         {
           bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
           unsigned long v;
+          unsigned char buf[56];
 
           if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
             return -1;
@@ -2189,13 +2339,14 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
 
       for (i = 0; i < cmd->ntoc; i++)
         {
+          struct mach_o_dylib_table_of_contents_external raw;
           bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
 
-          if (bfd_bread ((void *) buf, 8, abfd) != 8)
+          if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
             return -1;
 
-          toc->symbol_index = bfd_h_get_32 (abfd, buf + 0);
-          toc->module_index = bfd_h_get_32 (abfd, buf + 4);
+          toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
+          toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
         }
     }
 
@@ -2213,12 +2364,13 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
 
       for (i = 0; i < cmd->nindirectsyms; i++)
         {
+          unsigned char raw[4];
           unsigned int *is = &cmd->indirect_syms[i];
 
-          if (bfd_bread ((void *) buf, 4, abfd) != 4)
+          if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
             return -1;
 
-          *is = bfd_h_get_32 (abfd, buf + 0);
+          *is = bfd_h_get_32 (abfd, raw);
         }
     }
 
@@ -2237,14 +2389,15 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
 
       for (i = 0; i < cmd->nextrefsyms; i++)
         {
+          unsigned char raw[4];
           bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
 
-          if (bfd_bread ((void *) buf, 4, abfd) != 4)
+          if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
             return -1;
 
           /* Fields isym and flags are written as bit-fields, thus we need
              a specific processing for endianness.  */
-          v = bfd_h_get_32 (abfd, buf + 0);
+          v = bfd_h_get_32 (abfd, raw);
           if (bfd_big_endian (abfd))
             {
               ref->isym = (v >> 8) & 0xffffff;
@@ -2270,18 +2423,18 @@ bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
 {
   bfd_mach_o_symtab_command *symtab = &command->command.symtab;
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
-  unsigned char buf[16];
+  struct mach_o_symtab_command_external raw;
 
   BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
 
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, 16, abfd) != 16)
+  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
     return -1;
 
-  symtab->symoff = bfd_h_get_32 (abfd, buf);
-  symtab->nsyms = bfd_h_get_32 (abfd, buf + 4);
-  symtab->stroff = bfd_h_get_32 (abfd, buf + 8);
-  symtab->strsize = bfd_h_get_32 (abfd, buf + 12);
+  symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
+  symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
+  symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
+  symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
   symtab->symbols = NULL;
   symtab->strtab = NULL;
 
@@ -2301,8 +2454,8 @@ bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
 
   BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
 
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || bfd_bread ((void *) cmd->uuid, 16, abfd) != 16)
+  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+      || bfd_bread (cmd->uuid, 16, abfd) != 16)
     return -1;
 
   return 0;
@@ -2312,14 +2465,14 @@ static int
 bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
 {
   bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
-  char buf[8];
+  struct mach_o_linkedit_data_command_external raw;
 
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, 8, abfd) != 8)
+  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
     return -1;
 
-  cmd->dataoff = bfd_get_32 (abfd, buf + 0);
-  cmd->datasize = bfd_get_32 (abfd, buf + 4);
+  cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
+  cmd->datasize = bfd_get_32 (abfd, raw.datasize);
   return 0;
 }
 
@@ -2327,14 +2480,14 @@ static int
 bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
 {
   bfd_mach_o_str_command *cmd = &command->command.str;
-  char buf[4];
+  struct mach_o_str_command_external raw;
   unsigned long off;
 
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, 4, abfd) != 4)
+  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
     return -1;
 
-  off = bfd_get_32 (abfd, buf + 0);
+  off = bfd_get_32 (abfd, raw.str);
   cmd->stroff = command->offset + off;
   cmd->str_len = command->len - off;
   cmd->str = bfd_alloc (abfd, cmd->str_len);
@@ -2350,96 +2503,116 @@ static int
 bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
 {
   bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
-  char buf[40];
+  struct mach_o_dyld_info_command_external raw;
 
-  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, sizeof (buf), abfd) != sizeof (buf))
+  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
     return -1;
 
-  cmd->rebase_off = bfd_get_32 (abfd, buf + 0);
-  cmd->rebase_size = bfd_get_32 (abfd, buf + 4);
-  cmd->bind_off = bfd_get_32 (abfd, buf + 8);
-  cmd->bind_size = bfd_get_32 (abfd, buf + 12);
-  cmd->weak_bind_off = bfd_get_32 (abfd, buf + 16);
-  cmd->weak_bind_size = bfd_get_32 (abfd, buf + 20);
-  cmd->lazy_bind_off = bfd_get_32 (abfd, buf + 24);
-  cmd->lazy_bind_size = bfd_get_32 (abfd, buf + 28);
-  cmd->export_off = bfd_get_32 (abfd, buf + 32);
-  cmd->export_size = bfd_get_32 (abfd, buf + 36);
+  cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
+  cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
+  cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
+  cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
+  cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
+  cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
+  cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
+  cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
+  cmd->export_off = bfd_get_32 (abfd, raw.export_off);
+  cmd->export_size = bfd_get_32 (abfd, raw.export_size);
   return 0;
 }
 
+static bfd_boolean
+bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
+{
+  bfd_mach_o_version_min_command *cmd = &command->command.version_min;
+  struct mach_o_version_min_command_external raw;
+  unsigned int ver;
+
+  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+    return FALSE;
+
+  ver = bfd_get_32 (abfd, raw.version);
+  cmd->rel = ver >> 16;
+  cmd->maj = ver >> 8;
+  cmd->min = ver;
+  cmd->reserved = bfd_get_32 (abfd, raw.reserved);
+  return TRUE;
+}
+
 static int
 bfd_mach_o_read_segment (bfd *abfd,
                          bfd_mach_o_load_command *command,
                          unsigned int wide)
 {
-  unsigned char buf[64];
   bfd_mach_o_segment_command *seg = &command->command.segment;
   unsigned long i;
 
   if (wide)
     {
+      struct mach_o_segment_command_64_external raw;
+
       BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
 
-      if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-          || bfd_bread ((void *) buf, 64, abfd) != 64)
-       return -1;
+      if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+          || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+        return -1;
 
-      memcpy (seg->segname, buf, 16);
+      memcpy (seg->segname, raw.segname, 16);
       seg->segname[16] = '\0';
 
-      seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
-      seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
-      seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
-      seg->filesize = bfd_h_get_64 (abfd, buf + 40);
-      seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
-      seg->initprot = bfd_h_get_32 (abfd, buf + 52);
-      seg->nsects = bfd_h_get_32 (abfd, buf + 56);
-      seg->flags = bfd_h_get_32 (abfd, buf + 60);
+      seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
+      seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
+      seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
+      seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
+      seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
+      seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
+      seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
+      seg->flags = bfd_h_get_32 (abfd, raw.flags);
     }
   else
     {
+      struct mach_o_segment_command_32_external raw;
+
       BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
 
-      if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
-          || bfd_bread ((void *) buf, 48, abfd) != 48)
-       return -1;
+      if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+          || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+        return -1;
 
-      memcpy (seg->segname, buf, 16);
+      memcpy (seg->segname, raw.segname, 16);
       seg->segname[16] = '\0';
 
-      seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
-      seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
-      seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
-      seg->filesize = bfd_h_get_32 (abfd, buf +  28);
-      seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
-      seg->initprot = bfd_h_get_32 (abfd, buf + 36);
-      seg->nsects = bfd_h_get_32 (abfd, buf + 40);
-      seg->flags = bfd_h_get_32 (abfd, buf + 44);
+      seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
+      seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
+      seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
+      seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
+      seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
+      seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
+      seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
+      seg->flags = bfd_h_get_32 (abfd, raw.flags);
     }
+  seg->sect_head = NULL;
+  seg->sect_tail = NULL;
 
-  if (seg->nsects != 0)
+  for (i = 0; i < seg->nsects; i++)
     {
-      seg->sections = bfd_alloc (abfd, seg->nsects
-                                 * sizeof (bfd_mach_o_section));
-      if (seg->sections == NULL)
-       return -1;
+      bfd_vma segoff;
+      asection *sec;
 
-      for (i = 0; i < seg->nsects; i++)
-       {
-         bfd_vma segoff;
-          if (wide)
-            segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
-              + (i * BFD_MACH_O_SECTION_64_SIZE);
-          else
-            segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
-              + (i * BFD_MACH_O_SECTION_SIZE);
+      if (wide)
+        segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
+          + (i * BFD_MACH_O_SECTION_64_SIZE);
+      else
+        segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
+          + (i * BFD_MACH_O_SECTION_SIZE);
 
-         if (bfd_mach_o_read_section
-             (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
-           return -1;
-       }
+      sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
+      if (sec == NULL)
+        return -1;
+
+      bfd_mach_o_append_section_to_segment (seg, sec);
     }
 
   return 0;
@@ -2460,17 +2633,18 @@ bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
 static int
 bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
 {
-  unsigned char buf[8];
+  struct mach_o_load_command_external raw;
+  unsigned int cmd;
 
   /* Read command type and length.  */
   if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, 8, abfd) != 8)
+      || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
     return -1;
 
-  command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD;
-  command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
-                           ? TRUE : FALSE);
-  command->len = bfd_h_get_32 (abfd, buf + 4);
+  cmd = bfd_h_get_32 (abfd, raw.cmd);
+  command->type =  cmd & ~BFD_MACH_O_LC_REQ_DYLD;
+  command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
+  command->len = bfd_h_get_32 (abfd, raw.cmdsize);
 
   switch (command->type)
     {
@@ -2515,6 +2689,7 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
     case BFD_MACH_O_LC_FVMFILE:
     case BFD_MACH_O_LC_PREPAGE:
     case BFD_MACH_O_LC_ROUTINES:
+    case BFD_MACH_O_LC_ROUTINES_64:
       break;
     case BFD_MACH_O_LC_SUB_FRAMEWORK:
     case BFD_MACH_O_LC_SUB_UMBRELLA:
@@ -2537,6 +2712,7 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
       break;
     case BFD_MACH_O_LC_CODE_SIGNATURE:
     case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
+    case BFD_MACH_O_LC_FUNCTION_STARTS:
       if (bfd_mach_o_read_linkedit (abfd, command) != 0)
        return -1;
       break;
@@ -2544,9 +2720,14 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
       if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
        return -1;
       break;
+    case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
+    case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
+      if (!bfd_mach_o_read_version_min (abfd, command))
+       return -1;
+      break;
     default:
-      fprintf (stderr, "unable to read unknown load command 0x%lx\n",
-              (unsigned long) command->type);
+      (*_bfd_error_handler) (_("unable to read unknown load command 0x%lx"),
+                            (unsigned long) command->type);
       break;
     }
 
@@ -2558,7 +2739,7 @@ bfd_mach_o_flatten_sections (bfd *abfd)
 {
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
   long csect = 0;
-  unsigned long i, j;
+  unsigned long i;
 
   /* Count total number of sections.  */
   mdata->nsects = 0;
@@ -2588,12 +2769,13 @@ bfd_mach_o_flatten_sections (bfd *abfd)
          || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
        {
          bfd_mach_o_segment_command *seg;
+          bfd_mach_o_section *sec;
 
          seg = &mdata->commands[i].command.segment;
          BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
 
-         for (j = 0; j < seg->nsects; j++)
-           mdata->sections[csect++] = &seg->sections[j];
+          for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+           mdata->sections[csect++] = sec;
        }
     }
 }
@@ -2725,8 +2907,8 @@ bfd_mach_o_scan (bfd *abfd,
                                   &cputype, &cpusubtype);
   if (cputype == bfd_arch_unknown)
     {
-      fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
-              header->cputype, header->cpusubtype);
+      (*_bfd_error_handler) (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
+                            header->cputype, header->cpusubtype);
       return -1;
     }
 
@@ -2821,8 +3003,8 @@ bfd_mach_o_header_p (bfd *abfd,
   if (! (header.byteorder == BFD_ENDIAN_BIG
         || header.byteorder == BFD_ENDIAN_LITTLE))
     {
-      fprintf (stderr, "unknown header byte-order value 0x%lx\n",
-              (unsigned long) header.byteorder);
+      (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
+                            (unsigned long) header.byteorder);
       goto wrong;
     }
 
@@ -2923,19 +3105,19 @@ const bfd_target *
 bfd_mach_o_archive_p (bfd *abfd)
 {
   mach_o_fat_data_struct *adata = NULL;
-  unsigned char buf[20];
+  struct mach_o_fat_header_external hdr;
   unsigned long i;
 
   if (bfd_seek (abfd, 0, SEEK_SET) != 0
-      || bfd_bread ((void *) buf, 8, abfd) != 8)
+      || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
     goto error;
 
   adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
   if (adata == NULL)
     goto error;
 
-  adata->magic = bfd_getb32 (buf);
-  adata->nfat_arch = bfd_getb32 (buf + 4);
+  adata->magic = bfd_getb32 (hdr.magic);
+  adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
   if (adata->magic != 0xcafebabe)
     goto error;
   /* Avoid matching Java bytecode files, which have the same magic number.
@@ -2951,14 +3133,14 @@ bfd_mach_o_archive_p (bfd *abfd)
 
   for (i = 0; i < adata->nfat_arch; i++)
     {
-      if (bfd_seek (abfd, 8 + 20 * i, SEEK_SET) != 0
-          || bfd_bread ((void *) buf, 20, abfd) != 20)
+      struct mach_o_fat_arch_external arch;
+      if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
        goto error;
-      adata->archentries[i].cputype = bfd_getb32 (buf);
-      adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
-      adata->archentries[i].offset = bfd_getb32 (buf + 8);
-      adata->archentries[i].size = bfd_getb32 (buf + 12);
-      adata->archentries[i].align = bfd_getb32 (buf + 16);
+      adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
+      adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
+      adata->archentries[i].offset = bfd_getb32 (arch.offset);
+      adata->archentries[i].size = bfd_getb32 (arch.size);
+      adata->archentries[i].align = bfd_getb32 (arch.align);
     }
 
   abfd->tdata.mach_o_fat_data = adata;
@@ -3102,53 +3284,6 @@ bfd_mach_o_fat_extract (bfd *abfd,
   return NULL;
 }
 
-int
-bfd_mach_o_lookup_section (bfd *abfd,
-                          asection *section,
-                          bfd_mach_o_load_command **mcommand,
-                          bfd_mach_o_section **msection)
-{
-  struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
-  unsigned int i, j, num;
-
-  bfd_mach_o_load_command *ncmd = NULL;
-  bfd_mach_o_section *nsect = NULL;
-
-  BFD_ASSERT (mcommand != NULL);
-  BFD_ASSERT (msection != NULL);
-
-  num = 0;
-  for (i = 0; i < md->header.ncmds; i++)
-    {
-      struct bfd_mach_o_load_command *cmd = &md->commands[i];
-      struct bfd_mach_o_segment_command *seg = NULL;
-
-      if (cmd->type != BFD_MACH_O_LC_SEGMENT
-         || cmd->type != BFD_MACH_O_LC_SEGMENT_64)
-       continue;
-      seg = &cmd->command.segment;
-
-      for (j = 0; j < seg->nsects; j++)
-       {
-         struct bfd_mach_o_section *sect = &seg->sections[j];
-
-         if (sect->bfdsection == section)
-           {
-             if (num == 0)
-                {
-                  nsect = sect;
-                  ncmd = cmd;
-                }
-             num++;
-           }
-       }
-    }
-
-  *mcommand = ncmd;
-  *msection = nsect;
-  return num;
-}
-
 int
 bfd_mach_o_lookup_command (bfd *abfd,
                           bfd_mach_o_load_command_type type,
@@ -3239,12 +3374,24 @@ bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
 }
 
 static const char *
-bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
+bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
+                             unsigned long val)
 {
   for (; table->name; table++)
     if (table->val == val)
       return table->name;
-  return "*UNKNOWN*";
+  return NULL;
+}
+
+static const char *
+bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
+{
+  const char *res = bfd_mach_o_get_name_or_null (table, val);
+
+  if (res == NULL)
+    return "*UNKNOWN*";
+  else
+    return res;
 }
 
 static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
@@ -3382,9 +3529,40 @@ static bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
   { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
   { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
   { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
+  { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
+  { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
+  { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
+  { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
+  { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
   { NULL, 0}
 };
 
+/* Get the section type from NAME.  Return -1 if NAME is unknown.  */
+
+unsigned int
+bfd_mach_o_get_section_type_from_name (const char *name)
+{
+  bfd_mach_o_xlat_name *x;
+
+  for (x = bfd_mach_o_section_type_name; x->name; x++)
+    if (strcmp (x->name, name) == 0)
+      return x->val;
+  return (unsigned int)-1;
+}
+
+/* Get the section attribute from NAME.  Return -1 if NAME is unknown.  */
+
+unsigned int
+bfd_mach_o_get_section_attribute_from_name (const char *name)
+{
+  bfd_mach_o_xlat_name *x;
+
+  for (x = bfd_mach_o_section_attribute_name; x->name; x++)
+    if (strcmp (x->name, name) == 0)
+      return x->val;
+  return (unsigned int)-1;
+}
+
 static void
 bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
 {
@@ -3411,7 +3589,7 @@ static void
 bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
 {
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
-  unsigned int i, j;
+  unsigned int i;
   unsigned int sec_nbr = 0;
 
   fputs (_("Segments and Sections:\n"), file);
@@ -3420,6 +3598,7 @@ bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
   for (i = 0; i < mdata->header.ncmds; i++)
     {
       bfd_mach_o_segment_command *seg;
+      bfd_mach_o_section *sec;
 
       if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
          && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
@@ -3436,9 +3615,9 @@ bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
       fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
       fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
       fprintf (file, "]\n");
-      for (j = 0; j < seg->nsects; j++)
+
+      for (sec = seg->sect_head; sec != NULL; sec = sec->next)
        {
-         bfd_mach_o_section *sec = &seg->sections[j];
          fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
                   sec->segname, sec->sectname);
          fprintf_vma (file, sec->addr);
@@ -3504,7 +3683,7 @@ bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
                           bfd_mach_o_load_command *cmd, FILE *file)
 {
   bfd_mach_o_segment_command *seg = &cmd->command.segment;
-  unsigned int i;
+  bfd_mach_o_section *sec;
 
   fprintf (file, " name: %s\n", *seg->segname ? seg->segname : "*none*");
   fprintf (file, "    vmaddr: ");
@@ -3521,8 +3700,8 @@ bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
   fprintf (file, "\n");
   fprintf (file, "   nsects: %lu  ", seg->nsects);
   fprintf (file, " flags: %lx\n", seg->flags);
-  for (i = 0; i < seg->nsects; i++)
-    bfd_mach_o_print_section (abfd, &seg->sections[i], file);
+  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+    bfd_mach_o_print_section (abfd, sec, file);
 }
 
 static void
@@ -3748,9 +3927,16 @@ bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void * ptr)
   for (i = 0; i < mdata->header.ncmds; i++)
     {
       bfd_mach_o_load_command *cmd = &mdata->commands[i];
+      const char *cmd_name;
       
-      fprintf (file, "Load command %s:",
-               bfd_mach_o_get_name (bfd_mach_o_load_command_name, cmd->type));
+      cmd_name = bfd_mach_o_get_name_or_null
+        (bfd_mach_o_load_command_name, cmd->type);
+      fprintf (file, "Load command ");
+      if (cmd_name == NULL)
+        fprintf (file, "0x%02x:", cmd->type);
+      else
+        fprintf (file, "%s:", cmd_name);
+
       switch (cmd->type)
        {
        case BFD_MACH_O_LC_SEGMENT:
@@ -3808,6 +3994,7 @@ bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void * ptr)
           break;
         case BFD_MACH_O_LC_CODE_SIGNATURE:
         case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
+        case BFD_MACH_O_LC_FUNCTION_STARTS:
          {
            bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
            fprintf
@@ -3862,8 +4049,18 @@ bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void * ptr)
           fprintf (file, "\n");
           bfd_mach_o_print_dyld_info (abfd, cmd, file);
           break;
+       case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
+       case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
+          {
+            bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
+
+            fprintf (file, " %u.%u.%u\n", ver->rel, ver->maj, ver->min);
+          }
+          break;
        default:
          fprintf (file, "\n");
+          fprintf (file, "  offset: 0x%08lx\n", (unsigned long)cmd->offset);
+          fprintf (file, "    size: 0x%08lx\n", (unsigned long)cmd->len);
          break;
        }
       fputc ('\n', file);
@@ -4020,6 +4217,21 @@ bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
 #undef TARGET_BIG_ENDIAN
 #undef TARGET_ARCHIVE
 
+/* Not yet handled: creating an archive.  */
+#define bfd_mach_o_mkarchive                      _bfd_noarchive_mkarchive
+
+/* Not used.  */
+#define bfd_mach_o_read_ar_hdr                    _bfd_noarchive_read_ar_hdr
+#define bfd_mach_o_write_ar_hdr                   _bfd_noarchive_write_ar_hdr
+#define bfd_mach_o_slurp_armap                    _bfd_noarchive_slurp_armap
+#define bfd_mach_o_slurp_extended_name_table      _bfd_noarchive_slurp_extended_name_table
+#define bfd_mach_o_construct_extended_name_table  _bfd_noarchive_construct_extended_name_table
+#define bfd_mach_o_truncate_arname                _bfd_noarchive_truncate_arname
+#define bfd_mach_o_write_armap                    _bfd_noarchive_write_armap
+#define bfd_mach_o_get_elt_at_index               _bfd_noarchive_get_elt_at_index
+#define bfd_mach_o_generic_stat_arch_elt          _bfd_noarchive_generic_stat_arch_elt
+#define bfd_mach_o_update_armap_timestamp         _bfd_noarchive_update_armap_timestamp
+
 #define TARGET_NAME            mach_o_fat_vec
 #define TARGET_STRING          "mach-o-fat"
 #define TARGET_ARCHITECTURE    bfd_arch_unknown
This page took 0.054448 seconds and 4 git commands to generate.