/* Loading dynamic objects for GNU Make.
Copyright (C) 2012-2025 Free Software Foundation, Inc.
This file is part of GNU Make.

GNU Make 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.

GNU Make 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, see <https://www.gnu.org/licenses/>.  */

#include "makeint.h"

#if MAKE_LOAD

#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <errno.h>

#include "debug.h"
#include "filedef.h"
#include "variable.h"

/* Tru64 V4.0 does not have this flag */
#ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
#endif

#define GMK_SETUP       "_gmk_setup"
#define GMK_UNLOAD      "_gmk_unload"

typedef int (*setup_func_t)(unsigned int abi, const floc *flocp);
typedef void (*unload_func_t)(void);

struct load_list
  {
    struct load_list *next;
    const char *name;
    void *dlp;
    unload_func_t unload;
  };

static struct load_list *loaded_syms = NULL;

static setup_func_t
load_object (const floc *flocp, int noerror, const char *ldname,
             const char *setupnm)
{
  static void *global_dl = NULL;
  char *buf;
  const char *fp;
  char *endp;
  void *dlp;
  struct load_list *new;
  setup_func_t symp;

  if (! global_dl)
    {
      global_dl = dlopen (NULL, RTLD_NOW|RTLD_GLOBAL);
      if (! global_dl)
        {
          const char *err = dlerror ();
          OS (fatal, flocp, _("failed to open global symbol table: %s"), err);
        }
    }

  /* Find the prefix of the ldname.  */
  fp = strrchr (ldname, '/');
#ifdef HAVE_DOS_PATHS
  if (fp)
    {
      const char *fp2 = strchr (fp, '\\');

      if (fp2 > fp)
        fp = fp2;
    }
  else
    fp = strrchr (ldname, '\\');
  /* The (improbable) case of d:foo.  */
  if (fp && *fp && fp[1] == ':')
    fp++;
#endif
  if (!fp)
    fp = ldname;
  else
    ++fp;

  endp = buf = alloca (strlen (fp) + CSTRLEN (GMK_UNLOAD) + 1);
  while (isalnum ((unsigned char) *fp) || *fp == '_')
    *(endp++) = *(fp++);

  /* If we didn't find a symbol name yet, construct it from the prefix.  */
  if (! setupnm)
    {
      memcpy (endp, GMK_SETUP, CSTRLEN (GMK_SETUP) + 1);
      setupnm = buf;
    }

  DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), setupnm, ldname));

  symp = (setup_func_t) dlsym (global_dl, setupnm);
  if (symp)
    return symp;

  /* If the path has no "/", try the current directory first.  */
  dlp = NULL;
  if (! strchr (ldname, '/')
#ifdef HAVE_DOS_PATHS
      && ! strchr (ldname, '\\')
#endif
      )
    dlp = dlopen (concat (2, "./", ldname), RTLD_LAZY|RTLD_GLOBAL);

  /* If we haven't opened it yet, try the default search path.  */
  if (! dlp)
    dlp = dlopen (ldname, RTLD_LAZY|RTLD_GLOBAL);

  /* Still no?  Then fail.  */
  if (! dlp)
    {
      const char *err = dlerror ();
      if (noerror)
        DB (DB_BASIC, ("%s\n", err));
      else
        OS (error, flocp, "%s", err);
      return NULL;
    }

  DB (DB_VERBOSE, (_("Loaded shared object %s\n"), ldname));

  /* Assert that the GPL license symbol is defined.  */
  symp = (setup_func_t) dlsym (dlp, "plugin_is_GPL_compatible");
  if (! symp)
    OS (fatal, flocp,
        _("loaded object %s is not declared to be GPL compatible"), ldname);

  symp = (setup_func_t) dlsym (dlp, setupnm);
  if (! symp)
    {
      const char *err = dlerror ();
      OSSS (fatal, flocp, _("failed to load symbol %s from %s: %s"),
            setupnm, ldname, err);
    }

  new = xcalloc (sizeof (struct load_list));
  new->next = loaded_syms;
  loaded_syms = new;
  new->name = ldname;
  new->dlp = dlp;

  /* Compute the name of the unload function and look it up.  */
  memcpy (endp, GMK_UNLOAD, CSTRLEN (GMK_UNLOAD) + 1);

  new->unload = (unload_func_t) dlsym (dlp, buf);
  if (new->unload)
    DB (DB_VERBOSE, (_("Detected symbol %s in %s\n"), buf, ldname));

  return symp;
}

int
load_file (const floc *flocp, struct file *file, int noerror)
{
  const char *ldname = file->name;
  char *buf;
  char *setupnm = NULL;
  const char *fp;
  int r;
  setup_func_t symp;

  /* Break the input into an object file name and a symbol name.  If no symbol
     name was provided, compute one from the object file name.  */
  fp = strchr (ldname, '(');
  if (fp)
    {
      const char *ep;

      /* There's an open paren, so see if there's a close paren: if so use
         that as the symbol name.  We can't have whitespace: it would have
         been chopped up before this function is called.  */
      ep = strchr (fp+1, ')');
      if (ep && ep[1] == '\0')
        {
          size_t l = fp - ldname;

          ++fp;
          if (fp == ep)
            OS (fatal, flocp, _("empty symbol name for load: %s"), ldname);

          /* Make a copy of the ldname part.  */
          buf = alloca (strlen (ldname) + 1);
          memcpy (buf, ldname, l);
          buf[l] = '\0';
          ldname = buf;

          /* Make a copy of the symbol name part.  */
          setupnm = buf + l + 1;
          memcpy (setupnm, fp, ep - fp);
          setupnm[ep - fp] = '\0';
        }
    }

  /* Make sure this name is in the string cache.  */
  ldname = file->name = strcache_add (ldname);

  /* If this object has been loaded, we're done: return -1 to ensure make does
     not rebuild again.  If a rebuild is allowed it was set up when this
     object was initially loaded.  */
  file = lookup_file (ldname);
  if (file && file->loaded)
    return -1;

  /* Load it!  */
  symp = load_object (flocp, noerror, ldname, setupnm);
  if (! symp)
    return 0;

  /* Invoke the setup function.  */
  {
    unsigned int abi = GMK_ABI_VERSION;
    r = (*symp) (abi, flocp);
  }

  /* If the load didn't fail, add the file to the .LOADED variable.  */
  if (r)
    do_variable_definition(flocp, ".LOADED", ldname, o_file, f_append_value, 0,
                           s_global);

  return r;
}

int
unload_file (const char *name)
{
  struct load_list **dp = &loaded_syms;

  /* Unload and remove the entry for this file.  */
  while (*dp != NULL)
    {
      struct load_list *d = *dp;

      if (streq (d->name, name))
        {
          int rc;

          DB (DB_VERBOSE, (_("Unloading shared object %s\n"), name));

          if (d->unload)
            (*d->unload) ();

          rc = dlclose (d->dlp);
          if (rc)
            perror_with_name ("dlclose: ", d->name);

          *dp = d->next;
          free (d);
          return rc;
        }

      dp = &d->next;
    }

  return 0;
}

void
unload_all ()
{
  while (loaded_syms)
    {
      struct load_list *d = loaded_syms;
      loaded_syms = loaded_syms->next;

      if (d->unload)
        (*d->unload) ();

      if (dlclose (d->dlp))
        perror_with_name ("dlclose: ", d->name);

      free (d);
    }
}

#else

int
load_file (const floc *flocp, struct file *file UNUSED, int noerror)
{
  if (! noerror)
    O (fatal, flocp,
       _("'load' is not supported on this platform"));

  return 0;
}

int
unload_file (const char *name UNUSED)
{
  O (fatal, NILF, "INTERNAL: cannot unload when load is not supported");
}

void
unload_all ()
{
}

#endif  /* MAKE_LOAD */
