/* The library used by gdb.
   Copyright (C) 2014-2018 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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, or (at your option) any later
version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include <cc1plugin-config.h>
#include <vector>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sstream>
#include "marshall-c.hh"
#include "rpc.hh"
#include "connection.hh"
#include "names.hh"
#include "callbacks.hh"
#include "libiberty.h"
#include "xregex.h"
#include "findcomp.hh"
#include "compiler-name.hh"
#include "intl.h"

struct libcc1;

class libcc1_connection;

// The C compiler context that we hand back to our caller.
struct libcc1 : public gcc_c_context
{
  libcc1 (const gcc_base_vtable *, const gcc_c_fe_vtable *);
  ~libcc1 ();

  // A convenience function to print something.
  void print (const char *str)
  {
    this->print_function (this->print_datum, str);
  }

  libcc1_connection *connection;

  gcc_c_oracle_function *binding_oracle;
  gcc_c_symbol_address_function *address_oracle;
  void *oracle_datum;

  void (*print_function) (void *datum, const char *message);
  void *print_datum;

  std::vector<std::string> args;
  std::string source_file;

  /* Non-zero as an equivalent to gcc driver option "-v".  */
  bool verbose;

  /* Compiler to set by set_triplet_regexp or set_driver_filename.  */
  class compiler
  {
  protected:
    libcc1 *self_;
  public:
    compiler (libcc1 *self) : self_ (self)
    {
    }
    virtual char *find (std::string &compiler) const;
    virtual ~compiler ()
    {
    }
  } *compilerp;

  /* Compiler to set by set_triplet_regexp.  */
  class compiler_triplet_regexp : public compiler
  {
  private:
    std::string triplet_regexp_;
  public:
    virtual char *find (std::string &compiler) const;
    compiler_triplet_regexp (libcc1 *self, std::string triplet_regexp)
      : compiler (self), triplet_regexp_ (triplet_regexp)
    {
    }
    virtual ~compiler_triplet_regexp ()
    {
    }
  };

  /* Compiler to set by set_driver_filename.  */
  class compiler_driver_filename : public compiler
  {
  private:
    std::string driver_filename_;
  public:
    virtual char *find (std::string &compiler) const;
    compiler_driver_filename (libcc1 *self, std::string driver_filename)
      : compiler (self), driver_filename_ (driver_filename)
    {
    }
    virtual ~compiler_driver_filename ()
    {
    }
  };
};

// A local subclass of connection that holds a back-pointer to the
// gcc_c_context object that we provide to our caller.
class libcc1_connection : public cc1_plugin::connection
{
public:

  libcc1_connection (int fd, int aux_fd, libcc1 *b)
    : connection (fd, aux_fd),
      back_ptr (b)
  {
  }

  virtual void print (const char *buf)
  {
    back_ptr->print (buf);
  }

  libcc1 *back_ptr;
};

libcc1::libcc1 (const gcc_base_vtable *v,
		const gcc_c_fe_vtable *cv)
  : connection (NULL),
    binding_oracle (NULL),
    address_oracle (NULL),
    oracle_datum (NULL),
    print_function (NULL),
    print_datum (NULL),
    args (),
    source_file (),
    verbose (false),
    compilerp (new libcc1::compiler (this))
{
  base.ops = v;
  c_ops = cv;
}

libcc1::~libcc1 ()
{
  delete connection;
  delete compilerp;
}



// Enclose these functions in an anonymous namespace because they
// shouldn't be exported, but they can't be static because they're
// used as template arguments.
namespace {
  // This is a wrapper function that is called by the RPC system and
  // that then forwards the call to the library user.  Note that the
  // return value is not used; the type cannot be 'void' due to
  // limitations in our simple RPC.
  int
  c_call_binding_oracle (cc1_plugin::connection *conn,
			 enum gcc_c_oracle_request request,
			 const char *identifier)
  {
    libcc1 *self = ((libcc1_connection *) conn)->back_ptr;

    self->binding_oracle (self->oracle_datum, self, request, identifier);
    return 1;
  }

  // This is a wrapper function that is called by the RPC system and
  // that then forwards the call to the library user.
  gcc_address
  c_call_symbol_address (cc1_plugin::connection *conn, const char *identifier)
  {
    libcc1 *self = ((libcc1_connection *) conn)->back_ptr;

    return self->address_oracle (self->oracle_datum, self, identifier);
  }
} /* anonymous namespace */



static void
set_callbacks (struct gcc_c_context *s,
	       gcc_c_oracle_function *binding_oracle,
	       gcc_c_symbol_address_function *address_oracle,
	       void *datum)
{
  libcc1 *self = (libcc1 *) s;

  self->binding_oracle = binding_oracle;
  self->address_oracle = address_oracle;
  self->oracle_datum = datum;
}

// Instances of these rpc<> template functions are installed into the
// "c_vtable".  These functions are parameterized by type and method
// name and forward the call via the connection.

template<typename R, const char *&NAME>
R rpc (struct gcc_c_context *s)
{
  libcc1 *self = (libcc1 *) s;
  R result;

  if (!cc1_plugin::call (self->connection, NAME, &result))
    return 0;
  return result;
}

template<typename R, const char *&NAME, typename A>
R rpc (struct gcc_c_context *s, A arg)
{
  libcc1 *self = (libcc1 *) s;
  R result;

  if (!cc1_plugin::call (self->connection, NAME, &result, arg))
    return 0;
  return result;
}

template<typename R, const char *&NAME, typename A1, typename A2>
R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2)
{
  libcc1 *self = (libcc1 *) s;
  R result;

  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2))
    return 0;
  return result;
}

template<typename R, const char *&NAME, typename A1, typename A2, typename A3>
R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3)
{
  libcc1 *self = (libcc1 *) s;
  R result;

  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3))
    return 0;
  return result;
}

template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
	 typename A4>
R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
{
  libcc1 *self = (libcc1 *) s;
  R result;

  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
			 arg4))
    return 0;
  return result;
}

template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
	 typename A4, typename A5>
R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
{
  libcc1 *self = (libcc1 *) s;
  R result;

  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
			 arg4, arg5))
    return 0;
  return result;
}

template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
	 typename A4, typename A5, typename A6, typename A7>
R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
       A6 arg6, A7 arg7)
{
  libcc1 *self = (libcc1 *) s;
  R result;

  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
			 arg4, arg5, arg6, arg7))
    return 0;
  return result;
}

static const struct gcc_c_fe_vtable c_vtable =
{
  GCC_C_FE_VERSION_0,
  set_callbacks,

#define GCC_METHOD0(R, N) \
  rpc<R, cc1_plugin::c::N>,
#define GCC_METHOD1(R, N, A) \
  rpc<R, cc1_plugin::c::N, A>,
#define GCC_METHOD2(R, N, A, B) \
  rpc<R, cc1_plugin::c::N, A, B>,
#define GCC_METHOD3(R, N, A, B, C) \
  rpc<R, cc1_plugin::c::N, A, B, C>,
#define GCC_METHOD4(R, N, A, B, C, D) \
  rpc<R, cc1_plugin::c::N, A, B, C, D>,
#define GCC_METHOD5(R, N, A, B, C, D, E) \
  rpc<R, cc1_plugin::c::N, A, B, C, D, E>,
#define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
  rpc<R, cc1_plugin::c::N, A, B, C, D, E, F, G>,

#include "gcc-c-fe.def"

#undef GCC_METHOD0
#undef GCC_METHOD1
#undef GCC_METHOD2
#undef GCC_METHOD3
#undef GCC_METHOD4
#undef GCC_METHOD5
#undef GCC_METHOD7
};



// Construct an appropriate regexp to match the compiler name.
static std::string
make_regexp (const char *triplet_regexp, const char *compiler)
{
  std::stringstream buf;

  buf << "^" << triplet_regexp << "-";

  // Quote the compiler name in case it has something funny in it.
  for (const char *p = compiler; *p; ++p)
    {
      switch (*p)
	{
	case '.':
	case '^':
	case '$':
	case '*':
	case '+':
	case '?':
	case '(':
	case ')':
	case '[':
	case '{':
	case '\\':
	case '|':
	  buf << '\\';
	  break;
	}
      buf << *p;
    }
  buf << "$";

  return buf.str ();
}

static void
libcc1_set_verbose (struct gcc_base_context *s, int /* bool */ verbose)
{
  libcc1 *self = (libcc1 *) s;

  self->verbose = verbose != 0;
}

char *
libcc1::compiler::find (std::string &compiler ATTRIBUTE_UNUSED) const
{
  return xstrdup (_("Compiler has not been specified"));
}

char *
libcc1::compiler_triplet_regexp::find (std::string &compiler) const
{
  std::string rx = make_regexp (triplet_regexp_.c_str (), C_COMPILER_NAME);
  if (self_->verbose)
    fprintf (stderr, _("searching for compiler matching regex %s\n"),
	     rx.c_str());
  regex_t triplet;
  int code = regcomp (&triplet, rx.c_str (), REG_EXTENDED | REG_NOSUB);
  if (code != 0)
    {
      size_t len = regerror (code, &triplet, NULL, 0);
      char err[len];

      regerror (code, &triplet, err, len);

      return concat ("Could not compile regexp \"",
		     rx.c_str (),
		     "\": ",
		     err,
		     (char *) NULL);
    }

  if (!find_compiler (triplet, &compiler))
    {
      regfree (&triplet);
      return concat ("Could not find a compiler matching \"",
		     rx.c_str (),
		     "\"",
		     (char *) NULL);
    }
  regfree (&triplet);
  if (self_->verbose)
    fprintf (stderr, _("found compiler %s\n"), compiler.c_str());
  return NULL;
}

char *
libcc1::compiler_driver_filename::find (std::string &compiler) const
{
  // Simulate fnotice by fprintf.
  if (self_->verbose)
    fprintf (stderr, _("using explicit compiler filename %s\n"),
	     driver_filename_.c_str());
  compiler = driver_filename_;
  return NULL;
}

static char *
libcc1_set_arguments (struct gcc_base_context *s,
		      int argc, char **argv)
{
  libcc1 *self = (libcc1 *) s;

  std::string compiler;
  char *errmsg = self->compilerp->find (compiler);
  if (errmsg != NULL)
    return errmsg;

  self->args.push_back (compiler);

  for (int i = 0; i < argc; ++i)
    self->args.push_back (argv[i]);

  return NULL;
}

static char *
libcc1_set_triplet_regexp (struct gcc_base_context *s,
			   const char *triplet_regexp)
{
  libcc1 *self = (libcc1 *) s;

  delete self->compilerp;
  self->compilerp = new libcc1::compiler_triplet_regexp (self, triplet_regexp);
  return NULL;
}

static char *
libcc1_set_driver_filename (struct gcc_base_context *s,
			    const char *driver_filename)
{
  libcc1 *self = (libcc1 *) s;

  delete self->compilerp;
  self->compilerp = new libcc1::compiler_driver_filename (self,
							  driver_filename);
  return NULL;
}

static char *
libcc1_set_arguments_v0 (struct gcc_base_context *s,
			 const char *triplet_regexp,
			 int argc, char **argv)
{
  char *errmsg = libcc1_set_triplet_regexp (s, triplet_regexp);
  if (errmsg != NULL)
    return errmsg;

  return libcc1_set_arguments (s, argc, argv);
}

static void
libcc1_set_source_file (struct gcc_base_context *s,
			const char *file)
{
  libcc1 *self = (libcc1 *) s;

  self->source_file = file;
}

static void
libcc1_set_print_callback (struct gcc_base_context *s,
			   void (*print_function) (void *datum,
						   const char *message),
			   void *datum)
{
  libcc1 *self = (libcc1 *) s;

  self->print_function = print_function;
  self->print_datum = datum;
}

static int
fork_exec (libcc1 *self, char **argv, int spair_fds[2], int stderr_fds[2])
{
  pid_t child_pid = fork ();

  if (child_pid == -1)
    {
      close (spair_fds[0]);
      close (spair_fds[1]);
      close (stderr_fds[0]);
      close (stderr_fds[1]);
      return 0;
    }

  if (child_pid == 0)
    {
      // Child.
      dup2 (stderr_fds[1], 1);
      dup2 (stderr_fds[1], 2);
      close (stderr_fds[0]);
      close (stderr_fds[1]);
      close (spair_fds[0]);

      execvp (argv[0], argv);
      _exit (127);
    }
  else
    {
      // Parent.
      close (spair_fds[1]);
      close (stderr_fds[1]);

      cc1_plugin::status result = cc1_plugin::FAIL;
      if (self->connection->send ('H')
	  && ::cc1_plugin::marshall (self->connection, GCC_C_FE_VERSION_1))
	result = self->connection->wait_for_query ();

      close (spair_fds[0]);
      close (stderr_fds[0]);

      while (true)
	{
	  int status;

	  if (waitpid (child_pid, &status, 0) == -1)
	    {
	      if (errno != EINTR)
		return 0;
	    }

	  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
	    return 0;
	  break;
	}

      if (!result)
	return 0;
      return 1;
    }
}

static int
libcc1_compile (struct gcc_base_context *s,
		const char *filename)
{
  libcc1 *self = (libcc1 *) s;

  int fds[2];
  if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) != 0)
    {
      self->print ("could not create socketpair\n");
      return 0;
    }

  int stderr_fds[2];
  if (pipe (stderr_fds) != 0)
    {
      self->print ("could not create pipe\n");
      close (fds[0]);
      close (fds[1]);
      return 0;
    }

  self->args.push_back ("-fplugin=libcc1plugin");
  char buf[100];
  if (snprintf (buf, sizeof (buf), "-fplugin-arg-libcc1plugin-fd=%d", fds[1])
      >= (long) sizeof (buf))
    abort ();
  self->args.push_back (buf);

  self->args.push_back (self->source_file);
  self->args.push_back ("-c");
  self->args.push_back ("-o");
  self->args.push_back (filename);
  if (self->verbose)
    self->args.push_back ("-v");

  self->connection = new libcc1_connection (fds[0], stderr_fds[0], self);

  cc1_plugin::callback_ftype *fun
    = cc1_plugin::callback<int,
			   enum gcc_c_oracle_request,
			   const char *,
			   c_call_binding_oracle>;
  self->connection->add_callback ("binding_oracle", fun);

  fun = cc1_plugin::callback<gcc_address,
			     const char *,
			     c_call_symbol_address>;
  self->connection->add_callback ("address_oracle", fun);

  char **argv = new (std::nothrow) char *[self->args.size () + 1];
  if (argv == NULL)
    return 0;

  for (unsigned int i = 0; i < self->args.size (); ++i)
    argv[i] = const_cast<char *> (self->args[i].c_str ());
  argv[self->args.size ()] = NULL;

  return fork_exec (self, argv, fds, stderr_fds);
}

static int
libcc1_compile_v0 (struct gcc_base_context *s, const char *filename,
		   int verbose)
{
  libcc1_set_verbose (s, verbose);
  return libcc1_compile (s, filename);
}

static void
libcc1_destroy (struct gcc_base_context *s)
{
  libcc1 *self = (libcc1 *) s;

  delete self;
}

static const struct gcc_base_vtable vtable =
{
  GCC_FE_VERSION_1,
  libcc1_set_arguments_v0,
  libcc1_set_source_file,
  libcc1_set_print_callback,
  libcc1_compile_v0,
  libcc1_destroy,
  libcc1_set_verbose,
  libcc1_compile,
  libcc1_set_arguments,
  libcc1_set_triplet_regexp,
  libcc1_set_driver_filename,
};

extern "C" gcc_c_fe_context_function gcc_c_fe_context;

#ifdef __GNUC__
#pragma GCC visibility push(default)
#endif

extern "C"
struct gcc_c_context *
gcc_c_fe_context (enum gcc_base_api_version base_version,
		  enum gcc_c_api_version c_version)
{
  if ((base_version != GCC_FE_VERSION_0 && base_version != GCC_FE_VERSION_1)
      || (c_version != GCC_C_FE_VERSION_0 && c_version != GCC_C_FE_VERSION_1))
    return NULL;

  return new libcc1 (&vtable, &c_vtable);
}
