/* libdeps plugin for the GNU linker.
   Copyright (C) 2020-2021 Free Software Foundation, Inc.

   This file is part of the GNU Binutils.

   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, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include "bfd.h"
#if BFD_SUPPORTS_PLUGINS
#include "plugin-api.h"

#include <ctype.h> /* For isspace.  */

extern enum ld_plugin_status onload (struct ld_plugin_tv *tv);

/* Helper for calling plugin api message function.  */
#define TV_MESSAGE if (tv_message) (*tv_message)

/* Function pointers to cache hooks passed at onload time.  */
static ld_plugin_register_claim_file tv_register_claim_file = 0;
static ld_plugin_register_all_symbols_read tv_register_all_symbols_read = 0;
static ld_plugin_register_cleanup tv_register_cleanup = 0;
static ld_plugin_message tv_message = 0;
static ld_plugin_add_input_library tv_add_input_library = 0;
static ld_plugin_set_extra_library_path tv_set_extra_library_path = 0;

/* Handle/record information received in a transfer vector entry.  */
static enum ld_plugin_status
parse_tv_tag (struct ld_plugin_tv *tv)
{
#define SETVAR(x) x = tv->tv_u.x
  switch (tv->tv_tag)
    {
      case LDPT_REGISTER_CLAIM_FILE_HOOK:
	SETVAR(tv_register_claim_file);
	break;
      case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
	SETVAR(tv_register_all_symbols_read);
	break;
      case LDPT_REGISTER_CLEANUP_HOOK:
	SETVAR(tv_register_cleanup);
	break;
      case LDPT_MESSAGE:
	SETVAR(tv_message);
	break;
      case LDPT_ADD_INPUT_LIBRARY:
	SETVAR(tv_add_input_library);
	break;
      case LDPT_SET_EXTRA_LIBRARY_PATH:
	SETVAR(tv_set_extra_library_path);
	break;
      default:
	break;
    }
#undef SETVAR
  return LDPS_OK;
}

/* Defs for archive parsing.  */
#define ARMAGSIZE	8
typedef struct arhdr
{
  char ar_name[16];
  char ar_date[12];
  char ar_uid[6];
  char ar_gid[6];
  char ar_mode[8];
  char ar_size[10];
  char ar_fmag[2];
} arhdr;

typedef struct linerec
{
  struct linerec *next;
  char line[];
} linerec;

#define LIBDEPS "__.LIBDEP/ "

static linerec *line_head, **line_tail = &line_head;

static enum ld_plugin_status
get_libdeps (int fd)
{
  arhdr ah;
  int len;
  unsigned long mlen;
  linerec *lr;
  enum ld_plugin_status rc = LDPS_NO_SYMS;

  lseek (fd, ARMAGSIZE, SEEK_SET);
  for (;;)
    {
      len = read (fd, (void *) &ah, sizeof (ah));
      if (len != sizeof (ah))
	break;
      mlen = strtoul (ah.ar_size, NULL, 10);
      if (!mlen || strncmp (ah.ar_name, LIBDEPS, sizeof (LIBDEPS)-1))
	{
	  lseek (fd, mlen, SEEK_CUR);
	  continue;
	}
      lr = malloc (sizeof (linerec) + mlen);
      if (!lr)
	return LDPS_ERR;
      lr->next = NULL;
      len = read (fd, lr->line, mlen);
      lr->line[mlen-1] = '\0';
      *line_tail = lr;
      line_tail = &lr->next;
      rc = LDPS_OK;
      break;
    }
  return rc;
}

/* Turn a string into an argvec.  */
static char **
str2vec (char *in)
{
  char **res;
  char *s, *first, *end;
  char *sq, *dq;
  int i;

  end = in + strlen (in);
  s = in;
  while (isspace ((unsigned char) *s)) s++;
  first = s;

  i = 1;
  while ((s = strchr (s, ' ')))
    {
      s++;
      i++;
    }
  res = (char **)malloc ((i+1) * sizeof (char *));
  if (!res)
    return res;

  i = 0;
  sq = NULL;
  dq = NULL;
  res[0] = first;
  for (s = first; *s; s++)
    {
      if (*s == '\\')
	{
	  memmove (s, s+1, end-s-1);
	  end--;
	}
      if (isspace ((unsigned char) *s))
	{
	  if (sq || dq)
	    continue;
	  *s++ = '\0';
	  while (isspace ((unsigned char) *s)) s++;
	  if (*s)
	    res[++i] = s;
	}
      if (*s == '\'' && !dq)
	{
	  if (sq)
	    {
	      memmove (sq, sq+1, s-sq-1);
	      memmove (s-2, s+1, end-s-1);
	      end -= 2;
	      s--;
	      sq = NULL;
	    }
	  else
	    {
	      sq = s;
	    }
	}
      if (*s == '"' && !sq)
	{
	  if (dq)
	    {
	      memmove (dq, dq+1, s-dq-1);
	      memmove (s-2, s+1, end-s-1);
	      end -= 2;
	      s--;
	      dq = NULL;
	    }
	  else
	    {
	      dq = s;
	    }
	}
    }
  res[++i] = NULL;
  return res;
}

static char *prevfile;

/* Standard plugin API registerable hook.  */
static enum ld_plugin_status
onclaim_file (const struct ld_plugin_input_file *file, int *claimed)
{
  enum ld_plugin_status rv;

  *claimed = 0;

  /* If we've already seen this file, ignore it.  */
  if (prevfile && !strcmp (file->name, prevfile))
    return LDPS_OK;

  /* If it's not an archive member, ignore it.  */
  if (!file->offset)
    return LDPS_OK;

  if (prevfile)
    free (prevfile);

  prevfile = strdup (file->name);
  if (!prevfile)
    return LDPS_ERR;

  /* This hook only gets called on actual object files.
   * We have to examine the archive ourselves, to find
   * our LIBDEPS member.  */
  rv = get_libdeps (file->fd);
  if (rv == LDPS_ERR)
    return rv;

  if (rv == LDPS_OK)
    {
      linerec *lr = (linerec *)line_tail;
      /* Inform the user/testsuite.  */
      TV_MESSAGE (LDPL_INFO, "got deps for library %s: %s",
		  file->name, lr->line);
      fflush (NULL);
    }

  return LDPS_OK;
}

/* Standard plugin API registerable hook.  */
static enum ld_plugin_status
onall_symbols_read (void)
{
  linerec *lr;
  char **vec;
  enum ld_plugin_status rv = LDPS_OK;

  while ((lr = line_head))
    {
      line_head = lr->next;
      vec = str2vec (lr->line);
      if (vec)
	{
	  int i;
	  for (i = 0; vec[i]; i++)
	    {
	      if (vec[i][0] != '-')
		{
		  TV_MESSAGE (LDPL_WARNING, "ignoring libdep argument %s",
			      vec[i]);
		  fflush (NULL);
		  continue;
		}
	      if (vec[i][1] == 'l')
		rv = tv_add_input_library (vec[i]+2);
	      else if (vec[i][1] == 'L')
		rv = tv_set_extra_library_path (vec[i]+2);
	      else
		{
		  TV_MESSAGE (LDPL_WARNING, "ignoring libdep argument %s",
			      vec[i]);
		  fflush (NULL);
		}
	      if (rv != LDPS_OK)
		break;
	    }
	  free (vec);
	}
      free (lr);
    }
  line_tail = NULL;
  return rv;
}

/* Standard plugin API registerable hook.  */
static enum ld_plugin_status
oncleanup (void)
{
  if (prevfile)
    {
      free (prevfile);
      prevfile = NULL;
    }
  if (line_head)
    {
      linerec *lr;
      while ((lr = line_head))
	{
	  line_head = lr->next;
	  free (lr);
	}
      line_tail = NULL;
    }
  return LDPS_OK;
}

/* Standard plugin API entry point.  */
enum ld_plugin_status
onload (struct ld_plugin_tv *tv)
{
  enum ld_plugin_status rv;

  /* This plugin requires a valid tv array.  */
  if (!tv)
    return LDPS_ERR;

  /* First entry should always be LDPT_MESSAGE, letting us get
     hold of it easily so we can send output straight away.  */
  if (tv[0].tv_tag == LDPT_MESSAGE)
    tv_message = tv[0].tv_u.tv_message;

  do
    if ((rv = parse_tv_tag (tv)) != LDPS_OK)
      return rv;
  while ((tv++)->tv_tag != LDPT_NULL);

  /* Register hooks.  */
  if (tv_register_claim_file
      && tv_register_all_symbols_read
      && tv_register_cleanup)
    {
      (*tv_register_claim_file) (onclaim_file);
      (*tv_register_all_symbols_read) (onall_symbols_read);
      (*tv_register_cleanup) (oncleanup);
    }
  fflush (NULL);
  return LDPS_OK;
}
#endif /* BFD_SUPPORTS_PLUGINS */
