/* Darwin support for GDB, the GNU debugger.
   Copyright (C) 2008-2022 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 "gdbcmd.h"
#include "gdbcore.h"
#include "mach-o.h"
#include "aout/stab_gnu.h"
#include "complaints.h"
#include "gdb_bfd.h"
#include <string>
#include <algorithm>
#include "dwarf2/public.h"

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

#define macho_debug(LEVEL, FMT, ...) \
  debug_prefixed_printf_cond_nofunc (mach_o_debug_level > LEVEL, \
				     "machoread", FMT, ## __VA_ARGS__)

/* 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.  */

struct oso_el
{
  oso_el (asymbol **oso_sym_, asymbol **end_sym_, unsigned int nbr_syms_)
    : name((*oso_sym_)->name),
      mtime((*oso_sym_)->value),
      oso_sym(oso_sym_),
      end_sym(end_sym_),
      nbr_syms(nbr_syms_)
  {
  }

  /* 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;
};

static void
macho_new_init (struct objfile *objfile)
{
}

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

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

static void
macho_symtab_add_minsym (minimal_symbol_reader &reader,
			 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;
      enum minimal_symbol_type ms_type;

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

      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.  */

      reader.record_with_info (sym->name, symaddr, ms_type,
			       gdb_bfd_section_index (objfile->obfd,
						      sym->section));
    }
}

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

static void
macho_symtab_read (minimal_symbol_reader &reader,
		   struct objfile *objfile,
		   long number_of_symbols, asymbol **symbol_table,
		   std::vector<oso_el> *oso_vector_ptr)
{
  long i;
  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 (_("Unexpected empty N_SO stab"));
		}
	      else
		{
		  file_so = sym;
		  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 (_("%s: Unexpected debug stab outside SO markers"),
			 objfile_name (objfile));
	    }
	  else
	    {
	      /* Non-debugging symbols go to the minimal symbol table.  */
	      macho_symtab_add_minsym (reader, 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 (_("Empty SO section"));
		  state = S_NO_SO;
		}
	      else if (state == S_FIRST_SO)
		{
		  /* Second SO stab for the file name.  */
		  file_so = sym;
		  state = S_SECOND_SO;
		}
	      else
		complaint (_("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 (_("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)
		    oso_vector_ptr->emplace_back (oso_file, symbol_table + i,
						  nbr_syms);
		  state = S_NO_SO;
		}
	      else
		{
		  complaint (_("Missing nul SO"));
		  file_so = sym;
		  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 (_("unhandled stab for dwarf OSO file"));
		      break;
		    }
		}
	    }
	  else
	    complaint (_("non-debugging symbol within SO"));
	  break;
	}
    }

  if (state != S_NO_SO)
    complaint (_("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)
{
  const 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 std::sort OSOs, so that members of a library
   are gathered.  */

static bool
oso_el_compare_name (const oso_el &l, const oso_el &r)
{
  return strcmp (l.name, r.name) < 0;
}

/* 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 bound_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.minsym == NULL)
    {
      warning (_("can't find symbol '%s' in minsymtab"), name);
      return 0;
    }
  else
    return msym.value_address ();
}

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

static void
macho_add_oso_symfile (oso_el *oso, const gdb_bfd_ref_ptr &abfd,
		       const char *name,
		       struct objfile *main_objfile,
		       symfile_add_flags symfile_flags)
{
  int storage;
  int i;
  asymbol **symbol_table;
  asymbol **symp;
  struct bfd_hash_table table;
  int nbr_sections;

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

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

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

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

  bfd_set_cacheable (abfd.get (), 1);

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

  /* Init section flags.  */
  nbr_sections = bfd_count_sections (abfd.get ());
  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 (_("Duplicated symbol %s in symbol table"), sym->name);
	  else
	    {
	      macho_debug (4, _("Adding symbol %s (addr: %s)\n"),
			   sym->name, paddress (main_objfile->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;

		  macho_debug (3, _("resolve sect %s with %s (set to %s)\n"),
			       sec->name, sym->name,
			       paddress (main_objfile->arch (), res));
		  bfd_set_section_vma (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 interactive question
     from symfile.c:symbol_file_add_with_addrs_or_offsets.  */
  symbol_file_add_from_bfd
    (abfd.get (), name, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE),
     NULL,
     main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED
			    | OBJF_READNOW | OBJF_USERLOADED),
     main_objfile);
}

/* Read symbols from the vector of oso files.

   Note that this function sorts OSO_VECTOR_PTR.  */

static void
macho_symfile_read_all_oso (std::vector<oso_el> *oso_vector_ptr,
			    struct objfile *main_objfile,
			    symfile_add_flags symfile_flags)
{
  int ix;
  oso_el *oso;

  /* Sort oso by name so that files from libraries are gathered.  */
  std::sort (oso_vector_ptr->begin (), oso_vector_ptr->end (),
	     oso_el_compare_name);

  for (ix = 0; ix < oso_vector_ptr->size ();)
    {
      int pfx_len;

      oso = &(*oso_vector_ptr)[ix];

      /* Check if this is a library name.  */
      pfx_len = get_archive_prefix_len (oso->name);
      if (pfx_len > 0)
	{
	  int last_ix;
	  oso_el *oso2;
	  int ix2;

	  std::string archive_name (oso->name, pfx_len);

	  /* Compute number of oso for this archive.  */
	  for (last_ix = ix; last_ix < oso_vector_ptr->size (); last_ix++)
	    {
	      oso2 = &(*oso_vector_ptr)[last_ix];
	      if (strncmp (oso2->name, archive_name.c_str (), pfx_len) != 0)
		break;
	    }

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

	  gdb_bfd_ref_ptr member_bfd
	    (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL));

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

	  /* Load all oso in this library.  */
	  while (member_bfd != NULL)
	    {
	      const char *member_name = bfd_get_filename (member_bfd.get ());
	      int member_len = strlen (member_name);

	      /* If this member is referenced, add it as a symfile.  */
	      for (ix2 = ix; ix2 < last_ix; ix2++)
		{
		  oso2 = &(*oso_vector_ptr)[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,
					     bfd_get_filename (member_bfd.get ()),
					     main_objfile, symfile_flags);
		      oso2->name = NULL;
		      break;
		    }
		}

	      member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (),
							     member_bfd.get ());
	    }
	  for (ix2 = ix; ix2 < last_ix; ix2++)
	    {
	      oso2 = &(*oso_vector_ptr)[ix2];

	      if (oso2->name != NULL)
		warning (_("Could not find specified archive member "
			   "for OSO name \"%s\""), oso->name);
	    }
	  ix = last_ix;
	}
      else
	{
	  gdb_bfd_ref_ptr abfd (gdb_bfd_open (oso->name, gnutarget));
	  if (abfd == NULL)
	    warning (_("`%s': can't open to read symbols: %s."), oso->name,
		     bfd_errmsg (bfd_get_error ()));
	  else
	    macho_add_oso_symfile (oso, abfd, oso->name, main_objfile,
				   symfile_flags);

	  ix++;
	}
    }
}

/* 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
   and return *FILENAMEP with its original filename.
   Return NULL if no valid dsym file is found (FILENAMEP is not used in
   such case).  */

static gdb_bfd_ref_ptr
macho_check_dsym (struct objfile *objfile, std::string *filenamep)
{
  size_t name_len = strlen (objfile_name (objfile));
  size_t dsym_len = strlen (DSYM_SUFFIX);
  const char *base_name = lbasename (objfile_name (objfile));
  size_t base_len = strlen (base_name);
  char *dsym_filename = (char *) alloca (name_len + dsym_len + base_len + 1);
  bfd_mach_o_load_command *main_uuid;
  bfd_mach_o_load_command *dsym_uuid;

  strcpy (dsym_filename, objfile_name (objfile));
  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 (objfile));
      return NULL;
    }
  gdb_bfd_ref_ptr 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.get (), bfd_object))
    {
      warning (_("bad dsym file format: %s"), bfd_errmsg (bfd_get_error ()));
      return NULL;
    }

  if (bfd_mach_o_lookup_command (dsym_bfd.get (),
				 BFD_MACH_O_LC_UUID, &dsym_uuid) == 0)
    {
      warning (_("can't find UUID in %s"), dsym_filename);
      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 (objfile));
      return NULL;
    }
  *filenamep = std::string (dsym_filename);
  return dsym_bfd;
}

static void
macho_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
{
  bfd *abfd = objfile->obfd;
  long storage_needed;
  std::vector<oso_el> oso_vector;
  /* We have to hold on to the symbol table until the call to
     macho_symfile_read_all_oso at the end of this function.  */
  gdb::def_vector<asymbol *> symbol_table;

  /* 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))
    {
      std::string dsym_filename;

      /* 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)
	{
	  long symcount;

	  symbol_table.resize (storage_needed / sizeof (asymbol *));

	  minimal_symbol_reader reader (objfile);

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

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

	  macho_symtab_read (reader, objfile, symcount, symbol_table.data (),
			     &oso_vector);

	  reader.install ();
	}

      /* 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.  */
      gdb_bfd_ref_ptr dsym_bfd (macho_check_dsym (objfile, &dsym_filename));
      if (dsym_bfd != NULL)
	{
	  struct bfd_section *asect, *dsect;

	  macho_debug (0, _("dsym file found\n"));

	  /* 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 (dsect, bfd_section_size (asect));
	    }

	  /* Add the dsym file as a separate file.  */
	  symbol_file_add_separate (dsym_bfd.get (), dsym_filename.c_str (),
				    symfile_flags, objfile);

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

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

  /* Then the oso.  */
  if (!oso_vector.empty ())
    macho_symfile_read_all_oso (&oso_vector, 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;

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

  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,
		       const section_addr_info &addrs)
{
  unsigned int i;
  struct obj_section *osect;

  /* Allocate section_offsets.  */
  objfile->section_offsets.assign (gdb_bfd_count_sections (objfile->obfd), 0);

  /* 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.size (); i++)
    {
      ALL_OBJFILE_OSECTIONS (objfile, osect)
	{
	  const char *bfd_sect_name = osect->the_bfd_section->name;

	  if (bfd_sect_name == addrs[i].name)
	    {
	      osect->set_offset (addrs[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 - objfile->sections;;

      if (startswith (bfd_sect_name, "LC_SEGMENT."))
	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 = {
  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 */
  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 */
};

void _initialize_machoread ();
void
_initialize_machoread ()
{
  add_symtab_fns (bfd_target_mach_o_flavour, &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);
}
