/* Copyright (C) 2021-2025 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of 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, 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, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <assert.h>
#include <ctype.h>
#include <sys/param.h>
#include <unistd.h>

#include "gp-defs.h"
#include "util.h"
#include "collctrl.h"
#include "collect.h"
#include "StringBuilder.h"
#include "Settings.h"

static const char *LD_AUDIT[] = {
  //    "LD_AUDIT",	Do not set LD_AUDIT on Linux
  NULL
};

static const char *LD_PRELOAD[] = {
  "LD_PRELOAD",
  NULL
};

static const char *SP_PRELOAD[] = {
  "SP_COLLECTOR_PRELOAD",
  NULL
};

static const char *LD_LIBRARY_PATH[] = {
  "LD_LIBRARY_PATH",
  NULL,
};

static int
add_env (char *ev)
{
  int r = putenv (ev);
  if (r != 0)
    {
      dbe_write (2, GTXT ("Can't putenv of %s: run aborted\n"), ev);
      free (ev);
    }
  return r;
}

int
collect::putenv_libcollector_ld_audits ()
{
  StringBuilder sb;
  for (unsigned int ii = 0; ii < ARR_SIZE (LD_AUDIT) && LD_AUDIT[ii]; ++ii)
    {
      sb.sprintf ("%s=%s", LD_AUDIT[ii], SP_LIBAUDIT_NAME);
      // Append the current value. Check if already set
      char *old_val = getenv (LD_AUDIT[ii]);
      if (old_val != NULL)
	{
	  while (isspace (*old_val))
	    ++old_val;
	  if (*old_val != (char) 0)
	    {
	      int fromIdx = sb.length ();
	      sb.append (" ");
	      sb.append (old_val);
	      if (sb.indexOf (SP_LIBAUDIT_NAME, fromIdx) >= 0)
		continue;       // Already set. Do nothing.
	    }
	}
      if (add_env (sb.toString ()))
	return 1;
    }
  return 0;
}

int
collect::putenv_libcollector_ld_preloads ()
{
  // for those data types that get extra libs LD_PRELOAD'd, add them
  if (cc->get_synctrace_mode () != 0)
    add_ld_preload ("libgp-sync.so");
  if (cc->get_heaptrace_mode () != NULL)
    add_ld_preload ("libgp-heap.so");
  if (cc->get_iotrace_mode () != 0)
    add_ld_preload ("libgp-iotrace.so");
  add_ld_preload (SP_LIBCOLLECTOR_NAME);

  // --- putenv SP_COLLECTOR_PRELOAD*
  int ii;
  for (ii = 0; SP_PRELOAD[ii]; ii++)
    {
      // construct the SP_PRELOAD_* environment variables
      // and put them into the environment
      if (add_env (dbe_sprintf ("%s=%s", SP_PRELOAD[ii], sp_preload_list[ii])))
	return 1;
    }
  // --- putenv LD_PRELOADS
  /* purge LD_PRELOAD* of values containing contents of SP_LIBCOLLECTOR_NAME */
  if (putenv_purged_ld_preloads (SP_LIBCOLLECTOR_NAME))
    dbe_write (2, GTXT ("Warning: %s is already defined in one or more LD_PRELOAD environment variables\n"),
	       SP_LIBCOLLECTOR_NAME);
  if (putenv_ld_preloads ())
    return 1;
  return 0;
}

int
collect::putenv_libcollector_ld_misc ()
{
#if 0 // XXX 1 turns on LD_DEBUG
  putenv (xstrdup ("LD_DEBUG=audit,bindings,detail"));
#endif
  // workaround to have the dynamic linker use absolute names
  if (add_env (dbe_strdup ("LD_ORIGIN=yes")))
    return 1;

  // On Linux we have to provide SP_COLLECTOR_LIBRARY_PATH and LD_LIBRARY_PATH
  // so that -agentlib:gp-collector works
  // and so that collect -F works with 32/64-bit mix of processes

  StringBuilder sb;
  sb.append ("SP_COLLECTOR_LIBRARY_PATH=");
  int len = sb.length ();
  int cnt = 0;
  char *fname;
  char *ev = getenv (GPROFNG_PRELOAD_LIBDIRS);
  char *libpath_list = NULL;
  if (ev)
    { /* GPROFNG_PRELOAD_LIBDIRS is used only in the gprofng testing.
       * Use these directories first.  */
      ev = xstrdup (ev);
      for (char *s = ev; s;)
	{
	  char *s1 = strchr (s, ':');
	  if (s1)
	    *(s1++) = 0;
	  fname = dbe_sprintf ("%s/%s", s, LIBGP_COLLECTOR);
	  if (access (fname, R_OK | F_OK) == 0)
	    {
	      if (++cnt != 1)
		sb.append (':');
	      sb.append (s);
	    }
	  free (fname);
	  s = s1;
	}
      free (ev);
      ev = NULL;
    }
  if (settings->preload_libdirs == NULL)
    {
      settings->read_rc (false);
      ev = settings->preload_libdirs;
    }
  ev = dbe_strdup (ev);
  fname = dbe_sprintf ("%s/%s/%s", LIBDIR, PACKAGE, LIBGP_COLLECTOR);
  if (access (fname, R_OK | F_OK) == 0)
    {
      ++cnt;
      sb.appendf ("%s/%s", LIBDIR, PACKAGE);
    }
  free (fname);
  for (char *s = ev; s;)
    {
      char *s1 = strchr (s, ':');
      if (s1)
	*(s1++) = 0;
      if (*s == '/')
	{
	  fname = dbe_sprintf ("%s/%s/%s", s, PACKAGE, LIBGP_COLLECTOR);
	  if (access (fname, R_OK | F_OK) == 0)
	    {
	      if (++cnt != 1)
		sb.append (':');
	      sb.appendf ("%s", s);
	    }
	}
      else
	{
	  fname = dbe_sprintf ("%s/%s/%s/%s", run_dir, s, PACKAGE, LIBGP_COLLECTOR);
	  if (access (fname, R_OK | F_OK) == 0)
	    {
	      if (++cnt != 1)
		sb.append (':');
	      sb.appendf ("%s/%s/%s", run_dir, s, PACKAGE);
	    }
	}
      free (fname);
      s = s1;
    }
  free (ev);
  if (cnt == 0)
    {
      dbe_write (2, GTXT ("configuration error: can not find %s. run aborted\n"),
		 LIBGP_COLLECTOR);
      return 1;
    }
  libpath_list = sb.toString ();
  if (add_env (libpath_list))
    return 1;
  libpath_list += len;

  // --- set LD_LIBRARY_PATH using libpath_list
  char *old = getenv (LD_LIBRARY_PATH[0]);
  if (old)
    ev = dbe_sprintf ("%s=%s:%s", LD_LIBRARY_PATH[0], libpath_list, old);
  else
    ev = dbe_sprintf ("%s=%s", LD_LIBRARY_PATH[0], libpath_list);
  if (add_env (ev))
    return 1;
  return 0;
}

void
collect::add_ld_preload (const char *lib)
{
  for (int ii = 0; SP_PRELOAD[ii]; ii++)
    {
      char *old_sp = sp_preload_list[ii];
      if (old_sp == NULL)
	sp_preload_list[ii] = xstrdup (lib);
      else
	{
	  sp_preload_list[ii] = dbe_sprintf ("%s %s", old_sp, lib);
	  free (old_sp);
	}
    }
}

int
collect::putenv_memso ()
{
  // Set environment variable "MEM_USE_LOG" to 1, to keep it out of stderr
  if (add_env (dbe_strdup ("MEM_USE_LOG=1")))
    return 1;
  // Set environment variable "MEM_ABORT_ON_ERROR", to force a core dump
  if (add_env (dbe_strdup ("MEM_ABORT_ON_ERROR=1")))
    return 1;
  add_ld_preload ("mem.so");
  return putenv_ld_preloads ();
}

// set LD_PRELOAD and friends to prepend the given library or libraries

int
collect::putenv_ld_preloads ()
{
  for (int ii = 0; LD_PRELOAD[ii]; ii++)
    {
      char *old_val = getenv (LD_PRELOAD[ii]);
      int sp_num = ii;
      assert (SP_PRELOAD[sp_num]);
      char *preload_def;
      if (old_val)
	preload_def = dbe_sprintf ("%s=%s %s", LD_PRELOAD[ii], sp_preload_list[sp_num], old_val);
      else
	preload_def = dbe_sprintf ("%s=%s", LD_PRELOAD[ii], sp_preload_list[sp_num]);
      if (add_env (preload_def))
	return 1;
    }
  return 0;
}

/* copied from linetrace.c */
/*
   function: env_strip()
     Finds str in env; Removes
     all characters from previous ':' or ' '
     up to and including any trailing ':' or ' '.
   params:
     env: environment variable
     str: substring to find
     return: count of instances removed from env
 */
int
collect::env_strip (char *env, const char *str)
{
  int removed = 0;
  char *p, *q;
  if (env == NULL || str == NULL || *str == 0)
    return 0;
  size_t maxlen = strlen (env);
  size_t len = strlen (str);
  q = env;
  while ((p = strstr (q, str)) != NULL)
    {
      q = p;
      p += len;
      if (*p)
	{
	  while ((*p) && (*p != ':') && (*p != ' '))
	    p++;      /* skip the rest of the name*/
	  while ((*p == ':') || (*p == ' '))
	    p++; /* strip trailing separator */
	}
      while (*q != ':' && *q != ' ' && *q != '=' && q != env)
	q--; /* strip path */
      if (*p)
	{ /* copy the rest of the string */
	  if (q != env)
	    q++; /* restore leading separator (if any) */
	  size_t n = (maxlen - (q - env));
	  strncpy (q, p, n);
	}
      else
	*q = 0;
      removed++;
    }
  return removed;
}
/*
   function: putenv_purged_ld_preloads()
     Remove selected preload strings from all LD_PRELOAD* env vars.
   params:
     var: executable name (leading characters don't have to match)
     return: number of instances removed from all PRELOAD vars.
 */
int
collect::putenv_purged_ld_preloads (const char *var)
{
  int total_removed = 0;
  if (!var || *var == 0)
    return 0;
  for (int ii = 0; LD_PRELOAD[ii]; ii++)
    {
      char *ev = getenv (LD_PRELOAD[ii]);
      int removed = 0;
      if (!ev)
	continue;
      removed = env_strip (ev, var);
      if (!removed)
	continue;
      if (putenv (ev) != 0)
	dbe_write (2, GTXT ("Can't putenv of %s\n"), ev);
      total_removed += removed;
    }
  return total_removed;
}
/*
   function: putenv_append()
     append string to current enviroment variable setting and then do a putenv()
   params:
     var: environment variable name
     val: string to append
 */
int
collect::putenv_append (const char *var, const char *val)
{
  char *ev;
  if (!var || !val)
    return 1;
  const char *old_val = getenv (var);
  if (old_val == NULL || *old_val == 0)
    ev = dbe_sprintf ("%s=%s", var, val);
  else
    ev = dbe_sprintf ("%s=%s %s", var, old_val, val);

  // now put the new variable into the environment
  if (add_env (ev))
    return 1;
  return 0;
}

int
collect::putenv_libcollector (void)
{
  char buf[MAXPATHLEN + 1];
  // --- set SP_COLLECTOR_EXPNAME
  // fetch the experiment name and CWD
  char *exp = cc->get_experiment ();
  char *cwd = getcwd (buf, MAXPATHLEN);
  char *ev;

  // format the environment variable for the experiment directory name
  if (cwd != NULL && exp[0] != '/')  // experiment is a relative path
    ev = dbe_sprintf ("%s=%s/%s", SP_COLLECTOR_EXPNAME, cwd, exp);
  else      // getcwd failed or experiment is a fullpath
    ev = dbe_sprintf ("%s=%s", SP_COLLECTOR_EXPNAME, exp);

  // set the experiment directory name
  if (add_env (ev))
    return 1;

  // --- set SP_COLLECTOR_PARAMS
  // set the data descriptor
  exp = cc->get_data_desc ();
  if (add_env (dbe_sprintf ("%s=%s", SP_COLLECTOR_PARAMS, exp)))
    return 1;

  // --- set SP_COLLECTOR_FOLLOW_SPEC
  const char *follow_spec = cc->get_follow_cmp_spec ();
  if (follow_spec)
    // selective following has been enabled
    if (add_env (dbe_sprintf ("%s=%s", SP_COLLECTOR_FOLLOW_SPEC, follow_spec)))
      return 1;

  if (add_env (dbe_sprintf ("%s=%d", SP_COLLECTOR_FOUNDER, getpid ())))
    return 1;
  if (add_env (dbe_sprintf ("%s=1", SP_COLLECTOR_ORIGIN_COLLECT)))
    return 1;

  // --- set LD_*
  if (putenv_libcollector_ld_misc ())
    return 1;

  // --- set LD_PRELOAD*
  if (putenv_libcollector_ld_preloads () != 0)
    return 1;

  // --- set JAVA_TOOL_OPTIONS
  if (cc->get_java_mode () == 1)
    if (putenv_append ("JAVA_TOOL_OPTIONS", "-agentlib:gp-collector"))
	exit (1);
#if 0
  // --- set LD_AUDIT*
  if (putenv_libcollector_ld_audits () != 0)
    return 1;
#endif
  return 0;
}
