/* CTF linking.
   Copyright (C) 2019-2024 Free Software Foundation, Inc.

   This file is part of libctf.

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

#include <ctf-impl.h>
#include <string.h>

#if defined (PIC)
#pragma weak ctf_open
#endif

/* CTF linking consists of adding CTF archives full of content to be merged into
   this one to the current file (which must be writable) by calling
   ctf_link_add_ctf.  Once this is done, a call to ctf_link will merge the type
   tables together, generating new CTF files as needed, with this one as a
   parent, to contain types from the inputs which conflict.  ctf_link_add_strtab
   takes a callback which provides string/offset pairs to be added to the
   external symbol table and deduplicated from all CTF string tables in the
   output link; ctf_link_shuffle_syms takes a callback which provides symtab
   entries in ascending order, and shuffles the function and data sections to
   match; and ctf_link_write emits a CTF file (if there are no conflicts
   requiring per-compilation-unit sub-CTF files) or CTF archives (otherwise) and
   returns it, suitable for addition in the .ctf section of the output.  */

/* Return the name of the compilation unit this CTF dict or its parent applies
   to, or a non-null string otherwise: prefer the parent.  Used in debugging
   output.  Sometimes used for outputs too.  */
const char *
ctf_link_input_name (ctf_dict_t *fp)
{
  if (fp->ctf_parent && fp->ctf_parent->ctf_cuname)
    return fp->ctf_parent->ctf_cuname;
  else if (fp->ctf_cuname)
    return fp->ctf_cuname;
  else
    return "(unnamed)";
}

/* Return the cuname of a dict, or the string "unnamed-CU" if none.  */

static const char *
ctf_unnamed_cuname (ctf_dict_t *fp)
{
  const char *cuname = ctf_cuname (fp);

  if (!cuname)
    cuname = "unnamed-CU";

  return cuname;
}

/* The linker inputs look like this.  clin_fp is used for short-circuited
   CU-mapped links that can entirely avoid the first link phase in some
   situations in favour of just passing on the contained ctf_dict_t: it is
   always the sole ctf_dict_t inside the corresponding clin_arc.  If set, it
   gets assigned directly to the final link inputs and freed from there, so it
   never gets explicitly freed in the ctf_link_input.  */
typedef struct ctf_link_input
{
  char *clin_filename;
  ctf_archive_t *clin_arc;
  ctf_dict_t *clin_fp;
  int n;
} ctf_link_input_t;

static void
ctf_link_input_close (void *input)
{
  ctf_link_input_t *i = (ctf_link_input_t *) input;
  if (i->clin_arc)
    ctf_arc_close (i->clin_arc);
  free (i->clin_filename);
  free (i);
}

/* Like ctf_link_add_ctf, below, but with no error-checking, so it can be called
   in the middle of an ongoing link.  */
static int
ctf_link_add_ctf_internal (ctf_dict_t *fp, ctf_archive_t *ctf,
			   ctf_dict_t *fp_input, const char *name)
{
  int existing = 0;
  ctf_link_input_t *input;
  char *filename, *keyname;

  /* Existing: return it, or (if a different dict with the same name
     is already there) make up a new unique name.  Always use the actual name
     for the filename, because that needs to be ctf_open()ed.  */

  if ((input = ctf_dynhash_lookup (fp->ctf_link_inputs, name)) != NULL)
    {
      if ((fp_input != NULL && (input->clin_fp == fp_input))
	  || (ctf != NULL && (input->clin_arc == ctf)))
	return 0;
      existing = 1;
    }

  if ((filename = strdup (name)) == NULL)
    goto oom;

  if ((input = calloc (1, sizeof (ctf_link_input_t))) == NULL)
    goto oom1;

  input->clin_arc = ctf;
  input->clin_fp = fp_input;
  input->clin_filename = filename;
  input->n = ctf_dynhash_elements (fp->ctf_link_inputs);

  if (existing)
    {
      if (asprintf (&keyname, "%s#%li", name, (long int)
		    ctf_dynhash_elements (fp->ctf_link_inputs)) < 0)
	goto oom2;
    }
  else if ((keyname = strdup (name)) == NULL)
    goto oom2;

  if (ctf_dynhash_insert (fp->ctf_link_inputs, keyname, input) < 0)
    goto oom3;

  return 0;

 oom3:
  free (keyname);
 oom2:
  free (input);
 oom1:
  free (filename);
 oom:
  return ctf_set_errno (fp, ENOMEM);
}

/* Add a file, memory buffer, or unopened file (by name) to a link.

   You can call this with:

    CTF and NAME: link the passed ctf_archive_t, with the given NAME.
    NAME alone: open NAME as a CTF file when needed.
    BUF and NAME: open the BUF (of length N) as CTF, with the given NAME.  (Not
    yet implemented.)

    Passed in CTF args are owned by the dictionary and will be freed by it.
    The BUF arg is *not* owned by the dictionary, and the user should not free
    its referent until the link is done.

    The order of calls to this function influences the order of types in the
    final link output, but otherwise is not important.

    Repeated additions of the same NAME have no effect; repeated additions of
    different dicts with the same NAME add all the dicts with unique NAMEs
    derived from NAME.

    Private for now, but may in time become public once support for BUF is
    implemented.  */

static int
ctf_link_add (ctf_dict_t *fp, ctf_archive_t *ctf, const char *name,
	      void *buf _libctf_unused_, size_t n _libctf_unused_)
{
  if (buf)
    return (ctf_set_errno (fp, ECTF_NOTYET));

  if (!((ctf && name && !buf)
	|| (name && !buf && !ctf)
	|| (buf && name && !ctf)))
    return (ctf_set_errno (fp, EINVAL));

  /* We can only lazily open files if libctf.so is in use rather than
     libctf-nobfd.so.  This is a little tricky: in shared libraries, we can use
     a weak symbol so that -lctf -lctf-nobfd works, but in static libraries we
     must distinguish between the two libraries explicitly.  */

#if defined (PIC)
  if (!buf && !ctf && name && !ctf_open)
    return (ctf_set_errno (fp, ECTF_NEEDSBFD));
#elif NOBFD
  if (!buf && !ctf && name)
    return (ctf_set_errno (fp, ECTF_NEEDSBFD));
#endif

  if (fp->ctf_link_outputs)
    return (ctf_set_errno (fp, ECTF_LINKADDEDLATE));
  if (fp->ctf_link_inputs == NULL)
    fp->ctf_link_inputs = ctf_dynhash_create (ctf_hash_string,
					      ctf_hash_eq_string, free,
					      ctf_link_input_close);

  if (fp->ctf_link_inputs == NULL)
    return (ctf_set_errno (fp, ENOMEM));

  return ctf_link_add_ctf_internal (fp, ctf, NULL, name);
}

/* Add an opened CTF archive or unopened file (by name) to a link.
   If CTF is NULL and NAME is non-null, an unopened file is meant:
   otherwise, the specified archive is assumed to have the given NAME.

    Passed in CTF args are owned by the dictionary and will be freed by it.

    The order of calls to this function influences the order of types in the
    final link output, but otherwise is not important.  */

int
ctf_link_add_ctf (ctf_dict_t *fp, ctf_archive_t *ctf, const char *name)
{
  return ctf_link_add (fp, ctf, name, NULL, 0);
}

/* Lazily open a CTF archive for linking, if not already open.

   Returns the number of files contained within the opened archive (0 for none),
   or -1 on error, as usual.  */
static ssize_t
ctf_link_lazy_open (ctf_dict_t *fp, ctf_link_input_t *input)
{
  size_t count;
  int err;

  if (input->clin_arc)
    return ctf_archive_count (input->clin_arc);

  if (input->clin_fp)
    return 1;

  /* See ctf_link_add_ctf.  */
#if defined (PIC) || !NOBFD
  input->clin_arc = ctf_open (input->clin_filename, NULL, &err);
#else
  ctf_err_warn (fp, 0, ECTF_NEEDSBFD, _("cannot open %s lazily"),
		input->clin_filename);
  return ctf_set_errno (fp, ECTF_NEEDSBFD);
#endif

  /* Having no CTF sections is not an error.  We just don't need to do
     anything.  */

  if (!input->clin_arc)
    {
      if (err == ECTF_NOCTFDATA)
	return 0;

      ctf_err_warn (fp, 0, err, _("opening CTF %s failed"),
		    input->clin_filename);
      return ctf_set_errno (fp, err);
    }

  if ((count = ctf_archive_count (input->clin_arc)) == 0)
    ctf_arc_close (input->clin_arc);

  return (ssize_t) count;
}

/* Find a non-clashing unique name for a per-CU output dict, to prevent distinct
   members corresponding to inputs with identical cunames from overwriting each
   other.  The name should be something like NAME.  */

static char *
ctf_new_per_cu_name (ctf_dict_t *fp, const char *name)
{
  char *dynname;
  long int i = 0;

  if ((dynname = strdup (name)) == NULL)
    return NULL;

  while ((ctf_dynhash_lookup (fp->ctf_link_outputs, dynname)) != NULL)
    {
      free (dynname);
      if (asprintf (&dynname, "%s#%li", name, i++) < 0)
	return NULL;
    }

  return dynname;
}

/* Return a per-CU output CTF dictionary suitable for the given INPUT or CU,
   creating and interning it if need be.  */

static ctf_dict_t *
ctf_create_per_cu (ctf_dict_t *fp, ctf_dict_t *input, const char *cu_name)
{
  ctf_dict_t *cu_fp;
  const char *ctf_name = NULL;
  char *dynname = NULL;

  /* Already has a per-CU mapping?  Just return it.  */

  if (input && input->ctf_link_in_out)
    return input->ctf_link_in_out;

  /* Check the mapping table and translate the per-CU name we use
     accordingly.  */

  if (cu_name == NULL)
    cu_name = ctf_unnamed_cuname (input);

  if (fp->ctf_link_in_cu_mapping)
    {
      if ((ctf_name = ctf_dynhash_lookup (fp->ctf_link_in_cu_mapping,
					  cu_name)) == NULL)
	ctf_name = cu_name;
    }

  if (ctf_name == NULL)
    ctf_name = cu_name;

  /* Look up the per-CU dict.  If we don't know of one, or it is for a different input
     CU which just happens to have the same name, create a new one.  If we are creating
     a dict with no input specified, anything will do.  */

  if ((cu_fp = ctf_dynhash_lookup (fp->ctf_link_outputs, ctf_name)) == NULL
      || (input && cu_fp->ctf_link_in_out != fp))
    {
      int err;

      if ((cu_fp = ctf_create (&err)) == NULL)
	{
	  ctf_set_errno (fp, err);
	  ctf_err_warn (fp, 0, 0, _("cannot create per-CU CTF archive for "
				    "input CU %s"), cu_name);
	  return NULL;
	}

      ctf_import_unref (cu_fp, fp);

      if ((dynname = ctf_new_per_cu_name (fp, ctf_name)) == NULL)
	goto oom;

      ctf_cuname_set (cu_fp, cu_name);

      ctf_parent_name_set (cu_fp, _CTF_SECTION);
      cu_fp->ctf_link_in_out = fp;
      fp->ctf_link_in_out = cu_fp;

      if (ctf_dynhash_insert (fp->ctf_link_outputs, dynname, cu_fp) < 0)
	goto oom;
    }
  return cu_fp;

 oom:
  free (dynname);
  ctf_dict_close (cu_fp);
  ctf_set_errno (fp, ENOMEM);
  return NULL;
}

/* Add a mapping directing that the CU named FROM should have its
   conflicting/non-duplicate types (depending on link mode) go into a dict
   named TO.  Many FROMs can share a TO, but adding the same FROM with
   a different TO will replace the old mapping.

   We forcibly add a dict named TO in every case, even though it may well
   wind up empty, because clients that use this facility usually expect to find
   every TO dict present, even if empty, and malfunction otherwise.  */

int
ctf_link_add_cu_mapping (ctf_dict_t *fp, const char *from, const char *to)
{
  int err;
  char *f = NULL, *t = NULL, *existing;
  ctf_dynhash_t *one_out;

  /* Mappings cannot be set up if per-CU output dicts already exist.  */
  if (fp->ctf_link_outputs && ctf_dynhash_elements (fp->ctf_link_outputs) != 0)
      return (ctf_set_errno (fp, ECTF_LINKADDEDLATE));

  if (fp->ctf_link_in_cu_mapping == NULL)
    fp->ctf_link_in_cu_mapping = ctf_dynhash_create (ctf_hash_string,
						     ctf_hash_eq_string, free,
						     free);
  if (fp->ctf_link_in_cu_mapping == NULL)
    goto oom;

  if (fp->ctf_link_out_cu_mapping == NULL)
    fp->ctf_link_out_cu_mapping = ctf_dynhash_create (ctf_hash_string,
						      ctf_hash_eq_string, free,
						      (ctf_hash_free_fun)
						      ctf_dynhash_destroy);
  if (fp->ctf_link_out_cu_mapping == NULL)
    goto oom;

  /* If this FROM already exists, remove the mapping from both the FROM->TO
     and the TO->FROM lists: the user wants to change it.  */

  if ((existing = ctf_dynhash_lookup (fp->ctf_link_in_cu_mapping, from)) != NULL)
    {
      one_out = ctf_dynhash_lookup (fp->ctf_link_out_cu_mapping, existing);
      if (!ctf_assert (fp, one_out))
	return -1;				/* errno is set for us.  */

      ctf_dynhash_remove (one_out, from);
      ctf_dynhash_remove (fp->ctf_link_in_cu_mapping, from);
    }

  f = strdup (from);
  t = strdup (to);
  if (!f || !t)
    goto oom;

  /* Track both in a list from FROM to TO and in a list from TO to a list of
     FROM.  The former is used to create TUs with the mapped-to name at need:
     the latter is used in deduplicating links to pull in all input CUs
     corresponding to a single output CU.  */

  if ((err = ctf_dynhash_insert (fp->ctf_link_in_cu_mapping, f, t)) < 0)
    {
      ctf_set_errno (fp, err);
      goto oom_noerrno;
    }

  /* f and t are now owned by the in_cu_mapping: reallocate them.  */
  f = strdup (from);
  t = strdup (to);
  if (!f || !t)
    goto oom;

  if ((one_out = ctf_dynhash_lookup (fp->ctf_link_out_cu_mapping, t)) == NULL)
    {
      if ((one_out = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
					 free, NULL)) == NULL)
	goto oom;
      if ((err = ctf_dynhash_insert (fp->ctf_link_out_cu_mapping,
				     t, one_out)) < 0)
	{
	  ctf_dynhash_destroy (one_out);
	  ctf_set_errno (fp, err);
	  goto oom_noerrno;
	}
    }
  else
    {
      free (t);
      t = NULL;
    }

  if (ctf_dynhash_insert (one_out, f, NULL) < 0)
    {
      ctf_set_errno (fp, err);
      goto oom_noerrno;
    }

  return 0;

 oom:
  ctf_set_errno (fp, errno);
 oom_noerrno:
  free (f);
  free (t);
  return -1;
}

/* Set a function which is called to transform the names of archive members.
   This is useful for applying regular transformations to many names, where
   ctf_link_add_cu_mapping applies arbitrarily irregular changes to single
   names.  The member name changer is applied at ctf_link_write time, so it
   cannot conflate multiple CUs into one the way ctf_link_add_cu_mapping can.
   The changer function accepts a name and should return a new
   dynamically-allocated name, or NULL if the name should be left unchanged.  */
void
ctf_link_set_memb_name_changer (ctf_dict_t *fp,
				ctf_link_memb_name_changer_f *changer,
				void *arg)
{
  fp->ctf_link_memb_name_changer = changer;
  fp->ctf_link_memb_name_changer_arg = arg;
}

/* Set a function which is used to filter out unwanted variables from the link.  */
int
ctf_link_set_variable_filter (ctf_dict_t *fp, ctf_link_variable_filter_f *filter,
			      void *arg)
{
  fp->ctf_link_variable_filter = filter;
  fp->ctf_link_variable_filter_arg = arg;
  return 0;
}

/* Check if we can safely add a variable with the given type to this dict.  */

static int
check_variable (const char *name, ctf_dict_t *fp, ctf_id_t type,
		ctf_dvdef_t **out_dvd)
{
  ctf_dvdef_t *dvd;

  dvd = ctf_dynhash_lookup (fp->ctf_dvhash, name);
  *out_dvd = dvd;
  if (!dvd)
    return 1;

  if (dvd->dvd_type != type)
    {
      /* Variable here.  Wrong type: cannot add.  Just skip it, because there is
	 no way to express this in CTF.  Don't even warn: this case is too
	 common.  (This might be the parent, in which case we'll try adding in
	 the child first, and only then give up.)  */
      ctf_dprintf ("Inexpressible duplicate variable %s skipped.\n", name);
    }

  return 0;				      /* Already exists.  */
}

/* Link one variable named NAME of type TYPE found in IN_FP into FP.  */

static int
ctf_link_one_variable (ctf_dict_t *fp, ctf_dict_t *in_fp, const char *name,
		       ctf_id_t type, int cu_mapped)
{
  ctf_dict_t *per_cu_out_fp;
  ctf_id_t dst_type = 0;
  ctf_dvdef_t *dvd;

  /* See if this variable is filtered out.  */

  if (fp->ctf_link_variable_filter)
    {
      void *farg = fp->ctf_link_variable_filter_arg;
      if (fp->ctf_link_variable_filter (in_fp, name, type, farg))
	return 0;
    }

  /* If this type is mapped to a type in the parent dict, we want to try to add
     to that first: if it reports a duplicate, or if the type is in a child
     already, add straight to the child.  */

  if ((dst_type = ctf_dedup_type_mapping (fp, in_fp, type)) == CTF_ERR)
    return -1;					/* errno is set for us.  */

  if (dst_type != 0)
    {
      if (!ctf_assert (fp, ctf_type_isparent (fp, dst_type)))
	return -1;				/* errno is set for us.  */

      if (check_variable (name, fp, dst_type, &dvd))
	{
	  /* No variable here: we can add it.  */
	  if (ctf_add_variable (fp, name, dst_type) < 0)
	    return -1; 				/* errno is set for us.  */
	  return 0;
	}

      /* Already present?  Nothing to do.  */
      if (dvd && dvd->dvd_type == dst_type)
	return 0;
    }

  /* Can't add to the parent due to a name clash, or because it references a
     type only present in the child.  Try adding to the child, creating if need
     be.  If we can't do that, skip it.  Don't add to a child if we're doing a
     CU-mapped link, since that has only one output.  */

  if (cu_mapped)
    {
      ctf_dprintf ("Variable %s in input file %s depends on a type %lx hidden "
		   "due to conflicts: skipped.\n", name,
		   ctf_unnamed_cuname (in_fp), type);
      return 0;
    }

  if ((per_cu_out_fp = ctf_create_per_cu (fp, in_fp, NULL)) == NULL)
    return -1;					/* errno is set for us.  */

  /* If the type was not found, check for it in the child too.  */
  if (dst_type == 0)
    {
      if ((dst_type = ctf_dedup_type_mapping (per_cu_out_fp,
					      in_fp, type)) == CTF_ERR)
	return -1;				/* errno is set for us.   */

      if (dst_type == 0)
	{
	  ctf_err_warn (fp, 1, 0, _("type %lx for variable %s in input file %s "
				    "not found: skipped"), type, name,
			ctf_unnamed_cuname (in_fp));
	  /* Do not terminate the link: just skip the variable.  */
	  return 0;
	}
    }

  if (check_variable (name, per_cu_out_fp, dst_type, &dvd))
    if (ctf_add_variable (per_cu_out_fp, name, dst_type) < 0)
      return (ctf_set_errno (fp, ctf_errno (per_cu_out_fp)));
  return 0;
}

typedef struct link_sort_inputs_cb_arg
{
  int is_cu_mapped;
  ctf_dict_t *fp;
} link_sort_inputs_cb_arg_t;

/* Sort the inputs by N (the link order).  For CU-mapped links, this is a
   mapping of input to output name, not a mapping of input name to input
   ctf_link_input_t: compensate accordingly.  */
static int
ctf_link_sort_inputs (const ctf_next_hkv_t *one, const ctf_next_hkv_t *two,
		      void *arg)
{
  ctf_link_input_t *input_1;
  ctf_link_input_t *input_2;
  link_sort_inputs_cb_arg_t *cu_mapped = (link_sort_inputs_cb_arg_t *) arg;

  if (!cu_mapped || !cu_mapped->is_cu_mapped)
    {
      input_1 = (ctf_link_input_t *) one->hkv_value;
      input_2 = (ctf_link_input_t *) two->hkv_value;
    }
  else
    {
      const char *name_1 = (const char *) one->hkv_key;
      const char *name_2 = (const char *) two->hkv_key;

      input_1 = ctf_dynhash_lookup (cu_mapped->fp->ctf_link_inputs, name_1);
      input_2 = ctf_dynhash_lookup (cu_mapped->fp->ctf_link_inputs, name_2);

      /* There is no guarantee that CU-mappings actually have corresponding
	 inputs: the relative ordering in that case is unimportant.  */
      if (!input_1)
	return -1;
      if (!input_2)
	return 1;
    }

  if (input_1->n < input_2->n)
    return -1;
  else if (input_1->n > input_2->n)
    return 1;
  else
    return 0;
}

/* Count the number of input dicts in the ctf_link_inputs, or that subset of the
   ctf_link_inputs given by CU_NAMES if set.  Return the number of input dicts,
   and optionally the name and ctf_link_input_t of the single input archive if
   only one exists (no matter how many dicts it contains).  */
static ssize_t
ctf_link_deduplicating_count_inputs (ctf_dict_t *fp, ctf_dynhash_t *cu_names,
				     ctf_link_input_t **only_one_input)
{
  ctf_dynhash_t *inputs = fp->ctf_link_inputs;
  ctf_next_t *i = NULL;
  void *name, *input;
  ctf_link_input_t *one_input = NULL;
  const char *one_name = NULL;
  ssize_t count = 0, narcs = 0;
  int err;

  if (cu_names)
    inputs = cu_names;

  while ((err = ctf_dynhash_next (inputs, &i, &name, &input)) == 0)
    {
      ssize_t one_count;

      one_name = (const char *) name;
      /* If we are processing CU names, get the real input.  */
      if (cu_names)
	one_input = ctf_dynhash_lookup (fp->ctf_link_inputs, one_name);
      else
	one_input = (ctf_link_input_t *) input;

      if (!one_input)
	continue;

      one_count = ctf_link_lazy_open (fp, one_input);

      if (one_count < 0)
	{
	  ctf_next_destroy (i);
	  return -1;				/* errno is set for us.  */
	}

      count += one_count;
      narcs++;
    }
  if (err != ECTF_NEXT_END)
    {
      ctf_err_warn (fp, 0, err, _("iteration error counting deduplicating "
				  "CTF link inputs"));
      return ctf_set_errno (fp, err);
    }

  if (!count)
    return 0;

  if (narcs == 1)
    {
      if (only_one_input)
	*only_one_input = one_input;
    }
  else if (only_one_input)
    *only_one_input = NULL;

  return count;
}

/* Allocate and populate an inputs array big enough for a given set of inputs:
   either a specific set of CU names (those from that set found in the
   ctf_link_inputs), or the entire ctf_link_inputs (if cu_names is not set).
   The number of inputs (from ctf_link_deduplicating_count_inputs, above) is
   passed in NINPUTS: an array of uint32_t containing parent pointers
   (corresponding to those members of the inputs that have parents) is allocated
   and returned in PARENTS.

   The inputs are *archives*, not files: the archive can have multiple members
   if it is the result of a previous incremental link.  We want to add every one
   in turn, including the shared parent.  (The dedup machinery knows that a type
   used by a single dictionary and its parent should not be shared in
   CTF_LINK_SHARE_DUPLICATED mode.)

   If no inputs exist that correspond to these CUs, return NULL with the errno
   set to ECTF_NOCTFDATA.  */
static ctf_dict_t **
ctf_link_deduplicating_open_inputs (ctf_dict_t *fp, ctf_dynhash_t *cu_names,
				    ssize_t ninputs, uint32_t **parents)
{
  ctf_dynhash_t *inputs = fp->ctf_link_inputs;
  ctf_next_t *i = NULL;
  void *name, *input;
  link_sort_inputs_cb_arg_t sort_arg;
  ctf_dict_t **dedup_inputs = NULL;
  ctf_dict_t **walk;
  uint32_t *parents_ = NULL;
  int err;

  if (cu_names)
    inputs = cu_names;

  if ((dedup_inputs = calloc (ninputs, sizeof (ctf_dict_t *))) == NULL)
    goto oom;

  if ((parents_ = calloc (ninputs, sizeof (uint32_t))) == NULL)
    goto oom;

  walk = dedup_inputs;

  /* Counting done: push every input into the array, in the order they were
     passed to ctf_link_add_ctf (and ultimately ld).  */

  sort_arg.is_cu_mapped = (cu_names != NULL);
  sort_arg.fp = fp;

  while ((err = ctf_dynhash_next_sorted (inputs, &i, &name, &input,
					 ctf_link_sort_inputs, &sort_arg)) == 0)
    {
      const char *one_name = (const char *) name;
      ctf_link_input_t *one_input;
      ctf_dict_t *one_fp;
      ctf_dict_t *parent_fp = NULL;
      uint32_t parent_i = 0;
      ctf_next_t *j = NULL;

      /* If we are processing CU names, get the real input.  All the inputs
	 will have been opened, if they contained any CTF at all.  */
      if (cu_names)
	one_input = ctf_dynhash_lookup (fp->ctf_link_inputs, one_name);
      else
	one_input = (ctf_link_input_t *) input;

      if (!one_input || (!one_input->clin_arc && !one_input->clin_fp))
	continue;

      /* Short-circuit: if clin_fp is set, just use it.   */
      if (one_input->clin_fp)
	{
	  parents_[walk - dedup_inputs] = walk - dedup_inputs;
	  *walk = one_input->clin_fp;
	  walk++;
	  continue;
	}

      /* Get and insert the parent archive (if any), if this archive has
	 multiple members.  We assume, as elsewhere, that the parent is named
	 _CTF_SECTION.  */

      if ((parent_fp = ctf_dict_open (one_input->clin_arc, _CTF_SECTION,
				      &err)) == NULL)
	{
	  if (err != ECTF_NOMEMBNAM)
	    {
	      ctf_next_destroy (i);
	      ctf_set_errno (fp, err);
	      goto err;
	    }
	}
      else
	{
	  *walk = parent_fp;
	  parent_i = walk - dedup_inputs;
	  walk++;
	}

      /* We disregard the input archive name: either it is the parent (which we
	 already have), or we want to put everything into one TU sharing the
	 cuname anyway (if this is a CU-mapped link), or this is the final phase
	 of a relink with CU-mapping off (i.e. ld -r) in which case the cuname
	 is correctly set regardless.  */
      while ((one_fp = ctf_archive_next (one_input->clin_arc, &j, NULL,
					 1, &err)) != NULL)
	{
	  if (one_fp->ctf_flags & LCTF_CHILD)
	    {
	      /* The contents of the parents array for elements not
		 corresponding to children is undefined.  If there is no parent
		 (itself a sign of a likely linker bug or corrupt input), we set
		 it to itself.  */

	      ctf_import (one_fp, parent_fp);
	      if (parent_fp)
		parents_[walk - dedup_inputs] = parent_i;
	      else
		parents_[walk - dedup_inputs] = walk - dedup_inputs;
	    }
	  *walk = one_fp;
	  walk++;
	}
      if (err != ECTF_NEXT_END)
	{
	  ctf_next_destroy (i);
	  goto iterr;
	}
    }
  if (err != ECTF_NEXT_END)
    goto iterr;

  *parents = parents_;

  return dedup_inputs;

 oom:
  err = ENOMEM;

 iterr:
  ctf_set_errno (fp, err);

 err:
  free (dedup_inputs);
  free (parents_);
  ctf_err_warn (fp, 0, 0, _("error in deduplicating CTF link "
			    "input allocation"));
  return NULL;
}

/* Close INPUTS that have already been linked, first the passed array, and then
   that subset of the ctf_link_inputs archives they came from cited by the
   CU_NAMES.  If CU_NAMES is not specified, close all the ctf_link_inputs in one
   go, leaving it empty.  */
static int
ctf_link_deduplicating_close_inputs (ctf_dict_t *fp, ctf_dynhash_t *cu_names,
				     ctf_dict_t **inputs, ssize_t ninputs)
{
  ctf_next_t *it = NULL;
  void *name;
  int err;
  ssize_t i;

  /* This is the inverse of ctf_link_deduplicating_open_inputs: so first, close
     all the individual input dicts, opened by the archive iterator.  */
  for (i = 0; i < ninputs; i++)
    ctf_dict_close (inputs[i]);

  /* Now close the archives they are part of.  */
  if (cu_names)
    {
      while ((err = ctf_dynhash_next (cu_names, &it, &name, NULL)) == 0)
	{
	  /* Remove the input from the linker inputs, if it exists, which also
	     closes it.  */

	  ctf_dynhash_remove (fp->ctf_link_inputs, (const char *) name);
	}
      if (err != ECTF_NEXT_END)
	{
	  ctf_set_errno (fp, err);
	  ctf_err_warn (fp, 0, 0, _("iteration error in deduplicating link "
				    "input freeing"));
	}
    }
  else
    ctf_dynhash_empty (fp->ctf_link_inputs);

  return 0;
}

/* Do a deduplicating link of all variables in the inputs.

   Also, if we are not omitting the variable section, integrate all symbols from
   the symtypetabs into the variable section too.  (Duplication with the
   symtypetab section in the output will be eliminated at serialization time.)  */

static int
ctf_link_deduplicating_variables (ctf_dict_t *fp, ctf_dict_t **inputs,
				  size_t ninputs, int cu_mapped)
{
  size_t i;

  for (i = 0; i < ninputs; i++)
    {
      ctf_next_t *it = NULL;
      ctf_id_t type;
      const char *name;

      /* First the variables on the inputs.  */

      while ((type = ctf_variable_next (inputs[i], &it, &name)) != CTF_ERR)
	{
	  if (ctf_link_one_variable (fp, inputs[i], name, type, cu_mapped) < 0)
	    {
	      ctf_next_destroy (it);
	      return -1;			/* errno is set for us.  */
	    }
	}
      if (ctf_errno (inputs[i]) != ECTF_NEXT_END)
	return ctf_set_errno (fp, ctf_errno (inputs[i]));

      /* Next the symbols.  We integrate data symbols even though the compiler
	 is currently doing the same, to allow the compiler to stop in
	 future.  */

      while ((type = ctf_symbol_next (inputs[i], &it, &name, 0)) != CTF_ERR)
	{
	  if (ctf_link_one_variable (fp, inputs[i], name, type, 1) < 0)
	    {
	      ctf_next_destroy (it);
	      return -1;			/* errno is set for us.  */
	    }
	}
      if (ctf_errno (inputs[i]) != ECTF_NEXT_END)
	return ctf_set_errno (fp, ctf_errno (inputs[i]));

      /* Finally the function symbols.  */

      while ((type = ctf_symbol_next (inputs[i], &it, &name, 1)) != CTF_ERR)
	{
	  if (ctf_link_one_variable (fp, inputs[i], name, type, 1) < 0)
	    {
	      ctf_next_destroy (it);
	      return -1;			/* errno is set for us.  */
	    }
	}
      if (ctf_errno (inputs[i]) != ECTF_NEXT_END)
	return ctf_set_errno (fp, ctf_errno (inputs[i]));
    }
  return 0;
}

/* Check for symbol conflicts during linking.  Three possibilities: already
   exists, conflicting, or nonexistent.  We don't have a dvd structure we can
   use as a flag like check_variable does, so we use a tristate return
   value instead: -1: conflicting; 1: nonexistent: 0: already exists.  */

static int
check_sym (ctf_dict_t *fp, const char *name, ctf_id_t type, int functions)
{
  ctf_dynhash_t *thishash = functions ? fp->ctf_funchash : fp->ctf_objthash;
  ctf_dynhash_t *thathash = functions ? fp->ctf_objthash : fp->ctf_funchash;
  void *value;

  /* Wrong type (function when object is wanted, etc).  */
  if (ctf_dynhash_lookup_kv (thathash, name, NULL, NULL))
    return -1;

  /* Not present at all yet.  */
  if (!ctf_dynhash_lookup_kv (thishash, name, NULL, &value))
    return 1;

  /* Already present.  */
  if ((ctf_id_t) (uintptr_t) value == type)
    return 0;

  /* Wrong type.  */
  return -1;
}

/* Do a deduplicating link of one symtypetab (function info or data object) in
   one input dict.  */

static int
ctf_link_deduplicating_one_symtypetab (ctf_dict_t *fp, ctf_dict_t *input,
				       int cu_mapped, int functions)
{
  ctf_next_t *it = NULL;
  const char *name;
  ctf_id_t type;

  while ((type = ctf_symbol_next (input, &it, &name, functions)) != CTF_ERR)
    {
      ctf_id_t dst_type;
      ctf_dict_t *per_cu_out_fp;
      int sym;

      /* Look in the parent first.  */

      if ((dst_type = ctf_dedup_type_mapping (fp, input, type)) == CTF_ERR)
	return -1;				/* errno is set for us.  */

      if (dst_type != 0)
	{
	  if (!ctf_assert (fp, ctf_type_isparent (fp, dst_type)))
	    return -1;				/* errno is set for us.  */

	  sym = check_sym (fp, name, dst_type, functions);

	  /* Already present: next symbol.  */
	  if (sym == 0)
	    continue;
	  /* Not present: add it.  */
	  else if (sym > 0)
	    {
	      if (ctf_add_funcobjt_sym (fp, functions,
					name, dst_type) < 0)
		return -1; 			/* errno is set for us.  */
	      continue;
	    }
	}

      /* Can't add to the parent due to a name clash (most unlikely), or because
	 it references a type only present in the child.  Try adding to the
	 child, creating if need be.  If we can't do that, skip it.  Don't add
	 to a child if we're doing a CU-mapped link, since that has only one
	 output.  */
      if (cu_mapped)
	{
	  ctf_dprintf ("Symbol %s in input file %s depends on a type %lx "
		       "hidden due to conflicts: skipped.\n", name,
		       ctf_unnamed_cuname (input), type);
	  continue;
	}

      if ((per_cu_out_fp = ctf_create_per_cu (fp, input, NULL)) == NULL)
	return -1;				/* errno is set for us.  */

      /* If the type was not found, check for it in the child too.  */
      if (dst_type == 0)
	{
	  if ((dst_type = ctf_dedup_type_mapping (per_cu_out_fp,
						  input, type)) == CTF_ERR)
	    return -1;				/* errno is set for us.  */

	  if (dst_type == 0)
	    {
	      ctf_err_warn (fp, 1, 0,
			    _("type %lx for symbol %s in input file %s "
			      "not found: skipped"), type, name,
			    ctf_unnamed_cuname (input));
	      continue;
	    }
	}

      sym = check_sym (per_cu_out_fp, name, dst_type, functions);

      /* Already present: next symbol.  */
      if (sym == 0)
	continue;
      /* Not present: add it.  */
      else if (sym > 0)
	{
	  if (ctf_add_funcobjt_sym (per_cu_out_fp, functions,
				    name, dst_type) < 0)
	    return -1;				/* errno is set for us.  */
	}
      else
	{
	  /* Perhaps this should be an assertion failure.  */
	  ctf_err_warn (fp, 0, ECTF_DUPLICATE,
			_("symbol %s in input file %s found conflicting "
			  "even when trying in per-CU dict."), name,
			ctf_unnamed_cuname (input));
	  return (ctf_set_errno (fp, ECTF_DUPLICATE));
	}
    }
  if (ctf_errno (input) != ECTF_NEXT_END)
    {
      ctf_set_errno (fp, ctf_errno (input));
      ctf_err_warn (fp, 0, 0, functions ?
		    _("iterating over function symbols") :
		    _("iterating over data symbols"));
      return -1;
    }

  return 0;
}

/* Do a deduplicating link of the function info and data objects
   in the inputs.  */
static int
ctf_link_deduplicating_syms (ctf_dict_t *fp, ctf_dict_t **inputs,
			     size_t ninputs, int cu_mapped)
{
  size_t i;

  for (i = 0; i < ninputs; i++)
    {
      if (ctf_link_deduplicating_one_symtypetab (fp, inputs[i],
						 cu_mapped, 0) < 0)
	return -1;				/* errno is set for us.  */

      if (ctf_link_deduplicating_one_symtypetab (fp, inputs[i],
						 cu_mapped, 1) < 0)
	return -1;				/* errno is set for us.  */
    }

  return 0;
}

/* Do the per-CU part of a deduplicating link.  */
static int
ctf_link_deduplicating_per_cu (ctf_dict_t *fp)
{
  ctf_next_t *i = NULL;
  int err;
  void *out_cu;
  void *in_cus;

  /* Links with a per-CU mapping in force get a first pass of deduplication,
     dedupping the inputs for a given CU mapping into the output for that
     mapping.  The outputs from this process get fed back into the final pass
     that is carried out even for non-CU links.  */

  while ((err = ctf_dynhash_next (fp->ctf_link_out_cu_mapping, &i, &out_cu,
				  &in_cus)) == 0)
    {
      const char *out_name = (const char *) out_cu;
      ctf_dynhash_t *in = (ctf_dynhash_t *) in_cus;
      ctf_dict_t *out = NULL;
      ctf_dict_t **inputs;
      ctf_dict_t **outputs;
      ctf_archive_t *in_arc;
      ssize_t ninputs;
      ctf_link_input_t *only_input;
      uint32_t noutputs;
      uint32_t *parents;

      if ((ninputs = ctf_link_deduplicating_count_inputs (fp, in,
							  &only_input)) == -1)
	goto err_open_inputs;

      /* CU mapping with no inputs?  Skip.  */
      if (ninputs == 0)
	continue;

      if (labs ((long int) ninputs) > 0xfffffffe)
	{
	  ctf_set_errno (fp, EFBIG);
	  ctf_err_warn (fp, 0, 0, _("too many inputs in deduplicating "
				    "link: %li"), (long int) ninputs);
	  goto err_open_inputs;
	}

      /* Short-circuit: a cu-mapped link with only one input archive with
	 unconflicting contents is a do-nothing, and we can just leave the input
	 in place: we do have to change the cuname, though, so we unwrap it,
	 change the cuname, then stuff it back in the linker input again, via
	 the clin_fp short-circuit member.  ctf_link_deduplicating_open_inputs
	 will spot this member and jam it straight into the next link phase,
	 ignoring the corresponding archive.  */
      if (only_input && ninputs == 1)
	{
	  ctf_next_t *ai = NULL;
	  int err;

	  /* We can abuse an archive iterator to get the only member cheaply, no
	     matter what its name.  */
	  only_input->clin_fp = ctf_archive_next (only_input->clin_arc,
						  &ai, NULL, 0, &err);
	  if (!only_input->clin_fp)
	    {
	      ctf_set_errno (fp, err);
	      ctf_err_warn (fp, 0, 0, _("cannot open archive %s in "
					"CU-mapped CTF link"),
			    only_input->clin_filename);
	      goto err_open_inputs;
	    }
	  ctf_next_destroy (ai);

	  if (strcmp (only_input->clin_filename, out_name) != 0)
	    {
	      /* Renaming. We need to add a new input, then null out the
		 clin_arc and clin_fp of the old one to stop it being
		 auto-closed on removal.  The new input needs its cuname changed
		 to out_name, which is doable only because the cuname is a
		 dynamic property which can be changed even in readonly
		 dicts. */

	      ctf_cuname_set (only_input->clin_fp, out_name);
	      if (ctf_link_add_ctf_internal (fp, only_input->clin_arc,
					     only_input->clin_fp,
					     out_name) < 0)
		{
		  ctf_err_warn (fp, 0, 0, _("cannot add intermediate files "
					    "to link"));
		  goto err_open_inputs;
		}
	      only_input->clin_arc = NULL;
	      only_input->clin_fp = NULL;
	      ctf_dynhash_remove (fp->ctf_link_inputs,
				  only_input->clin_filename);
	    }
	  continue;
	}

      /* This is a real CU many-to-one mapping: we must dedup the inputs into
	 a new output to be used in the final link phase.  */

      if ((inputs = ctf_link_deduplicating_open_inputs (fp, in, ninputs,
							&parents)) == NULL)
	{
	  ctf_next_destroy (i);
	  goto err_inputs;
	}

      if ((out = ctf_create (&err)) == NULL)
	{
	  ctf_err_warn (fp, 0, err, _("cannot create per-CU CTF archive "
				      "for %s"),
			out_name);
	  ctf_set_errno (fp, err);
	  goto err_inputs;
	}

      /* Share the atoms table to reduce memory usage.  */
      out->ctf_dedup_atoms = fp->ctf_dedup_atoms_alloc;

      /* No ctf_imports at this stage: this per-CU dictionary has no parents.
	 Parent/child deduplication happens in the link's final pass.  However,
	 the cuname *is* important, as it is propagated into the final
	 dictionary.  */
      ctf_cuname_set (out, out_name);

      if (ctf_dedup (out, inputs, ninputs, parents, 1) < 0)
	{
	  ctf_set_errno (fp, ctf_errno (out));
	  ctf_err_warn (fp, 0, 0, _("CU-mapped deduplication failed for %s"),
			out_name);
	  goto err_inputs;
	}

      if ((outputs = ctf_dedup_emit (out, inputs, ninputs, parents,
				     &noutputs, 1)) == NULL)
	{
	  ctf_set_errno (fp, ctf_errno (out));
	  ctf_err_warn (fp, 0, 0, _("CU-mapped deduplicating link type emission "
				     "failed for %s"), out_name);
	  goto err_inputs;
	}
      if (!ctf_assert (fp, noutputs == 1))
	{
	  size_t j;
	  for (j = 1; j < noutputs; j++)
	    ctf_dict_close (outputs[j]);
	  goto err_inputs_outputs;
	}

      if (!(fp->ctf_link_flags & CTF_LINK_OMIT_VARIABLES_SECTION)
	  && ctf_link_deduplicating_variables (out, inputs, ninputs, 1) < 0)
	{
	  ctf_set_errno (fp, ctf_errno (out));
	  ctf_err_warn (fp, 0, 0, _("CU-mapped deduplicating link variable "
				    "emission failed for %s"), out_name);
	  goto err_inputs_outputs;
	}

      ctf_dedup_fini (out, outputs, noutputs);

      /* For now, we omit symbol section linking for CU-mapped links, until it
	 is clear how to unify the symbol table across such links.  (Perhaps we
	 should emit an unconditionally indexed symtab, like the compiler
	 does.)  */

      if (ctf_link_deduplicating_close_inputs (fp, in, inputs, ninputs) < 0)
	{
	  free (inputs);
	  free (parents);
	  goto err_outputs;
	}
      free (inputs);
      free (parents);

      /* Splice any errors or warnings created during this link back into the
	 dict that the caller knows about.  */
      ctf_list_splice (&fp->ctf_errs_warnings, &outputs[0]->ctf_errs_warnings);

      /* This output now becomes an input to the next link phase, with a name
	 equal to the CU name.  We have to wrap it in an archive wrapper
	 first.  */

      if ((in_arc = ctf_new_archive_internal (0, 0, NULL, outputs[0], NULL,
					      NULL, &err)) == NULL)
	{
	  ctf_set_errno (fp, err);
	  goto err_outputs;
	}

      if (ctf_link_add_ctf_internal (fp, in_arc, NULL,
				     ctf_cuname (outputs[0])) < 0)
	{
	  ctf_err_warn (fp, 0, 0, _("cannot add intermediate files to link"));
	  goto err_outputs;
	}

      ctf_dict_close (out);
      free (outputs);
      continue;

    err_inputs_outputs:
      ctf_list_splice (&fp->ctf_errs_warnings, &outputs[0]->ctf_errs_warnings);
      ctf_dict_close (outputs[0]);
      free (outputs);
    err_inputs:
      ctf_link_deduplicating_close_inputs (fp, in, inputs, ninputs);
      ctf_dict_close (out);
      free (inputs);
      free (parents);
    err_open_inputs:
      ctf_next_destroy (i);
      return -1;

    err_outputs:
      ctf_list_splice (&fp->ctf_errs_warnings, &outputs[0]->ctf_errs_warnings);
      ctf_dict_close (outputs[0]);
      free (outputs);
      ctf_next_destroy (i);
      return -1;				/* Errno is set for us.  */
    }
  if (err != ECTF_NEXT_END)
    {
      ctf_err_warn (fp, 0, err, _("iteration error in CU-mapped deduplicating "
				  "link"));
      return ctf_set_errno (fp, err);
    }

  return 0;
}

/* Empty all the ctf_link_outputs.  */
static int
ctf_link_empty_outputs (ctf_dict_t *fp)
{
  ctf_next_t *i = NULL;
  void *v;
  int err;

  ctf_dynhash_empty (fp->ctf_link_outputs);

  while ((err = ctf_dynhash_next (fp->ctf_link_inputs, &i, NULL, &v)) == 0)
    {
      ctf_dict_t *in = (ctf_dict_t *) v;
      in->ctf_link_in_out = NULL;
    }
  if (err != ECTF_NEXT_END)
    {
      fp->ctf_flags &= ~LCTF_LINKING;
      ctf_err_warn (fp, 1, err, _("iteration error removing old outputs"));
      return ctf_set_errno (fp, err);
    }
  return 0;
}

/* Do a deduplicating link using the ctf-dedup machinery.  */
static void
ctf_link_deduplicating (ctf_dict_t *fp)
{
  size_t i;
  ctf_dict_t **inputs, **outputs = NULL;
  ssize_t ninputs;
  uint32_t noutputs;
  uint32_t *parents;

  if (ctf_dedup_atoms_init (fp) < 0)
    {
      ctf_err_warn (fp, 0, 0, _("allocating CTF dedup atoms table"));
      return;					/* Errno is set for us.  */
    }

  if (fp->ctf_link_out_cu_mapping
      && (ctf_link_deduplicating_per_cu (fp) < 0))
    return;					/* Errno is set for us.  */

  if ((ninputs = ctf_link_deduplicating_count_inputs (fp, NULL, NULL)) < 0)
    return;					/* Errno is set for us.  */

  if ((inputs = ctf_link_deduplicating_open_inputs (fp, NULL, ninputs,
						    &parents)) == NULL)
    return;					/* Errno is set for us.  */

  if (ninputs == 1 && ctf_cuname (inputs[0]) != NULL)
    ctf_cuname_set (fp, ctf_cuname (inputs[0]));

  if (ctf_dedup (fp, inputs, ninputs, parents, 0) < 0)
    {
      ctf_err_warn (fp, 0, 0, _("deduplication failed for %s"),
		    ctf_link_input_name (fp));
      goto err;
    }

  if ((outputs = ctf_dedup_emit (fp, inputs, ninputs, parents, &noutputs,
				 0)) == NULL)
    {
      ctf_err_warn (fp, 0, 0, _("deduplicating link type emission failed "
				"for %s"), ctf_link_input_name (fp));
      goto err;
    }

  if (!ctf_assert (fp, outputs[0] == fp))
    {
      for (i = 1; i < noutputs; i++)
	ctf_dict_close (outputs[i]);
      goto err;
    }

  for (i = 0; i < noutputs; i++)
    {
      char *dynname;

      /* We already have access to this one.  Close the duplicate.  */
      if (i == 0)
	{
	  ctf_dict_close (outputs[0]);
	  continue;
	}

      if ((dynname = ctf_new_per_cu_name (fp, ctf_cuname (outputs[i]))) == NULL)
	goto oom_one_output;

      if (ctf_dynhash_insert (fp->ctf_link_outputs, dynname, outputs[i]) < 0)
	goto oom_one_output;

      continue;

    oom_one_output:
      ctf_set_errno (fp, ENOMEM);
      ctf_err_warn (fp, 0, 0, _("out of memory allocating link outputs"));
      free (dynname);

      for (; i < noutputs; i++)
	ctf_dict_close (outputs[i]);
      goto err;
    }

  if (!(fp->ctf_link_flags & CTF_LINK_OMIT_VARIABLES_SECTION)
      && ctf_link_deduplicating_variables (fp, inputs, ninputs, 0) < 0)
    {
      ctf_err_warn (fp, 0, 0, _("deduplicating link variable emission failed for "
				"%s"), ctf_link_input_name (fp));
      goto err_clean_outputs;
    }

  if (ctf_link_deduplicating_syms (fp, inputs, ninputs, 0) < 0)
    {
      ctf_err_warn (fp, 0, 0, _("deduplicating link symbol emission failed for "
				"%s"), ctf_link_input_name (fp));
      goto err_clean_outputs;
    }

  ctf_dedup_fini (fp, outputs, noutputs);

  /* Now close all the inputs, including per-CU intermediates.  */

  if (ctf_link_deduplicating_close_inputs (fp, NULL, inputs, ninputs) < 0)
    return;					/* errno is set for us.  */

  ninputs = 0;					/* Prevent double-close.  */
  ctf_set_errno (fp, 0);

  /* Fall through.  */

 err:
  for (i = 0; i < (size_t) ninputs; i++)
    ctf_dict_close (inputs[i]);
  free (inputs);
  free (parents);
  free (outputs);
  return;

 err_clean_outputs:
  ctf_link_empty_outputs (fp);
  goto err;
}

/* Merge types and variable sections in all dicts added to the link together.
   The result of any previous link is discarded.  */
int
ctf_link (ctf_dict_t *fp, int flags)
{
  int err;

  fp->ctf_link_flags = flags;

  if (fp->ctf_link_inputs == NULL)
    return 0;					/* Nothing to do. */

  if (fp->ctf_link_outputs != NULL)
    ctf_link_empty_outputs (fp);
  else
    fp->ctf_link_outputs = ctf_dynhash_create (ctf_hash_string,
					       ctf_hash_eq_string, free,
					       (ctf_hash_free_fun)
					       ctf_dict_close);

  if (fp->ctf_link_outputs == NULL)
    return ctf_set_errno (fp, ENOMEM);

  fp->ctf_flags |= LCTF_LINKING;
  ctf_link_deduplicating (fp);
  fp->ctf_flags &= ~LCTF_LINKING;

  if ((ctf_errno (fp) != 0) && (ctf_errno (fp) != ECTF_NOCTFDATA))
    return -1;

  /* Create empty CUs if requested.  We do not currently claim that multiple
     links in succession with CTF_LINK_EMPTY_CU_MAPPINGS set in some calls and
     not set in others will do anything especially sensible.  */

  if (fp->ctf_link_out_cu_mapping && (flags & CTF_LINK_EMPTY_CU_MAPPINGS))
    {
      ctf_next_t *i = NULL;
      void *k;

      while ((err = ctf_dynhash_next (fp->ctf_link_out_cu_mapping, &i, &k,
				      NULL)) == 0)
	{
	  const char *to = (const char *) k;
	  if (ctf_create_per_cu (fp, NULL, to) == NULL)
	    {
	      fp->ctf_flags &= ~LCTF_LINKING;
	      ctf_next_destroy (i);
	      return -1;			/* Errno is set for us.  */
	    }
	}
      if (err != ECTF_NEXT_END)
	{
	  fp->ctf_flags &= ~LCTF_LINKING;
	  ctf_err_warn (fp, 1, err, _("iteration error creating empty CUs"));
	  return ctf_set_errno (fp, err);
	}
    }

  return 0;
}

typedef struct ctf_link_out_string_cb_arg
{
  const char *str;
  uint32_t offset;
  int err;
} ctf_link_out_string_cb_arg_t;

/* Intern a string in the string table of an output per-CU CTF file.  */
static void
ctf_link_intern_extern_string (void *key _libctf_unused_, void *value,
			       void *arg_)
{
  ctf_dict_t *fp = (ctf_dict_t *) value;
  ctf_link_out_string_cb_arg_t *arg = (ctf_link_out_string_cb_arg_t *) arg_;

  if (!ctf_str_add_external (fp, arg->str, arg->offset))
    arg->err = ENOMEM;
}

/* Repeatedly call ADD_STRING to acquire strings from the external string table,
   adding them to the atoms table for this CU and all subsidiary CUs.

   Must be called on a dict that has not yet been serialized.

   If ctf_link is also called, it must be called first if you want the new CTF
   files ctf_link can create to get their strings dedupped against the ELF
   strtab properly.  */
int
ctf_link_add_strtab (ctf_dict_t *fp, ctf_link_strtab_string_f *add_string,
		     void *arg)
{
  const char *str;
  uint32_t offset;
  int err = 0;

  if (fp->ctf_stypes > 0)
    return ctf_set_errno (fp, ECTF_RDONLY);

  while ((str = add_string (&offset, arg)) != NULL)
    {
      ctf_link_out_string_cb_arg_t iter_arg = { str, offset, 0 };

      if (!ctf_str_add_external (fp, str, offset))
	err = ENOMEM;

      ctf_dynhash_iter (fp->ctf_link_outputs, ctf_link_intern_extern_string,
			&iter_arg);
      if (iter_arg.err)
	err = iter_arg.err;
    }

  if (err)
    ctf_set_errno (fp, err);

  return -err;
}

/* Inform the ctf-link machinery of a new symbol in the target symbol table
   (which must be some symtab that is not usually stripped, and which
   is in agreement with ctf_bfdopen_ctfsect).  May be called either before or
   after ctf_link_add_strtab.  As with that function, must be called on a dict which
   has not yet been serialized.  */
int
ctf_link_add_linker_symbol (ctf_dict_t *fp, ctf_link_sym_t *sym)
{
  ctf_in_flight_dynsym_t *cid;

  /* Cheat a little: if there is already an ENOMEM error code recorded against
     this dict, we shouldn't even try to add symbols because there will be no
     memory to do so: probably we failed to add some previous symbol.  This
     makes out-of-memory exits 'sticky' across calls to this function, so the
     caller doesn't need to worry about error conditions.  */

  if (ctf_errno (fp) == ENOMEM)
    return -ENOMEM;				/* errno is set for us.  */

  if (fp->ctf_stypes > 0)
    return ctf_set_errno (fp, ECTF_RDONLY);

  if (ctf_symtab_skippable (sym))
    return 0;

  if (sym->st_type != STT_OBJECT && sym->st_type != STT_FUNC)
    return 0;

  /* Add the symbol to the in-flight list.  */

  if ((cid = malloc (sizeof (ctf_in_flight_dynsym_t))) == NULL)
    goto oom;

  cid->cid_sym = *sym;
  ctf_list_append (&fp->ctf_in_flight_dynsyms, cid);

  return 0;

 oom:
  ctf_dynhash_destroy (fp->ctf_dynsyms);
  fp->ctf_dynsyms = NULL;
  ctf_set_errno (fp, ENOMEM);
  return -ENOMEM;
}

/* Impose an ordering on symbols.  The ordering takes effect immediately, but
   since the ordering info does not include type IDs, lookups may return nothing
   until such IDs are added by calls to ctf_add_*_sym.  Must be called after
   ctf_link_add_strtab and ctf_link_add_linker_symbol.  */
int
ctf_link_shuffle_syms (ctf_dict_t *fp)
{
  ctf_in_flight_dynsym_t *did, *nid;
  ctf_next_t *i = NULL;
  int err = ENOMEM;
  void *name_, *sym_;

  if (fp->ctf_stypes > 0)
    return ctf_set_errno (fp, ECTF_RDONLY);

  if (!fp->ctf_dynsyms)
    {
      fp->ctf_dynsyms = ctf_dynhash_create (ctf_hash_string,
					    ctf_hash_eq_string,
					    NULL, free);
      if (!fp->ctf_dynsyms)
	{
	  ctf_set_errno (fp, ENOMEM);
	  return -ENOMEM;
	}
    }

  /* Add all the symbols, excluding only those we already know are prohibited
     from appearing in symtypetabs.  */

  for (did = ctf_list_next (&fp->ctf_in_flight_dynsyms); did != NULL; did = nid)
    {
      ctf_link_sym_t *new_sym;

      nid = ctf_list_next (did);
      ctf_list_delete (&fp->ctf_in_flight_dynsyms, did);

      /* We might get a name or an external strtab offset.  The strtab offset is
	 guaranteed resolvable at this point, so turn it into a string.  */

      if (did->cid_sym.st_name == NULL)
	{
	  uint32_t off = CTF_SET_STID (did->cid_sym.st_nameidx, CTF_STRTAB_1);

	  did->cid_sym.st_name = ctf_strraw (fp, off);
	  did->cid_sym.st_nameidx_set = 0;
	  if (!ctf_assert (fp, did->cid_sym.st_name != NULL))
	    return -ECTF_INTERNAL;		/* errno is set for us.  */
	}

      /* The symbol might have turned out to be nameless, so we have to recheck
	 for skippability here.  */
      if (!ctf_symtab_skippable (&did->cid_sym))
	{
	  ctf_dprintf ("symbol from linker: %s (%x)\n", did->cid_sym.st_name,
		       did->cid_sym.st_symidx);

	  if ((new_sym = malloc (sizeof (ctf_link_sym_t))) == NULL)
	    goto local_oom;

	  memcpy (new_sym, &did->cid_sym, sizeof (ctf_link_sym_t));
	  if (ctf_dynhash_cinsert (fp->ctf_dynsyms, new_sym->st_name, new_sym) < 0)
	    goto local_oom;

	  if (fp->ctf_dynsymmax < new_sym->st_symidx)
	    fp->ctf_dynsymmax = new_sym->st_symidx;
	}

      free (did);
      continue;

    local_oom:
      free (did);
      free (new_sym);
      goto err;
    }

  /* If no symbols are reported, unwind what we have done and return.  This
     makes it a bit easier for the serializer to tell that no symbols have been
     reported and that it should look elsewhere for reported symbols.  */
  if (!ctf_dynhash_elements (fp->ctf_dynsyms))
    {
      ctf_dprintf ("No symbols: not a final link.\n");
      ctf_dynhash_destroy (fp->ctf_dynsyms);
      fp->ctf_dynsyms = NULL;
      return 0;
    }

  /* Construct a mapping from shndx to the symbol info.  */
  free (fp->ctf_dynsymidx);
  if ((fp->ctf_dynsymidx = calloc (fp->ctf_dynsymmax + 1,
				   sizeof (ctf_link_sym_t *))) == NULL)
    goto err;

  while ((err = ctf_dynhash_next (fp->ctf_dynsyms, &i, &name_, &sym_)) == 0)
    {
      const char *name = (const char *) name;
      ctf_link_sym_t *symp = (ctf_link_sym_t *) sym_;

      if (!ctf_assert (fp, symp->st_symidx <= fp->ctf_dynsymmax))
	{
	  ctf_next_destroy (i);
	  err = ctf_errno (fp);
	  goto err;
	}
      fp->ctf_dynsymidx[symp->st_symidx] = symp;
    }
  if (err != ECTF_NEXT_END)
    {
      ctf_err_warn (fp, 0, err, _("error iterating over shuffled symbols"));
      goto err;
    }
  return 0;

 err:
  /* Leave the in-flight symbols around: they'll be freed at
     dict close time regardless.  */
  ctf_dynhash_destroy (fp->ctf_dynsyms);
  fp->ctf_dynsyms = NULL;
  free (fp->ctf_dynsymidx);
  fp->ctf_dynsymidx = NULL;
  fp->ctf_dynsymmax = 0;
  ctf_set_errno (fp, err);
  return -err;
}

typedef struct ctf_name_list_accum_cb_arg
{
  char **names;
  ctf_dict_t *fp;
  ctf_dict_t **files;
  size_t i;
  char **dynames;
  size_t ndynames;
} ctf_name_list_accum_cb_arg_t;

/* Accumulate the names and a count of the names in the link output hash.  */
static void
ctf_accumulate_archive_names (void *key, void *value, void *arg_)
{
  const char *name = (const char *) key;
  ctf_dict_t *fp = (ctf_dict_t *) value;
  char **names;
  ctf_dict_t **files;
  ctf_name_list_accum_cb_arg_t *arg = (ctf_name_list_accum_cb_arg_t *) arg_;

  if ((names = realloc (arg->names, sizeof (char *) * ++(arg->i))) == NULL)
    {
      (arg->i)--;
      ctf_set_errno (arg->fp, ENOMEM);
      return;
    }

  if ((files = realloc (arg->files, sizeof (ctf_dict_t *) * arg->i)) == NULL)
    {
      (arg->i)--;
      ctf_set_errno (arg->fp, ENOMEM);
      return;
    }

  /* Allow the caller to get in and modify the name at the last minute.  If the
     caller *does* modify the name, we have to stash away the new name the
     caller returned so we can free it later on.  (The original name is the key
     of the ctf_link_outputs hash and is freed by the dynhash machinery.)  */

  if (fp->ctf_link_memb_name_changer)
    {
      char **dynames;
      char *dyname;
      void *nc_arg = fp->ctf_link_memb_name_changer_arg;

      dyname = fp->ctf_link_memb_name_changer (fp, name, nc_arg);

      if (dyname != NULL)
	{
	  if ((dynames = realloc (arg->dynames,
				  sizeof (char *) * ++(arg->ndynames))) == NULL)
	    {
	      (arg->ndynames)--;
	      ctf_set_errno (arg->fp, ENOMEM);
	      return;
	    }
	    arg->dynames = dynames;
	    name = (const char *) dyname;
	}
    }

  arg->names = names;
  arg->names[(arg->i) - 1] = (char *) name;
  arg->files = files;
  arg->files[(arg->i) - 1] = fp;
}

/* Change the name of the parent CTF section, if the name transformer has got to
   it.  */
static void
ctf_change_parent_name (void *key _libctf_unused_, void *value, void *arg)
{
  ctf_dict_t *fp = (ctf_dict_t *) value;
  const char *name = (const char *) arg;

  ctf_parent_name_set (fp, name);
}

/* Warn if we may suffer information loss because the CTF input files are too
   old.  Usually we provide complete backward compatibility, but compiler
   changes etc which never hit a release may have a flag in the header that
   simply prevents those changes from being used.  */
static void
ctf_link_warn_outdated_inputs (ctf_dict_t *fp)
{
  ctf_next_t *i = NULL;
  void *name_;
  void *input_;
  int err;

  while ((err = ctf_dynhash_next (fp->ctf_link_inputs, &i, &name_, &input_)) == 0)
    {
      const char *name = (const char *) name_;
      ctf_link_input_t *input = (ctf_link_input_t *) input_;
      ctf_next_t *j = NULL;
      ctf_dict_t *ifp;
      int err;

      /* We only care about CTF archives by this point: lazy-opened archives
	 have always been opened by this point, and short-circuited entries have
	 a matching corresponding archive member. Entries with NULL clin_arc can
	 exist, and constitute old entries renamed via a name changer: the
	 renamed entries exist elsewhere in the list, so we can just skip
	 those.  */

      if (!input->clin_arc)
	continue;

      /* All entries in the archive will necessarily contain the same
	 CTF_F_NEWFUNCINFO flag, so we only need to check the first. We don't
	 even need to do that if we can't open it for any reason at all: the
	 link will fail later on regardless, since an input can't be opened. */

      ifp = ctf_archive_next (input->clin_arc, &j, NULL, 0, &err);
      if (!ifp)
	continue;
      ctf_next_destroy (j);

      if (!(ifp->ctf_header->cth_flags & CTF_F_NEWFUNCINFO)
	  && (ifp->ctf_header->cth_varoff - ifp->ctf_header->cth_funcoff) > 0)
	ctf_err_warn (fp, 1, 0, _("linker input %s has CTF func info but uses "
				  "an old, unreleased func info format: "
				  "this func info section will be dropped."),
		      name);
    }
  if (err != ECTF_NEXT_END)
    ctf_err_warn (fp, 0, err, _("error checking for outdated inputs"));
}

/* Write out a CTF archive (if there are per-CU CTF files) or a CTF file
   (otherwise) into a new dynamically-allocated string, and return it.
   Members with sizes above THRESHOLD are compressed.  */
unsigned char *
ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold)
{
  ctf_name_list_accum_cb_arg_t arg;
  char **names;
  char *transformed_name = NULL;
  ctf_dict_t **files;
  FILE *f = NULL;
  size_t i;
  int err;
  long fsize;
  const char *errloc;
  unsigned char *buf = NULL;

  memset (&arg, 0, sizeof (ctf_name_list_accum_cb_arg_t));
  arg.fp = fp;
  fp->ctf_flags |= LCTF_LINKING;

  ctf_link_warn_outdated_inputs (fp);

  if (fp->ctf_link_outputs)
    {
      ctf_dynhash_iter (fp->ctf_link_outputs, ctf_accumulate_archive_names, &arg);
      if (ctf_errno (fp) < 0)
	{
	  errloc = "hash creation";
	  goto err;
	}
    }

  /* No extra outputs? Just write a simple ctf_dict_t.  */
  if (arg.i == 0)
    {
      unsigned char *ret = ctf_write_mem (fp, size, threshold);
      fp->ctf_flags &= ~LCTF_LINKING;
      return ret;
    }

  /* Writing an archive.  Stick ourselves (the shared repository, parent of all
     other archives) on the front of it with the default name.  */
  if ((names = realloc (arg.names, sizeof (char *) * (arg.i + 1))) == NULL)
    {
      errloc = "name reallocation";
      goto err_no;
    }
  arg.names = names;
  memmove (&(arg.names[1]), arg.names, sizeof (char *) * (arg.i));

  arg.names[0] = (char *) _CTF_SECTION;
  if (fp->ctf_link_memb_name_changer)
    {
      void *nc_arg = fp->ctf_link_memb_name_changer_arg;

      transformed_name = fp->ctf_link_memb_name_changer (fp, _CTF_SECTION,
							 nc_arg);

      if (transformed_name != NULL)
	{
	  arg.names[0] = transformed_name;
	  ctf_dynhash_iter (fp->ctf_link_outputs, ctf_change_parent_name,
			    transformed_name);
	}
    }

  /* Propagate the link flags to all the dicts in this link.  */
  for (i = 0; i < arg.i; i++)
    {
      arg.files[i]->ctf_link_flags = fp->ctf_link_flags;
      arg.files[i]->ctf_flags |= LCTF_LINKING;
    }

  if ((files = realloc (arg.files,
			sizeof (struct ctf_dict *) * (arg.i + 1))) == NULL)
    {
      errloc = "ctf_dict reallocation";
      goto err_no;
    }
  arg.files = files;
  memmove (&(arg.files[1]), arg.files, sizeof (ctf_dict_t *) * (arg.i));
  arg.files[0] = fp;

  if ((f = tmpfile ()) == NULL)
    {
      errloc = "tempfile creation";
      goto err_no;
    }

  if ((err = ctf_arc_write_fd (fileno (f), arg.files, arg.i + 1,
			       (const char **) arg.names,
			       threshold)) < 0)
    {
      errloc = "archive writing";
      ctf_set_errno (fp, err);
      goto err;
    }

  if (fseek (f, 0, SEEK_END) < 0)
    {
      errloc = "seeking to end";
      goto err_no;
    }

  if ((fsize = ftell (f)) < 0)
    {
      errloc = "filesize determination";
      goto err_no;
    }

  if (fseek (f, 0, SEEK_SET) < 0)
    {
      errloc = "filepos resetting";
      goto err_no;
    }

  if ((buf = malloc (fsize)) == NULL)
    {
      errloc = "CTF archive buffer allocation";
      goto err_no;
    }

  while (!feof (f) && fread (buf, fsize, 1, f) == 0)
    if (ferror (f))
      {
	errloc = "reading archive from temporary file";
	goto err_no;
      }

  *size = fsize;
  free (arg.names);
  free (arg.files);
  free (transformed_name);
  if (arg.ndynames)
    {
      size_t i;
      for (i = 0; i < arg.ndynames; i++)
	free (arg.dynames[i]);
      free (arg.dynames);
    }
  fclose (f);
  return buf;

 err_no:
  ctf_set_errno (fp, errno);

  /* Turn off the is-linking flag on all the dicts in this link.  */
  for (i = 0; i < arg.i; i++)
    arg.files[i]->ctf_flags &= ~LCTF_LINKING;
 err:
  free (buf);
  if (f)
    fclose (f);
  free (arg.names);
  free (arg.files);
  free (transformed_name);
  if (arg.ndynames)
    {
      size_t i;
      for (i = 0; i < arg.ndynames; i++)
	free (arg.dynames[i]);
      free (arg.dynames);
    }
  ctf_err_warn (fp, 0, 0, _("cannot write archive in link: %s failure"),
		errloc);
  return NULL;
}
