OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [mach-o.c] - Diff between revs 14 and 161

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 14 Rev 161
Line 24... Line 24...
#include "mach-o.h"
#include "mach-o.h"
#include "bfd.h"
#include "bfd.h"
#include "libbfd.h"
#include "libbfd.h"
#include "libiberty.h"
#include "libiberty.h"
#include "aout/stab_gnu.h"
#include "aout/stab_gnu.h"
 
#include "mach-o/reloc.h"
 
#include "mach-o/external.h"
#include <ctype.h>
#include <ctype.h>
 
 
#define bfd_mach_o_object_p bfd_mach_o_gen_object_p
#define bfd_mach_o_object_p bfd_mach_o_gen_object_p
#define bfd_mach_o_core_p bfd_mach_o_gen_core_p
#define bfd_mach_o_core_p bfd_mach_o_gen_core_p
#define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
#define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
Line 130... Line 132...
    { NULL, NULL, 0}
    { NULL, NULL, 0}
  };
  };
 
 
struct mach_o_segment_name_xlat
struct mach_o_segment_name_xlat
{
{
 
  /* Segment name.  */
  const char *segname;
  const char *segname;
 
 
 
  /* List of known sections for the segment.  */
  const struct mach_o_section_name_xlat *sections;
  const struct mach_o_section_name_xlat *sections;
};
};
 
 
 
/* List of known segment names.  */
 
 
static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
  {
  {
    { "__DWARF", dwarf_section_names_xlat },
 
    { "__TEXT", text_section_names_xlat },
    { "__TEXT", text_section_names_xlat },
    { "__DATA", data_section_names_xlat },
    { "__DATA", data_section_names_xlat },
 
    { "__DWARF", dwarf_section_names_xlat },
    { NULL, NULL }
    { NULL, NULL }
  };
  };
 
 
 
 
/* Mach-O to bfd names.  */
/* Mach-O to bfd names.  */
 
 
static void
void
bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section,
bfd_mach_o_normalize_section_name (const char *segname, const char *sectname,
                                        char **name, flagword *flags)
                                   const char **name, flagword *flags)
{
{
  const struct mach_o_segment_name_xlat *seg;
  const struct mach_o_segment_name_xlat *seg;
  char *res;
 
  unsigned int len;
 
  const char *pfx = "";
 
 
 
  *name = NULL;
  *name = NULL;
  *flags = SEC_NO_FLAGS;
  *flags = SEC_NO_FLAGS;
 
 
  for (seg = segsec_names_xlat; seg->segname; seg++)
  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;
          const struct mach_o_section_name_xlat *sec;
 
 
          for (sec = seg->sections; sec->mach_o_name; 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);
                  *name = sec->bfd_name;
                  res = bfd_alloc (abfd, len + 1);
 
 
 
                  if (res == NULL)
 
                    return;
 
                  strcpy (res, sec->bfd_name);
 
                  *name = res;
 
                  *flags = sec->flags;
                  *flags = sec->flags;
                  return;
                  return;
                }
                }
            }
            }
 
          return;
 
        }
        }
        }
    }
    }
 
 
  len = strlen (section->segname) + 1
static void
    + strlen (section->sectname) + 1;
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
  /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
     with an underscore.  */
     with an underscore.  */
  if (section->segname[0] != '_')
  if (segname[0] != '_')
    {
    {
      static const char seg_pfx[] = "LC_SEGMENT.";
      static const char seg_pfx[] = "LC_SEGMENT.";
 
 
      pfx = seg_pfx;
      pfx = seg_pfx;
      len += sizeof (seg_pfx) - 1;
      len += sizeof (seg_pfx) - 1;
    }
    }
 
 
  res = bfd_alloc (abfd, len);
  res = bfd_alloc (abfd, len);
  if (res == NULL)
  if (res == NULL)
    return;
    return;
  snprintf (res, len, "%s%s.%s", pfx, section->segname, section->sectname);
  snprintf (res, len, "%s%s.%s", pfx, segname, sectname);
  *name = res;
  *name = res;
 
  *flags = SEC_NO_FLAGS;
}
}
 
 
/* Convert a bfd section name to a Mach-O segment + section name.  */
/* Convert a bfd section name to a Mach-O segment + section name.  */
 
 
static void
static void
Line 374... Line 390...
  unsigned long j;
  unsigned long j;
 
 
  if (nsyms < 0)
  if (nsyms < 0)
    return nsyms;
    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)
  if (bfd_mach_o_read_symtab_symbols (abfd) != 0)
    {
    {
      (*_bfd_error_handler) (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
      (*_bfd_error_handler) (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
      return 0;
      return 0;
    }
    }
Line 596... Line 619...
}
}
 
 
static bfd_boolean
static bfd_boolean
bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
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;
  unsigned int size;
 
 
  size = mach_o_wide_p (header) ?
  size = mach_o_wide_p (header) ?
    BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
    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->magic, raw.magic);
  bfd_h_put_32 (abfd, header->cputype, buf + 4);
  bfd_h_put_32 (abfd, header->cputype, raw.cputype);
  bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
  bfd_h_put_32 (abfd, header->cpusubtype, raw.cpusubtype);
  bfd_h_put_32 (abfd, header->filetype, buf + 12);
  bfd_h_put_32 (abfd, header->filetype, raw.filetype);
  bfd_h_put_32 (abfd, header->ncmds, buf + 16);
  bfd_h_put_32 (abfd, header->ncmds, raw.ncmds);
  bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
  bfd_h_put_32 (abfd, header->sizeofcmds, raw.sizeofcmds);
  bfd_h_put_32 (abfd, header->flags, buf + 24);
  bfd_h_put_32 (abfd, header->flags, raw.flags);
 
 
  if (mach_o_wide_p (header))
  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
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
      || bfd_bwrite ((void *) buf, size, abfd) != size)
      || bfd_bwrite (&raw, size, abfd) != size)
    return FALSE;
    return FALSE;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
static int
static int
bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
{
{
  bfd_mach_o_thread_command *cmd = &command->command.thread;
  bfd_mach_o_thread_command *cmd = &command->command.thread;
  unsigned int i;
  unsigned int i;
  unsigned char buf[8];
  struct mach_o_thread_command_external raw;
  unsigned int offset;
  unsigned int offset;
 
 
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
              || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
              || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
 
 
  offset = 8;
  offset = 8;
  for (i = 0; i < cmd->nflavours; i++)
  for (i = 0; i < cmd->nflavours; i++)
    {
    {
      BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
      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].flavour, raw.flavour);
      bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
      bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count);
 
 
      if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
      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;
        return -1;
 
 
      offset += cmd->flavours[i].size + 8;
      offset += cmd->flavours[i].size + sizeof (raw);
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
Line 658... Line 682...
{
{
  return (asect->reloc_count + 1) * sizeof (arelent *);
  return (asect->reloc_count + 1) * sizeof (arelent *);
}
}
 
 
static int
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)
                                   arelent *res, asymbol **syms)
{
{
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
  bfd_mach_o_reloc_info reloc;
  bfd_mach_o_reloc_info reloc;
  bfd_vma addr;
  bfd_vma addr;
  bfd_vma symnum;
  bfd_vma symnum;
  asymbol **sym;
  asymbol **sym;
 
 
  addr = bfd_get_32 (abfd, buf + 0);
  addr = bfd_get_32 (abfd, raw->r_address);
  symnum = bfd_get_32 (abfd, buf + 4);
  symnum = bfd_get_32 (abfd, raw->r_symbolnum);
 
 
  if (addr & BFD_MACH_O_SR_SCATTERED)
  if (addr & BFD_MACH_O_SR_SCATTERED)
    {
    {
      unsigned int j;
      unsigned int j;
 
 
Line 736... Line 761...
bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
                                unsigned long count,
                                unsigned long count,
                                arelent *res, asymbol **syms)
                                arelent *res, asymbol **syms)
{
{
  unsigned long i;
  unsigned long i;
  char *native_relocs;
  struct mach_o_reloc_info_external *native_relocs;
  bfd_size_type native_size;
  bfd_size_type native_size;
 
 
  /* Allocate and read relocs.  */
  /* Allocate and read relocs.  */
  native_size = count * BFD_MACH_O_RELENT_SIZE;
  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)
  if (native_relocs == NULL)
    return -1;
    return -1;
 
 
  if (bfd_seek (abfd, filepos, SEEK_SET) != 0
  if (bfd_seek (abfd, filepos, SEEK_SET) != 0
      || bfd_bread (native_relocs, native_size, abfd) != native_size)
      || bfd_bread (native_relocs, native_size, abfd) != native_size)
    goto err;
    goto err;
 
 
  for (i = 0; i < count; i++)
  for (i = 0; i < count; i++)
    {
    {
      char *buf = native_relocs + BFD_MACH_O_RELENT_SIZE * i;
      if (bfd_mach_o_canonicalize_one_reloc (abfd, &native_relocs[i],
 
                                             &res[i], syms) < 0)
      if (bfd_mach_o_canonicalize_one_reloc (abfd, buf, &res[i], syms) < 0)
 
        goto err;
        goto err;
    }
    }
  free (native_relocs);
  free (native_relocs);
  return i;
  return i;
 err:
 err:
Line 883... Line 908...
  /* Convert and write.  */
  /* Convert and write.  */
  entries = section->bfdsection->orelocation;
  entries = section->bfdsection->orelocation;
  for (i = 0; i < section->nreloc; i++)
  for (i = 0; i < section->nreloc; i++)
    {
    {
      arelent *rel = entries[i];
      arelent *rel = entries[i];
      char buf[8];
      struct mach_o_reloc_info_external raw;
      bfd_mach_o_reloc_info info, *pinfo = &info;
      bfd_mach_o_reloc_info info, *pinfo = &info;
 
 
      /* Convert relocation to an intermediate representation.  */
      /* Convert relocation to an intermediate representation.  */
      if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
      if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
        return FALSE;
        return FALSE;
Line 900... Line 925...
          v = BFD_MACH_O_SR_SCATTERED
          v = BFD_MACH_O_SR_SCATTERED
            | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
            | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
            | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
            | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
            | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
            | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
            | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
            | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
          bfd_put_32 (abfd, v, buf);
          /* Note: scattered relocs have field in reverse order...  */
          bfd_put_32 (abfd, pinfo->r_value, buf + 4);
          bfd_put_32 (abfd, v, raw.r_address);
 
          bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
        }
        }
      else
      else
        {
        {
          unsigned long v;
          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)
          v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
            | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
            | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
            | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
            | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
            | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
            | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
            | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
            | 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)
          != BFD_MACH_O_RELENT_SIZE)
        return FALSE;
        return FALSE;
    }
    }
  return TRUE;
  return TRUE;
}
}
 
 
static int
static int
bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
{
{
  unsigned char buf[BFD_MACH_O_SECTION_SIZE];
  struct mach_o_section_32_external raw;
 
 
  memcpy (buf, section->sectname, 16);
  memcpy (raw.sectname, section->sectname, 16);
  memcpy (buf + 16, section->segname, 16);
  memcpy (raw.segname, section->segname, 16);
  bfd_h_put_32 (abfd, section->addr, buf + 32);
  bfd_h_put_32 (abfd, section->addr, raw.addr);
  bfd_h_put_32 (abfd, section->size, buf + 36);
  bfd_h_put_32 (abfd, section->size, raw.size);
  bfd_h_put_32 (abfd, section->offset, buf + 40);
  bfd_h_put_32 (abfd, section->offset, raw.offset);
  bfd_h_put_32 (abfd, section->align, buf + 44);
  bfd_h_put_32 (abfd, section->align, raw.align);
  bfd_h_put_32 (abfd, section->reloff, buf + 48);
  bfd_h_put_32 (abfd, section->reloff, raw.reloff);
  bfd_h_put_32 (abfd, section->nreloc, buf + 52);
  bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
  bfd_h_put_32 (abfd, section->flags, buf + 56);
  bfd_h_put_32 (abfd, section->flags, raw.flags);
  bfd_h_put_32 (abfd, section->reserved1, buf + 60);
  bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
  bfd_h_put_32 (abfd, section->reserved2, buf + 64);
  bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
 
 
  if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
  if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
      != BFD_MACH_O_SECTION_SIZE)
      != BFD_MACH_O_SECTION_SIZE)
    return -1;
    return -1;
 
 
  return 0;
  return 0;
}
}
 
 
static int
static int
bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
{
{
  unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
  struct mach_o_section_64_external raw;
 
 
  memcpy (buf, section->sectname, 16);
  memcpy (raw.sectname, section->sectname, 16);
  memcpy (buf + 16, section->segname, 16);
  memcpy (raw.segname, section->segname, 16);
  bfd_h_put_64 (abfd, section->addr, buf + 32);
  bfd_h_put_64 (abfd, section->addr, raw.addr);
  bfd_h_put_64 (abfd, section->size, buf + 40);
  bfd_h_put_64 (abfd, section->size, raw.size);
  bfd_h_put_32 (abfd, section->offset, buf + 48);
  bfd_h_put_32 (abfd, section->offset, raw.offset);
  bfd_h_put_32 (abfd, section->align, buf + 52);
  bfd_h_put_32 (abfd, section->align, raw.align);
  bfd_h_put_32 (abfd, section->reloff, buf + 56);
  bfd_h_put_32 (abfd, section->reloff, raw.reloff);
  bfd_h_put_32 (abfd, section->nreloc, buf + 60);
  bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
  bfd_h_put_32 (abfd, section->flags, buf + 64);
  bfd_h_put_32 (abfd, section->flags, raw.flags);
  bfd_h_put_32 (abfd, section->reserved1, buf + 68);
  bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
  bfd_h_put_32 (abfd, section->reserved2, buf + 72);
  bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
  bfd_h_put_32 (abfd, section->reserved3, buf + 76);
  bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
 
 
  if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
  if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
      != BFD_MACH_O_SECTION_64_SIZE)
      != BFD_MACH_O_SECTION_64_SIZE)
    return -1;
    return -1;
 
 
  return 0;
  return 0;
}
}
 
 
static int
static int
bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
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;
  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);
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
 
 
  for (i = 0; i < seg->nsects; i++)
  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
    if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
    if (!bfd_mach_o_write_relocs (abfd, sec))
      return -1;
      return -1;
 
 
  memcpy (buf, seg->segname, 16);
  memcpy (raw.segname, seg->segname, 16);
  bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
  bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
  bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
  bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
  bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
  bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
  bfd_h_put_32 (abfd, seg->filesize, buf + 28);
  bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
  bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
  bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
  bfd_h_put_32 (abfd, seg->initprot, buf + 36);
  bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
  bfd_h_put_32 (abfd, seg->nsects, buf + 40);
  bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
  bfd_h_put_32 (abfd, seg->flags, buf + 44);
  bfd_h_put_32 (abfd, seg->flags, raw.flags);
 
 
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
      || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_SIZE - 8, abfd)
      || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
          != BFD_MACH_O_LC_SEGMENT_SIZE - 8))
 
    return -1;
    return -1;
 
 
  for (i = 0; i < seg->nsects; i++)
  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
    if (bfd_mach_o_write_section_32 (abfd, &seg->sections[i]))
    if (bfd_mach_o_write_section_32 (abfd, sec))
      return -1;
      return -1;
 
 
  return 0;
  return 0;
}
}
 
 
static int
static int
bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
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;
  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);
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
 
 
  for (i = 0; i < seg->nsects; i++)
  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
    if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
    if (!bfd_mach_o_write_relocs (abfd, sec))
      return -1;
      return -1;
 
 
  memcpy (buf, seg->segname, 16);
  memcpy (raw.segname, seg->segname, 16);
  bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
  bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
  bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
  bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
  bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
  bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
  bfd_h_put_64 (abfd, seg->filesize, buf + 40);
  bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
  bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
  bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
  bfd_h_put_32 (abfd, seg->initprot, buf + 52);
  bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
  bfd_h_put_32 (abfd, seg->nsects, buf + 56);
  bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
  bfd_h_put_32 (abfd, seg->flags, buf + 60);
  bfd_h_put_32 (abfd, seg->flags, raw.flags);
 
 
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
      || (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_64_SIZE - 8, abfd)
      || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
          != BFD_MACH_O_LC_SEGMENT_64_SIZE - 8))
 
    return -1;
    return -1;
 
 
  for (i = 0; i < seg->nsects; i++)
  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
    if (bfd_mach_o_write_section_64 (abfd, &seg->sections[i]))
    if (bfd_mach_o_write_section_64 (abfd, sec))
      return -1;
      return -1;
 
 
  return 0;
  return 0;
}
}
 
 
static bfd_boolean
static bfd_boolean
bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
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_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_symtab_command *sym = &command->command.symtab;
  bfd_mach_o_symtab_command *sym = &command->command.symtab;
  unsigned char buf[16];
 
  unsigned long i;
  unsigned long i;
  unsigned int wide = bfd_mach_o_wide_p (abfd);
  unsigned int wide = bfd_mach_o_wide_p (abfd);
  unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
  unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
  struct bfd_strtab_hash *strtab;
  struct bfd_strtab_hash *strtab;
  asymbol **symbols = bfd_get_outsymbols (abfd);
  asymbol **symbols = bfd_get_outsymbols (abfd);
Line 1084... Line 1107...
        {
        {
          str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
          str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
          if (str_index == (bfd_size_type) -1)
          if (str_index == (bfd_size_type) -1)
            goto err;
            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)
      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
      else
        bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
        {
 
          struct mach_o_nlist_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_32 (abfd, s->symbol.section->vma + s->symbol.value,
 
                        raw.n_value);
 
 
      if (bfd_bwrite ((void *) buf, symlen, abfd) != symlen)
          if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
        goto err;
        goto err;
    }
    }
 
    }
  sym->strsize = _bfd_stringtab_size (strtab);
  sym->strsize = _bfd_stringtab_size (strtab);
  sym->stroff = mdata->filelen;
  sym->stroff = mdata->filelen;
  mdata->filelen += sym->strsize;
  mdata->filelen += sym->strsize;
 
 
  if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
  if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
    goto err;
    goto err;
  _bfd_stringtab_free (strtab);
  _bfd_stringtab_free (strtab);
 
 
  /* The command.  */
  /* The command.  */
  bfd_h_put_32 (abfd, sym->symoff, buf);
  {
  bfd_h_put_32 (abfd, sym->nsyms, buf + 4);
    struct mach_o_symtab_command_external raw;
  bfd_h_put_32 (abfd, sym->stroff, buf + 8);
 
  bfd_h_put_32 (abfd, sym->strsize, buf + 12);
    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 + 8, SEEK_SET) != 0
    if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
      || bfd_bwrite ((void *) buf, 16, abfd) != 16)
        || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
    return FALSE;
    return FALSE;
 
  }
 
 
  return TRUE;
  return TRUE;
 
 
 err:
 err:
  _bfd_stringtab_free (strtab);
  _bfd_stringtab_free (strtab);
Line 1197... Line 1242...
  if (!bfd_mach_o_mangle_symbols (abfd))
  if (!bfd_mach_o_mangle_symbols (abfd))
    return FALSE;
    return FALSE;
 
 
  for (i = 0; i < mdata->header.ncmds; i++)
  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];
      bfd_mach_o_load_command *cur = &mdata->commands[i];
      unsigned long typeflag;
      unsigned long typeflag;
 
 
      typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
      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, typeflag, raw.cmd);
      bfd_h_put_32 (abfd, cur->len, buf + 4);
      bfd_h_put_32 (abfd, cur->len, raw.cmdsize);
 
 
      if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
      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;
        return FALSE;
 
 
      switch (cur->type)
      switch (cur->type)
        {
        {
        case BFD_MACH_O_LC_SEGMENT:
        case BFD_MACH_O_LC_SEGMENT:
Line 1257... Line 1302...
    }
    }
 
 
  return TRUE;
  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.  */
/* Build Mach-O load commands from the sections.  */
 
 
bfd_boolean
bfd_boolean
bfd_mach_o_build_commands (bfd *abfd)
bfd_mach_o_build_commands (bfd *abfd)
{
{
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  unsigned int wide = mach_o_wide_p (&mdata->header);
  unsigned int wide = mach_o_wide_p (&mdata->header);
  bfd_mach_o_segment_command *seg;
  bfd_mach_o_segment_command *seg;
  bfd_mach_o_section *sections;
 
  asection *sec;
  asection *sec;
  bfd_mach_o_load_command *cmd;
  bfd_mach_o_load_command *cmd;
  bfd_mach_o_load_command *symtab_cmd;
  bfd_mach_o_load_command *symtab_cmd;
  int target_index;
  int target_index;
 
 
  /* Return now if commands are already built.  */
  /* Return now if commands are already built.  */
  if (mdata->header.ncmds)
  if (mdata->header.ncmds)
    return FALSE;
    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->header.ncmds = 2;
  mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
  mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
                               * sizeof (bfd_mach_o_load_command));
                               * sizeof (bfd_mach_o_load_command));
  if (mdata->commands == NULL)
  if (mdata->commands == NULL)
    return FALSE;
    return FALSE;
  cmd = &mdata->commands[0];
  cmd = &mdata->commands[0];
  seg = &cmd->command.segment;
  seg = &cmd->command.segment;
 
 
  seg->nsects = bfd_count_sections (abfd);
  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.  */
  /* Set segment command.  */
  if (wide)
  if (wide)
    {
    {
      cmd->type = BFD_MACH_O_LC_SEGMENT_64;
      cmd->type = BFD_MACH_O_LC_SEGMENT_64;
Line 1334... Line 1409...
 
 
  /* Create Mach-O sections.  */
  /* Create Mach-O sections.  */
  target_index = 0;
  target_index = 0;
  for (sec = abfd->sections; sec; sec = sec->next)
  for (sec = abfd->sections; sec; sec = sec->next)
    {
    {
      sections->bfdsection = sec;
      bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
      bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
 
      sections->addr = bfd_get_section_vma (abfd, sec);
      bfd_mach_o_append_section_to_segment (seg, sec);
      sections->size = bfd_get_section_size (sec);
 
      sections->align = bfd_get_section_alignment (abfd, sec);
      if (msect->flags == 0)
 
        {
      if (sections->size != 0)
          /* We suppose it hasn't been set.  Convert from BFD flags.  */
        {
          bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
          mdata->filelen = FILE_ALIGN (mdata->filelen, sections->align);
        }
          sections->offset = mdata->filelen;
      msect->addr = bfd_get_section_vma (abfd, sec);
        }
      msect->size = bfd_get_section_size (sec);
      else
      msect->align = bfd_get_section_alignment (abfd, sec);
        sections->offset = 0;
 
      sections->reloff = 0;
 
      sections->nreloc = 0;
 
      sections->reserved1 = 0;
 
      sections->reserved2 = 0;
 
      sections->reserved3 = 0;
 
 
 
      sec->filepos = sections->offset;
      if (msect->size != 0)
 
        {
 
          mdata->filelen = FILE_ALIGN (mdata->filelen, msect->align);
 
          msect->offset = mdata->filelen;
 
        }
 
      else
 
        msect->offset = 0;
 
 
 
      sec->filepos = msect->offset;
      sec->target_index = ++target_index;
      sec->target_index = ++target_index;
 
 
      mdata->filelen += sections->size;
      mdata->filelen += msect->size;
      sections++;
 
    }
    }
  seg->filesize = mdata->filelen - seg->fileoff;
  seg->filesize = mdata->filelen - seg->fileoff;
  seg->vmsize = seg->filesize;
  seg->vmsize = seg->filesize;
 
 
  return TRUE;
  return TRUE;
Line 1418... Line 1494...
}
}
 
 
static bfd_boolean
static bfd_boolean
bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
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;
  unsigned int size;
  bfd_vma (*get32) (const void *) = NULL;
  bfd_vma (*get32) (const void *) = NULL;
 
 
  /* Just read the magic number.  */
  /* Just read the magic number.  */
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
  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;
    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->byteorder = BFD_ENDIAN_BIG;
      header->magic = BFD_MACH_O_MH_MAGIC;
      header->magic = BFD_MACH_O_MH_MAGIC;
      header->version = 1;
      header->version = 1;
      get32 = bfd_getb32;
      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->byteorder = BFD_ENDIAN_LITTLE;
      header->magic = BFD_MACH_O_MH_MAGIC;
      header->magic = BFD_MACH_O_MH_MAGIC;
      header->version = 1;
      header->version = 1;
      get32 = bfd_getl32;
      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->byteorder = BFD_ENDIAN_BIG;
      header->magic = BFD_MACH_O_MH_MAGIC_64;
      header->magic = BFD_MACH_O_MH_MAGIC_64;
      header->version = 2;
      header->version = 2;
      get32 = bfd_getb32;
      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->byteorder = BFD_ENDIAN_LITTLE;
      header->magic = BFD_MACH_O_MH_MAGIC_64;
      header->magic = BFD_MACH_O_MH_MAGIC_64;
      header->version = 2;
      header->version = 2;
      get32 = bfd_getl32;
      get32 = bfd_getl32;
Line 1466... Line 1542...
  /* Once the size of the header is known, read the full header.  */
  /* Once the size of the header is known, read the full header.  */
  size = mach_o_wide_p (header) ?
  size = mach_o_wide_p (header) ?
    BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
    BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
 
 
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
      || bfd_bread ((void *) buf, size, abfd) != size)
      || bfd_bread (&raw, size, abfd) != size)
    return FALSE;
    return FALSE;
 
 
  header->cputype = (*get32) (buf + 4);
  header->cputype = (*get32) (raw.cputype);
  header->cpusubtype = (*get32) (buf + 8);
  header->cpusubtype = (*get32) (raw.cpusubtype);
  header->filetype = (*get32) (buf + 12);
  header->filetype = (*get32) (raw.filetype);
  header->ncmds = (*get32) (buf + 16);
  header->ncmds = (*get32) (raw.ncmds);
  header->sizeofcmds = (*get32) (buf + 20);
  header->sizeofcmds = (*get32) (raw.sizeofcmds);
  header->flags = (*get32) (buf + 24);
  header->flags = (*get32) (raw.flags);
 
 
  if (mach_o_wide_p (header))
  if (mach_o_wide_p (header))
    header->reserved = (*get32) (buf + 28);
    header->reserved = (*get32) (raw.reserved);
 
 
  return TRUE;
  return TRUE;
}
}
 
 
static asection *
bfd_boolean
bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
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)
                             unsigned long prot)
{
{
  asection *bfdsec;
 
  char *sname;
 
  flagword flags;
  flagword flags;
 
  bfd_mach_o_section *section;
 
 
  bfd_mach_o_convert_section_name_to_bfd (abfd, section, &sname, &flags);
  flags = bfd_get_section_flags (abfd, sec);
  if (sname == NULL)
  section = bfd_mach_o_get_mach_o_section (sec);
    return NULL;
 
 
 
  if (flags == SEC_NO_FLAGS)
  if (flags == SEC_NO_FLAGS)
    {
    {
      /* Try to guess flags.  */
      /* Try to guess flags.  */
      if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
      if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
Line 1526... Line 1636...
  if (section->offset != 0)
  if (section->offset != 0)
    flags |= SEC_HAS_CONTENTS;
    flags |= SEC_HAS_CONTENTS;
  if (section->nreloc != 0)
  if (section->nreloc != 0)
    flags |= SEC_RELOC;
    flags |= SEC_RELOC;
 
 
  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
  bfd_set_section_flags (abfd, sec, flags);
  if (bfdsec == NULL)
 
    return NULL;
 
 
 
  bfdsec->vma = section->addr;
  sec->vma = section->addr;
  bfdsec->lma = section->addr;
  sec->lma = section->addr;
  bfdsec->size = section->size;
  sec->size = section->size;
  bfdsec->filepos = section->offset;
  sec->filepos = section->offset;
  bfdsec->alignment_power = section->align;
  sec->alignment_power = section->align;
  bfdsec->segment_mark = 0;
  sec->segment_mark = 0;
  bfdsec->reloc_count = section->nreloc;
  sec->reloc_count = section->nreloc;
  bfdsec->rel_filepos = section->reloff;
  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_read_section_32 (bfd *abfd,
                            bfd_mach_o_section *section,
 
                            unsigned int offset,
                            unsigned int offset,
                            unsigned long prot)
                            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
  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))
          != BFD_MACH_O_SECTION_SIZE))
    return -1;
    return NULL;
 
 
 
  sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
 
  if (sec == NULL)
 
    return NULL;
 
 
  memcpy (section->sectname, buf, 16);
  section = bfd_mach_o_get_mach_o_section (sec);
  section->sectname[16] = '\0';
  memcpy (section->segname, raw.segname, sizeof (raw.segname));
  memcpy (section->segname, buf + 16, 16);
  section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
  section->segname[16] = '\0';
  memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
  section->addr = bfd_h_get_32 (abfd, buf + 32);
  section->segname[BFD_MACH_O_SECTNAME_SIZE] = 0;
  section->size = bfd_h_get_32 (abfd, buf + 36);
  section->addr = bfd_h_get_32 (abfd, raw.addr);
  section->offset = bfd_h_get_32 (abfd, buf + 40);
  section->size = bfd_h_get_32 (abfd, raw.size);
  section->align = bfd_h_get_32 (abfd, buf + 44);
  section->offset = bfd_h_get_32 (abfd, raw.offset);
  section->reloff = bfd_h_get_32 (abfd, buf + 48);
  section->align = bfd_h_get_32 (abfd, raw.align);
  section->nreloc = bfd_h_get_32 (abfd, buf + 52);
  section->reloff = bfd_h_get_32 (abfd, raw.reloff);
  section->flags = bfd_h_get_32 (abfd, buf + 56);
  section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
  section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
  section->flags = bfd_h_get_32 (abfd, raw.flags);
  section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
  section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
 
  section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
  section->reserved3 = 0;
  section->reserved3 = 0;
  section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
 
 
 
  if (section->bfdsection == NULL)
  bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
    return -1;
 
 
 
  return 0;
  return sec;
}
}
 
 
static int
static asection *
bfd_mach_o_read_section_64 (bfd *abfd,
bfd_mach_o_read_section_64 (bfd *abfd,
                            bfd_mach_o_section *section,
 
                            unsigned int offset,
                            unsigned int offset,
                            unsigned long prot)
                            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
  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))
          != BFD_MACH_O_SECTION_64_SIZE))
    return -1;
    return NULL;
 
 
  memcpy (section->sectname, buf, 16);
  sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
  section->sectname[16] = '\0';
  if (sec == NULL)
  memcpy (section->segname, buf + 16, 16);
    return NULL;
  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)
  section = bfd_mach_o_get_mach_o_section (sec);
    return -1;
  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);
 
 
  return 0;
  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_read_section (bfd *abfd,
                         bfd_mach_o_section *section,
 
                         unsigned int offset,
                         unsigned int offset,
                         unsigned long prot,
                         unsigned long prot,
                         unsigned int wide)
                         unsigned int wide)
{
{
  if (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
  else
    return bfd_mach_o_read_section_32 (abfd, section, offset, prot);
    return bfd_mach_o_read_section_32 (abfd, offset, prot);
}
}
 
 
static int
static int
bfd_mach_o_read_symtab_symbol (bfd *abfd,
bfd_mach_o_read_symtab_symbol (bfd *abfd,
                               bfd_mach_o_symtab_command *sym,
                               bfd_mach_o_symtab_command *sym,
Line 1636... Line 1765...
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  unsigned int wide = mach_o_wide_p (&mdata->header);
  unsigned int wide = mach_o_wide_p (&mdata->header);
  unsigned int symwidth =
  unsigned int symwidth =
    wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
    wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
  unsigned int symoff = sym->symoff + (i * symwidth);
  unsigned int symoff = sym->symoff + (i * symwidth);
  unsigned char buf[16];
  struct mach_o_nlist_64_external raw;
  unsigned char type = -1;
  unsigned char type = -1;
  unsigned char section = -1;
  unsigned char section = -1;
  short desc = -1;
  short desc = -1;
  symvalue value = -1;
  symvalue value = -1;
  unsigned long stroff = -1;
  unsigned long stroff = -1;
  unsigned int symtype = -1;
  unsigned int symtype = -1;
 
 
  BFD_ASSERT (sym->strtab != NULL);
  BFD_ASSERT (sym->strtab != NULL);
 
 
  if (bfd_seek (abfd, symoff, SEEK_SET) != 0
  if (bfd_seek (abfd, symoff, SEEK_SET) != 0
      || bfd_bread ((void *) buf, symwidth, abfd) != symwidth)
      || bfd_bread (&raw, symwidth, abfd) != symwidth)
    {
    {
      (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
      (*_bfd_error_handler)
 
        (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
                             symwidth, (unsigned long) symoff);
                             symwidth, (unsigned long) symoff);
      return -1;
      return -1;
    }
    }
 
 
  stroff = bfd_h_get_32 (abfd, buf);
  stroff = bfd_h_get_32 (abfd, raw.n_strx);
  type = bfd_h_get_8 (abfd, buf + 4);
  type = bfd_h_get_8 (abfd, raw.n_type);
  symtype = type & BFD_MACH_O_N_TYPE;
  symtype = type & BFD_MACH_O_N_TYPE;
  section = bfd_h_get_8 (abfd, buf + 5);
  section = bfd_h_get_8 (abfd, raw.n_sect);
  desc = bfd_h_get_16 (abfd, buf + 6);
  desc = bfd_h_get_16 (abfd, raw.n_desc);
  if (wide)
  if (wide)
    value = bfd_h_get_64 (abfd, buf + 8);
    value = bfd_h_get_64 (abfd, raw.n_value);
  else
  else
    value = bfd_h_get_32 (abfd, buf + 8);
    value = bfd_h_get_32 (abfd, raw.n_value);
 
 
  if (stroff >= sym->strsize)
  if (stroff >= sym->strsize)
    {
    {
      (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: symbol name out of range (%lu >= %lu)"),
      (*_bfd_error_handler)
 
        (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
                             (unsigned long) stroff,
                             (unsigned long) stroff,
                             (unsigned long) sym->strsize);
                             (unsigned long) sym->strsize);
      return -1;
      return -1;
    }
    }
 
 
Line 1828... Line 1959...
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_symtab_command *sym = mdata->symtab;
  bfd_mach_o_symtab_command *sym = mdata->symtab;
  unsigned long i;
  unsigned long i;
  int ret;
  int ret;
 
 
  if (sym->symbols)
  if (sym == NULL || sym->symbols)
 
    {
 
      /* Return now if there are no symbols or if already loaded.  */
    return 0;
    return 0;
 
    }
 
 
  sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
  sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
 
 
  if (sym->symbols == NULL)
  if (sym->symbols == NULL)
    {
    {
Line 1862... Line 1996...
                                 bfd_mach_o_asymbol *s,
                                 bfd_mach_o_asymbol *s,
                                 unsigned long i)
                                 unsigned long i)
{
{
  unsigned long isymoff = dysym->indirectsymoff + (i * 4);
  unsigned long isymoff = dysym->indirectsymoff + (i * 4);
  unsigned long sym_index;
  unsigned long sym_index;
  unsigned char buf[4];
  unsigned char raw[4];
 
 
  BFD_ASSERT (i < dysym->nindirectsyms);
  BFD_ASSERT (i < dysym->nindirectsyms);
 
 
  if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
  if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
      || bfd_bread ((void *) buf, 4, abfd) != 4)
      || bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
    {
    {
      (*_bfd_error_handler) (_("bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"),
      (*_bfd_error_handler)
                               (unsigned long) 4, isymoff);
        (_("bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"),
 
         (unsigned long) sizeof (raw), isymoff);
      return -1;
      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);
  return bfd_mach_o_read_symtab_symbol (abfd, sym, s, sym_index);
}
}
 
 
static const char *
static const char *
Line 1919... Line 2054...
 
 
static int
static int
bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
{
{
  bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
  bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
  unsigned char buf[4];
  struct mach_o_str_command_external raw;
  unsigned int nameoff;
  unsigned int nameoff;
 
 
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
              || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
              || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
 
 
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
      || bfd_bread ((void *) buf, 4, abfd) != 4)
      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
    return -1;
    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_offset = command->offset + nameoff;
  cmd->name_len = command->len - nameoff;
  cmd->name_len = command->len - nameoff;
  cmd->name_str = bfd_alloc (abfd, cmd->name_len);
  cmd->name_str = bfd_alloc (abfd, cmd->name_len);
  if (cmd->name_str == NULL)
  if (cmd->name_str == NULL)
Line 1946... Line 2081...
 
 
static int
static int
bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
{
{
  bfd_mach_o_dylib_command *cmd = &command->command.dylib;
  bfd_mach_o_dylib_command *cmd = &command->command.dylib;
  unsigned char buf[16];
  struct mach_o_dylib_command_external raw;
  unsigned int nameoff;
  unsigned int nameoff;
 
 
  switch (command->type)
  switch (command->type)
    {
    {
    case BFD_MACH_O_LC_LOAD_DYLIB:
    case BFD_MACH_O_LC_LOAD_DYLIB:
Line 1961... Line 2096...
    default:
    default:
      BFD_FAIL ();
      BFD_FAIL ();
      return -1;
      return -1;
    }
    }
 
 
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
      || bfd_bread ((void *) buf, 16, abfd) != 16)
      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
    return -1;
    return -1;
 
 
  nameoff = bfd_h_get_32 (abfd, buf + 0);
  nameoff = bfd_h_get_32 (abfd, raw.name);
  cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
  cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
  cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
  cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
  cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
  cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
 
 
  cmd->name_offset = command->offset + nameoff;
  cmd->name_offset = command->offset + nameoff;
  cmd->name_len = command->len - nameoff;
  cmd->name_len = command->len - nameoff;
  cmd->name_str = bfd_alloc (abfd, cmd->name_len);
  cmd->name_str = bfd_alloc (abfd, cmd->name_len);
  if (cmd->name_str == NULL)
  if (cmd->name_str == NULL)
Line 1996... Line 2131...
static int
static int
bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
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_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_thread_command *cmd = &command->command.thread;
  bfd_mach_o_thread_command *cmd = &command->command.thread;
  unsigned char buf[8];
 
  unsigned int offset;
  unsigned int offset;
  unsigned int nflavours;
  unsigned int nflavours;
  unsigned int i;
  unsigned int i;
 
 
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
  BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
Line 2009... Line 2143...
  /* Count the number of threads.  */
  /* Count the number of threads.  */
  offset = 8;
  offset = 8;
  nflavours = 0;
  nflavours = 0;
  while (offset != command->len)
  while (offset != command->len)
    {
    {
 
      struct mach_o_thread_command_external raw;
 
 
      if (offset >= command->len)
      if (offset >= command->len)
        return -1;
        return -1;
 
 
      if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
      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;
        return -1;
 
 
      offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
      offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
      nflavours++;
      nflavours++;
    }
    }
 
 
  /* Allocate threads.  */
  /* Allocate threads.  */
  cmd->flavours = bfd_alloc
  cmd->flavours = bfd_alloc
Line 2031... Line 2167...
 
 
  offset = 8;
  offset = 8;
  nflavours = 0;
  nflavours = 0;
  while (offset != command->len)
  while (offset != command->len)
    {
    {
 
      struct mach_o_thread_command_external raw;
 
 
      if (offset >= command->len)
      if (offset >= command->len)
        return -1;
        return -1;
 
 
      if (nflavours >= cmd->nflavours)
      if (nflavours >= cmd->nflavours)
        return -1;
        return -1;
 
 
      if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
      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;
        return -1;
 
 
      cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
      cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
      cmd->flavours[nflavours].offset = command->offset + offset + 8;
      cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
      cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
      cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
      offset += cmd->flavours[nflavours].size + 8;
      offset += cmd->flavours[nflavours].size + sizeof (raw);
      nflavours++;
      nflavours++;
    }
    }
 
 
  for (i = 0; i < nflavours; i++)
  for (i = 0; i < nflavours; i++)
    {
    {
Line 2104... Line 2242...
static int
static int
bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
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_dysymtab_command *cmd = &command->command.dysymtab;
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  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);
  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)
    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;
    return -1;
 
 
  cmd->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
    cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
  cmd->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
    cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
  cmd->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
    cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
  cmd->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
    cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
  cmd->iundefsym = bfd_h_get_32 (abfd, buf + 16);
    cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
  cmd->nundefsym = bfd_h_get_32 (abfd, buf + 20);
    cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
  cmd->tocoff = bfd_h_get_32 (abfd, buf + 24);
    cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
  cmd->ntoc = bfd_h_get_32 (abfd, buf + 28);
    cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
  cmd->modtaboff = bfd_h_get_32 (abfd, buf + 32);
    cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
  cmd->nmodtab = bfd_h_get_32 (abfd, buf + 36);
    cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
  cmd->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
    cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
  cmd->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
    cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
  cmd->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
    cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
  cmd->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
    cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
  cmd->extreloff = bfd_h_get_32 (abfd, buf + 56);
    cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
  cmd->nextrel = bfd_h_get_32 (abfd, buf + 60);
    cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
  cmd->locreloff = bfd_h_get_32 (abfd, buf + 64);
    cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
  cmd->nlocrel = bfd_h_get_32 (abfd, buf + 68);
    cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
 
  }
 
 
  if (cmd->nmodtab != 0)
  if (cmd->nmodtab != 0)
    {
    {
      unsigned int i;
      unsigned int i;
      int wide = bfd_mach_o_wide_p (abfd);
      int wide = bfd_mach_o_wide_p (abfd);
Line 2149... Line 2290...
 
 
      for (i = 0; i < cmd->nmodtab; i++)
      for (i = 0; i < cmd->nmodtab; i++)
        {
        {
          bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
          bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
          unsigned long v;
          unsigned long v;
 
          unsigned char buf[56];
 
 
          if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
          if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
            return -1;
            return -1;
 
 
          module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
          module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
Line 2195... Line 2337...
      if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
      if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
        return -1;
        return -1;
 
 
      for (i = 0; i < cmd->ntoc; i++)
      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];
          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;
            return -1;
 
 
          toc->symbol_index = bfd_h_get_32 (abfd, buf + 0);
          toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
          toc->module_index = bfd_h_get_32 (abfd, buf + 4);
          toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
        }
        }
    }
    }
 
 
  if (cmd->nindirectsyms != 0)
  if (cmd->nindirectsyms != 0)
    {
    {
Line 2219... Line 2362...
      if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
      if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
        return -1;
        return -1;
 
 
      for (i = 0; i < cmd->nindirectsyms; i++)
      for (i = 0; i < cmd->nindirectsyms; i++)
        {
        {
 
          unsigned char raw[4];
          unsigned int *is = &cmd->indirect_syms[i];
          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;
            return -1;
 
 
          *is = bfd_h_get_32 (abfd, buf + 0);
          *is = bfd_h_get_32 (abfd, raw);
        }
        }
    }
    }
 
 
  if (cmd->nextrefsyms != 0)
  if (cmd->nextrefsyms != 0)
    {
    {
Line 2243... Line 2387...
      if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
      if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
        return -1;
        return -1;
 
 
      for (i = 0; i < cmd->nextrefsyms; i++)
      for (i = 0; i < cmd->nextrefsyms; i++)
        {
        {
 
          unsigned char raw[4];
          bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
          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;
            return -1;
 
 
          /* Fields isym and flags are written as bit-fields, thus we need
          /* Fields isym and flags are written as bit-fields, thus we need
             a specific processing for endianness.  */
             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))
          if (bfd_big_endian (abfd))
            {
            {
              ref->isym = (v >> 8) & 0xffffff;
              ref->isym = (v >> 8) & 0xffffff;
              ref->flags = v & 0xff;
              ref->flags = v & 0xff;
            }
            }
Line 2276... Line 2421...
static int
static int
bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
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_symtab_command *symtab = &command->command.symtab;
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  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);
  BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
 
 
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
      || bfd_bread ((void *) buf, 16, abfd) != 16)
      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
    return -1;
    return -1;
 
 
  symtab->symoff = bfd_h_get_32 (abfd, buf);
  symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
  symtab->nsyms = bfd_h_get_32 (abfd, buf + 4);
  symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
  symtab->stroff = bfd_h_get_32 (abfd, buf + 8);
  symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
  symtab->strsize = bfd_h_get_32 (abfd, buf + 12);
  symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
  symtab->symbols = NULL;
  symtab->symbols = NULL;
  symtab->strtab = NULL;
  symtab->strtab = NULL;
 
 
  if (symtab->nsyms != 0)
  if (symtab->nsyms != 0)
    abfd->flags |= HAS_SYMS;
    abfd->flags |= HAS_SYMS;
Line 2307... Line 2452...
{
{
  bfd_mach_o_uuid_command *cmd = &command->command.uuid;
  bfd_mach_o_uuid_command *cmd = &command->command.uuid;
 
 
  BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
  BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
 
 
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
      || bfd_bread ((void *) cmd->uuid, 16, abfd) != 16)
      || bfd_bread (cmd->uuid, 16, abfd) != 16)
    return -1;
    return -1;
 
 
  return 0;
  return 0;
}
}
 
 
static int
static int
bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
{
{
  bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
  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
  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
      || bfd_bread ((void *) buf, 8, abfd) != 8)
      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
    return -1;
    return -1;
 
 
  cmd->dataoff = bfd_get_32 (abfd, buf + 0);
  cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
  cmd->datasize = bfd_get_32 (abfd, buf + 4);
  cmd->datasize = bfd_get_32 (abfd, raw.datasize);
  return 0;
  return 0;
}
}
 
 
static int
static int
bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
{
{
  bfd_mach_o_str_command *cmd = &command->command.str;
  bfd_mach_o_str_command *cmd = &command->command.str;
  char buf[4];
  struct mach_o_str_command_external raw;
  unsigned long off;
  unsigned long off;
 
 
  if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
      || bfd_bread ((void *) buf, 4, abfd) != 4)
      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
    return -1;
    return -1;
 
 
  off = bfd_get_32 (abfd, buf + 0);
  off = bfd_get_32 (abfd, raw.str);
  cmd->stroff = command->offset + off;
  cmd->stroff = command->offset + off;
  cmd->str_len = command->len - off;
  cmd->str_len = command->len - off;
  cmd->str = bfd_alloc (abfd, cmd->str_len);
  cmd->str = bfd_alloc (abfd, cmd->str_len);
  if (cmd->str == NULL)
  if (cmd->str == NULL)
    return -1;
    return -1;
Line 2356... Line 2501...
 
 
static int
static int
bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
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;
  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
  if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
      || bfd_bread ((void *) buf, sizeof (buf), abfd) != sizeof (buf))
      || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
    return -1;
    return -1;
 
 
  cmd->rebase_off = bfd_get_32 (abfd, buf + 0);
  cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
  cmd->rebase_size = bfd_get_32 (abfd, buf + 4);
  cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
  cmd->bind_off = bfd_get_32 (abfd, buf + 8);
  cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
  cmd->bind_size = bfd_get_32 (abfd, buf + 12);
  cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
  cmd->weak_bind_off = bfd_get_32 (abfd, buf + 16);
  cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
  cmd->weak_bind_size = bfd_get_32 (abfd, buf + 20);
  cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
  cmd->lazy_bind_off = bfd_get_32 (abfd, buf + 24);
  cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
  cmd->lazy_bind_size = bfd_get_32 (abfd, buf + 28);
  cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
  cmd->export_off = bfd_get_32 (abfd, buf + 32);
  cmd->export_off = bfd_get_32 (abfd, raw.export_off);
  cmd->export_size = bfd_get_32 (abfd, buf + 36);
  cmd->export_size = bfd_get_32 (abfd, raw.export_size);
  return 0;
  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
static int
bfd_mach_o_read_segment (bfd *abfd,
bfd_mach_o_read_segment (bfd *abfd,
                         bfd_mach_o_load_command *command,
                         bfd_mach_o_load_command *command,
                         unsigned int wide)
                         unsigned int wide)
{
{
  unsigned char buf[64];
 
  bfd_mach_o_segment_command *seg = &command->command.segment;
  bfd_mach_o_segment_command *seg = &command->command.segment;
  unsigned long i;
  unsigned long i;
 
 
  if (wide)
  if (wide)
    {
    {
 
      struct mach_o_segment_command_64_external raw;
 
 
      BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
      BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
 
 
      if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
      if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
          || bfd_bread ((void *) buf, 64, abfd) != 64)
          || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
        return -1;
        return -1;
 
 
      memcpy (seg->segname, buf, 16);
      memcpy (seg->segname, raw.segname, 16);
      seg->segname[16] = '\0';
      seg->segname[16] = '\0';
 
 
      seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
      seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
      seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
      seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
      seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
      seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
      seg->filesize = bfd_h_get_64 (abfd, buf + 40);
      seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
      seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
      seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
      seg->initprot = bfd_h_get_32 (abfd, buf + 52);
      seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
      seg->nsects = bfd_h_get_32 (abfd, buf + 56);
      seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
      seg->flags = bfd_h_get_32 (abfd, buf + 60);
      seg->flags = bfd_h_get_32 (abfd, raw.flags);
    }
    }
  else
  else
    {
    {
 
      struct mach_o_segment_command_32_external raw;
 
 
      BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
      BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
 
 
      if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
      if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
          || bfd_bread ((void *) buf, 48, abfd) != 48)
          || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
        return -1;
        return -1;
 
 
      memcpy (seg->segname, buf, 16);
      memcpy (seg->segname, raw.segname, 16);
      seg->segname[16] = '\0';
      seg->segname[16] = '\0';
 
 
      seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
      seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
      seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
      seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
      seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
      seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
      seg->filesize = bfd_h_get_32 (abfd, buf +  28);
      seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
      seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
      seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
      seg->initprot = bfd_h_get_32 (abfd, buf + 36);
      seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
      seg->nsects = bfd_h_get_32 (abfd, buf + 40);
      seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
      seg->flags = bfd_h_get_32 (abfd, buf + 44);
      seg->flags = bfd_h_get_32 (abfd, raw.flags);
    }
    }
 
  seg->sect_head = NULL;
  if (seg->nsects != 0)
  seg->sect_tail = NULL;
    {
 
      seg->sections = bfd_alloc (abfd, seg->nsects
 
                                 * sizeof (bfd_mach_o_section));
 
      if (seg->sections == NULL)
 
        return -1;
 
 
 
      for (i = 0; i < seg->nsects; i++)
      for (i = 0; i < seg->nsects; i++)
        {
        {
          bfd_vma segoff;
          bfd_vma segoff;
 
      asection *sec;
 
 
          if (wide)
          if (wide)
            segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
            segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
              + (i * BFD_MACH_O_SECTION_64_SIZE);
              + (i * BFD_MACH_O_SECTION_64_SIZE);
          else
          else
            segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
            segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
              + (i * BFD_MACH_O_SECTION_SIZE);
              + (i * BFD_MACH_O_SECTION_SIZE);
 
 
          if (bfd_mach_o_read_section
      sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
              (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
      if (sec == NULL)
            return -1;
            return -1;
        }
 
 
      bfd_mach_o_append_section_to_segment (seg, sec);
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
Line 2466... Line 2631...
}
}
 
 
static int
static int
bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
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.  */
  /* Read command type and length.  */
  if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
  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;
    return -1;
 
 
  command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD;
  cmd = bfd_h_get_32 (abfd, raw.cmd);
  command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
  command->type =  cmd & ~BFD_MACH_O_LC_REQ_DYLD;
                            ? TRUE : FALSE);
  command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
  command->len = bfd_h_get_32 (abfd, buf + 4);
  command->len = bfd_h_get_32 (abfd, raw.cmdsize);
 
 
  switch (command->type)
  switch (command->type)
    {
    {
    case BFD_MACH_O_LC_SEGMENT:
    case BFD_MACH_O_LC_SEGMENT:
      if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
      if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
Line 2521... Line 2687...
    case BFD_MACH_O_LC_IDFVMLIB:
    case BFD_MACH_O_LC_IDFVMLIB:
    case BFD_MACH_O_LC_IDENT:
    case BFD_MACH_O_LC_IDENT:
    case BFD_MACH_O_LC_FVMFILE:
    case BFD_MACH_O_LC_FVMFILE:
    case BFD_MACH_O_LC_PREPAGE:
    case BFD_MACH_O_LC_PREPAGE:
    case BFD_MACH_O_LC_ROUTINES:
    case BFD_MACH_O_LC_ROUTINES:
 
    case BFD_MACH_O_LC_ROUTINES_64:
      break;
      break;
    case BFD_MACH_O_LC_SUB_FRAMEWORK:
    case BFD_MACH_O_LC_SUB_FRAMEWORK:
    case BFD_MACH_O_LC_SUB_UMBRELLA:
    case BFD_MACH_O_LC_SUB_UMBRELLA:
    case BFD_MACH_O_LC_SUB_LIBRARY:
    case BFD_MACH_O_LC_SUB_LIBRARY:
    case BFD_MACH_O_LC_SUB_CLIENT:
    case BFD_MACH_O_LC_SUB_CLIENT:
Line 2543... Line 2710...
      if (bfd_mach_o_read_uuid (abfd, command) != 0)
      if (bfd_mach_o_read_uuid (abfd, command) != 0)
        return -1;
        return -1;
      break;
      break;
    case BFD_MACH_O_LC_CODE_SIGNATURE:
    case BFD_MACH_O_LC_CODE_SIGNATURE:
    case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
    case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
 
    case BFD_MACH_O_LC_FUNCTION_STARTS:
      if (bfd_mach_o_read_linkedit (abfd, command) != 0)
      if (bfd_mach_o_read_linkedit (abfd, command) != 0)
        return -1;
        return -1;
      break;
      break;
    case BFD_MACH_O_LC_DYLD_INFO:
    case BFD_MACH_O_LC_DYLD_INFO:
      if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
      if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
        return -1;
        return -1;
      break;
      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:
    default:
      (*_bfd_error_handler) (_("unable to read unknown load command 0x%lx"),
      (*_bfd_error_handler) (_("unable to read unknown load command 0x%lx"),
                             (unsigned long) command->type);
                             (unsigned long) command->type);
      break;
      break;
    }
    }
Line 2564... Line 2737...
static void
static void
bfd_mach_o_flatten_sections (bfd *abfd)
bfd_mach_o_flatten_sections (bfd *abfd)
{
{
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  long csect = 0;
  long csect = 0;
  unsigned long i, j;
  unsigned long i;
 
 
  /* Count total number of sections.  */
  /* Count total number of sections.  */
  mdata->nsects = 0;
  mdata->nsects = 0;
 
 
  for (i = 0; i < mdata->header.ncmds; i++)
  for (i = 0; i < mdata->header.ncmds; i++)
Line 2594... Line 2767...
    {
    {
      if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
      if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
          || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
          || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
        {
        {
          bfd_mach_o_segment_command *seg;
          bfd_mach_o_segment_command *seg;
 
          bfd_mach_o_section *sec;
 
 
          seg = &mdata->commands[i].command.segment;
          seg = &mdata->commands[i].command.segment;
          BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
          BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
 
 
          for (j = 0; j < seg->nsects; j++)
          for (sec = seg->sect_head; sec != NULL; sec = sec->next)
            mdata->sections[csect++] = &seg->sections[j];
            mdata->sections[csect++] = sec;
        }
        }
    }
    }
}
}
 
 
int
int
Line 2929... Line 3103...
 
 
const bfd_target *
const bfd_target *
bfd_mach_o_archive_p (bfd *abfd)
bfd_mach_o_archive_p (bfd *abfd)
{
{
  mach_o_fat_data_struct *adata = NULL;
  mach_o_fat_data_struct *adata = NULL;
  unsigned char buf[20];
  struct mach_o_fat_header_external hdr;
  unsigned long i;
  unsigned long i;
 
 
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
  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;
    goto error;
 
 
  adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
  adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
  if (adata == NULL)
  if (adata == NULL)
    goto error;
    goto error;
 
 
  adata->magic = bfd_getb32 (buf);
  adata->magic = bfd_getb32 (hdr.magic);
  adata->nfat_arch = bfd_getb32 (buf + 4);
  adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
  if (adata->magic != 0xcafebabe)
  if (adata->magic != 0xcafebabe)
    goto error;
    goto error;
  /* Avoid matching Java bytecode files, which have the same magic number.
  /* Avoid matching Java bytecode files, which have the same magic number.
     In the Java bytecode file format this field contains the JVM version,
     In the Java bytecode file format this field contains the JVM version,
     which starts at 43.0.  */
     which starts at 43.0.  */
Line 2957... Line 3131...
  if (adata->archentries == NULL)
  if (adata->archentries == NULL)
    goto error;
    goto error;
 
 
  for (i = 0; i < adata->nfat_arch; i++)
  for (i = 0; i < adata->nfat_arch; i++)
    {
    {
      if (bfd_seek (abfd, 8 + 20 * i, SEEK_SET) != 0
      struct mach_o_fat_arch_external arch;
          || bfd_bread ((void *) buf, 20, abfd) != 20)
      if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
        goto error;
        goto error;
      adata->archentries[i].cputype = bfd_getb32 (buf);
      adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
      adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
      adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
      adata->archentries[i].offset = bfd_getb32 (buf + 8);
      adata->archentries[i].offset = bfd_getb32 (arch.offset);
      adata->archentries[i].size = bfd_getb32 (buf + 12);
      adata->archentries[i].size = bfd_getb32 (arch.size);
      adata->archentries[i].align = bfd_getb32 (buf + 16);
      adata->archentries[i].align = bfd_getb32 (arch.align);
    }
    }
 
 
  abfd->tdata.mach_o_fat_data = adata;
  abfd->tdata.mach_o_fat_data = adata;
  return abfd->xvec;
  return abfd->xvec;
 
 
Line 3109... Line 3283...
 
 
  return NULL;
  return NULL;
}
}
 
 
int
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_lookup_command (bfd *abfd,
                           bfd_mach_o_load_command_type type,
                           bfd_mach_o_load_command_type type,
                           bfd_mach_o_load_command **mcommand)
                           bfd_mach_o_load_command **mcommand)
{
{
  struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
  struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
Line 3245... Line 3372...
  if (first)
  if (first)
    fprintf (file, "-");
    fprintf (file, "-");
}
}
 
 
static const char *
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++)
  for (; table->name; table++)
    if (table->val == val)
    if (table->val == val)
      return table->name;
      return table->name;
 
  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*";
  return "*UNKNOWN*";
 
  else
 
    return res;
}
}
 
 
static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
{
{
  { "vax", BFD_MACH_O_CPU_TYPE_VAX },
  { "vax", BFD_MACH_O_CPU_TYPE_VAX },
Line 3388... Line 3527...
  { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
  { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
  { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
  { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
  { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
  { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
  { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
  { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
  { "dyld_info", BFD_MACH_O_LC_DYLD_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}
  { 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
static void
bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
{
{
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_header *h = &mdata->header;
  bfd_mach_o_header *h = &mdata->header;
Line 3417... Line 3587...
 
 
static void
static void
bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
{
{
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
  unsigned int i, j;
  unsigned int i;
  unsigned int sec_nbr = 0;
  unsigned int sec_nbr = 0;
 
 
  fputs (_("Segments and Sections:\n"), file);
  fputs (_("Segments and Sections:\n"), file);
  fputs (_(" #: Segment name     Section name     Address\n"), file);
  fputs (_(" #: Segment name     Section name     Address\n"), file);
 
 
  for (i = 0; i < mdata->header.ncmds; i++)
  for (i = 0; i < mdata->header.ncmds; i++)
    {
    {
      bfd_mach_o_segment_command *seg;
      bfd_mach_o_segment_command *seg;
 
      bfd_mach_o_section *sec;
 
 
      if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
      if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
          && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
          && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
        continue;
        continue;
 
 
Line 3442... Line 3613...
      fputc (' ', file);
      fputc (' ', file);
      fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
      fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
      fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
      fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
      fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
      fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
      fprintf (file, "]\n");
      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,
          fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
                   sec->segname, sec->sectname);
                   sec->segname, sec->sectname);
          fprintf_vma (file, sec->addr);
          fprintf_vma (file, sec->addr);
          fprintf (file, " ");
          fprintf (file, " ");
          fprintf_vma  (file, sec->size);
          fprintf_vma  (file, sec->size);
Line 3510... Line 3681...
static void
static void
bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
                          bfd_mach_o_load_command *cmd, FILE *file)
                          bfd_mach_o_load_command *cmd, FILE *file)
{
{
  bfd_mach_o_segment_command *seg = &cmd->command.segment;
  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, " name: %s\n", *seg->segname ? seg->segname : "*none*");
  fprintf (file, "    vmaddr: ");
  fprintf (file, "    vmaddr: ");
  fprintf_vma (file, seg->vmaddr);
  fprintf_vma (file, seg->vmaddr);
  fprintf (file, "   vmsize: ");
  fprintf (file, "   vmsize: ");
Line 3527... Line 3698...
  fprintf (file, " endoff: ");
  fprintf (file, " endoff: ");
  fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
  fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
  fprintf (file, "\n");
  fprintf (file, "\n");
  fprintf (file, "   nsects: %lu  ", seg->nsects);
  fprintf (file, "   nsects: %lu  ", seg->nsects);
  fprintf (file, " flags: %lx\n", seg->flags);
  fprintf (file, " flags: %lx\n", seg->flags);
  for (i = 0; i < seg->nsects; i++)
  for (sec = seg->sect_head; sec != NULL; sec = sec->next)
    bfd_mach_o_print_section (abfd, &seg->sections[i], file);
    bfd_mach_o_print_section (abfd, sec, file);
}
}
 
 
static void
static void
bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
                           bfd_mach_o_load_command *cmd, FILE *file)
                           bfd_mach_o_load_command *cmd, FILE *file)
Line 3754... Line 3925...
  fputc ('\n', file);
  fputc ('\n', file);
 
 
  for (i = 0; i < mdata->header.ncmds; i++)
  for (i = 0; i < mdata->header.ncmds; i++)
    {
    {
      bfd_mach_o_load_command *cmd = &mdata->commands[i];
      bfd_mach_o_load_command *cmd = &mdata->commands[i];
 
      const char *cmd_name;
 
 
 
      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);
 
 
      fprintf (file, "Load command %s:",
 
               bfd_mach_o_get_name (bfd_mach_o_load_command_name, cmd->type));
 
      switch (cmd->type)
      switch (cmd->type)
        {
        {
        case BFD_MACH_O_LC_SEGMENT:
        case BFD_MACH_O_LC_SEGMENT:
        case BFD_MACH_O_LC_SEGMENT_64:
        case BFD_MACH_O_LC_SEGMENT_64:
          bfd_mach_o_print_segment (abfd, cmd, file);
          bfd_mach_o_print_segment (abfd, cmd, file);
Line 3814... Line 3992...
          fprintf (file, "\n");
          fprintf (file, "\n");
          bfd_mach_o_print_dysymtab (abfd, cmd, file);
          bfd_mach_o_print_dysymtab (abfd, cmd, file);
          break;
          break;
        case BFD_MACH_O_LC_CODE_SIGNATURE:
        case BFD_MACH_O_LC_CODE_SIGNATURE:
        case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
        case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
 
        case BFD_MACH_O_LC_FUNCTION_STARTS:
          {
          {
            bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
            bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
            fprintf
            fprintf
              (file, "\n"
              (file, "\n"
               "  dataoff: 0x%08lx  datasize: 0x%08lx  (endoff: 0x%08lx)\n",
               "  dataoff: 0x%08lx  datasize: 0x%08lx  (endoff: 0x%08lx)\n",
Line 3868... Line 4047...
          }
          }
        case BFD_MACH_O_LC_DYLD_INFO:
        case BFD_MACH_O_LC_DYLD_INFO:
          fprintf (file, "\n");
          fprintf (file, "\n");
          bfd_mach_o_print_dyld_info (abfd, cmd, file);
          bfd_mach_o_print_dyld_info (abfd, cmd, file);
          break;
          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:
        default:
          fprintf (file, "\n");
          fprintf (file, "\n");
 
          fprintf (file, "  offset: 0x%08lx\n", (unsigned long)cmd->offset);
 
          fprintf (file, "    size: 0x%08lx\n", (unsigned long)cmd->len);
          break;
          break;
        }
        }
      fputc ('\n', file);
      fputc ('\n', file);
    }
    }
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.