/* Copyright (c) 2009, 2010, 2011, 2013  Chris Faylor

  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <errno.h>
#include <getopt.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <locale.h>
#include <sys/cygwin.h>
#include <cygwin/version.h>
#include <unistd.h>
#include <libgen.h>

#define _WIN32_WINNT 0x0a00
#include <windows.h>
#include <imagehlp.h>
#include <psapi.h>

struct option longopts[] =
{
  {"help", no_argument, NULL, 'h'},
  {"verbose", no_argument, NULL, 'v'},
  {"version", no_argument, NULL, 'V'},
  {"data-relocs", no_argument, NULL, 'd'},
  {"function-relocs", no_argument, NULL, 'r'},
  {"unused", no_argument, NULL, 'u'},
  {0, no_argument, NULL, 0}
};
const char *opts = "dhruvV";

static int process_file (const wchar_t *);

static int
error (const char *fmt, ...)
{
  va_list ap;
  va_start (ap, fmt);
  fprintf (stderr, "ldd: ");
  vfprintf (stderr, fmt, ap);
  fprintf (stderr, "\nTry `ldd --help' for more information.\n");
  exit (1);
}

static void
usage ()
{
  printf ("Usage: %s [OPTION]... FILE...\n\
\n\
Print shared library dependencies\n\
\n\
  -h, --help              print this help and exit\n\
  -V, --version           print version information and exit\n\
  -r, --function-relocs   process data and function relocations\n\
                          (currently unimplemented)\n\
  -u, --unused            print unused direct dependencies\n\
                          (currently unimplemented)\n\
  -v, --verbose           print all information\n\
                          (currently unimplemented)\n",
	   program_invocation_short_name);
}

static void
print_version ()
{
  printf ("ldd (cygwin) %d.%d.%d\n"
	  "Print shared library dependencies\n"
	  "Copyright (C) 2009 - %s Chris Faylor\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);
}

#define print_errno_error_and_return(__fn) \
  do {\
    fprintf (stderr, "ldd: %s: %s\n", (__fn), strerror (errno));\
    return 1;\
  } while (0)

#define set_errno_and_return(x) \
  do {\
    cygwin_internal (CW_SETERRNO, __FILE__, __LINE__ - 2);\
    return (x);\
  } while (0)


static HANDLE hProcess;

static struct filelist
{
  struct filelist *next;
  char *name;
} *head;

static bool
saw_file (char *name)
{
  filelist *p;

  for (p = head; p; p = p->next)
    if (strcasecmp (name, p->name) == 0)
      return true;

  p = (filelist *) malloc(sizeof (struct filelist));
  p->next = head;
  p->name = strdup (name);
  head = p;
  return false;
}

static wchar_t *
get_module_filename (HANDLE hp, HMODULE hm)
{
  size_t len;
  wchar_t *buf = NULL;
  DWORD res;
  for (len = 1024; (res = GetModuleFileNameExW (hp, hm, (buf = (wchar_t *) realloc (buf, len * sizeof (wchar_t))), len)) == len; len += 1024)
    continue;
  if (!res)
    {
      free (buf);
      buf = NULL;
    }
  return buf;
}

static wchar_t *
load_dll (const wchar_t *fn)
{
  wchar_t *buf = get_module_filename (GetCurrentProcess (), NULL);
  if (!buf)
    {
      printf ("ldd: GetModuleFileName returned an error %u\n",
	      (unsigned int) GetLastError ());
      exit (1);		/* FIXME */
    }

  wchar_t *newbuf = (wchar_t *) malloc ((sizeof (L"\"\" -- ") + wcslen (buf) + wcslen (fn)) * sizeof (wchar_t));
  newbuf[0] = L'"';
  wcscpy (newbuf + 1, buf);
  wchar_t *p = wcsstr (newbuf, L"\\ldd");
  if (!p)
    {
      printf ("ldd: can't parse my own filename \"%ls\"\n", buf);
      exit (1);
    }
  p[3] = L'h';
  wcscat (newbuf, L"\" -- ");
  wcscat (newbuf, fn);
  free (buf);
  return newbuf;
}

static int
start_process (const wchar_t *fn, bool& isdll)
{
  STARTUPINFOW si = {};
  PROCESS_INFORMATION pi;
  si.cb = sizeof (si);
  wchar_t *cmd;
  /* OCaml natdynlink plugins (.cmxs) cannot be handled by ldd because they
     can only be loaded by flexdll_dlopen() */
  if (wcslen (fn) < 4 || (wcscasecmp (wcschr (fn, L'\0') - 4, L".dll") != 0
       && wcscasecmp (wcschr (fn, L'\0') - 4, L".oct") != 0
       && wcscasecmp (wcschr (fn, L'\0') - 3, L".so") != 0))
    {
      cmd = wcsdup (fn);
      isdll = false;
    }
  else
    {
      cmd = load_dll (fn);
      isdll = true;
    }
  if (CreateProcessW (NULL, cmd, NULL, NULL, FALSE, DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi))
    {
      free (cmd);
      hProcess = pi.hProcess;
      DebugSetProcessKillOnExit (true);
      return 0;
    }

  free (cmd);
  set_errno_and_return (1);
}

struct dlls
  {
    LPVOID lpBaseOfDll;
    struct dlls *next;
  };

#define SLOP strlen (" (?)")
char *
tocyg (wchar_t *win_fn)
{
  ssize_t cwlen = cygwin_conv_path (CCP_WIN_W_TO_POSIX, win_fn, NULL, 0);
  char *fn;
  if (cwlen <= 0)
    {
      int len = wcstombs (NULL, win_fn, 0) + 1;
      if ((fn = (char *) malloc (len)))
	wcstombs (fn, win_fn, len);
    }
  else
    {
      char *fn_cyg = (char *) malloc (cwlen + SLOP + 1);
      if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, win_fn, fn_cyg, cwlen) == 0)
	fn = fn_cyg;
      else
	{
	  free (fn_cyg);
	  int len = wcstombs (NULL, win_fn, 0);
	  fn = (char *) malloc (len + SLOP + 1);
	  wcstombs (fn, win_fn, len + SLOP + 1);
	}
    }
  return fn;
}

#define CYGWIN_DLL_LEN (wcslen (L"\\cygwin1.dll"))
static int
print_dlls (dlls *dll, const wchar_t *dllfn, const wchar_t *process_fn)
{
  head = NULL;			/* FIXME: memory leak */
  while ((dll = dll->next))
    {
      char *fn;
      wchar_t *fullpath = get_module_filename (hProcess, (HMODULE) dll->lpBaseOfDll);
      if (!fullpath)
	fn = strdup ("???");
      else if (dllfn && wcscmp (fullpath, dllfn) == 0)
	{
	  free (fullpath);
	  continue;
	}
      else
	{
	  fn = tocyg (fullpath);
	  saw_file (basename (fn));
	  free (fullpath);
	}
      printf ("\t%s => %s (%p)\n", basename (fn), fn, dll->lpBaseOfDll);
      free (fn);
    }
  if (process_fn)
    return process_file (process_fn);
  return 0;
}

static int
report (const char *in_fn, bool multiple)
{
  if (multiple)
    printf ("%s:\n", in_fn);
  char *fn = realpath (in_fn, NULL);
  if (!fn)
    print_errno_error_and_return (in_fn);

  ssize_t len = cygwin_conv_path (CCP_POSIX_TO_WIN_W, fn, NULL, 0);
  if (len <= 0)
    print_errno_error_and_return (fn);

  bool isdll;
  wchar_t fn_win[len + 1];
  if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, fn, fn_win, len))
    print_errno_error_and_return (fn);

  if (!fn || start_process (fn_win, isdll))
    print_errno_error_and_return (in_fn);

  DEBUG_EVENT ev;

  dlls dll_list = {};
  dlls *dll_last = &dll_list;
  const wchar_t *process_fn = NULL;

  int res = 0;

  while (1)
    {
      bool exitnow = false;
      DWORD cont = DBG_CONTINUE;
      if (!WaitForDebugEvent (&ev, INFINITE))
	break;
      switch (ev.dwDebugEventCode)
	{
	case CREATE_PROCESS_DEBUG_EVENT:
	  if (!isdll)
	    {
	      PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER) alloca (4096);
	      PIMAGE_NT_HEADERS nt_header;
	      PVOID entry_point;
	      static const unsigned char int3 = 0xcc;
	      SIZE_T bytes;

	      if (!ReadProcessMemory (hProcess,
				      ev.u.CreateProcessInfo.lpBaseOfImage,
				      dos_header, 4096, &bytes))
		print_errno_error_and_return (in_fn);

	      nt_header = PIMAGE_NT_HEADERS (PBYTE (dos_header)
					     + dos_header->e_lfanew);
	      entry_point = (PVOID)
		  ((caddr_t) ev.u.CreateProcessInfo.lpBaseOfImage
		   + nt_header->OptionalHeader.AddressOfEntryPoint);

	      if (!WriteProcessMemory (hProcess, entry_point, &int3, 1, &bytes))
		print_errno_error_and_return (in_fn);
	    }
	  break;
	case LOAD_DLL_DEBUG_EVENT:
	  dll_last->next = (dlls *) malloc (sizeof (dlls));
	  dll_last->next->lpBaseOfDll = ev.u.LoadDll.lpBaseOfDll;
	  dll_last->next->next = NULL;
	  dll_last = dll_last->next;
	  break;
	case EXCEPTION_DEBUG_EVENT:
	  switch (ev.u.Exception.ExceptionRecord.ExceptionCode)
	    {
	    case STATUS_ENTRYPOINT_NOT_FOUND:
	      /* A STATUS_ENTRYPOINT_NOT_FOUND might be encountered right after
		 loading all DLLs.  We have to handle it here, otherwise ldd
		 runs into an endless loop. */
	      goto print_and_exit;
	    case STATUS_DLL_NOT_FOUND:
	      process_fn = fn_win;
	      break;
	    case STATUS_BREAKPOINT:
	      if (!isdll)
		TerminateProcess (hProcess, 0);
	      break;
	    }
	  if (ev.u.Exception.ExceptionRecord.ExceptionFlags &
	      EXCEPTION_NONCONTINUABLE) {
	    res = 1;
	    goto print_and_exit;
	  }
	  break;
	case EXIT_PROCESS_DEBUG_EVENT:
print_and_exit:
	  print_dlls (&dll_list, isdll ? fn_win : NULL, process_fn);
	  exitnow = true;
	  break;
	default:
	  break;
	}
      if (!ContinueDebugEvent (ev.dwProcessId, ev.dwThreadId, cont))
	{
	  cygwin_internal (CW_SETERRNO, __FILE__, __LINE__ - 2);
	  print_errno_error_and_return (in_fn);
	}
      if (exitnow)
	break;
    }

  return res;
}

int
main (int argc, char **argv)
{
  int optch;

  /* Use locale from environment.  If not set or set to "C", use UTF-8. */
  setlocale (LC_CTYPE, "");
  if (!strcmp (setlocale (LC_CTYPE, NULL), "C"))
    setlocale (LC_CTYPE, "en_US.UTF-8");
  while ((optch = getopt_long (argc, argv, opts, longopts, NULL)) != -1)
    switch (optch)
      {
      case 'd':
      case 'r':
      case 'u':
	error ("option not implemented `-%c'", optch);
	exit (1);
      case 'h':
	usage ();
	exit (0);
      case 'V':
	print_version ();
	return 0;
      default:
	fprintf (stderr, "Try `%s --help' for more information.\n",
		 program_invocation_short_name);
	return 1;
      }
  argv += optind;
  if (!*argv)
    error ("missing file arguments");

  int ret = 0;
  bool multiple = !!argv[1];
  char *fn;
  while ((fn = *argv++))
    if (report (fn, multiple))
      ret = 1;
  exit (ret);
}

static bool printing = false;


/* dump of import directory
   section begins at pointer 'section base'
   section RVA is 'section_rva'
   import directory begins at pointer 'imp' */
static int
dump_import_directory (const void *const section_base,
		       const DWORD section_rva,
		       const IMAGE_IMPORT_DESCRIPTOR *imp)
{
  /* get memory address given the RVA */
  #define adr(rva) ((const void*) ((char*) section_base+((DWORD) (rva))-section_rva))

  /* continue until address inaccessible or there's no DLL name */
  for (; !IsBadReadPtr (imp, sizeof (*imp)) && imp->Name; imp++)
    {
      wchar_t full_path[PATH_MAX];
      wchar_t *dummy;
      char *fn = (char *) adr (imp->Name);

      if (saw_file (fn))
	continue;

      int len = mbstowcs (NULL, fn, 0);
      if (len <= 0)
	continue;
      wchar_t fnw[len + 1];
      mbstowcs (fnw, fn, len + 1);
      /* output DLL's name */
      char *print_fn;
      if (!SearchPathW (NULL, fnw, NULL, PATH_MAX, full_path, &dummy))
	{
	  print_fn = strdup ("not found");
	  printing = true;
	}
      else if (!printing)
	continue;
      else
	{
	  print_fn = tocyg (full_path);
	  strcat (print_fn, " (?)");
	}

      printf ("\t%s => %s\n", (char *) fn, print_fn);
      free (print_fn);
    }
  #undef adr

  return 0;
}

/* load a file in RAM (memory-mapped)
   return pointer to loaded file
   0 if no success  */
static void *
map_file (const wchar_t *filename)
{
  HANDLE hFile, hMapping;
  void *basepointer;
  if ((hFile = CreateFileW (filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
			   0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)) == INVALID_HANDLE_VALUE)
    {
      fprintf (stderr, "couldn't open %ls\n", filename);
      return 0;
    }
  if (!(hMapping = CreateFileMapping (hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0)))
    {
      fprintf (stderr, "CreateFileMapping failed with windows error %u\n",
	       (unsigned int) GetLastError ());
      CloseHandle (hFile);
      return 0;
    }
  if (!(basepointer = MapViewOfFile (hMapping, FILE_MAP_READ, 0, 0, 0)))
    {
      fprintf (stderr, "MapViewOfFile failed with windows error %u\n",
	       (unsigned int) GetLastError ());
      CloseHandle (hMapping);
      CloseHandle (hFile);
      return 0;
    }

  CloseHandle (hMapping);
  CloseHandle (hFile);

  return basepointer;
}


/* this will return a pointer immediatly behind the DOS-header
   0 if error */
static void *
skip_dos_stub (const IMAGE_DOS_HEADER *dos_ptr)
{
  /* look there's enough space for a DOS-header */
  if (IsBadReadPtr (dos_ptr, sizeof (*dos_ptr)))
      {
	fprintf (stderr, "not enough space for DOS-header\n");
	return 0;
      }

   /* validate MZ */
   if (dos_ptr->e_magic != IMAGE_DOS_SIGNATURE)
      {
	fprintf (stderr, "not a DOS-stub\n");
	return 0;
      }

  /* ok, then, go get it */
  return (char*) dos_ptr + dos_ptr->e_lfanew;
}


/* find the directory's section index given the RVA
   Returns -1 if impossible */
static int
get_directory_index (const unsigned dir_rva,
		     const unsigned dir_length,
		     const int number_of_sections,
		     const IMAGE_SECTION_HEADER *sections)
{
  int sect;
  for (sect = 0; sect < number_of_sections; sect++)
  {
    /* compare directory RVA to section RVA */
    if (sections[sect].VirtualAddress <= dir_rva
       && dir_rva < sections[sect].VirtualAddress+sections[sect].SizeOfRawData)
      return sect;
  }

  return -1;
}

/* dump imports of a single file
   Returns 0 if successful, !=0 else */
static int
process_file (const wchar_t *filename)
{
  void *basepointer;    /* Points to loaded PE file
			 * This is memory mapped stuff
			 */
  int number_of_sections;
  DWORD import_rva;           /* RVA of import directory */
  DWORD import_length;        /* length of import directory */
  int import_index;           /* index of section with import directory */

  /* ensure byte-alignment for struct tag_header */
  #include <pshpack1.h>

  const struct tag_header
    {
      DWORD signature;
      IMAGE_FILE_HEADER file_head;
      IMAGE_OPTIONAL_HEADER opt_head;
      IMAGE_SECTION_HEADER section_header[1];  /* an array of unknown length */
    } *header;

  /* revert to regular alignment */
  #include <poppack.h>

  printing = false;

  /* first, load file */
  basepointer = map_file (filename);
  if (!basepointer)
      {
	puts ("cannot load file");
	return 1;
      }

  /* get header pointer; validate a little bit */
  header = (tag_header *) skip_dos_stub ((IMAGE_DOS_HEADER *) basepointer);
  if (!header)
      {
	puts ("cannot skip DOS stub");
	UnmapViewOfFile (basepointer);
	return 2;
      }

  /* look there's enough space for PE headers */
  if (IsBadReadPtr (header, sizeof (*header)))
      {
	puts ("not enough space for PE headers");
	UnmapViewOfFile (basepointer);
	return 3;
      }

  /* validate PE signature */
  if (header->signature != IMAGE_NT_SIGNATURE)
      {
	puts ("not a PE file");
	UnmapViewOfFile (basepointer);
	return 4;
      }

  /* get number of sections */
  number_of_sections = header->file_head.NumberOfSections;

  /* check there are sections... */
  if (number_of_sections < 1)
      {
	UnmapViewOfFile (basepointer);
	return 5;
      }

  /* validate there's enough space for section headers */
  if (IsBadReadPtr (header->section_header, number_of_sections*sizeof (IMAGE_SECTION_HEADER)))
      {
	puts ("not enough space for section headers");
	UnmapViewOfFile (basepointer);
	return 6;
      }

  /* get RVA and length of import directory */
  import_rva = header->opt_head.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  import_length = header->opt_head.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;

  /* check there's stuff to care about */
  if (!import_rva || !import_length)
      {
	UnmapViewOfFile (basepointer);
	return 0;       /* success! */
    }

  /* get import directory pointer */
  import_index = get_directory_index (import_rva,import_length,number_of_sections,header->section_header);

  /* check directory was found */
  if (import_index < 0)
      {
	puts ("couldn't find import directory in sections");
	UnmapViewOfFile (basepointer);
	return 7;
      }

  /* The pointer to the start of the import directory's section */
  const void *section_address = (char*) basepointer + header->section_header[import_index].PointerToRawData;
  if (dump_import_directory (section_address,
			   header->section_header[import_index].VirtualAddress,
				    /* the last parameter is the pointer to the import directory:
				       section address + (import RVA - section RVA)
				       The difference is the offset of the import directory in the section */
			   (const IMAGE_IMPORT_DESCRIPTOR *) ((char *) section_address+import_rva-header->section_header[import_index].VirtualAddress)))
    {
      UnmapViewOfFile (basepointer);
      return 8;
    }

  UnmapViewOfFile (basepointer);
  return 0;
}
