/* dumper.cc

   Written by Egor Duda <deo@logos-m.ru>

   This file is part of Cygwin.

   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 (file COPYING.dumper) for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <ansidecl.h>
#define PACKAGE
#include <bfd.h>
#include <elf/common.h>
#include <elf/external.h>
#include <sys/procfs.h>
#include <sys/cygwin.h>
#include <cygwin/version.h>
#include <getopt.h>
#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <windows.h>

#include "dumper.h"

#define NOTE_NAME_SIZE 16

typedef struct _note_header
  {
    Elf_External_Note elf_note_header;
    char name[NOTE_NAME_SIZE - 1];	/* external note contains first byte of data */
  }
#ifdef __GNUC__
__attribute__ ((packed))
#endif
  note_header;

BOOL verbose = FALSE;

int deb_printf (const char *format,...)
{
  if (!verbose)
    return 0;
  va_list va;
  va_start (va, format);
  int ret_val = vprintf (format, va);
  va_end (va);
  return ret_val;
}

dumper::dumper (DWORD pid, DWORD tid, const char *file_name)
{
  this->file_name = strdup (file_name);

  this->pid = pid;
  this->tid = tid;
  core_bfd = NULL;
  excl_list = new exclusion (20);

  list = last = NULL;

  status_section = NULL;

  memory_num = module_num = thread_num = 0;

  hProcess = OpenProcess (PROCESS_ALL_ACCESS,
			  FALSE,	/* no inheritance */
			  pid);
  if (!hProcess)
    {
      fprintf (stderr, "Failed to open process #%u, error %ld\n",
	       (unsigned int) pid, (long) GetLastError ());
      return;
    }

  init_core_dump ();

  if (!sane ())
    dumper_abort ();
}

dumper::~dumper ()
{
  close ();
  free (file_name);
}

void
dumper::dumper_abort ()
{
  close ();
  unlink (file_name);
}

void
dumper::close ()
{
  if (core_bfd)
    bfd_close (core_bfd);
  if (excl_list)
    delete excl_list;
  if (hProcess)
    CloseHandle (hProcess);
  core_bfd = NULL;
  hProcess = NULL;
  excl_list = NULL;
}

int
dumper::sane ()
{
  if (hProcess == NULL || core_bfd == NULL || excl_list == NULL)
    return 0;
  return 1;
}

void
print_section_name (bfd* abfd, asection* sect, PTR obj)
{
  deb_printf (" %s", bfd_get_section_name (abfd, sect));
}

void
dumper::print_core_section_list ()
{
  deb_printf ("current sections:");
  bfd_map_over_sections (core_bfd, &print_section_name, NULL);
  deb_printf ("\n");
}

process_entity *
dumper::add_process_entity_to_list (process_entity_type type)
{
  if (!sane ())
    return NULL;

  process_entity *new_entity = (process_entity *) malloc (sizeof (process_entity));
  if (new_entity == NULL)
    return NULL;
  new_entity->next = NULL;
  new_entity->section = NULL;
  if (last == NULL)
    list = new_entity;
  else
    last->next = new_entity;
  last = new_entity;
  return new_entity;
}

int
dumper::add_thread (DWORD tid, HANDLE hThread)
{
  if (!sane ())
    return 0;

  CONTEXT *pcontext;

  process_entity *new_entity = add_process_entity_to_list (pr_ent_thread);
  if (new_entity == NULL)
    return 0;
  new_entity->type = pr_ent_thread;
  thread_num++;

  new_entity->u.thread.tid = tid;
  new_entity->u.thread.hThread = hThread;

  pcontext = &(new_entity->u.thread.context);
  pcontext->ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
  if (!GetThreadContext (hThread, pcontext))
    {
      deb_printf ("Failed to read thread context (tid=%x), error %ld\n", tid, GetLastError ());
      return 0;
    }

  deb_printf ("added thread %u\n", tid);
  return 1;
}

int
dumper::add_mem_region (LPBYTE base, SIZE_T size)
{
  if (!sane ())
    return 0;

  if (base == NULL || size == 0)
    return 1;			// just ignore empty regions

  process_entity *new_entity = add_process_entity_to_list (pr_ent_memory);
  if (new_entity == NULL)
    return 0;
  new_entity->type = pr_ent_memory;
  memory_num++;

  new_entity->u.memory.base = base;
  new_entity->u.memory.size = size;

  deb_printf ("added memory region %p-%p\n", base, base + size);
  return 1;
}

/* split_add_mem_region scans list of regions to be excluded from dumping process
   (excl_list) and removes all "excluded" parts from given region. */
int
dumper::split_add_mem_region (LPBYTE base, SIZE_T size)
{
  if (!sane ())
    return 0;

  if (base == NULL || size == 0)
    return 1;			// just ignore empty regions

  LPBYTE last_base = base;

  for (process_mem_region * p = excl_list->region;
       p < excl_list->region + excl_list->last;
       p++)
    {
      if (p->base >= base + size || p->base + p->size <= base)
	continue;

      if (p->base <= base)
	{
	  last_base = p->base + p->size;
	  continue;
	}

      add_mem_region (last_base, p->base - last_base);
      last_base = p->base + p->size;
    }

  if (last_base < base + size)
    add_mem_region (last_base, base + size - last_base);

  return 1;
}

int
dumper::add_module (LPVOID base_address)
{
  if (!sane ())
    return 0;

  char *module_name = psapi_get_module_name (hProcess, base_address);
  if (module_name == NULL)
    return 1;

  process_entity *new_entity = add_process_entity_to_list (pr_ent_module);
  if (new_entity == NULL)
    return 0;
  new_entity->type = pr_ent_module;
  module_num++;

  new_entity->u.module.base_address = base_address;
  new_entity->u.module.name = module_name;

  parse_pe (module_name, excl_list);

  deb_printf ("added module %p %s\n", base_address, module_name);
  return 1;
}

#define PAGE_BUFFER_SIZE 4096

int
dumper::collect_memory_sections ()
{
  if (!sane ())
    return 0;

  LPBYTE current_page_address;
  LPBYTE last_base = (LPBYTE) 0xFFFFFFFF;
  SIZE_T last_size = (SIZE_T) 0;
  SIZE_T done;

  char mem_buf[PAGE_BUFFER_SIZE];

  MEMORY_BASIC_INFORMATION mbi;

  if (hProcess == NULL)
    return 0;

  for (current_page_address = 0; current_page_address < (LPBYTE) 0xFFFF0000;)
    {
      if (!VirtualQueryEx (hProcess, current_page_address, &mbi, sizeof (mbi)))
	break;

      int skip_region_p = 0;

      if (mbi.Protect & (PAGE_NOACCESS | PAGE_GUARD) ||
	  mbi.State != MEM_COMMIT)
	skip_region_p = 1;

      if (!skip_region_p)
	{
	  /* just to make sure that later we'll be able to read it.
	     According to MS docs either region is all-readable or
	     all-nonreadable */
	  if (!ReadProcessMemory (hProcess, current_page_address, mem_buf, sizeof (mem_buf), &done))
	    {
	      DWORD err = GetLastError ();
	      const char *pt[10];
	      pt[0] = (mbi.Protect & PAGE_READONLY) ? "RO " : "";
	      pt[1] = (mbi.Protect & PAGE_READWRITE) ? "RW " : "";
	      pt[2] = (mbi.Protect & PAGE_WRITECOPY) ? "WC " : "";
	      pt[3] = (mbi.Protect & PAGE_EXECUTE) ? "EX " : "";
	      pt[4] = (mbi.Protect & PAGE_EXECUTE_READ) ? "EXRO " : "";
	      pt[5] = (mbi.Protect & PAGE_EXECUTE_READWRITE) ? "EXRW " : "";
	      pt[6] = (mbi.Protect & PAGE_EXECUTE_WRITECOPY) ? "EXWC " : "";
	      pt[7] = (mbi.Protect & PAGE_GUARD) ? "GRD " : "";
	      pt[8] = (mbi.Protect & PAGE_NOACCESS) ? "NA " : "";
	      pt[9] = (mbi.Protect & PAGE_NOCACHE) ? "NC " : "";
	      char buf[10 * 6];
	      buf[0] = '\0';
	      for (int i = 0; i < 10; i++)
		strcat (buf, pt[i]);

	      deb_printf ("warning: failed to read memory at %p-%p (protect = %s), error %ld.\n",
			  current_page_address,
			  current_page_address + mbi.RegionSize,
			  buf, err);
	      skip_region_p = 1;
	    }
	}

      if (!skip_region_p)
	{
	  if (last_base + last_size == current_page_address)
	    last_size += mbi.RegionSize;
	  else
	    {
	      split_add_mem_region (last_base, last_size);
	      last_base = (LPBYTE) mbi.BaseAddress;
	      last_size = mbi.RegionSize;
	    }
	}
      else
	{
	  split_add_mem_region (last_base, last_size);
	  last_base = NULL;
	  last_size = 0;
	}

      current_page_address += mbi.RegionSize;
    }

  /* dump last sections, if any */
  split_add_mem_region (last_base, last_size);
  return 1;
};

int
dumper::dump_memory_region (asection * to, process_mem_region * memory)
{
  if (!sane ())
    return 0;

  SIZE_T size = memory->size;
  SIZE_T todo;
  SIZE_T done;
  LPBYTE pos = memory->base;
  DWORD sect_pos = 0;

  if (to == NULL || memory == NULL)
    return 0;

  char mem_buf[PAGE_BUFFER_SIZE];

  while (size > 0)
    {
      todo = MIN (size, PAGE_BUFFER_SIZE);
      if (!ReadProcessMemory (hProcess, pos, mem_buf, todo, &done))
	{
	  deb_printf ("Failed to read process memory at %x(%x), error %ld\n", pos, todo, GetLastError ());
	  return 0;
	}
      size -= done;
      pos += done;
      if (!bfd_set_section_contents (core_bfd, to, mem_buf, sect_pos, done))
	{
	  bfd_perror ("writing memory region to bfd");
	  dumper_abort ();
	  return 0;
	};
      sect_pos += done;
    }
  return 1;
}

int
dumper::dump_thread (asection * to, process_thread * thread)
{
  if (!sane ())
    return 0;

  if (to == NULL || thread == NULL)
    return 0;

  win32_pstatus thread_pstatus;

  note_header header;
  bfd_putl32 (NOTE_NAME_SIZE, header.elf_note_header.namesz);
  bfd_putl32 (sizeof (thread_pstatus), header.elf_note_header.descsz);
  bfd_putl32 (NT_WIN32PSTATUS, header.elf_note_header.type);
  strncpy ((char *) &header.elf_note_header.name, "win32thread", NOTE_NAME_SIZE);

  thread_pstatus.data_type = NOTE_INFO_THREAD;
  thread_pstatus.data.thread_info.tid = thread->tid;

  if (tid == 0)
    {
      /* this is a special case. we don't know, which thread
	 was active when exception occured, so let's blame
	 the first one */
      thread_pstatus.data.thread_info.is_active_thread = TRUE;
      tid = (DWORD) - 1;
    }
  else if (tid > 0 && thread->tid == tid)
    thread_pstatus.data.thread_info.is_active_thread = TRUE;
  else
    thread_pstatus.data.thread_info.is_active_thread = FALSE;

  memcpy (&(thread_pstatus.data.thread_info.thread_context),
	  &(thread->context),
	  sizeof (thread->context));

  if (!bfd_set_section_contents (core_bfd, to, &header,
				 0,
				 sizeof (header)) ||
      !bfd_set_section_contents (core_bfd, to, &thread_pstatus,
				 sizeof (header),
				 sizeof (thread_pstatus)))
    {
      bfd_perror ("writing thread info to bfd");
      dumper_abort ();
      return 0;
    };
  return 1;
}

int
dumper::dump_module (asection * to, process_module * module)
{
  if (!sane ())
    return 0;

  if (to == NULL || module == NULL)
    return 0;

  struct win32_pstatus *module_pstatus_ptr;

  int note_length = sizeof (struct win32_pstatus) + strlen (module->name);

  char *buf = (char *) malloc (note_length);

  if (!buf)
    {
      fprintf (stderr, "Error alloating memory. Dumping aborted.\n");
      goto out;
    };

  module_pstatus_ptr = (struct win32_pstatus *) buf;

  note_header header;
  bfd_putl32 (NOTE_NAME_SIZE, header.elf_note_header.namesz);
  bfd_putl32 (note_length, header.elf_note_header.descsz);
  bfd_putl32 (NT_WIN32PSTATUS, header.elf_note_header.type);
  strncpy ((char *) &header.elf_note_header.name, "win32module", NOTE_NAME_SIZE);

  module_pstatus_ptr->data_type = NOTE_INFO_MODULE;
  module_pstatus_ptr->data.module_info.base_address = module->base_address;
  module_pstatus_ptr->data.module_info.module_name_size = strlen (module->name) + 1;
  strcpy (module_pstatus_ptr->data.module_info.module_name, module->name);

  if (!bfd_set_section_contents (core_bfd, to, &header,
				 0,
				 sizeof (header)) ||
      !bfd_set_section_contents (core_bfd, to, module_pstatus_ptr,
				 sizeof (header),
				 note_length))
    {
      bfd_perror ("writing module info to bfd");
      goto out;
    };
  return 1;

out:
  if (buf)
    free (buf);
  dumper_abort ();
  return 0;

}

int
dumper::collect_process_information ()
{
  int exception_level = 0;

  if (!sane ())
    return 0;

  if (!DebugActiveProcess (pid))
    {
      fprintf (stderr, "Cannot attach to process #%u, error %ld",
	       (unsigned int) pid, (long) GetLastError ());
      return 0;
    }

  char event_name[sizeof ("cygwin_error_start_event") + 20];
  sprintf (event_name, "cygwin_error_start_event%16x", (unsigned int) pid);
  HANDLE sync_with_debugee = OpenEvent (EVENT_MODIFY_STATE, FALSE, event_name);

  DEBUG_EVENT current_event;

  while (1)
    {
      if (!WaitForDebugEvent (&current_event, 20000))
	return 0;

      deb_printf ("got debug event %d\n", current_event.dwDebugEventCode);

      switch (current_event.dwDebugEventCode)
	{
	case CREATE_THREAD_DEBUG_EVENT:

	  if (!add_thread (current_event.dwThreadId,
			   current_event.u.CreateThread.hThread))
	    goto failed;

	  break;

	case CREATE_PROCESS_DEBUG_EVENT:

	  if (!add_module (current_event.u.CreateProcessInfo.lpBaseOfImage) ||
	      !add_thread (current_event.dwThreadId,
			   current_event.u.CreateProcessInfo.hThread))
	    goto failed;

	  break;

	case EXIT_PROCESS_DEBUG_EVENT:

	  deb_printf ("debugee quits");
	  ContinueDebugEvent (current_event.dwProcessId,
			      current_event.dwThreadId,
			      DBG_CONTINUE);

	  return 1;

	  break;

	case LOAD_DLL_DEBUG_EVENT:

	  if (!add_module (current_event.u.LoadDll.lpBaseOfDll))
	    goto failed;

	  break;

	case EXCEPTION_DEBUG_EVENT:

	  exception_level++;
	  if (exception_level == 2)
	    break;
	  else if (exception_level > 2)
	    return 0;

	  collect_memory_sections ();

	  /* got all info. time to dump */

	  if (!prepare_core_dump ())
	    {
	      fprintf (stderr, "Failed to prepare core dump\n");
	      goto failed;
	    };

	  if (!write_core_dump ())
	    {
	      fprintf (stderr, "Failed to write core dump\n");
	      goto failed;
	    };

	  /* signal a debugee that we've finished */
	  if (sync_with_debugee)
	    SetEvent (sync_with_debugee);

	  break;

	default:

	  break;

	}

      ContinueDebugEvent (current_event.dwProcessId,
			  current_event.dwThreadId,
			  DBG_CONTINUE);
    }
failed:
  /* set debugee free */
  if (sync_with_debugee)
    SetEvent (sync_with_debugee);

  return 0;
}

int
dumper::init_core_dump ()
{
  bfd_init ();

  core_bfd = bfd_openw (file_name, "elf32-i386");
  if (core_bfd == NULL)
    {
      bfd_perror ("opening bfd");
      goto failed;
    }

  if (!bfd_set_format (core_bfd, bfd_core))
    {
      bfd_perror ("setting bfd format");
      goto failed;
    }

  if (!bfd_set_arch_mach (core_bfd, bfd_arch_i386, 0))
    {
      bfd_perror ("setting bfd architecture");
      goto failed;
    }

  return 1;

failed:
  dumper_abort ();
  return 0;

}

int
dumper::prepare_core_dump ()
{
  if (!sane ())
    return 0;

  int sect_no = 0;
  char sect_name[50];

  flagword sect_flags;
  SIZE_T sect_size;
  bfd_vma sect_vma;

  asection *new_section;

  for (process_entity * p = list; p != NULL; p = p->next)
    {
      sect_no++;

      unsigned long phdr_type = PT_LOAD;

      switch (p->type)
	{
	case pr_ent_memory:
	  sprintf (sect_name, ".mem/%u", sect_no);
	  sect_flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD;
	  sect_size = p->u.memory.size;
	  sect_vma = (bfd_vma) (p->u.memory.base);
	  phdr_type = PT_LOAD;
	  break;

	case pr_ent_thread:
	  sprintf (sect_name, ".note/%u", sect_no);
	  sect_flags = SEC_HAS_CONTENTS | SEC_LOAD;
	  sect_size = sizeof (note_header) + sizeof (struct win32_pstatus);
	  sect_vma = 0;
	  phdr_type = PT_NOTE;
	  break;

	case pr_ent_module:
	  sprintf (sect_name, ".note/%u", sect_no);
	  sect_flags = SEC_HAS_CONTENTS | SEC_LOAD;
	  sect_size = sizeof (note_header) + sizeof (struct win32_pstatus) +
	    (bfd_size_type) (strlen (p->u.module.name));
	  sect_vma = 0;
	  phdr_type = PT_NOTE;
	  break;

	default:
	  continue;
	}

      if (p->type == pr_ent_module && status_section != NULL)
	{
	  if (!bfd_set_section_size (core_bfd,
				     status_section,
				     (bfd_get_section_size (status_section)
				      + sect_size)))
	    {
	      bfd_perror ("resizing status section");
	      goto failed;
	    };
	  continue;
	}

      deb_printf ("creating section (type%u) %s(%u), flags=%08x\n",
		  p->type, sect_name, sect_size, sect_flags);

      bfd_set_error (bfd_error_no_error);
      char *buf = strdup (sect_name);
      new_section = bfd_make_section (core_bfd, buf);
      if (new_section == NULL)
	{
	  if (bfd_get_error () == bfd_error_no_error)
	    fprintf (stderr, "error creating new section (%s), section already exists.\n", buf);
	  else
	    bfd_perror ("creating section");
	  goto failed;
	}

      if (!bfd_set_section_flags (core_bfd, new_section, sect_flags) ||
	  !bfd_set_section_size (core_bfd, new_section, sect_size))
	{
	  bfd_perror ("setting section attributes");
	  goto failed;
	};

      new_section->vma = sect_vma;
      new_section->lma = 0;
      new_section->output_section = new_section;
      new_section->output_offset = 0;
      p->section = new_section;
      int section_count = 1;

      bfd_boolean filehdr = 0;
      bfd_boolean phdrs = 0;

      bfd_vma at = 0;
      bfd_boolean valid_at = 0;

      flagword flags = 0;
      bfd_boolean valid_flags = 1;

      if (p->type == pr_ent_memory)
	{
	  MEMORY_BASIC_INFORMATION mbi;
	  if (!VirtualQueryEx (hProcess, (LPVOID)sect_vma, &mbi, sizeof (mbi)))
	    {
	      bfd_perror ("getting mem region flags");
	      goto failed;
	    }

	  static const struct
	  {
	    DWORD protect;
	    flagword flags;
	  } mappings[] =
	    {
	      { PAGE_READONLY, PF_R },
	      { PAGE_READWRITE, PF_R | PF_W },
	      { PAGE_WRITECOPY, PF_W },
	      { PAGE_EXECUTE, PF_X },
	      { PAGE_EXECUTE_READ, PF_X | PF_R },
	      { PAGE_EXECUTE_READWRITE, PF_X | PF_R | PF_W },
	      { PAGE_EXECUTE_WRITECOPY, PF_X | PF_W }
	    };

	  for (size_t i = 0;
	       i < sizeof (mappings) / sizeof (mappings[0]);
	       i++)
	    if ((mbi.Protect & mappings[i].protect) != 0)
	      flags |= mappings[i].flags;
	}

      if (!bfd_record_phdr (core_bfd, phdr_type,
			    valid_flags, flags,
			    valid_at, at,
			    filehdr, phdrs,
			    section_count, &new_section))
	{
	  bfd_perror ("recording program headers");
	  goto failed;
	}
    }
  return 1;

failed:
  dumper_abort ();
  return 0;
}

int
dumper::write_core_dump ()
{
  if (!sane ())
    return 0;

  for (process_entity * p = list; p != NULL; p = p->next)
    {
      if (p->section == NULL)
	continue;

      deb_printf ("writing section type=%u base=%p size=%p flags=%08x\n",
		  p->type,
		  p->section->vma,
		  bfd_get_section_size (p->section),
		  p->section->flags);

      switch (p->type)
	{
	case pr_ent_memory:
	  dump_memory_region (p->section, &(p->u.memory));
	  break;

	case pr_ent_thread:
	  dump_thread (p->section, &(p->u.thread));
	  break;

	case pr_ent_module:
	  dump_module (p->section, &(p->u.module));
	  break;

	default:
	  continue;

	}
    }
  return 1;
}

static void
usage (FILE *stream, int status)
{
  fprintf (stream, "\
Usage: %s [OPTION] FILENAME WIN32PID\n\
\n\
Dump core from WIN32PID to FILENAME.core\n\
\n\
 -d, --verbose  be verbose while dumping\n\
 -h, --help     output help information and exit\n\
 -q, --quiet    be quiet while dumping (default)\n\
 -V, --version  output version information and exit\n\
\n", program_invocation_short_name);
  exit (status);
}

struct option longopts[] = {
  {"verbose", no_argument, NULL, 'd'},
  {"help", no_argument, NULL, 'h'},
  {"quiet", no_argument, NULL, 'q'},
  {"version", no_argument, 0, 'V'},
  {0, no_argument, NULL, 0}
};
const char *opts = "dhqV";

static void
print_version ()
{
  printf ("dumper (cygwin) %d.%d.%d\n"
	  "Core Dumper for Cygwin\n"
	  "Copyright (C) 1999 - %s Cygwin Authors\n"
	  "This is free software; see the source for copying conditions.  There is NO\n"
	  "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
	  CYGWIN_VERSION_DLL_MAJOR / 1000,
	  CYGWIN_VERSION_DLL_MAJOR % 1000,
	  CYGWIN_VERSION_DLL_MINOR,
	  strrchr (__DATE__, ' ') + 1);
}

int
main (int argc, char **argv)
{
  int opt;
  const char *p = "";
  DWORD pid;

  while ((opt = getopt_long (argc, argv, opts, longopts, NULL) ) != EOF)
    switch (opt)
      {
      case 'd':
	verbose = TRUE;
	break;
      case 'q':
	verbose = FALSE;
	break;
      case 'h':
	usage (stdout, 0);
      case 'V':
	print_version ();
	exit (0);
      default:
	fprintf (stderr, "Try `%s --help' for more information.\n",
		 program_invocation_short_name);
	exit (1);
      }

  if (argv && *(argv + optind) && *(argv + optind +1))
    {
      ssize_t len = cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_RELATIVE,
				      *(argv + optind), NULL, 0);
      char *win32_name = (char *) alloca (len);
      cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_RELATIVE,  *(argv + optind),
			win32_name, len);
      if ((p = strrchr (win32_name, '\\')))
	p++;
      else
	p = win32_name;
      pid = strtoul (*(argv + optind + 1), NULL, 10);
    }
  else
    {
      usage (stderr, 1);
      return -1;
    }

  char *core_file = (char *) malloc (strlen (p) + sizeof (".core"));
  if (!core_file)
    {
      fprintf (stderr, "error allocating memory\n");
      return -1;
    }
  sprintf (core_file, "%s.core", p);

  DWORD tid = 0;

  if (verbose)
    printf ("dumping process #%u to %s\n", (unsigned int) pid, core_file);

  dumper d (pid, tid, core_file);
  if (!d.sane ())
    return -1;
  d.collect_process_information ();
  free (core_file);

  return 0;
};
