/* Darwin support for GDB, the GNU debugger.
   Copyright (C) 2008-2013 Free Software Foundation, Inc.

   Contributed by AdaCore.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "bfd.h"
#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "mach-o.h"
#include "gdb_assert.h"
#include "aout/stab_gnu.h"
#include "vec.h"
#include "psympriv.h"
#include "complaints.h"
#include "gdb_bfd.h"

#include <string.h>

/* If non-zero displays debugging message.  */
static unsigned int mach_o_debug_level = 0;

/* Dwarf debugging information are never in the final executable.  They stay
   in object files and the executable contains the list of object files read
   during the link.
   Each time an oso (other source) is found in the executable, the reader
   creates such a structure.  They are read after the processing of the
   executable.  */

typedef struct oso_el
{
  /* Object file name.  Can also be a member name.  */
  const char *name;

  /* Associated time stamp.  */
  unsigned long mtime;

  /* Stab symbols range for this OSO.  */
  asymbol **oso_sym;
  asymbol **end_sym;

  /* Number of interesting stabs in the range.  */
  unsigned int nbr_syms;
}
oso_el;

/* Vector of object files to be read after the executable.  This is one
   global variable but it's life-time is the one of macho_symfile_read.  */
DEF_VEC_O (oso_el);
static VEC (oso_el) *oso_vector;

static void
macho_new_init (struct objfile *objfile)
{
}

static void
macho_symfile_init (struct objfile *objfile)
{
  objfile->flags |= OBJF_REORDERED;
}

/*  Add a new OSO to the vector of OSO to load.  */

static void
macho_register_oso (struct objfile *objfile,
                    asymbol **oso_sym, asymbol **end_sym,
                    unsigned int nbr_syms)
{
  oso_el el;

  el.name = (*oso_sym)->name;
  el.mtime = (*oso_sym)->value;
  el.oso_sym = oso_sym;
  el.end_sym = end_sym;
  el.nbr_syms = nbr_syms;
  VEC_safe_push (oso_el, oso_vector, &el);
}

/* Add symbol SYM to the minimal symbol table of OBJFILE.  */

static void
macho_symtab_add_minsym (struct objfile *objfile, const asymbol *sym)
{
  if (sym->name == NULL || *sym->name == '\0')
    {
      /* Skip names that don't exist (shouldn't happen), or names
         that are null strings (may happen).  */
      return;
    }

  if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK))
    {
      CORE_ADDR symaddr;
      CORE_ADDR offset;
      enum minimal_symbol_type ms_type;

      offset = ANOFFSET (objfile->section_offsets, sym->section->index);

      /* Bfd symbols are section relative.  */
      symaddr = sym->value + sym->section->vma;

      /* Select global/local/weak symbols.  Note that bfd puts abs
         symbols in their own section, so all symbols we are
         interested in will have a section.  */
      /* Relocate all non-absolute and non-TLS symbols by the
         section offset.  */
      if (sym->section != bfd_abs_section_ptr
          && !(sym->section->flags & SEC_THREAD_LOCAL))
        symaddr += offset;

      if (sym->section == bfd_abs_section_ptr)
        ms_type = mst_abs;
      else if (sym->section->flags & SEC_CODE)
        {
          if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
            ms_type = mst_text;
          else
            ms_type = mst_file_text;
        }
      else if (sym->section->flags & SEC_ALLOC)
        {
          if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
            {
              if (sym->section->flags & SEC_LOAD)
                ms_type = mst_data;
              else
                ms_type = mst_bss;
            }
          else if (sym->flags & BSF_LOCAL)
            {
              /* Not a special stabs-in-elf symbol, do regular
                 symbol processing.  */
              if (sym->section->flags & SEC_LOAD)
                ms_type = mst_file_data;
              else
                ms_type = mst_file_bss;
            }
          else
            ms_type = mst_unknown;
        }
      else
        return;	/* Skip this symbol.  */

      prim_record_minimal_symbol_and_info
        (sym->name, symaddr, ms_type, sym->section->index,
         sym->section, objfile);
    }
}

/* Build the minimal symbol table from SYMBOL_TABLE of length
   NUMBER_OF_SYMBOLS for OBJFILE.  Registers OSO filenames found.  */

static void
macho_symtab_read (struct objfile *objfile,
		   long number_of_symbols, asymbol **symbol_table)
{
  long i;
  const asymbol *dir_so = NULL;
  const asymbol *file_so = NULL;
  asymbol **oso_file = NULL;
  unsigned int nbr_syms = 0;

  /* Current state while reading stabs.  */
  enum
  {
    /* Not within an SO part.  Only non-debugging symbols should be present,
       and will be added to the minimal symbols table.  */
    S_NO_SO,

    /* First SO read.  Introduce an SO section, and may be followed by a second
       SO.  The SO section should contain onl debugging symbols.  */
    S_FIRST_SO,

    /* Second non-null SO found, just after the first one.  Means that the first
       is in fact a directory name.  */
    S_SECOND_SO,

    /* Non-null OSO found.  Debugging info are DWARF in this OSO file.  */
    S_DWARF_FILE,

    S_STAB_FILE
  } state = S_NO_SO;

  for (i = 0; i < number_of_symbols; i++)
    {
      const asymbol *sym = symbol_table[i];
      bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym;

      switch (state)
        {
        case S_NO_SO:
	  if (mach_o_sym->n_type == N_SO)
            {
              /* Start of object stab.  */
	      if (sym->name == NULL || sym->name[0] == 0)
                {
                  /* Unexpected empty N_SO.  */
                  complaint (&symfile_complaints,
                             _("Unexpected empty N_SO stab"));
                }
              else
                {
                  file_so = sym;
                  dir_so = NULL;
                  state = S_FIRST_SO;
                }
            }
          else if (sym->flags & BSF_DEBUGGING)
            {
              if (mach_o_sym->n_type == N_OPT)
                {
                  /* No complaint for OPT.  */
                  break;
                }

              /* Debugging symbols are not expected here.  */
              complaint (&symfile_complaints,
                         _("%s: Unexpected debug stab outside SO markers"),
                         objfile->name);
            }
          else
            {
              /* Non-debugging symbols go to the minimal symbol table.  */
              macho_symtab_add_minsym (objfile, sym);
            }
          break;

        case S_FIRST_SO:
        case S_SECOND_SO:
	  if (mach_o_sym->n_type == N_SO)
            {
	      if (sym->name == NULL || sym->name[0] == 0)
                {
                  /* Unexpected empty N_SO.  */
                  complaint (&symfile_complaints, _("Empty SO section"));
                  state = S_NO_SO;
                }
              else if (state == S_FIRST_SO)
                {
                  /* Second SO stab for the file name.  */
                  dir_so = file_so;
                  file_so = sym;
                  state = S_SECOND_SO;
                }
              else
                complaint (&symfile_complaints, _("Three SO in a raw"));
            }
          else if (mach_o_sym->n_type == N_OSO)
            {
	      if (sym->name == NULL || sym->name[0] == 0)
                {
                  /* Empty OSO.  Means that this file was compiled with
                     stabs.  */
                  state = S_STAB_FILE;
                  warning (_("stabs debugging not supported for %s"),
                           file_so->name);
                }
              else
                {
                  /* Non-empty OSO for a Dwarf file.  */
                  oso_file = symbol_table + i;
                  nbr_syms = 0;
                  state = S_DWARF_FILE;
                }
            }
          else
            complaint (&symfile_complaints,
                       _("Unexpected stab after SO"));
          break;

        case S_STAB_FILE:
        case S_DWARF_FILE:
	  if (mach_o_sym->n_type == N_SO)
            {
	      if (sym->name == NULL || sym->name[0] == 0)
                {
                  /* End of file.  */
                  if (state == S_DWARF_FILE)
                    macho_register_oso (objfile, oso_file, symbol_table + i,
                                        nbr_syms);
                  state = S_NO_SO;
                }
              else
                {
                  complaint (&symfile_complaints, _("Missing nul SO"));
                  file_so = sym;
                  dir_so = NULL;
                  state = S_FIRST_SO;
                }
            }
          else if (sym->flags & BSF_DEBUGGING)
            {
              if (state == S_STAB_FILE)
                {
                  /* FIXME: to be implemented.  */
                }
              else
                {
                  switch (mach_o_sym->n_type)
                    {
                    case N_FUN:
                      if (sym->name == NULL || sym->name[0] == 0)
                        break;
                      /* Fall through.  */
                    case N_STSYM:
                      /* Interesting symbol.  */
                      nbr_syms++;
                      break;
                    case N_ENSYM:
                    case N_BNSYM:
                    case N_GSYM:
                      break;
                    default:
                      complaint (&symfile_complaints,
                                 _("unhandled stab for dwarf OSO file"));
                      break;
                    }
                }
            }
          else
            complaint (&symfile_complaints,
                       _("non-debugging symbol within SO"));
          break;
        }
    }

  if (state != S_NO_SO)
    complaint (&symfile_complaints, _("missing nul SO"));
}

/* If NAME describes an archive member (ie: ARCHIVE '(' MEMBER ')'),
   returns the length of the archive name.
   Returns -1 otherwise.  */

static int
get_archive_prefix_len (const char *name)
{
  char *lparen;
  int name_len = strlen (name);

  if (name_len == 0 || name[name_len - 1] != ')')
    return -1;

  lparen = strrchr (name, '(');
  if (lparen == NULL || lparen == name)
    return -1;
  return lparen - name;
}

/* Compare function to qsort OSOs, so that members of a library are
   gathered.  */

static int
oso_el_compare_name (const void *vl, const void *vr)
{
  const oso_el *l = (const oso_el *)vl;
  const oso_el *r = (const oso_el *)vr;

  return strcmp (l->name, r->name);
}

/* Hash table entry structure for the stabs symbols in the main object file.
   This is used to speed up lookup for symbols in the OSO.  */

struct macho_sym_hash_entry
{
  struct bfd_hash_entry base;
  const asymbol *sym;
};

/* Routine to create an entry in the hash table.  */

static struct bfd_hash_entry *
macho_sym_hash_newfunc (struct bfd_hash_entry *entry,
                        struct bfd_hash_table *table,
                        const char *string)
{
  struct macho_sym_hash_entry *ret = (struct macho_sym_hash_entry *) entry;

  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (ret == NULL)
    ret = (struct macho_sym_hash_entry *) bfd_hash_allocate (table,
                                                             sizeof (* ret));
  if (ret == NULL)
    return NULL;

  /* Call the allocation method of the superclass.  */
  ret = (struct macho_sym_hash_entry *)
	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string);

  if (ret)
    {
      /* Initialize the local fields.  */
      ret->sym = NULL;
    }

  return (struct bfd_hash_entry *) ret;
}

/* Get the value of SYM from the minimal symtab of MAIN_OBJFILE.  This is used
   to get the value of global and common symbols.  */

static CORE_ADDR
macho_resolve_oso_sym_with_minsym (struct objfile *main_objfile, asymbol *sym)
{
  /* For common symbol and global symbols, use the min symtab.  */
  struct minimal_symbol *msym;
  const char *name = sym->name;

  if (name[0] == bfd_get_symbol_leading_char (main_objfile->obfd))
    ++name;
  msym = lookup_minimal_symbol (name, NULL, main_objfile);
  if (msym == NULL)
    {
      warning (_("can't find symbol '%s' in minsymtab"), name);
      return 0;
    }
  else
    return SYMBOL_VALUE_ADDRESS (msym);
}

/* Add oso file OSO/ABFD as a symbol file.  */

static void
macho_add_oso_symfile (oso_el *oso, bfd *abfd,
                       struct objfile *main_objfile, int symfile_flags)
{
  int storage;
  int i;
  asymbol **symbol_table;
  asymbol **symp;
  struct bfd_hash_table table;
  int nbr_sections;
  struct cleanup *cleanup;

  /* Per section flag to mark which section have been rebased.  */
  unsigned char *sections_rebased;

  if (mach_o_debug_level > 0)
    printf_unfiltered
      (_("Loading debugging symbols from oso: %s\n"), oso->name);

  if (!bfd_check_format (abfd, bfd_object))
    {
      warning (_("`%s': can't read symbols: %s."), oso->name,
               bfd_errmsg (bfd_get_error ()));
      gdb_bfd_unref (abfd);
      return;
    }

  if (abfd->my_archive == NULL && oso->mtime != bfd_get_mtime (abfd))
    {
      warning (_("`%s': file time stamp mismatch."), oso->name);
      gdb_bfd_unref (abfd);
      return;
    }

  if (!bfd_hash_table_init_n (&table, macho_sym_hash_newfunc,
                              sizeof (struct macho_sym_hash_entry),
                              oso->nbr_syms))
    {
      warning (_("`%s': can't create hash table"), oso->name);
      gdb_bfd_unref (abfd);
      return;
    }

  bfd_set_cacheable (abfd, 1);

  /* Read symbols table.  */
  storage = bfd_get_symtab_upper_bound (abfd);
  symbol_table = (asymbol **) xmalloc (storage);
  bfd_canonicalize_symtab (abfd, symbol_table);

  /* Init section flags.  */
  nbr_sections = bfd_count_sections (abfd);
  sections_rebased = (unsigned char *) alloca (nbr_sections);
  for (i = 0; i < nbr_sections; i++)
    sections_rebased[i] = 0;

  /* Put symbols for the OSO file in the hash table.  */
  for (symp = oso->oso_sym; symp != oso->end_sym; symp++)
    {
      const asymbol *sym = *symp;
      bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym;

      switch (mach_o_sym->n_type)
        {
        case N_ENSYM:
        case N_BNSYM:
        case N_GSYM:
          sym = NULL;
          break;
        case N_FUN:
          if (sym->name == NULL || sym->name[0] == 0)
            sym = NULL;
          break;
        case N_STSYM:
          break;
        default:
          sym = NULL;
          break;
        }
      if (sym != NULL)
        {
          struct macho_sym_hash_entry *ent;

          ent = (struct macho_sym_hash_entry *)
            bfd_hash_lookup (&table, sym->name, TRUE, FALSE);
          if (ent->sym != NULL)
            complaint (&symfile_complaints,
                       _("Duplicated symbol %s in symbol table"), sym->name);
          else
            {
              if (mach_o_debug_level > 4)
                {
                  struct gdbarch *arch = get_objfile_arch (main_objfile);
                  printf_unfiltered
                    (_("Adding symbol %s (addr: %s)\n"),
                     sym->name, paddress (arch, sym->value));
                }
              ent->sym = sym;
            }
        }
    }

  /* Relocate symbols of the OSO.  */
  for (i = 0; symbol_table[i]; i++)
    {
      asymbol *sym = symbol_table[i];
      bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym;

      if (mach_o_sym->n_type & BFD_MACH_O_N_STAB)
        continue;
      if ((mach_o_sym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF
           && sym->value != 0)
        {
          /* For common symbol use the min symtab and modify the OSO
             symbol table.  */
          CORE_ADDR res;

          res = macho_resolve_oso_sym_with_minsym (main_objfile, sym);
          if (res != 0)
            {
              sym->section = bfd_com_section_ptr;
              sym->value = res;
            }
        }
      else if ((mach_o_sym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
        {
          /* Normal symbol.  */
          asection *sec = sym->section;
          bfd_mach_o_section *msec;
          unsigned int sec_type;

          /* Skip buggy ones.  */
          if (sec == NULL || sections_rebased[sec->index] != 0)
            continue;

          /* Only consider regular, non-debugging sections.  */
          msec = bfd_mach_o_get_mach_o_section (sec);
          sec_type = msec->flags & BFD_MACH_O_SECTION_TYPE_MASK;
          if ((sec_type == BFD_MACH_O_S_REGULAR
               || sec_type == BFD_MACH_O_S_ZEROFILL)
              && (msec->flags & BFD_MACH_O_S_ATTR_DEBUG) == 0)
            {
              CORE_ADDR addr = 0;

              if ((mach_o_sym->n_type & BFD_MACH_O_N_EXT) != 0)
                {
                  /* Use the min symtab for global symbols.  */
                  addr = macho_resolve_oso_sym_with_minsym (main_objfile, sym);
                }
              else
                {
                  struct macho_sym_hash_entry *ent;

                  ent = (struct macho_sym_hash_entry *)
                    bfd_hash_lookup (&table, sym->name, FALSE, FALSE);
                  if (ent != NULL)
                    addr = bfd_asymbol_value (ent->sym);
                }

              /* Adjust the section.  */
              if (addr != 0)
                {
                  CORE_ADDR res = addr - sym->value;

                  if (mach_o_debug_level > 3)
                    {
                      struct gdbarch *arch = get_objfile_arch (main_objfile);
                      printf_unfiltered
                        (_("resolve sect %s with %s (set to %s)\n"),
                         sec->name, sym->name,
                         paddress (arch, res));
                    }
                  bfd_set_section_vma (abfd, sec, res);
                  sections_rebased[sec->index] = 1;
                }
            }
          else
            {
              /* Mark the section as never rebased.  */
              sections_rebased[sec->index] = 2;
            }
        }
    }

  bfd_hash_table_free (&table);

  /* We need to clear SYMFILE_MAINLINE to avoid interractive question
     from symfile.c:symbol_file_add_with_addrs_or_offsets.  */
  cleanup = make_cleanup_bfd_unref (abfd);
  symbol_file_add_from_bfd
    (abfd, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE), NULL,
     main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED
			    | OBJF_READNOW | OBJF_USERLOADED),
     main_objfile);
  do_cleanups (cleanup);
}

/* Read symbols from the vector of oso files.  */

static void
macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
{
  int ix;
  VEC (oso_el) *vec;
  oso_el *oso;
  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);

  vec = oso_vector;
  oso_vector = NULL;

  /* Sort oso by name so that files from libraries are gathered.  */
  qsort (VEC_address (oso_el, vec), VEC_length (oso_el, vec),
         sizeof (oso_el), oso_el_compare_name);

  for (ix = 0; VEC_iterate (oso_el, vec, ix, oso);)
    {
      int pfx_len;

      /* Check if this is a library name.  */
      pfx_len = get_archive_prefix_len (oso->name);
      if (pfx_len > 0)
	{
	  bfd *archive_bfd;
	  bfd *member_bfd;
	  char *archive_name = XNEWVEC (char, pfx_len + 1);
          int last_ix;
          oso_el *oso2;
          int ix2;

	  memcpy (archive_name, oso->name, pfx_len);
	  archive_name[pfx_len] = '\0';

	  make_cleanup (xfree, archive_name);

          /* Compute number of oso for this archive.  */
          for (last_ix = ix;
               VEC_iterate (oso_el, vec, last_ix, oso2); last_ix++)
            {
              if (strncmp (oso2->name, archive_name, pfx_len) != 0)
                break;
            }

	  /* Open the archive and check the format.  */
	  archive_bfd = gdb_bfd_open (archive_name, gnutarget, -1);
	  if (archive_bfd == NULL)
	    {
	      warning (_("Could not open OSO archive file \"%s\""),
		       archive_name);
              ix = last_ix;
	      continue;
	    }
	  if (!bfd_check_format (archive_bfd, bfd_archive))
	    {
	      warning (_("OSO archive file \"%s\" not an archive."),
		       archive_name);
	      gdb_bfd_unref (archive_bfd);
              ix = last_ix;
	      continue;
	    }

	  member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL);

	  if (member_bfd == NULL)
	    {
	      warning (_("Could not read archive members out of "
			 "OSO archive \"%s\""), archive_name);
	      gdb_bfd_unref (archive_bfd);
              ix = last_ix;
	      continue;
	    }

          /* Load all oso in this library.  */
	  while (member_bfd != NULL)
	    {
	      bfd *prev;
	      const char *member_name = member_bfd->filename;
              int member_len = strlen (member_name);

              /* If this member is referenced, add it as a symfile.  */
              for (ix2 = ix; ix2 < last_ix; ix2++)
                {
                  oso2 = VEC_index (oso_el, vec, ix2);

                  if (oso2->name
                      && strlen (oso2->name) == pfx_len + member_len + 2
                      && !memcmp (member_name, oso2->name + pfx_len + 1,
                                  member_len))
                    {
                      macho_add_oso_symfile (oso2, member_bfd,
                                             main_objfile, symfile_flags);
                      oso2->name = NULL;
                      break;
                    }
                }

              prev = member_bfd;
	      member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd,
							     member_bfd);

              /* Free previous member if not referenced by an oso.  */
              if (ix2 >= last_ix)
                gdb_bfd_unref (prev);
	    }
          for (ix2 = ix; ix2 < last_ix; ix2++)
            {
              oso_el *oso2 = VEC_index (oso_el, vec, ix2);

              if (oso2->name != NULL)
                warning (_("Could not find specified archive member "
                           "for OSO name \"%s\""), oso->name);
            }
          ix = last_ix;
	}
      else
	{
          bfd *abfd;

	  abfd = gdb_bfd_open (oso->name, gnutarget, -1);
	  if (!abfd)
            warning (_("`%s': can't open to read symbols: %s."), oso->name,
                     bfd_errmsg (bfd_get_error ()));
          else
            macho_add_oso_symfile (oso, abfd, main_objfile, symfile_flags);

          ix++;
        }
    }

  VEC_free (oso_el, vec);
  do_cleanups (cleanup);
}

/* DSYM (debug symbols) files contain the debug info of an executable.
   This is a separate file created by dsymutil(1) and is similar to debug
   link feature on ELF.
   DSYM files are located in a subdirectory.  Append DSYM_SUFFIX to the
   executable name and the executable base name to get the DSYM file name.  */
#define DSYM_SUFFIX ".dSYM/Contents/Resources/DWARF/"

/* Check if a dsym file exists for OBJFILE.  If so, returns a bfd for it.
   Return NULL if no valid dsym file is found.  */

static bfd *
macho_check_dsym (struct objfile *objfile)
{
  size_t name_len = strlen (objfile->name);
  size_t dsym_len = strlen (DSYM_SUFFIX);
  const char *base_name = lbasename (objfile->name);
  size_t base_len = strlen (base_name);
  char *dsym_filename = alloca (name_len + dsym_len + base_len + 1);
  bfd *dsym_bfd;
  bfd_mach_o_load_command *main_uuid;
  bfd_mach_o_load_command *dsym_uuid;

  strcpy (dsym_filename, objfile->name);
  strcpy (dsym_filename + name_len, DSYM_SUFFIX);
  strcpy (dsym_filename + name_len + dsym_len, base_name);

  if (access (dsym_filename, R_OK) != 0)
    return NULL;

  if (bfd_mach_o_lookup_command (objfile->obfd,
                                 BFD_MACH_O_LC_UUID, &main_uuid) == 0)
    {
      warning (_("can't find UUID in %s"), objfile->name);
      return NULL;
    }
  dsym_bfd = gdb_bfd_openr (dsym_filename, gnutarget);
  if (dsym_bfd == NULL)
    {
      warning (_("can't open dsym file %s"), dsym_filename);
      return NULL;
    }

  if (!bfd_check_format (dsym_bfd, bfd_object))
    {
      gdb_bfd_unref (dsym_bfd);
      warning (_("bad dsym file format: %s"), bfd_errmsg (bfd_get_error ()));
      return NULL;
    }

  if (bfd_mach_o_lookup_command (dsym_bfd,
                                 BFD_MACH_O_LC_UUID, &dsym_uuid) == 0)
    {
      warning (_("can't find UUID in %s"), dsym_filename);
      gdb_bfd_unref (dsym_bfd);
      return NULL;
    }
  if (memcmp (dsym_uuid->command.uuid.uuid, main_uuid->command.uuid.uuid,
              sizeof (main_uuid->command.uuid.uuid)))
    {
      warning (_("dsym file UUID doesn't match the one in %s"), objfile->name);
      gdb_bfd_unref (dsym_bfd);
      return NULL;
    }
  return dsym_bfd;
}

static void
macho_symfile_read (struct objfile *objfile, int symfile_flags)
{
  bfd *abfd = objfile->obfd;
  CORE_ADDR offset;
  long storage_needed;
  bfd *dsym_bfd;

  /* Get symbols from the symbol table only if the file is an executable.
     The symbol table of object files is not relocated and is expected to
     be in the executable.  */
  if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
    {
      /* Process the normal symbol table first.  */
      storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
      if (storage_needed < 0)
	error (_("Can't read symbols from %s: %s"),
	       bfd_get_filename (objfile->obfd),
	       bfd_errmsg (bfd_get_error ()));

      if (storage_needed > 0)
	{
	  asymbol **symbol_table;
	  long symcount;
          struct cleanup *back_to;

	  symbol_table = (asymbol **) xmalloc (storage_needed);
	  make_cleanup (xfree, symbol_table);

          init_minimal_symbol_collection ();
          back_to = make_cleanup_discard_minimal_symbols ();

	  symcount = bfd_canonicalize_symtab (objfile->obfd, symbol_table);

	  if (symcount < 0)
	    error (_("Can't read symbols from %s: %s"),
		   bfd_get_filename (objfile->obfd),
		   bfd_errmsg (bfd_get_error ()));

	  macho_symtab_read (objfile, symcount, symbol_table);

          install_minimal_symbols (objfile);
          do_cleanups (back_to);
	}

      /* Try to read .eh_frame / .debug_frame.  */
      /* First, locate these sections.  We ignore the result status
	 as it only checks for debug info.  */
      dwarf2_has_info (objfile, NULL);
      dwarf2_build_frame_info (objfile);

      /* Check for DSYM file.  */
      dsym_bfd = macho_check_dsym (objfile);
      if (dsym_bfd != NULL)
	{
	  int ix;
	  oso_el *oso;
          struct bfd_section *asect, *dsect;
	  struct cleanup *cleanup;

	  if (mach_o_debug_level > 0)
	    printf_unfiltered (_("dsym file found\n"));

	  /* Remove oso.  They won't be used.  */
	  VEC_free (oso_el, oso_vector);
	  oso_vector = NULL;

          /* Set dsym section size.  */
          for (asect = objfile->obfd->sections, dsect = dsym_bfd->sections;
               asect && dsect;
               asect = asect->next, dsect = dsect->next)
            {
              if (strcmp (asect->name, dsect->name) != 0)
                break;
              bfd_set_section_size (dsym_bfd, dsect,
                                    bfd_get_section_size (asect));
            }

	  /* Add the dsym file as a separate file.  */
	  cleanup = make_cleanup_bfd_unref (dsym_bfd);
          symbol_file_add_separate (dsym_bfd, symfile_flags, objfile);
	  do_cleanups (cleanup);

	  /* Don't try to read dwarf2 from main file or shared libraries.  */
          return;
	}
    }

  if (dwarf2_has_info (objfile, NULL))
    {
      /* DWARF 2 sections */
      dwarf2_build_psymtabs (objfile);
    }

  /* Then the oso.  */
  if (oso_vector != NULL)
    macho_symfile_read_all_oso (objfile, symfile_flags);
}

static bfd_byte *
macho_symfile_relocate (struct objfile *objfile, asection *sectp,
                        bfd_byte *buf)
{
  bfd *abfd = objfile->obfd;

  /* We're only interested in sections with relocation
     information.  */
  if ((sectp->flags & SEC_RELOC) == 0)
    return NULL;

  if (mach_o_debug_level > 0)
    printf_unfiltered (_("Relocate section '%s' of %s\n"),
                       sectp->name, objfile->name);

  return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
}

static void
macho_symfile_finish (struct objfile *objfile)
{
}

static void
macho_symfile_offsets (struct objfile *objfile,
                       struct section_addr_info *addrs)
{
  unsigned int i;
  unsigned int num_sections;
  struct obj_section *osect;

  /* Allocate section_offsets.  */
  objfile->num_sections = bfd_count_sections (objfile->obfd);
  objfile->section_offsets = (struct section_offsets *)
    obstack_alloc (&objfile->objfile_obstack,
                   SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
  memset (objfile->section_offsets, 0,
          SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));

  /* This code is run when we first add the objfile with
     symfile_add_with_addrs_or_offsets, when "addrs" not "offsets" are
     passed in.  The place in symfile.c where the addrs are applied
     depends on the addrs having section names.  But in the dyld code
     we build an anonymous array of addrs, so that code is a no-op.
     Because of that, we have to apply the addrs to the sections here.
     N.B. if an objfile slides after we've already created it, then it
     goes through objfile_relocate.  */

  for (i = 0; i < addrs->num_sections; i++)
    {
      ALL_OBJFILE_OSECTIONS (objfile, osect)
	{
	  const char *bfd_sect_name = osect->the_bfd_section->name;

	  if (strcmp (bfd_sect_name, addrs->other[i].name) == 0)
	    {
	      obj_section_offset (osect) = addrs->other[i].addr;
	      break;
	    }
	}
    }

  objfile->sect_index_text = 0;

  ALL_OBJFILE_OSECTIONS (objfile, osect)
    {
      const char *bfd_sect_name = osect->the_bfd_section->name;
      int sect_index = osect->the_bfd_section->index;

      if (strncmp (bfd_sect_name, "LC_SEGMENT.", 11) == 0)
	bfd_sect_name += 11;
      if (strcmp (bfd_sect_name, "__TEXT") == 0
	  || strcmp (bfd_sect_name, "__TEXT.__text") == 0)
	objfile->sect_index_text = sect_index;
    }
}

static const struct sym_fns macho_sym_fns = {
  bfd_target_mach_o_flavour,

  macho_new_init,               /* init anything gbl to entire symtab */
  macho_symfile_init,           /* read initial info, setup for sym_read() */
  macho_symfile_read,           /* read a symbol file into symtab */
  NULL,				/* sym_read_psymbols */
  macho_symfile_finish,         /* finished with file, cleanup */
  macho_symfile_offsets,        /* xlate external to internal form */
  default_symfile_segments,	/* Get segment information from a file.  */
  NULL,
  macho_symfile_relocate,	/* Relocate a debug section.  */
  NULL,				/* sym_get_probes */
  &psym_functions
};

/* -Wmissing-prototypes */
extern initialize_file_ftype _initialize_machoread;

void
_initialize_machoread ()
{
  add_symtab_fns (&macho_sym_fns);

  add_setshow_zuinteger_cmd ("mach-o", class_obscure,
			     &mach_o_debug_level,
			     _("Set if printing Mach-O symbols processing."),
			     _("Show if printing Mach-O symbols processing."),
			     NULL, NULL, NULL,
			     &setdebuglist, &showdebuglist);
}
