/* Read the export table symbols from a portable executable and
   convert to internal format, for GDB. Used as a last resort if no
   debugging symbols recognized.

   Copyright (C) 2003-2016 Free Software Foundation, Inc.

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

   Contributed by Raoul M. Gough (RaoulGough@yahoo.co.uk).  */

#include "defs.h"

#include "coff-pe-read.h"

#include "bfd.h"
#include "gdbtypes.h"

#include "command.h"
#include "gdbcmd.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "common/common-utils.h"
#include "coff/internal.h"

#include <ctype.h>

/* Internal section information */

/* Coff PE read debugging flag:
   default value is 0,
   value 1 outputs problems encountered while parsing PE file,
   value above 1 also lists all generated minimal symbols.  */
static unsigned int debug_coff_pe_read;

struct read_pe_section_data
{
  CORE_ADDR vma_offset;		/* Offset to loaded address of section.  */
  unsigned long rva_start;	/* Start offset within the pe.  */
  unsigned long rva_end;	/* End offset within the pe.  */
  enum minimal_symbol_type ms_type;	/* Type to assign symbols in
					   section.  */
  unsigned int index;		/* BFD section number.  */
  char *section_name;		/* Recorded section name.  */
};

#define IMAGE_SCN_CNT_CODE 0x20
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x40
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x80
#define PE_SECTION_INDEX_TEXT     0
#define PE_SECTION_INDEX_DATA     1
#define PE_SECTION_INDEX_BSS      2
#define PE_SECTION_TABLE_SIZE     3
#define PE_SECTION_INDEX_INVALID -1

/* Get the index of the named section in our own array, which contains
   text, data and bss in that order.  Return PE_SECTION_INDEX_INVALID
   if passed an unrecognised section name.  */

static int
read_pe_section_index (const char *section_name)
{
  if (strcmp (section_name, ".text") == 0)
    {
      return PE_SECTION_INDEX_TEXT;
    }

  else if (strcmp (section_name, ".data") == 0)
    {
      return PE_SECTION_INDEX_DATA;
    }

  else if (strcmp (section_name, ".bss") == 0)
    {
      return PE_SECTION_INDEX_BSS;
    }

  else
    {
      return PE_SECTION_INDEX_INVALID;
    }
}

/* Get the index of the named section in our own full array.
   text, data and bss in that order.  Return PE_SECTION_INDEX_INVALID
   if passed an unrecognised section name.  */

static int
get_pe_section_index (const char *section_name,
		      struct read_pe_section_data *sections,
		      int nb_sections)
{
  int i;

  for (i = 0; i < nb_sections; i++)
    if (strcmp (sections[i].section_name, section_name) == 0)
      return i;
  return PE_SECTION_INDEX_INVALID;
}

/* Structure used by get_section_vmas function below
   to access section_data array and the size of the array
   stored in nb_sections field.  */
struct pe_sections_info
{
  int nb_sections;
  struct read_pe_section_data *sections;
};

/* Record the virtual memory address of a section.  */

static void
get_section_vmas (bfd *abfd, asection *sectp, void *context)
{
  struct pe_sections_info *data = (struct pe_sections_info *) context;
  struct read_pe_section_data *sections = data->sections;
  int sectix = get_pe_section_index (sectp->name, sections,
				     data->nb_sections);

  if (sectix != PE_SECTION_INDEX_INVALID)
    {
      /* Data within the section start at rva_start in the pe and at
         bfd_get_section_vma() within memory.  Store the offset.  */

      sections[sectix].vma_offset
	= bfd_get_section_vma (abfd, sectp) - sections[sectix].rva_start;
    }
}

/* Create a minimal symbol entry for an exported symbol.
   SYM_NAME contains the exported name or NULL if exported by ordinal,
   FUNC_RVA contains the Relative Virtual Address of the symbol,
   ORDINAL is the ordinal index value of the symbol,
   SECTION_DATA contains information about the section in which the
   symbol is declared,
   DLL_NAME is the internal name of the DLL file,
   OBJFILE is the objfile struct of DLL_NAME.  */

static void
add_pe_exported_sym (const char *sym_name,
		     unsigned long func_rva,
		     int ordinal,
		     const struct read_pe_section_data *section_data,
		     const char *dll_name, struct objfile *objfile)
{
  char *qualified_name, *bare_name;
  /* Add the stored offset to get the loaded address of the symbol.  */
  CORE_ADDR vma = func_rva + section_data->vma_offset;

  /* Generate a (hopefully unique) qualified name using the first part
     of the dll name, e.g. KERNEL32!AddAtomA.  This matches the style
     used by windbg from the "Microsoft Debugging Tools for Windows".  */

  if (sym_name == NULL || *sym_name == '\0')
    bare_name = xstrprintf ("#%d", ordinal);
  else
    bare_name = xstrdup (sym_name);

  qualified_name = xstrprintf ("%s!%s", dll_name, bare_name);

  if ((section_data->ms_type == mst_unknown) && debug_coff_pe_read)
    fprintf_unfiltered (gdb_stdlog , _("Unknown section type for \"%s\""
			" for entry \"%s\" in dll \"%s\"\n"),
			section_data->section_name, sym_name, dll_name);

  prim_record_minimal_symbol_and_info (qualified_name, vma,
				       section_data->ms_type,
				       section_data->index, objfile);

  /* Enter the plain name as well, which might not be unique.  */
  prim_record_minimal_symbol_and_info (bare_name, vma, section_data->ms_type,
				       section_data->index, objfile);
  if (debug_coff_pe_read > 1)
    fprintf_unfiltered (gdb_stdlog, _("Adding exported symbol \"%s\""
			" in dll \"%s\"\n"), sym_name, dll_name);
  xfree (qualified_name);
  xfree (bare_name);
}

/* Create a minimal symbol entry for an exported forward symbol.
   Return 1 if the forwarded function was found 0 otherwise.
   SYM_NAME contains the exported name or NULL if exported by ordinal,
   FORWARD_DLL_NAME is the name of the DLL in which the target symobl resides,
   FORWARD_FUNC_NAME is the name of the target symbol in that DLL,
   ORDINAL is the ordinal index value of the symbol,
   DLL_NAME is the internal name of the DLL file,
   OBJFILE is the objfile struct of DLL_NAME.  */

static int
add_pe_forwarded_sym (const char *sym_name, const char *forward_dll_name,
		      const char *forward_func_name, int ordinal,
		      const char *dll_name, struct objfile *objfile)
{
  CORE_ADDR vma, baseaddr;
  struct bound_minimal_symbol msymbol;
  enum minimal_symbol_type msymtype;
  char *qualified_name, *bare_name;
  int forward_dll_name_len = strlen (forward_dll_name);
  int forward_func_name_len = strlen (forward_func_name);
  int forward_len = forward_dll_name_len + forward_func_name_len + 2;
  char *forward_qualified_name = (char *) alloca (forward_len);
  short section;

  xsnprintf (forward_qualified_name, forward_len, "%s!%s", forward_dll_name,
	     forward_func_name);


  msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name);

  if (!msymbol.minsym)
    {
      int i;

      for (i = 0; i < forward_dll_name_len; i++)
	forward_qualified_name[i] = tolower (forward_qualified_name[i]);
      msymbol = lookup_minimal_symbol_and_objfile (forward_qualified_name);
    }

  if (!msymbol.minsym)
    {
      if (debug_coff_pe_read)
	fprintf_unfiltered (gdb_stdlog, _("Unable to find function \"%s\" in"
			    " dll \"%s\", forward of \"%s\" in dll \"%s\"\n"),
			    forward_func_name, forward_dll_name, sym_name,
			    dll_name);
      return 0;
    }

  if (debug_coff_pe_read > 1)
    fprintf_unfiltered (gdb_stdlog, _("Adding forwarded exported symbol"
			" \"%s\" in dll \"%s\", pointing to \"%s\"\n"),
			sym_name, dll_name, forward_qualified_name);

  vma = BMSYMBOL_VALUE_ADDRESS (msymbol);
  msymtype = MSYMBOL_TYPE (msymbol.minsym);
  section = MSYMBOL_SECTION (msymbol.minsym);

  /* Generate a (hopefully unique) qualified name using the first part
     of the dll name, e.g. KERNEL32!AddAtomA.  This matches the style
     used by windbg from the "Microsoft Debugging Tools for Windows".  */

  if (sym_name == NULL || *sym_name == '\0')
    bare_name = xstrprintf ("#%d", ordinal);
  else
    bare_name = xstrdup (sym_name);

  qualified_name = xstrprintf ("%s!%s", dll_name, bare_name);

  /* Note that this code makes a minimal symbol whose value may point
     outside of any section in this objfile.  These symbols can't
     really be relocated properly, but nevertheless we make a stab at
     it, choosing an approach consistent with the history of this
     code.  */
  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));

  prim_record_minimal_symbol_and_info (qualified_name, vma - baseaddr,
				       msymtype, section, objfile);

  /* Enter the plain name as well, which might not be unique.  */
  prim_record_minimal_symbol_and_info (bare_name, vma - baseaddr, msymtype,
				       section, objfile);
  xfree (qualified_name);
  xfree (bare_name);

  return 1;
}

/* Truncate a dll_name at the last dot character.  */

static void
read_pe_truncate_name (char *dll_name)
{
  char *last_point = strrchr (dll_name, '.');

  if (last_point != NULL)
    *last_point = '\0';
}

/* Low-level support functions, direct from the ld module pe-dll.c.  */
static unsigned int
pe_get16 (bfd *abfd, int where)
{
  unsigned char b[2];

  bfd_seek (abfd, (file_ptr) where, SEEK_SET);
  bfd_bread (b, (bfd_size_type) 2, abfd);
  return b[0] + (b[1] << 8);
}

static unsigned int
pe_get32 (bfd *abfd, int where)
{
  unsigned char b[4];

  bfd_seek (abfd, (file_ptr) where, SEEK_SET);
  bfd_bread (b, (bfd_size_type) 4, abfd);
  return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
}

static unsigned int
pe_as16 (void *ptr)
{
  unsigned char *b = (unsigned char *) ptr;

  return b[0] + (b[1] << 8);
}

static unsigned int
pe_as32 (void *ptr)
{
  unsigned char *b = (unsigned char *) ptr;

  return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
}

/* Read the (non-debug) export symbol table from a portable
   executable.  Code originally lifted from the ld function
   pe_implied_import_dll in pe-dll.c.  */

void
read_pe_exported_syms (struct objfile *objfile)
{
  bfd *dll = objfile->obfd;
  unsigned long nbnormal, nbforward;
  unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
  unsigned long export_opthdrrva, export_opthdrsize;
  unsigned long export_rva, export_size, nsections, secptr, expptr;
  unsigned long exp_funcbase;
  unsigned char *expdata, *erva;
  unsigned long name_rvas, ordinals, nexp, ordbase;
  char *dll_name = (char *) dll->filename;
  int otherix = PE_SECTION_TABLE_SIZE;
  int is_pe64 = 0;
  int is_pe32 = 0;

  /* Array elements are for text, data and bss in that order
     Initialization with RVA_START > RVA_END guarantees that
     unused sections won't be matched.  */
  struct read_pe_section_data *section_data;
  struct pe_sections_info pe_sections_info;

  struct cleanup *back_to = make_cleanup (null_cleanup, 0);

  char const *target = bfd_get_target (objfile->obfd);

  section_data = XCNEWVEC (struct read_pe_section_data, PE_SECTION_TABLE_SIZE);

  make_cleanup (free_current_contents, &section_data);

  for (i=0; i < PE_SECTION_TABLE_SIZE; i++)
    {
      section_data[i].vma_offset = 0;
      section_data[i].rva_start = 1;
      section_data[i].rva_end = 0;
    };
  section_data[PE_SECTION_INDEX_TEXT].ms_type = mst_text;
  section_data[PE_SECTION_INDEX_TEXT].section_name = ".text";
  section_data[PE_SECTION_INDEX_DATA].ms_type = mst_data;
  section_data[PE_SECTION_INDEX_DATA].section_name = ".data";
  section_data[PE_SECTION_INDEX_BSS].ms_type = mst_bss;
  section_data[PE_SECTION_INDEX_BSS].section_name = ".bss";

  is_pe64 = (strcmp (target, "pe-x86-64") == 0
	     || strcmp (target, "pei-x86-64") == 0);
  is_pe32 = (strcmp (target, "pe-i386") == 0
	     || strcmp (target, "pei-i386") == 0
	     || strcmp (target, "pe-arm-wince-little") == 0
	     || strcmp (target, "pei-arm-wince-little") == 0);
  if (!is_pe32 && !is_pe64)
    {
      /* This is not a recognized PE format file.  Abort now, because
	 the code is untested on anything else.  *FIXME* test on
	 further architectures and loosen or remove this test.  */
      do_cleanups (back_to);
      return;
    }

  /* Get pe_header, optional header and numbers of export entries.  */
  pe_header_offset = pe_get32 (dll, 0x3c);
  opthdr_ofs = pe_header_offset + 4 + 20;
  if (is_pe64)
    num_entries = pe_get32 (dll, opthdr_ofs + 108);
  else
    num_entries = pe_get32 (dll, opthdr_ofs + 92);

  if (num_entries < 1)		/* No exports.  */
    {
      do_cleanups (back_to);
      return;
    }
  if (is_pe64)
    {
      export_opthdrrva = pe_get32 (dll, opthdr_ofs + 112);
      export_opthdrsize = pe_get32 (dll, opthdr_ofs + 116);
    }
  else
    {
      export_opthdrrva = pe_get32 (dll, opthdr_ofs + 96);
      export_opthdrsize = pe_get32 (dll, opthdr_ofs + 100);
    }
  nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
  secptr = (pe_header_offset + 4 + 20 +
	    pe_get16 (dll, pe_header_offset + 4 + 16));
  expptr = 0;
  export_size = 0;

  /* Get the rva and size of the export section.  */
  for (i = 0; i < nsections; i++)
    {
      char sname[8];
      unsigned long secptr1 = secptr + 40 * i;
      unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
      unsigned long vsize = pe_get32 (dll, secptr1 + 16);
      unsigned long fptr = pe_get32 (dll, secptr1 + 20);

      bfd_seek (dll, (file_ptr) secptr1, SEEK_SET);
      bfd_bread (sname, (bfd_size_type) sizeof (sname), dll);

      if ((strcmp (sname, ".edata") == 0)
	  || (vaddr <= export_opthdrrva && export_opthdrrva < vaddr + vsize))
	{
	  if (strcmp (sname, ".edata") != 0)
	    {
	      if (debug_coff_pe_read)
		fprintf_unfiltered (gdb_stdlog, _("Export RVA for dll "
				    "\"%s\" is in section \"%s\"\n"),
				    dll_name, sname);
	    }
	  else if (export_opthdrrva != vaddr && debug_coff_pe_read)
	    fprintf_unfiltered (gdb_stdlog, _("Wrong value of export RVA"
				" for dll \"%s\": 0x%lx instead of 0x%lx\n"),
				dll_name, export_opthdrrva, vaddr);
	  expptr = fptr + (export_opthdrrva - vaddr);
	  break;
	}
    }

  export_rva = export_opthdrrva;
  export_size = export_opthdrsize;

  if (export_size == 0)
    {
      /* Empty export table.  */
      do_cleanups (back_to);
      return;
    }

  /* Scan sections and store the base and size of the relevant
     sections.  */
  for (i = 0; i < nsections; i++)
    {
      unsigned long secptr1 = secptr + 40 * i;
      unsigned long vsize = pe_get32 (dll, secptr1 + 8);
      unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
      unsigned long characteristics = pe_get32 (dll, secptr1 + 36);
      char sec_name[SCNNMLEN + 1];
      int sectix;
      unsigned int bfd_section_index;
      asection *section;

      bfd_seek (dll, (file_ptr) secptr1 + 0, SEEK_SET);
      bfd_bread (sec_name, (bfd_size_type) SCNNMLEN, dll);
      sec_name[SCNNMLEN] = '\0';

      sectix = read_pe_section_index (sec_name);
      section = bfd_get_section_by_name (dll, sec_name);
      if (section)
	bfd_section_index = section->index;
      else
	bfd_section_index = -1;

      if (sectix != PE_SECTION_INDEX_INVALID)
	{
	  section_data[sectix].rva_start = vaddr;
	  section_data[sectix].rva_end = vaddr + vsize;
	  section_data[sectix].index = bfd_section_index;
	}
      else
	{
	  char *name;

	  section_data = XRESIZEVEC (struct read_pe_section_data, section_data,
				     otherix + 1);
	  name = xstrdup (sec_name);
	  section_data[otherix].section_name = name;
	  make_cleanup (xfree, name);
	  section_data[otherix].rva_start = vaddr;
	  section_data[otherix].rva_end = vaddr + vsize;
	  section_data[otherix].vma_offset = 0;
	  section_data[otherix].index = bfd_section_index;
	  if (characteristics & IMAGE_SCN_CNT_CODE)
	    section_data[otherix].ms_type = mst_text;
	  else if (characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
	    section_data[otherix].ms_type = mst_data;
	  else if (characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
	    section_data[otherix].ms_type = mst_bss;
	  else
	    section_data[otherix].ms_type = mst_unknown;
	  otherix++;
	}
    }

  expdata = (unsigned char *) xmalloc (export_size);
  make_cleanup (xfree, expdata);

  bfd_seek (dll, (file_ptr) expptr, SEEK_SET);
  bfd_bread (expdata, (bfd_size_type) export_size, dll);
  erva = expdata - export_rva;

  nexp = pe_as32 (expdata + 24);
  name_rvas = pe_as32 (expdata + 32);
  ordinals = pe_as32 (expdata + 36);
  ordbase = pe_as32 (expdata + 16);
  exp_funcbase = pe_as32 (expdata + 28);

  /* Use internal dll name instead of full pathname.  */
  dll_name = (char *) (pe_as32 (expdata + 12) + erva);

  pe_sections_info.nb_sections = otherix;
  pe_sections_info.sections = section_data;

  bfd_map_over_sections (dll, get_section_vmas, &pe_sections_info);

  /* Truncate name at first dot. Should maybe also convert to all
     lower case for convenience on Windows.  */
  read_pe_truncate_name (dll_name);

  if (debug_coff_pe_read)
    fprintf_unfiltered (gdb_stdlog, _("DLL \"%s\" has %ld export entries,"
			" base=%ld\n"), dll_name, nexp, ordbase);
  nbforward = 0;
  nbnormal = 0;
  /* Iterate through the list of symbols.  */
  for (i = 0; i < nexp; i++)
    {
      /* Pointer to the names vector.  */
      unsigned long name_rva = pe_as32 (erva + name_rvas + i * 4);
      /* Retrieve ordinal value.  */

      unsigned long ordinal = pe_as16 (erva + ordinals + i * 2);


      /* Pointer to the function address vector.  */
      /* This is relatived to ordinal value. */
      unsigned long func_rva = pe_as32 (erva + exp_funcbase +
                                        ordinal * 4);

      /* Find this symbol's section in our own array.  */
      int sectix = 0;
      int section_found = 0;

      /* First handle forward cases.  */
      if (func_rva >= export_rva && func_rva < export_rva + export_size)
	{
	  char *forward_name = (char *) (erva + func_rva);
	  char *funcname = (char *) (erva + name_rva);
	  char *forward_dll_name = forward_name;
	  char *forward_func_name = forward_name;
	  char *sep = strrchr (forward_name, '.');

	  if (sep)
	    {
	      int len = (int) (sep - forward_name);

	      forward_dll_name = (char *) alloca (len + 1);
	      strncpy (forward_dll_name, forward_name, len);
	      forward_dll_name[len] = '\0';
	      forward_func_name = ++sep;
	    }
	  if (add_pe_forwarded_sym (funcname, forward_dll_name,
				    forward_func_name, ordinal,
				    dll_name, objfile) != 0)
	    ++nbforward;
	  continue;
	}

      for (sectix = 0; sectix < otherix; ++sectix)
	{
	  if ((func_rva >= section_data[sectix].rva_start)
	      && (func_rva < section_data[sectix].rva_end))
	    {
	      char *sym_name = (char *) (erva + name_rva);

	      section_found = 1;
	      add_pe_exported_sym (sym_name, func_rva, ordinal,
				   section_data + sectix, dll_name, objfile);
	      ++nbnormal;
	      break;
	    }
	}
      if (!section_found)
	{
	  char *funcname = (char *) (erva + name_rva);

	  if (name_rva == 0)
	    {
	      add_pe_exported_sym (NULL, func_rva, ordinal,
				   section_data, dll_name, objfile);
	      ++nbnormal;
	    }
	  else if (debug_coff_pe_read)
	    fprintf_unfiltered (gdb_stdlog, _("Export name \"%s\" ord. %lu,"
				" RVA 0x%lx in dll \"%s\" not handled\n"),
				funcname, ordinal, func_rva, dll_name);
	}
    }

  if (debug_coff_pe_read)
    fprintf_unfiltered (gdb_stdlog, _("Finished reading \"%s\", exports %ld,"
			" forwards %ld, total %ld/%ld.\n"), dll_name, nbnormal,
			nbforward, nbnormal + nbforward, nexp);
  /* Discard expdata and section_data.  */
  do_cleanups (back_to);
}

/* Extract from ABFD the offset of the .text section.
   This offset is mainly related to the offset within the file.
   The value was previously expected to be 0x1000 for all files,
   but some Windows OS core DLLs seem to use 0x10000 section alignement
   which modified the return value of that function.
   Still return default 0x1000 value if ABFD is NULL or
   if '.text' section is not found, but that should not happen...  */

#define DEFAULT_COFF_PE_TEXT_SECTION_OFFSET 0x1000

CORE_ADDR
pe_text_section_offset (struct bfd *abfd)

{
  unsigned long pe_header_offset, i;
  unsigned long nsections, secptr;
  int is_pe64 = 0;
  int is_pe32 = 0;
  char const *target;

  if (!abfd)
    return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;

  target = bfd_get_target (abfd);

  is_pe64 = (strcmp (target, "pe-x86-64") == 0
	     || strcmp (target, "pei-x86-64") == 0);
  is_pe32 = (strcmp (target, "pe-i386") == 0
	     || strcmp (target, "pei-i386") == 0
	     || strcmp (target, "pe-arm-wince-little") == 0
	     || strcmp (target, "pei-arm-wince-little") == 0);

  if (!is_pe32 && !is_pe64)
    {
      /* This is not a recognized PE format file.  Abort now, because
	 the code is untested on anything else.  *FIXME* test on
	 further architectures and loosen or remove this test.  */
      return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;
    }

  /* Get pe_header, optional header and numbers of sections.  */
  pe_header_offset = pe_get32 (abfd, 0x3c);
  nsections = pe_get16 (abfd, pe_header_offset + 4 + 2);
  secptr = (pe_header_offset + 4 + 20 +
	    pe_get16 (abfd, pe_header_offset + 4 + 16));

  /* Get the rva and size of the export section.  */
  for (i = 0; i < nsections; i++)
    {
      char sname[SCNNMLEN + 1];
      unsigned long secptr1 = secptr + 40 * i;
      unsigned long vaddr = pe_get32 (abfd, secptr1 + 12);

      bfd_seek (abfd, (file_ptr) secptr1, SEEK_SET);
      bfd_bread (sname, (bfd_size_type) SCNNMLEN, abfd);
      sname[SCNNMLEN] = '\0';
      if (strcmp (sname, ".text") == 0)
	return vaddr;
    }

  return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;
}

/* Implements "show debug coff_pe_read" command.  */

static void
show_debug_coff_pe_read (struct ui_file *file, int from_tty,
			 struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Coff PE read debugging is %s.\n"), value);
}

/* Provide a prototype to silence -Wmissing-prototypes.  */

void _initialize_coff_pe_read (void);

/* Adds "Set/show debug coff_pe_read" commands.  */

void
_initialize_coff_pe_read (void)
{
  add_setshow_zuinteger_cmd ("coff-pe-read", class_maintenance,
			     &debug_coff_pe_read,
			     _("Set coff PE read debugging."),
			     _("Show coff PE read debugging."),
			     _("When set, debugging messages for coff reading "
			       "of exported symbols are displayed."),
			     NULL, show_debug_coff_pe_read,
			     &setdebuglist, &showdebuglist);
}
