/* CTF type deduplication.
   Copyright (C) 2019-2022 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>
#include <errno.h>
#include <assert.h>
#include "hashtab.h"

/* (In the below, relevant functions are named in square brackets.)  */

/* Type deduplication is a three-phase process:

    [ctf_dedup, ctf_dedup_hash_type, ctf_dedup_rhash_type]
    1) come up with unambiguous hash values for all types: no two types may have
       the same hash value, and any given type should have only one hash value
       (for optimal deduplication).

    [ctf_dedup, ctf_dedup_detect_name_ambiguity,
     ctf_dedup_conflictify_unshared, ctf_dedup_mark_conflicting_hash]
    2) mark those distinct types with names that collide (and thus cannot be
       declared simultaneously in the same translation unit) as conflicting, and
       recursively mark all types that cite one of those types as conflicting as
       well.  Possibly mark all types cited in only one TU as conflicting, if
       the CTF_LINK_SHARE_DUPLICATED link mode is active.

    [ctf_dedup_emit, ctf_dedup_emit_struct_members, ctf_dedup_id_to_target]
    3) emit all the types, one hash value at a time.  Types not marked
       conflicting are emitted once, into the shared dictionary: types marked
       conflicting are emitted once per TU into a dictionary corresponding to
       each TU in which they appear.  Structs marked conflicting get at the very
       least a forward emitted into the shared dict so that other dicts can cite
       it if needed.

   [id_to_packed_id]
   This all works over an array of inputs (usually in the same order as the
   inputs on the link line).  We don't use the ctf_link_inputs hash directly
   because it is convenient to be able to address specific input types as a
   *global type ID* or 'GID', a pair of an array offset and a ctf_id_t.  Since
   both are already 32 bits or less or can easily be constrained to that range,
   we can pack them both into a single 64-bit hash word for easy lookups, which
   would be much more annoying to do with a ctf_dict_t * and a ctf_id_t.  (On
   32-bit platforms, we must do that anyway, since pointers, and thus hash keys
   and values, are only 32 bits wide).  We track which inputs are parents of
   which other inputs so that we can correctly recognize that types we have
   traversed in children may cite types in parents, and so that we can process
   the parents first.)

   Note that thanks to ld -r, the deduplicator can be fed its own output, so the
   inputs may themselves have child dicts.  Since we need to support this usage
   anyway, we can use it in one other place.  If the caller finds translation
   units to be too small a unit ambiguous types, links can be 'cu-mapped', where
   the caller provides a mapping of input TU names to output child dict names.
   This mapping can fuse many child TUs into one potential child dict, so that
   ambiguous types in any of those input TUs go into the same child dict.
   When a many:1 cu-mapping is detected, the ctf_dedup machinery is called
   repeatedly, once for every output name that has more than one input, to fuse
   all the input TUs associated with a given output dict into one, and once again
   as normal to deduplicate all those intermediate outputs (and any 1:1 inputs)
   together.  This has much higher memory usage than otherwise, because in the
   intermediate state, all the output TUs are in memory at once and cannot be
   lazily opened.  It also has implications for the emission code: if types
   appear ambiguously in multiple input TUs that are all mapped to the same
   child dict, we cannot put them in children in the cu-mapping link phase
   because this output is meant to *become* a child in the next link stage and
   parent/child relationships are only one level deep: so instead, we just hide
   all but one of the ambiguous types.

   There are a few other subtleties here that make this more complex than it
   seems.  Let's go over the steps above in more detail.

   1) HASHING.

   [ctf_dedup_hash_type, ctf_dedup_rhash_type]
   Hashing proceeds recursively, mixing in the properties of each input type
   (including its name, if any), and then adding the hash values of every type
   cited by that type.  The result is stashed in the cd_type_hashes so other
   phases can find the hash values of input types given their IDs, and so that
   if we encounter this type again while hashing we can just return its hash
   value: it is also stashed in the *output mapping*, a mapping from hash value
   to the set of GIDs corresponding to that type in all inputs.  We also keep
   track of the GID of the first appearance of the type in any input (in
   cd_output_first_gid), and the GID of structs, unions, and forwards that only
   appear in one TU (in cd_struct_origin).  See below for where these things are
   used.

   Everything in this phase is time-critical, because it is operating over
   non-deduplicated types and so may have hundreds or thousands of times the
   data volume to deal with than later phases.  Trace output is hidden behind
   ENABLE_LIBCTF_HASH_DEBUGGING to prevent the sheer number of calls to
   ctf_dprintf from slowing things down (tenfold slowdowns are observed purely
   from the calls to ctf_dprintf(), even with debugging switched off), and keep
   down the volume of output (hundreds of gigabytes of debug output are not
   uncommon on larger links).

   We have to do *something* about potential cycles in the type graph.  We'd
   like to avoid emitting forwards in the final output if possible, because
   forwards aren't much use: they have no members.  We are mostly saved from
   needing to worry about this at emission time by ctf_add_struct*()
   automatically replacing newly-created forwards when the real struct/union
   comes along.  So we only have to avoid getting stuck in cycles during the
   hashing phase, while also not confusing types that cite members that are
   structs with each other.  It is easiest to solve this problem by noting two
   things:

    - all cycles in C depend on the presence of tagged structs/unions
    - all tagged structs/unions have a unique name they can be disambiguated by

   [ctf_dedup_is_stub]
   This means that we can break all cycles by ceasing to hash in cited types at
   every tagged struct/union and instead hashing in a stub consisting of the
   struct/union's *decorated name*, which is the name preceded by "s " or "u "
   depending on the namespace (cached in cd_decorated_names).  Forwards are
   decorated identically (so a forward to "struct foo" would be represented as
   "s foo"): this means that a citation of a forward to a type and a citation of
   a concrete definition of a type with the same name ends up getting the same
   hash value.

   Of course, it is quite possible to have two TUs with structs with the same
   name and different definitions, but that's OK because when we scan for types
   with ambiguous names we will identify these and mark them conflicting.

   We populate one thing to help conflictedness marking.  No unconflicted type
   may cite a conflicted one, but this means that conflictedness marking must
   walk from types to the types that cite them, which is the opposite of the
   usual order.  We can make this easier to do by constructing a *citers* graph
   in cd_citers, which points from types to the types that cite them: because we
   emit forwards corresponding to every conflicted struct/union, we don't need
   to do this for citations of structs/unions by other types.  This is very
   convenient for us, because that's the only type we don't traverse
   recursively: so we can construct the citers graph at the same time as we
   hash, rather than needing to add an extra pass.  (This graph is a dynhash of
   *type hash values*, so it's small: in effect it is automatically
   deduplicated.)

   2) COLLISIONAL MARKING.

   [ctf_dedup_detect_name_ambiguity, ctf_dedup_mark_conflicting_hash]
   We identify types whose names collide during the hashing process, and count
   the rough number of uses of each name (caching may throw it off a bit: this
   doesn't need to be accurate).  We then mark the less-frequently-cited types
   with each names conflicting: the most-frequently-cited one goes into the
   shared type dictionary, while all others are duplicated into per-TU
   dictionaries, named after the input TU, that have the shared dictionary as a
   parent.  For structures and unions this is not quite good enough: we'd like
   to have citations of forwards to ambiguously named structures and unions
   *stay* as citations of forwards, so that the user can tell that the caller
   didn't actually know which structure definition was meant: but if we put one
   of those structures into the shared dictionary, it would supplant and replace
   the forward, leaving no sign.  So structures and unions do not take part in
   this popularity contest: if their names are ambiguous, they are just
   duplicated, and only a forward appears in the shared dict.

   [ctf_dedup_propagate_conflictedness]
   The process of marking types conflicted is itself recursive: we recursively
   traverse the cd_citers graph populated in the hashing pass above and mark
   everything that we encounter conflicted (without wasting time re-marking
   anything that is already marked).  This naturally terminates just where we
   want it to (at types that are cited by no other types, and at structures and
   unions) and suffices to ensure that types that cite conflicted types are
   always marked conflicted.

   [ctf_dedup_conflictify_unshared, ctf_dedup_multiple_input_dicts]
   When linking in CTF_LINK_SHARE_DUPLICATED mode, we would like all types that
   are used in only one TU to end up in a per-CU dict. The easiest way to do
   that is to mark them conflicted.  ctf_dedup_conflictify_unshared does this,
   traversing the output mapping and using ctf_dedup_multiple_input_dicts to
   check the number of input dicts each distinct type hash value came from:
   types that only came from one get marked conflicted.  One caveat here is that
   we need to consider both structs and forwards to them: a struct that appears
   in one TU and has a dozen citations to an opaque forward in other TUs should
   *not* be considered to be used in only one TU, because users would find it
   useful to be able to traverse into opaque structures of that sort: so we use
   cd_struct_origin to check both structs/unions and the forwards corresponding
   to them.

   3) EMISSION.

   [ctf_dedup_walk_output_mapping, ctf_dedup_rwalk_output_mapping,
    ctf_dedup_rwalk_one_output_mapping]
   Emission involves another walk of the entire output mapping, this time
   traversing everything other than struct members, recursively.  Types are
   emitted from leaves to trunk, emitting all types a type cites before emitting
   the type itself.  We sort the output mapping before traversing it, for
   reproducibility and also correctness: the input dicts may have parent/child
   relationships, so we simply sort all types that first appear in parents
   before all children, then sort types that first appear in dicts appearing
   earlier on the linker command line before those that appear later, then sort
   by input ctf_id_t.  (This is where we use cd_output_first_gid, collected
   above.)

   The walking is done using a recursive traverser which arranges to not revisit
   any type already visited and to call its callback once per input GID for
   input GIDs corresponding to conflicted output types.  The traverser only
   finds input types and calls a callback for them as many times as the output
   needs to appear: it doesn't try to figure out anything about where the output
   might go.  That's done by the callback based on whether the type is
   marked conflicted or not.

   [ctf_dedup_emit_type, ctf_dedup_id_to_target, ctf_dedup_synthesize_forward]
   ctf_dedup_emit_type is the (sole) callback for ctf_dedup_walk_output_mapping.
   Conflicted types have all necessary dictionaries created, and then we emit
   the type into each dictionary in turn, working over each input CTF type
   corresponding to each hash value and using ctf_dedup_id_to_target to map each
   input ctf_id_t into the corresponding type in the output (dealing with input
   ctf_id_t's with parents in the process by simply chasing to the parent dict
   if the type we're looking up is in there).  Emitting structures involves
   simply noting that the members of this structure need emission later on:
   because you cannot cite a single structure member from another type, we avoid
   emitting the members at this stage to keep recursion depths down a bit.

   At this point, if we have by some mischance decided that two different types
   with child types that hash to different values have in fact got the same hash
   value themselves and *not* marked it conflicting, the type walk will walk
   only *one* of them and in all likelihood we'll find that we are trying to
   emit a type into some child dictionary that references a type that was never
   emitted into that dictionary and assertion-fail.  This always indicates a bug
   in the conflictedness marking machinery or the hashing code, or both.

   ctf_dedup_id_to_target calls ctf_dedup_synthesize_forward to do one extra
   thing, alluded to above: if this is a conflicted tagged structure or union,
   and the target is the shared dict (i.e., the type we're being asked to emit
   is not itself conflicted so can't just point straight at the conflicted
   type), we instead synthesise a forward with the same name, emit it into the
   shared dict, record it in cd_output_emission_conflicted_forwards so that we
   don't re-emit it, and return it.  This means that cycles that contain
   conflicts do not cause the entire cycle to be replicated in every child: only
   that piece of the cycle which takes you back as far as the closest tagged
   struct/union needs to be replicated.  This trick means that no part of the
   deduplicator needs a cycle detector: every recursive walk can stop at tagged
   structures.

   [ctf_dedup_emit_struct_members]
   The final stage of emission is to walk over all structures with members
   that need emission and emit all of them. Every type has been emitted at
   this stage, so emission cannot fail.

   [ctf_dedup_populate_type_mappings, ctf_dedup_populate_type_mapping]
   Finally, we update the input -> output type ID mappings used by the ctf-link
   machinery to update all the other sections.  This is surprisingly expensive
   and may be replaced with a scheme which lets the ctf-link machinery extract
   the needed info directly from the deduplicator.  */

/* Possible future optimizations are flagged with 'optimization opportunity'
   below.  */

/* Global optimization opportunity: a GC pass, eliminating types with no direct
   or indirect citations from the other sections in the dictionary.  */

/* Internal flag values for ctf_dedup_hash_type.  */

/* Child call: consider forwardable types equivalent to forwards or stubs below
   this point.  */
#define CTF_DEDUP_HASH_INTERNAL_CHILD         0x01

/* Transform references to single ctf_id_ts in passed-in inputs into a number
   that will fit in a uint64_t.  Needs rethinking if CTF_MAX_TYPE is boosted.

   On 32-bit platforms, we pack things together differently: see the note
   above.  */

#if UINTPTR_MAX < UINT64_MAX
# define IDS_NEED_ALLOCATION 1
# define CTF_DEDUP_GID(fp, input, type) id_to_packed_id (fp, input, type)
# define CTF_DEDUP_GID_TO_INPUT(id) packed_id_to_input (id)
# define CTF_DEDUP_GID_TO_TYPE(id) packed_id_to_type (id)
#else
# define CTF_DEDUP_GID(fp, input, type)	\
  (void *) (((uint64_t) input) << 32 | (type))
# define CTF_DEDUP_GID_TO_INPUT(id) ((int) (((uint64_t) id) >> 32))
# define CTF_DEDUP_GID_TO_TYPE(id) (ctf_id_t) (((uint64_t) id) & ~(0xffffffff00000000ULL))
#endif

#ifdef IDS_NEED_ALLOCATION

 /* This is the 32-bit path, which stores GIDs in a pool and returns a pointer
    into the pool.  It is notably less efficient than the 64-bit direct storage
    approach, but with a smaller key, this is all we can do.  */

static void *
id_to_packed_id (ctf_dict_t *fp, int input_num, ctf_id_t type)
{
  const void *lookup;
  ctf_type_id_key_t *dynkey = NULL;
  ctf_type_id_key_t key = { input_num, type };

  if (!ctf_dynhash_lookup_kv (fp->ctf_dedup.cd_id_to_dict_t,
			      &key, &lookup, NULL))
    {
      if ((dynkey = malloc (sizeof (ctf_type_id_key_t))) == NULL)
	goto oom;
      memcpy (dynkey, &key, sizeof (ctf_type_id_key_t));

      if (ctf_dynhash_insert (fp->ctf_dedup.cd_id_to_dict_t, dynkey, NULL) < 0)
	goto oom;

      ctf_dynhash_lookup_kv (fp->ctf_dedup.cd_id_to_dict_t,
			     dynkey, &lookup, NULL);
    }
  /* We use a raw assert() here because there isn't really a way to get any sort
     of error back from this routine without vastly complicating things for the
     much more common case of !IDS_NEED_ALLOCATION.  */
  assert (lookup);
  return (void *) lookup;

 oom:
  free (dynkey);
  ctf_set_errno (fp, ENOMEM);
  return NULL;
}

static int
packed_id_to_input (const void *id)
{
  const ctf_type_id_key_t *key = (ctf_type_id_key_t *) id;

  return key->ctii_input_num;
}

static ctf_id_t
packed_id_to_type (const void *id)
{
  const ctf_type_id_key_t *key = (ctf_type_id_key_t *) id;

  return key->ctii_type;
}
#endif

/* Make an element in a dynhash-of-dynsets, or return it if already present.  */

static ctf_dynset_t *
make_set_element (ctf_dynhash_t *set, const void *key)
{
  ctf_dynset_t *element;

  if ((element = ctf_dynhash_lookup (set, key)) == NULL)
    {
      if ((element = ctf_dynset_create (htab_hash_string,
					htab_eq_string,
					NULL)) == NULL)
	return NULL;

      if (ctf_dynhash_insert (set, (void *) key, element) < 0)
	{
	  ctf_dynset_destroy (element);
	  return NULL;
	}
    }

  return element;
}

/* Initialize the dedup atoms table.  */
int
ctf_dedup_atoms_init (ctf_dict_t *fp)
{
  if (fp->ctf_dedup_atoms)
    return 0;

  if (!fp->ctf_dedup_atoms_alloc)
    {
      if ((fp->ctf_dedup_atoms_alloc
	   = ctf_dynset_create (htab_hash_string, htab_eq_string,
				free)) == NULL)
	return ctf_set_errno (fp, ENOMEM);
    }
  fp->ctf_dedup_atoms = fp->ctf_dedup_atoms_alloc;
  return 0;
}

/* Intern things in the dedup atoms table.  */

static const char *
intern (ctf_dict_t *fp, char *atom)
{
  const void *foo;

  if (atom == NULL)
    return NULL;

  if (!ctf_dynset_exists (fp->ctf_dedup_atoms, atom, &foo))
    {
      if (ctf_dynset_insert (fp->ctf_dedup_atoms, atom) < 0)
	{
	  ctf_set_errno (fp, ENOMEM);
	  return NULL;
	}
      foo = atom;
    }
  else
    free (atom);

  return (const char *) foo;
}

/* Add an indication of the namespace to a type name in a way that is not valid
   for C identifiers.  Used to maintain hashes of type names to other things
   while allowing for the four C namespaces (normal, struct, union, enum).
   Return a new dynamically-allocated string.  */
static const char *
ctf_decorate_type_name (ctf_dict_t *fp, const char *name, int kind)
{
  ctf_dedup_t *d = &fp->ctf_dedup;
  const char *ret;
  const char *k;
  char *p;
  size_t i;

  switch (kind)
    {
    case CTF_K_STRUCT:
      k = "s ";
      i = 0;
      break;
    case CTF_K_UNION:
      k = "u ";
      i = 1;
      break;
    case CTF_K_ENUM:
      k = "e ";
      i = 2;
      break;
    default:
      k = "";
      i = 3;
    }

  if ((ret = ctf_dynhash_lookup (d->cd_decorated_names[i], name)) == NULL)
    {
      char *str;

      if ((str = malloc (strlen (name) + strlen (k) + 1)) == NULL)
	goto oom;

      p = stpcpy (str, k);
      strcpy (p, name);
      ret = intern (fp, str);
      if (!ret)
	goto oom;

      if (ctf_dynhash_cinsert (d->cd_decorated_names[i], name, ret) < 0)
	goto oom;
    }

  return ret;

 oom:
  ctf_set_errno (fp, ENOMEM);
  return NULL;
}

/* Hash a type, possibly debugging-dumping something about it as well.  */
static inline void
ctf_dedup_sha1_add (ctf_sha1_t *sha1, const void *buf, size_t len,
		    const char *description _libctf_unused_,
		    unsigned long depth _libctf_unused_)
{
  ctf_sha1_add (sha1, buf, len);

#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
  ctf_sha1_t tmp;
  char tmp_hval[CTF_SHA1_SIZE];
  tmp = *sha1;
  ctf_sha1_fini (&tmp, tmp_hval);
  ctf_dprintf ("%lu: after hash addition of %s: %s\n", depth, description,
	       tmp_hval);
#endif
}

static const char *
ctf_dedup_hash_type (ctf_dict_t *fp, ctf_dict_t *input,
		     ctf_dict_t **inputs, uint32_t *parents,
		     int input_num, ctf_id_t type, int flags,
		     unsigned long depth,
		     int (*populate_fun) (ctf_dict_t *fp,
					  ctf_dict_t *input,
					  ctf_dict_t **inputs,
					  int input_num,
					  ctf_id_t type,
					  void *id,
					  const char *decorated_name,
					  const char *hash));

/* Determine whether this type is being hashed as a stub (in which case it is
   unsafe to cache it).  */
static int
ctf_dedup_is_stub (const char *name, int kind, int fwdkind, int flags)
{
  /* We can cache all types unless we are recursing to children and are hashing
     in a tagged struct, union or forward, all of which are replaced with their
     decorated name as a stub and will have different hash values when hashed at
     the top level.  */

  return ((flags & CTF_DEDUP_HASH_INTERNAL_CHILD) && name
	  && (kind == CTF_K_STRUCT || kind == CTF_K_UNION
	      || (kind == CTF_K_FORWARD && (fwdkind == CTF_K_STRUCT
					    || fwdkind == CTF_K_UNION))));
}

/* Populate struct_origin if need be (not already populated, or populated with
   a different origin), in which case it must go to -1, "shared".)

   Only called for forwards or forwardable types with names, when the link mode
   is CTF_LINK_SHARE_DUPLICATED.  */
static int
ctf_dedup_record_origin (ctf_dict_t *fp, int input_num, const char *decorated,
			 void *id)
{
  ctf_dedup_t *d = &fp->ctf_dedup;
  void *origin;
  int populate_origin = 0;

  if (ctf_dynhash_lookup_kv (d->cd_struct_origin, decorated, NULL, &origin))
    {
      if (CTF_DEDUP_GID_TO_INPUT (origin) != input_num
	  && CTF_DEDUP_GID_TO_INPUT (origin) != -1)
	{
	  populate_origin = 1;
	  origin = CTF_DEDUP_GID (fp, -1, -1);
	}
    }
  else
    {
      populate_origin = 1;
      origin = id;
    }

  if (populate_origin)
    if (ctf_dynhash_cinsert (d->cd_struct_origin, decorated, origin) < 0)
      return ctf_set_errno (fp, errno);
  return 0;
}

/* Do the underlying hashing and recursion for ctf_dedup_hash_type (which it
   calls, recursively).  */

static const char *
ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
		      uint32_t *parents, int input_num, ctf_id_t type,
		      void *type_id, const ctf_type_t *tp, const char *name,
		      const char *decorated, int kind, int flags,
		      unsigned long depth,
		      int (*populate_fun) (ctf_dict_t *fp,
					   ctf_dict_t *input,
					   ctf_dict_t **inputs,
					   int input_num,
					   ctf_id_t type,
					   void *id,
					   const char *decorated_name,
					   const char *hash))
{
  ctf_dedup_t *d = &fp->ctf_dedup;
  ctf_next_t *i = NULL;
  ctf_sha1_t hash;
  ctf_id_t child_type;
  char hashbuf[CTF_SHA1_SIZE];
  const char *hval = NULL;
  const char *whaterr;
  int err = 0;

  const char *citer = NULL;
  ctf_dynset_t *citers = NULL;

  /* Add a citer to the citers set.  */
#define ADD_CITER(citers, hval)						\
  do									\
    {									\
      whaterr = N_("error updating citers");				\
      if (!citers)							\
	if ((citers = ctf_dynset_create (htab_hash_string,		\
					 htab_eq_string,		\
					 NULL)) == NULL)		\
	  goto oom;							\
      if (ctf_dynset_cinsert (citers, hval) < 0)			\
	goto oom;							\
    }									\
  while (0)

  /* If this is a named struct or union or a forward to one, and this is a child
     traversal, treat this type as if it were a forward -- do not recurse to
     children, ignore all content not already hashed in, and hash in the
     decorated name of the type instead.  */

  if (ctf_dedup_is_stub (name, kind, tp->ctt_type, flags))
    {
#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
      ctf_dprintf ("Struct/union/forward citation: substituting forwarding "
		   "stub with decorated name %s\n", decorated);

#endif
      ctf_sha1_init (&hash);
      ctf_dedup_sha1_add (&hash, decorated, strlen (decorated) + 1,
			  "decorated struct/union/forward name", depth);
      ctf_sha1_fini (&hash, hashbuf);

      if ((hval = intern (fp, strdup (hashbuf))) == NULL)
	{
	  ctf_err_warn (fp, 0, 0, _("%s (%i): out of memory during forwarding-"
				    "stub hashing for type with GID %p"),
			ctf_link_input_name (input), input_num, type_id);
	  return NULL;				/* errno is set for us.  */
	}

      /* In share-duplicated link mode, make sure the origin of this type is
	 recorded, even if this is a type in a parent dict which will not be
	 directly traversed.  */
      if (d->cd_link_flags & CTF_LINK_SHARE_DUPLICATED
	  && ctf_dedup_record_origin (fp, input_num, decorated, type_id) < 0)
	return NULL;				/* errno is set for us.  */

      return hval;
    }

  /* Now ensure that subsequent recursive calls (but *not* the top-level call)
     get this treatment.  */
  flags |= CTF_DEDUP_HASH_INTERNAL_CHILD;

  /* If this is a struct, union, or forward with a name, record the unique
     originating input TU, if there is one.  */

  if (decorated && (ctf_forwardable_kind (kind) || kind != CTF_K_FORWARD))
    if (d->cd_link_flags & CTF_LINK_SHARE_DUPLICATED
	&& ctf_dedup_record_origin (fp, input_num, decorated, type_id) < 0)
      return NULL;				/* errno is set for us.  */

#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
  ctf_dprintf ("%lu: hashing thing with ID %i/%lx (kind %i): %s.\n",
	       depth, input_num, type, kind, name ? name : "");
#endif

  /* Some type kinds don't have names: the API provides no way to set the name,
     so the type the deduplicator outputs will be nameless even if the input
     somehow has a name, and the name should not be mixed into the hash.  */

  switch (kind)
    {
    case CTF_K_POINTER:
    case CTF_K_ARRAY:
    case CTF_K_FUNCTION:
    case CTF_K_VOLATILE:
    case CTF_K_CONST:
    case CTF_K_RESTRICT:
    case CTF_K_SLICE:
      name = NULL;
    }

  /* Mix in invariant stuff, transforming the type kind if needed.  Note that
     the vlen is *not* hashed in: the actual variable-length info is hashed in
     instead, piecewise.  The vlen is not part of the type, only the
     variable-length data is: identical types with distinct vlens are quite
     possible.  Equally, we do not want to hash in the isroot flag: both the
     compiler and the deduplicator set the nonroot flag to indicate clashes with
     *other types in the same TU* with the same name: so two types can easily
     have distinct nonroot flags, yet be exactly the same type.*/

  ctf_sha1_init (&hash);
  if (name)
    ctf_dedup_sha1_add (&hash, name, strlen (name) + 1, "name", depth);
  ctf_dedup_sha1_add (&hash, &kind, sizeof (uint32_t), "kind", depth);

  /* Hash content of this type.  */
  switch (kind)
    {
    case CTF_K_UNKNOWN:
      /* No extra state.  */
      break;
    case CTF_K_FORWARD:

      /* Add the forwarded kind, stored in the ctt_type.  */
      ctf_dedup_sha1_add (&hash, &tp->ctt_type, sizeof (tp->ctt_type),
			  "forwarded kind", depth);
      break;
    case CTF_K_INTEGER:
    case CTF_K_FLOAT:
      {
	ctf_encoding_t ep;
	memset (&ep, 0, sizeof (ctf_encoding_t));

	ctf_dedup_sha1_add (&hash, &tp->ctt_size, sizeof (uint32_t), "size",
			    depth);
	if (ctf_type_encoding (input, type, &ep) < 0)
	  {
	    whaterr = N_("error getting encoding");
	    goto input_err;
	  }
	ctf_dedup_sha1_add (&hash, &ep, sizeof (ctf_encoding_t), "encoding",
			    depth);
	break;
      }
      /* Types that reference other types.  */
    case CTF_K_TYPEDEF:
    case CTF_K_VOLATILE:
    case CTF_K_CONST:
    case CTF_K_RESTRICT:
    case CTF_K_POINTER:
      /* Hash the referenced type, if not already hashed, and mix it in.  */
      child_type = ctf_type_reference (input, type);
      if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, input_num,
				       child_type, flags, depth,
				       populate_fun)) == NULL)
	{
	  whaterr = N_("error doing referenced type hashing");
	  goto err;
	}
      ctf_dedup_sha1_add (&hash, hval, strlen (hval) + 1, "referenced type",
			  depth);
      citer = hval;

      break;

      /* The slices of two types hash identically only if the type they overlay
	 also has the same encoding.  This is not ideal, but in practice will work
	 well enough.  We work directly rather than using the CTF API because
	 we do not want the slice's normal automatically-shine-through
	 semantics to kick in here.  */
    case CTF_K_SLICE:
      {
	const ctf_slice_t *slice;
	const ctf_dtdef_t *dtd;
	ssize_t size;
	ssize_t increment;

	child_type = ctf_type_reference (input, type);
	ctf_get_ctt_size (input, tp, &size, &increment);
	ctf_dedup_sha1_add (&hash, &size, sizeof (ssize_t), "size", depth);

	if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, input_num,
					 child_type, flags, depth,
					 populate_fun)) == NULL)
	  {
	    whaterr = N_("error doing slice-referenced type hashing");
	    goto err;
	  }
	ctf_dedup_sha1_add (&hash, hval, strlen (hval) + 1, "sliced type",
			    depth);
	citer = hval;

	if ((dtd = ctf_dynamic_type (input, type)) != NULL)
	  slice = (ctf_slice_t *) dtd->dtd_vlen;
	else
	  slice = (ctf_slice_t *) ((uintptr_t) tp + increment);

	ctf_dedup_sha1_add (&hash, &slice->cts_offset,
			    sizeof (slice->cts_offset), "slice offset", depth);
	ctf_dedup_sha1_add (&hash, &slice->cts_bits,
			    sizeof (slice->cts_bits), "slice bits", depth);
	break;
      }

    case CTF_K_ARRAY:
      {
	ctf_arinfo_t ar;

	if (ctf_array_info (input, type, &ar) < 0)
	  {
	    whaterr = N_("error getting array info");
	    goto input_err;
	  }

	if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, input_num,
					 ar.ctr_contents, flags, depth,
					 populate_fun)) == NULL)
	  {
	    whaterr = N_("error doing array contents type hashing");
	    goto err;
	  }
	ctf_dedup_sha1_add (&hash, hval, strlen (hval) + 1, "array contents",
			    depth);
	ADD_CITER (citers, hval);

	if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, input_num,
					 ar.ctr_index, flags, depth,
					 populate_fun)) == NULL)
	  {
	    whaterr = N_("error doing array index type hashing");
	    goto err;
	  }
	ctf_dedup_sha1_add (&hash, hval, strlen (hval) + 1, "array index",
			    depth);
	ctf_dedup_sha1_add (&hash, &ar.ctr_nelems, sizeof (ar.ctr_nelems),
			    "element count", depth);
	ADD_CITER (citers, hval);

	break;
      }
    case CTF_K_FUNCTION:
      {
	ctf_funcinfo_t fi;
	ctf_id_t *args;
	uint32_t j;

	if (ctf_func_type_info (input, type, &fi) < 0)
	  {
	    whaterr = N_("error getting func type info");
	    goto input_err;
	  }

	if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, input_num,
					 fi.ctc_return, flags, depth,
					 populate_fun)) == NULL)
	  {
	    whaterr = N_("error getting func return type");
	    goto err;
	  }
	ctf_dedup_sha1_add (&hash, hval, strlen (hval) + 1, "func return",
			    depth);
	ctf_dedup_sha1_add (&hash, &fi.ctc_argc, sizeof (fi.ctc_argc),
			    "func argc", depth);
	ctf_dedup_sha1_add (&hash, &fi.ctc_flags, sizeof (fi.ctc_flags),
			    "func flags", depth);
	ADD_CITER (citers, hval);

	if ((args = calloc (fi.ctc_argc, sizeof (ctf_id_t))) == NULL)
	  {
	    err = ENOMEM;
	    whaterr = N_("error doing memory allocation");
	    goto err;
	  }

	if (ctf_func_type_args (input, type, fi.ctc_argc, args) < 0)
	  {
	    free (args);
	    whaterr = N_("error getting func arg type");
	    goto input_err;
	  }
	for (j = 0; j < fi.ctc_argc; j++)
	  {
	    if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents,
					     input_num, args[j], flags, depth,
					     populate_fun)) == NULL)
	      {
		free (args);
		whaterr = N_("error doing func arg type hashing");
		goto err;
	      }
	    ctf_dedup_sha1_add (&hash, hval, strlen (hval) + 1, "func arg type",
				depth);
	    ADD_CITER (citers, hval);
	  }
	free (args);
	break;
      }
    case CTF_K_ENUM:
      {
	int val;
	const char *ename;

	ctf_dedup_sha1_add (&hash, &tp->ctt_size, sizeof (uint32_t),
			    "enum size", depth);
	while ((ename = ctf_enum_next (input, type, &i, &val)) != NULL)
	  {
	    ctf_dedup_sha1_add (&hash, ename, strlen (ename) + 1, "enumerator",
				depth);
	    ctf_dedup_sha1_add (&hash, &val, sizeof (val), "enumerand", depth);
	  }
	if (ctf_errno (input) != ECTF_NEXT_END)
	  {
	    whaterr = N_("error doing enum member iteration");
	    goto input_err;
	  }
	break;
      }
    /* Top-level only.  */
    case CTF_K_STRUCT:
    case CTF_K_UNION:
      {
	ssize_t offset;
	const char *mname;
	ctf_id_t membtype;
	ssize_t size;

	ctf_get_ctt_size (input, tp, &size, NULL);
	ctf_dedup_sha1_add (&hash, &size, sizeof (ssize_t), "struct size",
			    depth);

	while ((offset = ctf_member_next (input, type, &i, &mname, &membtype,
					  0)) >= 0)
	  {
	    if (mname == NULL)
	      mname = "";
	    ctf_dedup_sha1_add (&hash, mname, strlen (mname) + 1,
				"member name", depth);

#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
	    ctf_dprintf ("%lu: Traversing to member %s\n", depth, mname);
#endif
	    if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents,
					     input_num, membtype, flags, depth,
					     populate_fun)) == NULL)
	      {
		whaterr = N_("error doing struct/union member type hashing");
		goto iterr;
	      }

	    ctf_dedup_sha1_add (&hash, hval, strlen (hval) + 1, "member hash",
				depth);
	    ctf_dedup_sha1_add (&hash, &offset, sizeof (offset), "member offset",
				depth);
	    ADD_CITER (citers, hval);
	  }
	if (ctf_errno (input) != ECTF_NEXT_END)
	  {
	    whaterr = N_("error doing struct/union member iteration");
	    goto input_err;
	  }
	break;
      }
    default:
      whaterr = N_("error: unknown type kind");
      goto err;
    }
  ctf_sha1_fini (&hash, hashbuf);

  if ((hval = intern (fp, strdup (hashbuf))) == NULL)
    {
      whaterr = N_("cannot intern hash");
      goto oom;
    }

  /* Populate the citers for this type's subtypes, now the hash for the type
     itself is known.  */
  whaterr = N_("error tracking citers");

  if (citer)
    {
      ctf_dynset_t *citer_hashes;

      if ((citer_hashes = make_set_element (d->cd_citers, citer)) == NULL)
	goto oom;
      if (ctf_dynset_cinsert (citer_hashes, hval) < 0)
	goto oom;
    }
  else if (citers)
    {
      const void *k;

      while ((err = ctf_dynset_cnext (citers, &i, &k)) == 0)
	{
	  ctf_dynset_t *citer_hashes;
	  citer = (const char *) k;

	  if ((citer_hashes = make_set_element (d->cd_citers, citer)) == NULL)
	    goto oom;

	  if (ctf_dynset_exists (citer_hashes, hval, NULL))
	    continue;
	  if (ctf_dynset_cinsert (citer_hashes, hval) < 0)
	    goto oom;
	}
      if (err != ECTF_NEXT_END)
	goto err;
      ctf_dynset_destroy (citers);
    }

  return hval;

 iterr:
  ctf_next_destroy (i);
 input_err:
  err = ctf_errno (input);
 err:
  ctf_sha1_fini (&hash, NULL);
  ctf_err_warn (fp, 0, err, _("%s (%i): %s: during type hashing for type %lx, "
			      "kind %i"), ctf_link_input_name (input),
		input_num, gettext (whaterr), type, kind);
  return NULL;
 oom:
  ctf_set_errno (fp, errno);
  ctf_err_warn (fp, 0, 0, _("%s (%i): %s: during type hashing for type %lx, "
			    "kind %i"), ctf_link_input_name (input),
		input_num, gettext (whaterr), type, kind);
  return NULL;
}

/* Hash a TYPE in the INPUT: FP is the eventual output, where the ctf_dedup
   state is stored.  INPUT_NUM is the number of this input in the set of inputs.
   Record its hash in FP's cd_type_hashes once it is known.  PARENTS is
   described in the comment above ctf_dedup.

   (The flags argument currently accepts only the flag
   CTF_DEDUP_HASH_INTERNAL_CHILD, an implementation detail used to prevent
   struct/union hashing in recursive traversals below the TYPE.)

   We use the CTF API rather than direct access wherever possible, because types
   that appear identical through the API should be considered identical, with
   one exception: slices should only be considered identical to other slices,
   not to the corresponding unsliced type.

   The POPULATE_FUN is a mandatory hook that populates other mappings with each
   type we see (excepting types that are recursively hashed as stubs).  The
   caller should not rely on the order of calls to this hook, though it will be
   called at least once for every non-stub reference to every type.

   Returns a hash value (an atom), or NULL on error.  */

static const char *
ctf_dedup_hash_type (ctf_dict_t *fp, ctf_dict_t *input,
		     ctf_dict_t **inputs, uint32_t *parents,
		     int input_num, ctf_id_t type, int flags,
		     unsigned long depth,
		     int (*populate_fun) (ctf_dict_t *fp,
					  ctf_dict_t *input,
					  ctf_dict_t **inputs,
					  int input_num,
					  ctf_id_t type,
					  void *id,
					  const char *decorated_name,
					  const char *hash))
{
  ctf_dedup_t *d = &fp->ctf_dedup;
  const ctf_type_t *tp;
  void *type_id;
  const char *hval = NULL;
  const char *name;
  const char *whaterr;
  const char *decorated = NULL;
  uint32_t kind, fwdkind;

  depth++;

#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
  ctf_dprintf ("%lu: ctf_dedup_hash_type (%i, %lx, flags %x)\n", depth, input_num, type, flags);
#endif

  /* The unimplemented type doesn't really exist, but must be noted in parent
     hashes: so it gets a fixed, arbitrary hash.  */
  if (type == 0)
    return "00000000000000000000";

  /* Possible optimization: if the input type is in the parent type space, just
     copy recursively-cited hashes from the parent's types into the output
     mapping rather than rehashing them.  */

  type_id = CTF_DEDUP_GID (fp, input_num, type);

  if ((tp = ctf_lookup_by_id (&input, type)) == NULL)
    {
      ctf_set_errno (fp, ctf_errno (input));
      ctf_err_warn (fp, 0, 0, _("%s (%i): lookup failure for type %lx: "
				"flags %x"), ctf_link_input_name (input),
		    input_num, type, flags);
      return NULL;		/* errno is set for us.  */
    }

  kind = LCTF_INFO_KIND (input, tp->ctt_info);
  name = ctf_strraw (input, tp->ctt_name);

  if (tp->ctt_name == 0 || !name || name[0] == '\0')
    name = NULL;

  /* Decorate the name appropriately for the namespace it appears in: forwards
     appear in the namespace of their referent.  */

  fwdkind = kind;
  if (name)
    {
      if (kind == CTF_K_FORWARD)
	fwdkind = tp->ctt_type;

      if ((decorated = ctf_decorate_type_name (fp, name, fwdkind)) == NULL)
	return NULL;				/* errno is set for us.  */
    }

  /* If not hashing a stub, we can rely on various sorts of caches.

     Optimization opportunity: we may be able to avoid calling the populate_fun
     sometimes here.  */

  if (!ctf_dedup_is_stub (name, kind, fwdkind, flags))
    {
      if ((hval = ctf_dynhash_lookup (d->cd_type_hashes, type_id)) != NULL)
	{
#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
	  ctf_dprintf ("%lu: Known hash for ID %i/%lx: %s\n", depth, input_num,
		       type,  hval);
#endif
	  populate_fun (fp, input, inputs, input_num, type, type_id,
			decorated, hval);

	  return hval;
	}
    }

  /* We have never seen this type before, and must figure out its hash and the
     hashes of the types it cites.

     Hash this type, and call ourselves recursively.  (The hashing part is
     optional, and is disabled if overidden_hval is set.)  */

  if ((hval = ctf_dedup_rhash_type (fp, input, inputs, parents, input_num,
				    type, type_id, tp, name, decorated,
				    kind, flags, depth, populate_fun)) == NULL)
    return NULL;				/* errno is set for us.  */

  /* The hash of this type is now known: record it unless caching is unsafe
     because the hash value will change later.  This will be the final storage
     of this type's hash, so we call the population function on it.  */

  if (!ctf_dedup_is_stub (name, kind, fwdkind, flags))
    {
#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
      ctf_dprintf ("Caching %lx, ID %p (%s), %s in final location\n", type,
		   type_id, name ? name : "", hval);
#endif

      if (ctf_dynhash_cinsert (d->cd_type_hashes, type_id, hval) < 0)
	{
	  whaterr = N_("error hash caching");
	  goto oom;
	}

      if (populate_fun (fp, input, inputs, input_num, type, type_id,
			decorated, hval) < 0)
	{
	  whaterr = N_("error calling population function");
	  goto err;				/* errno is set for us. */
	}
    }

#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
  ctf_dprintf ("%lu: Returning final hash for ID %i/%lx: %s\n", depth,
	       input_num, type, hval);
#endif
  return hval;

 oom:
  ctf_set_errno (fp, errno);
 err:
  ctf_err_warn (fp, 0, 0, _("%s (%i): %s: during type hashing, "
			    "type %lx, kind %i"),
		ctf_link_input_name (input), input_num,
		gettext (whaterr), type, kind);
  return NULL;
}

/* Populate a number of useful mappings not directly used by the hashing
   machinery: the output mapping, the cd_name_counts mapping from name -> hash
   -> count of hashval deduplication state for a given hashed type, and the
   cd_output_first_tu mapping.  */

static int
ctf_dedup_populate_mappings (ctf_dict_t *fp, ctf_dict_t *input _libctf_unused_,
			     ctf_dict_t **inputs _libctf_unused_,
			     int input_num _libctf_unused_,
			     ctf_id_t type _libctf_unused_, void *id,
			     const char *decorated_name,
			     const char *hval)
{
  ctf_dedup_t *d = &fp->ctf_dedup;
  ctf_dynset_t *type_ids;
  ctf_dynhash_t *name_counts;
  long int count;

#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
  ctf_dprintf ("Hash %s, %s, into output mapping for %i/%lx @ %s\n",
	       hval, decorated_name ? decorated_name : "(unnamed)",
	       input_num, type, ctf_link_input_name (input));

  const char *orig_hval;

  /* Make sure we never map a single GID to multiple hash values.  */

  if ((orig_hval = ctf_dynhash_lookup (d->cd_output_mapping_guard, id)) != NULL)
    {
      /* We can rely on pointer identity here, since all hashes are
	 interned.  */
      if (!ctf_assert (fp, orig_hval == hval))
	return -1;
    }
  else
    if (ctf_dynhash_cinsert (d->cd_output_mapping_guard, id, hval) < 0)
      return ctf_set_errno (fp, errno);
#endif

  /* Record the type in the output mapping: if this is the first time this type
     has been seen, also record it in the cd_output_first_gid.  Because we
     traverse types in TU order and we do not merge types after the hashing
     phase, this will be the lowest TU this type ever appears in.  */

  if ((type_ids = ctf_dynhash_lookup (d->cd_output_mapping,
				      hval)) == NULL)
    {
      if (ctf_dynhash_cinsert (d->cd_output_first_gid, hval, id) < 0)
	return ctf_set_errno (fp, errno);

      if ((type_ids = ctf_dynset_create (htab_hash_pointer,
					 htab_eq_pointer,
					 NULL)) == NULL)
	return ctf_set_errno (fp, errno);
      if (ctf_dynhash_insert (d->cd_output_mapping, (void *) hval,
			      type_ids) < 0)
	{
	  ctf_dynset_destroy (type_ids);
	  return ctf_set_errno (fp, errno);
	}
    }
#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
    {
      /* Verify that all types with this hash are of the same kind, and that the
	 first TU a type was seen in never falls.  */

      int err;
      const void *one_id;
      ctf_next_t *i = NULL;
      int orig_kind = ctf_type_kind_unsliced (input, type);
      int orig_first_tu;

      orig_first_tu = CTF_DEDUP_GID_TO_INPUT
	(ctf_dynhash_lookup (d->cd_output_first_gid, hval));
      if (!ctf_assert (fp, orig_first_tu <= CTF_DEDUP_GID_TO_INPUT (id)))
	return -1;

      while ((err = ctf_dynset_cnext (type_ids, &i, &one_id)) == 0)
	{
	  ctf_dict_t *foo = inputs[CTF_DEDUP_GID_TO_INPUT (one_id)];
	  ctf_id_t bar = CTF_DEDUP_GID_TO_TYPE (one_id);
	  if (ctf_type_kind_unsliced (foo, bar) != orig_kind)
	    {
	      ctf_err_warn (fp, 1, 0, "added wrong kind to output mapping "
			    "for hash %s named %s: %p/%lx from %s is "
			    "kind %i, but newly-added %p/%lx from %s is "
			    "kind %i", hval,
			    decorated_name ? decorated_name : "(unnamed)",
			    (void *) foo, bar,
			    ctf_link_input_name (foo),
			    ctf_type_kind_unsliced (foo, bar),
			    (void *) input, type,
			    ctf_link_input_name (input), orig_kind);
	      if (!ctf_assert (fp, ctf_type_kind_unsliced (foo, bar)
			       == orig_kind))
		return -1;
	    }
	}
      if (err != ECTF_NEXT_END)
	return ctf_set_errno (fp, err);
    }
#endif

  /* This function will be repeatedly called for the same types many times:
     don't waste time reinserting the same keys in that case.  */
  if (!ctf_dynset_exists (type_ids, id, NULL)
      && ctf_dynset_insert (type_ids, id) < 0)
    return ctf_set_errno (fp, errno);

  /* The rest only needs to happen for types with names.  */
  if (!decorated_name)
    return 0;

  /* Count the number of occurrences of the hash value for this GID.  */

  hval = ctf_dynhash_lookup (d->cd_type_hashes, id);

  /* Mapping from name -> hash(hashval, count) not already present?  */
  if ((name_counts = ctf_dynhash_lookup (d->cd_name_counts,
					 decorated_name)) == NULL)
    {
      if ((name_counts = ctf_dynhash_create (ctf_hash_string,
					     ctf_hash_eq_string,
					     NULL, NULL)) == NULL)
	  return ctf_set_errno (fp, errno);
      if (ctf_dynhash_cinsert (d->cd_name_counts, decorated_name,
			       name_counts) < 0)
	{
	  ctf_dynhash_destroy (name_counts);
	  return ctf_set_errno (fp, errno);
	}
    }

  /* This will, conveniently, return NULL (i.e. 0) for a new entry.  */
  count = (long int) (uintptr_t) ctf_dynhash_lookup (name_counts, hval);

  if (ctf_dynhash_cinsert (name_counts, hval,
			   (const void *) (uintptr_t) (count + 1)) < 0)
    return ctf_set_errno (fp, errno);

  return 0;
}

/* Mark a single hash as corresponding to a conflicting type.  Mark all types
   that cite it as conflicting as well, terminating the recursive walk only when
   types that are already conflicted or types do not cite other types are seen.
   (Tagged structures and unions do not appear in the cd_citers graph, so the
   walk also terminates there, since any reference to a conflicting structure is
   just going to reference an unconflicting forward instead: see
   ctf_dedup_maybe_synthesize_forward.)  */

static int
ctf_dedup_mark_conflicting_hash (ctf_dict_t *fp, const char *hval)
{
  ctf_dedup_t *d = &fp->ctf_dedup;
  ctf_next_t *i = NULL;
  int err;
  const void *k;
  ctf_dynset_t *citers;

  /* Mark conflicted if not already so marked.  */
  if (ctf_dynset_exists (d->cd_conflicting_types, hval, NULL))
    return 0;

  ctf_dprintf ("Marking %s as conflicted\n", hval);

  if (ctf_dynset_cinsert (d->cd_conflicting_types, hval) < 0)
    {
      ctf_dprintf ("Out of memory marking %s as conflicted\n", hval);
      ctf_set_errno (fp, errno);
      return -1;
    }

  /* If any types cite this type, mark them conflicted too.  */
  if ((citers = ctf_dynhash_lookup (d->cd_citers, hval)) == NULL)
    return 0;

  while ((err = ctf_dynset_cnext (citers, &i, &k)) == 0)
    {
      const char *hv = (const char *) k;

      if (ctf_dynset_exists (d->cd_conflicting_types, hv, NULL))
	continue;

      if (ctf_dedup_mark_conflicting_hash (fp, hv) < 0)
	{
	  ctf_next_destroy (i);
	  return -1;				/* errno is set for us.  */
	}
    }
  if (err != ECTF_NEXT_END)
    return ctf_set_errno (fp, err);

  return 0;
}

/* Look up a type kind from the output mapping, given a type hash value.  */
static int
ctf_dedup_hash_kind (ctf_dict_t *fp, ctf_dict_t **inputs, const char *hash)
{
  ctf_dedup_t *d = &fp->ctf_dedup;
  void *id;
  ctf_dynset_t *type_ids;

  /* Precondition: the output mapping is populated.  */
  if (!ctf_assert (fp, ctf_dynhash_elements (d->cd_output_mapping) > 0))
    return -1;

  /* Look up some GID from the output hash for this type.  (They are all
     identical, so we can pick any).  Don't assert if someone calls this
     function wrongly, but do assert if the output mapping knows about the hash,
     but has nothing associated with it.  */

  type_ids = ctf_dynhash_lookup (d->cd_output_mapping, hash);
  if (!type_ids)
    {
      ctf_dprintf ("Looked up type kind by nonexistent hash %s.\n", hash);
      return ctf_set_errno (fp, ECTF_INTERNAL);
    }
  id = ctf_dynset_lookup_any (type_ids);
  if (!ctf_assert (fp, id))
    return -1;

  return ctf_type_kind_unsliced (inputs[CTF_DEDUP_GID_TO_INPUT (id)],
				 CTF_DEDUP_GID_TO_TYPE (id));
}

/* Used to keep a count of types: i.e. distinct type hash values.  */
typedef struct ctf_dedup_type_counter
{
  ctf_dict_t *fp;
  ctf_dict_t **inputs;
  int num_non_forwards;
} ctf_dedup_type_counter_t;

/* Add to the type counter for one name entry from the cd_name_counts.  */
static int
ctf_dedup_count_types (void *key_, void *value _libctf_unused_, void *arg_)
{
  const char *hval = (const char *) key_;
  int kind;
  ctf_dedup_type_counter_t *arg = (ctf_dedup_type_counter_t *) arg_;

  kind = ctf_dedup_hash_kind (arg->fp, arg->inputs, hval);

  /* We rely on ctf_dedup_hash_kind setting the fp to -ECTF_INTERNAL on error to
     smuggle errors out of here.  */

  if (kind != CTF_K_FORWARD)
    {
      arg->num_non_forwards++;
      ctf_dprintf ("Counting hash %s: kind %i: num_non_forwards is %i\n",
		   hval, kind, arg->num_non_forwards);
    }

  /* We only need to know if there is more than one non-forward (an ambiguous
     type): don't waste time iterating any more than needed to figure that
     out.  */

  if (arg->num_non_forwards > 1)
    return 1;

  return 0;
}

/* Detect name ambiguity and mark ambiguous names as conflicting, other than the
   most common.  */
static int
ctf_dedup_detect_name_ambiguity (ctf_dict_t *fp, ctf_dict_t **inputs)
{
  ctf_dedup_t *d = &fp->ctf_dedup;
  ctf_next_t *i = NULL;
  void *k;
  void *v;
  int err;
  const char *whaterr;

  /* Go through cd_name_counts for all CTF namespaces in turn.  */

  while ((err = ctf_dynhash_next (d->cd_name_counts, &i, &k, &v)) == 0)
    {
      const char *decorated = (const char *) k;
      ctf_dynhash_t *name_counts = (ctf_dynhash_t *) v;
      ctf_next_t *j = NULL;

      /* If this is a forwardable kind or a forward (which we can tell without
	 consulting the type because its decorated name has a space as its
	 second character: see ctf_decorate_type_name), we are only interested
	 in whether this name has many hashes associated with it: any such name
	 is necessarily ambiguous, and types with that name are conflicting.
	 Once we know whether this is true, we can skip to the next name: so use
	 ctf_dynhash_iter_find for efficiency.  */

      if (decorated[0] != '\0' && decorated[1] == ' ')
	{
	  ctf_dedup_type_counter_t counters = { fp, inputs, 0 };
	  ctf_dynhash_t *counts = (ctf_dynhash_t *) v;

	  ctf_dynhash_iter_find (counts, ctf_dedup_count_types, &counters);

	  /* Check for assertion failure and pass it up.  */
	  if (ctf_errno (fp) == ECTF_INTERNAL)
	    goto assert_err;

	  if (counters.num_non_forwards > 1)
	    {
	      const void *hval_;

	      while ((err = ctf_dynhash_cnext (counts, &j, &hval_, NULL)) == 0)
		{
		  const char *hval = (const char *) hval_;
		  ctf_dynset_t *type_ids;
		  void *id;
		  int kind;

		  /* Dig through the types in this hash to find the non-forwards
		     and mark them ambiguous.  */

		  type_ids = ctf_dynhash_lookup (d->cd_output_mapping, hval);

		  /* Nonexistent? Must be a forward with no referent.  */
		  if (!type_ids)
		    continue;

		  id = ctf_dynset_lookup_any (type_ids);

		  kind = ctf_type_kind (inputs[CTF_DEDUP_GID_TO_INPUT (id)],
					CTF_DEDUP_GID_TO_TYPE (id));

		  if (kind != CTF_K_FORWARD)
		    {
		      ctf_dprintf ("Marking %p, with hash %s, conflicting: one "
				   "of many non-forward GIDs for %s\n", id,
				   hval, (char *) k);
		      ctf_dedup_mark_conflicting_hash (fp, hval);
		    }
		}
	      if (err != ECTF_NEXT_END)
		{
		  whaterr = N_("error marking conflicting structs/unions");
		  goto iterr;
		}
	    }
	}
      else
	{
	  /* This is an ordinary type.  Find the most common type with this
	     name, and mark it unconflicting: all others are conflicting.  (We
	     cannot do this sort of popularity contest with forwardable types
	     because any forwards to that type would be immediately unified with
	     the most-popular type on insertion, and we want conflicting structs
	     et al to have all forwards left intact, so the user is notified
	     that this type is conflicting.  TODO: improve this in future by
	     setting such forwards non-root-visible.)

	     If multiple distinct types are "most common", pick the one that
	     appears first on the link line, and within that, the one with the
	     lowest type ID.  (See sort_output_mapping.)  */

	  const void *key;
	  const void *count;
	  const char *hval;
	  long max_hcount = -1;
	  void *max_gid = NULL;
	  const char *max_hval = NULL;

	  if (ctf_dynhash_elements (name_counts) <= 1)
	    continue;

	  /* First find the most common.  */
	  while ((err = ctf_dynhash_cnext (name_counts, &j, &key, &count)) == 0)
	    {
	      hval = (const char *) key;

	      if ((long int) (uintptr_t) count > max_hcount)
		{
		  max_hcount = (long int) (uintptr_t) count;
		  max_hval = hval;
		  max_gid = ctf_dynhash_lookup (d->cd_output_first_gid, hval);
		}
	      else if ((long int) (uintptr_t) count == max_hcount)
		{
		  void *gid = ctf_dynhash_lookup (d->cd_output_first_gid, hval);

		  if (CTF_DEDUP_GID_TO_INPUT(gid) < CTF_DEDUP_GID_TO_INPUT(max_gid)
		      || (CTF_DEDUP_GID_TO_INPUT(gid) == CTF_DEDUP_GID_TO_INPUT(max_gid)
			  && CTF_DEDUP_GID_TO_TYPE(gid) < CTF_DEDUP_GID_TO_TYPE(max_gid)))
		    {
		      max_hval = hval;
		      max_gid = ctf_dynhash_lookup (d->cd_output_first_gid, hval);
		    }
		}
	    }
	  if (err != ECTF_NEXT_END)
	    {
	      whaterr = N_("error finding commonest conflicting type");
	      goto iterr;
	    }

	  /* Mark all the others as conflicting.   */
	  while ((err = ctf_dynhash_cnext (name_counts, &j, &key, NULL)) == 0)
	    {
	      hval = (const char *) key;
	      if (strcmp (max_hval, hval) == 0)
		continue;

	      ctf_dprintf ("Marking %s, an uncommon hash for %s, conflicting\n",
			   hval, (const char *) k);
	      if (ctf_dedup_mark_conflicting_hash (fp, hval) < 0)
		{
		  whaterr = N_("error marking hashes as conflicting");
		  goto err;
		}
	    }
	  if (err != ECTF_NEXT_END)
	    {
	      whaterr = N_("marking uncommon conflicting types");
	      goto iterr;
	    }
	}
    }
  if (err != ECTF_NEXT_END)
    {
      whaterr = N_("scanning for ambiguous names");
      goto iterr;
    }

  return 0;

 err:
  ctf_next_destroy (i);
  ctf_err_warn (fp, 0, 0, "%s", gettext (whaterr));
  return -1;					/* errno is set for us.  */

 iterr:
  ctf_err_warn (fp, 0, err, _("iteration failed: %s"), gettext (whaterr));
  return ctf_set_errno (fp, err);

 assert_err:
  ctf_next_destroy (i);
  return -1; 					/* errno is set for us.  */
}

/* Initialize the deduplication machinery.  */

static int
ctf_dedup_init (ctf_dict_t *fp)
{
  ctf_dedup_t *d = &fp->ctf_dedup;
  size_t i;

  if (ctf_dedup_atoms_init (fp) < 0)
      goto oom;

#if IDS_NEED_ALLOCATION
  if ((d->cd_id_to_dict_t = ctf_dynhash_create (ctf_hash_type_id_key,
						ctf_hash_eq_type_id_key,
						free, NULL)) == NULL)
    goto oom;
#endif

  for (i = 0; i < 4; i++)
    {
      if ((d->cd_decorated_names[i] = ctf_dynhash_create (ctf_hash_string,
							  ctf_hash_eq_string,
							  NULL, NULL)) == NULL)
	goto oom;
    }

  if ((d->cd_name_counts
       = ctf_dynhash_create (ctf_hash_string,
			     ctf_hash_eq_string, NULL,
			     (ctf_hash_free_fun) ctf_dynhash_destroy)) == NULL)
    goto oom;

  if ((d->cd_type_hashes
       = ctf_dynhash_create (ctf_hash_integer,
			     ctf_hash_eq_integer,
			     NULL, NULL)) == NULL)
    goto oom;

  if ((d->cd_struct_origin
       = ctf_dynhash_create (ctf_hash_string,
			     ctf_hash_eq_string,
			     NULL, NULL)) == NULL)
    goto oom;

  if ((d->cd_citers
       = ctf_dynhash_create (ctf_hash_string,
			     ctf_hash_eq_string, NULL,
			     (ctf_hash_free_fun) ctf_dynset_destroy)) == NULL)
    goto oom;

  if ((d->cd_output_mapping
       = ctf_dynhash_create (ctf_hash_string,
			     ctf_hash_eq_string, NULL,
			     (ctf_hash_free_fun) ctf_dynset_destroy)) == NULL)
    goto oom;

  if ((d->cd_output_first_gid
       = ctf_dynhash_create (ctf_hash_string,
			     ctf_hash_eq_string,
			     NULL, NULL)) == NULL)
    goto oom;

#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
  if ((d->cd_output_mapping_guard
       = ctf_dynhash_create (ctf_hash_integer,
			     ctf_hash_eq_integer, NULL, NULL)) == NULL)
    goto oom;
#endif

  if ((d->cd_input_nums
       = ctf_dynhash_create (ctf_hash_integer,
			     ctf_hash_eq_integer,
			     NULL, NULL)) == NULL)
    goto oom;

  if ((d->cd_emission_struct_members
       = ctf_dynhash_create (ctf_hash_integer,
			     ctf_hash_eq_integer,
			     NULL, NULL)) == NULL)
    goto oom;

  if ((d->cd_conflicting_types
       = ctf_dynset_create (htab_hash_string,
			    htab_eq_string, NULL)) == NULL)
    goto oom;

  return 0;

 oom:
  ctf_err_warn (fp, 0, ENOMEM, _("ctf_dedup_init: cannot initialize: "
				 "out of memory"));
  return ctf_set_errno (fp, ENOMEM);
}

/* No ctf_dedup calls are allowed after this call other than starting a new
   deduplication via ctf_dedup (not even ctf_dedup_type_mapping lookups).  */
void
ctf_dedup_fini (ctf_dict_t *fp, ctf_dict_t **outputs, uint32_t noutputs)
{
  ctf_dedup_t *d = &fp->ctf_dedup;
  size_t i;

  /* ctf_dedup_atoms is kept across links.  */
#if IDS_NEED_ALLOCATION
  ctf_dynhash_destroy (d->cd_id_to_dict_t);
#endif
  for (i = 0; i < 4; i++)
    ctf_dynhash_destroy (d->cd_decorated_names[i]);
  ctf_dynhash_destroy (d->cd_name_counts);
  ctf_dynhash_destroy (d->cd_type_hashes);
  ctf_dynhash_destroy (d->cd_struct_origin);
  ctf_dynhash_destroy (d->cd_citers);
  ctf_dynhash_destroy (d->cd_output_mapping);
  ctf_dynhash_destroy (d->cd_output_first_gid);
#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
  ctf_dynhash_destroy (d->cd_output_mapping_guard);
#endif
  ctf_dynhash_destroy (d->cd_input_nums);
  ctf_dynhash_destroy (d->cd_emission_struct_members);
  ctf_dynset_destroy (d->cd_conflicting_types);

  /* Free the per-output state.  */
  if (outputs)
    {
      for (i = 0; i < noutputs; i++)
	{
	  ctf_dedup_t *od = &outputs[i]->ctf_dedup;
	  ctf_dynhash_destroy (od->cd_output_emission_hashes);
	  ctf_dynhash_destroy (od->cd_output_emission_conflicted_forwards);
	  ctf_dict_close (od->cd_output);
	}
    }
  memset (d, 0, sizeof (ctf_dedup_t));
}

/* Return 1 if this type is cited by multiple input dictionaries.  */

static int
ctf_dedup_multiple_input_dicts (ctf_dict_t *output, ctf_dict_t **inputs,
				const char *hval)
{
  ctf_dedup_t *d = &output->ctf_dedup;
  ctf_dynset_t *type_ids;
  ctf_next_t *i = NULL;
  void *id;
  ctf_dict_t *found = NULL, *relative_found = NULL;
  const char *type_id;
  ctf_dict_t *input_fp;
  ctf_id_t input_id;
  const char *name;
  const char *decorated;
  int fwdkind;
  int multiple = 0;
  int err;

  type_ids = ctf_dynhash_lookup (d->cd_output_mapping, hval);
  if (!ctf_assert (output, type_ids))
    return -1;

  /* Scan across the IDs until we find proof that two disjoint dictionaries
     are referenced.  Exit as soon as possible.  Optimization opportunity, but
     possibly not worth it, given that this is only executed in
     CTF_LINK_SHARE_DUPLICATED mode.  */

  while ((err = ctf_dynset_next (type_ids, &i, &id)) == 0)
    {
      ctf_dict_t *fp = inputs[CTF_DEDUP_GID_TO_INPUT (id)];

      if (fp == found || fp == relative_found)
	continue;

      if (!found)
	{
	  found = fp;
	  continue;
	}

      if (!relative_found
	  && (fp->ctf_parent == found || found->ctf_parent == fp))
	{
	  relative_found = fp;
	  continue;
	}

      multiple = 1;
      ctf_next_destroy (i);
      break;
    }
  if ((err != ECTF_NEXT_END) && (err != 0))
    {
      ctf_err_warn (output, 0, err, _("iteration error "
				      "propagating conflictedness"));
      return ctf_set_errno (output, err);
    }

  if (multiple)
    return multiple;

  /* This type itself does not appear in multiple input dicts: how about another
     related type with the same name (e.g. a forward if this is a struct,
     etc).  */

  type_id = ctf_dynset_lookup_any (type_ids);
  if (!ctf_assert (output, type_id))
    return -1;

  input_fp = inputs[CTF_DEDUP_GID_TO_INPUT (type_id)];
  input_id = CTF_DEDUP_GID_TO_TYPE (type_id);
  fwdkind = ctf_type_kind_forwarded (input_fp, input_id);
  name = ctf_type_name_raw (input_fp, input_id);

  if ((fwdkind == CTF_K_STRUCT || fwdkind == CTF_K_UNION)
      && name[0] != '\0')
    {
      const void *origin;

      if ((decorated = ctf_decorate_type_name (output, name,
					       fwdkind)) == NULL)
	return -1;				/* errno is set for us.  */

      origin = ctf_dynhash_lookup (d->cd_struct_origin, decorated);
      if ((origin != NULL) && (CTF_DEDUP_GID_TO_INPUT (origin) < 0))
	multiple = 1;
    }

  return multiple;
}

/* Demote unconflicting types which reference only one input, or which reference
   two inputs where one input is the parent of the other, into conflicting
   types.  Only used if the link mode is CTF_LINK_SHARE_DUPLICATED.  */

static int
ctf_dedup_conflictify_unshared (ctf_dict_t *output, ctf_dict_t **inputs)
{
  ctf_dedup_t *d = &output->ctf_dedup;
  ctf_next_t *i = NULL;
  int err;
  const void *k;
  ctf_dynset_t *to_mark = NULL;

  if ((to_mark = ctf_dynset_create (htab_hash_string, htab_eq_string,
				    NULL)) == NULL)
    goto err_no;

  while ((err = ctf_dynhash_cnext (d->cd_output_mapping, &i, &k, NULL)) == 0)
    {
      const char *hval = (const char *) k;
      int conflicting;

      /* Types referenced by only one dict, with no type appearing under that
	 name elsewhere, are marked conflicting.  */

      conflicting = !ctf_dedup_multiple_input_dicts (output, inputs, hval);

      if (conflicting < 0)
	goto err;				/* errno is set for us.  */

      if (conflicting)
	if (ctf_dynset_cinsert (to_mark, hval) < 0)
	  goto err;
    }
  if (err != ECTF_NEXT_END)
    goto iterr;

  while ((err = ctf_dynset_cnext (to_mark, &i, &k)) == 0)
    {
      const char *hval = (const char *) k;

      if (ctf_dedup_mark_conflicting_hash (output, hval) < 0)
	goto err;
    }
  if (err != ECTF_NEXT_END)
    goto iterr;

  ctf_dynset_destroy (to_mark);

  return 0;

 err_no:
  ctf_set_errno (output, errno);
 err:
  err = ctf_errno (output);
  ctf_next_destroy (i);
 iterr:
  ctf_dynset_destroy (to_mark);
  ctf_err_warn (output, 0, err, _("conflictifying unshared types"));
  return ctf_set_errno (output, err);
}

/* The core deduplicator.  Populate cd_output_mapping in the output ctf_dedup
   with a mapping of all types that belong in this dictionary and where they
   come from, and cd_conflicting_types with an indication of whether each type
   is conflicted or not.  OUTPUT is the top-level output: INPUTS is the array of
   input dicts; NINPUTS is the size of that array; PARENTS is an NINPUTS-element
   array with each element corresponding to a input which is a child dict set to
   the number in the INPUTS array of that input's parent.

   If CU_MAPPED is set, this is a first pass for a link with a non-empty CU
   mapping: only one output will result.

   Only deduplicates: does not emit the types into the output.  Call
   ctf_dedup_emit afterwards to do that.  */

int
ctf_dedup (ctf_dict_t *output, ctf_dict_t **inputs, uint32_t ninputs,
	   uint32_t *parents, int cu_mapped)
{
  ctf_dedup_t *d = &output->ctf_dedup;
  size_t i;
  ctf_next_t *it = NULL;

  if (ctf_dedup_init (output) < 0)
    return -1; 					/* errno is set for us.  */

  for (i = 0; i < ninputs; i++)
    {
      ctf_dprintf ("Input %i: %s\n", (int) i, ctf_link_input_name (inputs[i]));
      if (ctf_dynhash_insert (d->cd_input_nums, inputs[i],
			      (void *) (uintptr_t) i) < 0)
	{
	  ctf_set_errno (output, errno);
	  ctf_err_warn (output, 0, errno, _("ctf_dedup: cannot initialize: %s\n"),
			ctf_errmsg (errno));
	  goto err;
	}
    }

  /* Some flags do not apply when CU-mapping: this is not a duplicated link,
     because there is only one output and we really don't want to end up marking
     all nonconflicting but appears-only-once types as conflicting (which in the
     CU-mapped link means we'd mark them all as non-root-visible!).  */
  d->cd_link_flags = output->ctf_link_flags;
  if (cu_mapped)
    d->cd_link_flags &= ~(CTF_LINK_SHARE_DUPLICATED);

  /* Compute hash values for all types, recursively, treating child structures
     and unions equivalent to forwards, and hashing in the name of the referent
     of each such type into structures, unions, and non-opaque forwards.
     Populate a mapping from decorated name (including an indication of
     struct/union/enum namespace) to count of type hash values in
     cd_name_counts, a mapping from and a mapping from hash values to input type
     IDs in cd_output_mapping.  */

  ctf_dprintf ("Computing type hashes\n");
  for (i = 0; i < ninputs; i++)
    {
      ctf_id_t id;

      while ((id = ctf_type_next (inputs[i], &it, NULL, 1)) != CTF_ERR)
	{
	  if (ctf_dedup_hash_type (output, inputs[i], inputs,
				   parents, i, id, 0, 0,
				   ctf_dedup_populate_mappings) == NULL)
	    goto err;				/* errno is set for us.  */
	}
      if (ctf_errno (inputs[i]) != ECTF_NEXT_END)
	{
	  ctf_set_errno (output, ctf_errno (inputs[i]));
	  ctf_err_warn (output, 0, 0, _("iteration failure "
					"computing type hashes"));
	  goto err;
	}
    }

  /* Go through the cd_name_counts name->hash->count mapping for all CTF
     namespaces: any name with many hashes associated with it at this stage is
     necessarily ambiguous.  Mark all the hashes except the most common as
     conflicting in the output.  */

  ctf_dprintf ("Detecting type name ambiguity\n");
  if (ctf_dedup_detect_name_ambiguity (output, inputs) < 0)
      goto err;					/* errno is set for us.  */

  /* If the link mode is CTF_LINK_SHARE_DUPLICATED, we change any unconflicting
     types whose output mapping references only one input dict into a
     conflicting type, so that they end up in the per-CU dictionaries.  */

  if (d->cd_link_flags & CTF_LINK_SHARE_DUPLICATED)
    {
      ctf_dprintf ("Conflictifying unshared types\n");
      if (ctf_dedup_conflictify_unshared (output, inputs) < 0)
	goto err;				/* errno is set for us.  */
    }
  return 0;

 err:
  ctf_dedup_fini (output, NULL, 0);
  return -1;
}

static int
ctf_dedup_rwalk_output_mapping (ctf_dict_t *output, ctf_dict_t **inputs,
				uint32_t ninputs, uint32_t *parents,
				ctf_dynset_t *already_visited,
				const char *hval,
				int (*visit_fun) (const char *hval,
						  ctf_dict_t *output,
						  ctf_dict_t **inputs,
						  uint32_t ninputs,
						  uint32_t *parents,
						  int already_visited,
						  ctf_dict_t *input,
						  ctf_id_t type,
						  void *id,
						  int depth,
						  void *arg),
				void *arg, unsigned long depth);

/* Like ctf_dedup_rwalk_output_mapping (which see), only takes a single target
   type and visits it.  */
static int
ctf_dedup_rwalk_one_output_mapping (ctf_dict_t *output,
				    ctf_dict_t **inputs, uint32_t ninputs,
				    uint32_t *parents,
				    ctf_dynset_t *already_visited,
				    int visited, void *type_id,
				    const char *hval,
				    int (*visit_fun) (const char *hval,
						      ctf_dict_t *output,
						      ctf_dict_t **inputs,
						      uint32_t ninputs,
						      uint32_t *parents,
						      int already_visited,
						      ctf_dict_t *input,
						      ctf_id_t type,
						      void *id,
						      int depth,
						      void *arg),
				    void *arg, unsigned long depth)
{
  ctf_dedup_t *d = &output->ctf_dedup;
  ctf_dict_t *fp;
  int input_num;
  ctf_id_t type;
  int ret;
  const char *whaterr;

  input_num = CTF_DEDUP_GID_TO_INPUT (type_id);
  fp = inputs[input_num];
  type = CTF_DEDUP_GID_TO_TYPE (type_id);

  ctf_dprintf ("%lu: Starting walk over type %s, %i/%lx (%p), from %s, "
	       "kind %i\n", depth, hval, input_num, type, (void *) fp,
	       ctf_link_input_name (fp), ctf_type_kind_unsliced (fp, type));

  /* Get the single call we do if this type has already been visited out of the
     way.  */
  if (visited)
    return visit_fun (hval, output, inputs, ninputs, parents, visited, fp,
		      type, type_id, depth, arg);

  /* This macro is really ugly, but the alternative is repeating this code many
     times, which is worse.  */

#define CTF_TYPE_WALK(type, errlabel, errmsg)				\
  do									\
    {									\
      void *type_id;							\
      const char *hashval;						\
      int cited_type_input_num = input_num;				\
									\
      if ((fp->ctf_flags & LCTF_CHILD) && (LCTF_TYPE_ISPARENT (fp, type))) \
	cited_type_input_num = parents[input_num];			\
									\
      type_id = CTF_DEDUP_GID (output, cited_type_input_num, type);	\
									\
      if (type == 0)							\
	{								\
	  ctf_dprintf ("Walking: unimplemented type\n");		\
	  break;							\
	}								\
									\
      ctf_dprintf ("Looking up ID %i/%lx in type hashes\n",		\
		   cited_type_input_num, type);				\
      hashval = ctf_dynhash_lookup (d->cd_type_hashes, type_id);	\
      if (!ctf_assert (output, hashval))				\
	{								\
	  whaterr = N_("error looking up ID in type hashes");		\
	  goto errlabel;						\
	}								\
      ctf_dprintf ("ID %i/%lx has hash %s\n", cited_type_input_num, type, \
		   hashval);						\
									\
      ret = ctf_dedup_rwalk_output_mapping (output, inputs, ninputs, parents, \
					    already_visited, hashval,	\
					    visit_fun, arg, depth);	\
      if (ret < 0)							\
	{								\
	  whaterr = errmsg;						\
	  goto errlabel;						\
	}								\
    }									\
  while (0)

  switch (ctf_type_kind_unsliced (fp, type))
    {
    case CTF_K_UNKNOWN:
    case CTF_K_FORWARD:
    case CTF_K_INTEGER:
    case CTF_K_FLOAT:
    case CTF_K_ENUM:
      /* No types referenced.  */
      break;

    case CTF_K_TYPEDEF:
    case CTF_K_VOLATILE:
    case CTF_K_CONST:
    case CTF_K_RESTRICT:
    case CTF_K_POINTER:
    case CTF_K_SLICE:
      CTF_TYPE_WALK (ctf_type_reference (fp, type), err,
		     N_("error during referenced type walk"));
      break;

    case CTF_K_ARRAY:
      {
	ctf_arinfo_t ar;

	if (ctf_array_info (fp, type, &ar) < 0)
	  {
	    whaterr = N_("error during array info lookup");
	    goto err_msg;
	  }

	CTF_TYPE_WALK (ar.ctr_contents, err,
		       N_("error during array contents type walk"));
	CTF_TYPE_WALK (ar.ctr_index, err,
		       N_("error during array index type walk"));
	break;
      }

    case CTF_K_FUNCTION:
      {
	ctf_funcinfo_t fi;
	ctf_id_t *args;
	uint32_t j;

	if (ctf_func_type_info (fp, type, &fi) < 0)
	  {
	    whaterr = N_("error during func type info lookup");
	    goto err_msg;
	  }

	CTF_TYPE_WALK (fi.ctc_return, err,
		       N_("error during func return type walk"));

	if ((args = calloc (fi.ctc_argc, sizeof (ctf_id_t))) == NULL)
	  {
	    whaterr = N_("error doing memory allocation");
	    goto err_msg;
	  }

	if (ctf_func_type_args (fp, type, fi.ctc_argc, args) < 0)
	  {
	    whaterr = N_("error doing func arg type lookup");
	    free (args);
	    goto err_msg;
	  }

	for (j = 0; j < fi.ctc_argc; j++)
	  CTF_TYPE_WALK (args[j], err_free_args,
			 N_("error during Func arg type walk"));
	free (args);
	break;

      err_free_args:
	free (args);
	goto err;
      }
    case CTF_K_STRUCT:
    case CTF_K_UNION:
      /* We do not recursively traverse the members of structures: they are
	 emitted later, in a separate pass.  */
	break;
    default:
      whaterr = N_("CTF dict corruption: unknown type kind");
      goto err_msg;
    }

  return visit_fun (hval, output, inputs, ninputs, parents, visited, fp, type,
		    type_id, depth, arg);

 err_msg:
  ctf_set_errno (output, ctf_errno (fp));
  ctf_err_warn (output, 0, 0, _("%s in input file %s at type ID %lx"),
		gettext (whaterr), ctf_link_input_name (fp), type);
 err:
  return -1;
}
/* Recursively traverse the output mapping, and do something with each type
   visited, from leaves to root.  VISIT_FUN, called as recursion unwinds,
   returns a negative error code or zero.  Type hashes may be visited more than
   once, but are not recursed through repeatedly: ALREADY_VISITED tracks whether
   types have already been visited.  */
static int
ctf_dedup_rwalk_output_mapping (ctf_dict_t *output, ctf_dict_t **inputs,
				uint32_t ninputs, uint32_t *parents,
				ctf_dynset_t *already_visited,
				const char *hval,
				int (*visit_fun) (const char *hval,
						  ctf_dict_t *output,
						  ctf_dict_t **inputs,
						  uint32_t ninputs,
						  uint32_t *parents,
						  int already_visited,
						  ctf_dict_t *input,
						  ctf_id_t type,
						  void *id,
						  int depth,
						  void *arg),
				void *arg, unsigned long depth)
{
  ctf_dedup_t *d = &output->ctf_dedup;
  ctf_next_t *i = NULL;
  int err;
  int visited = 1;
  ctf_dynset_t *type_ids;
  void *id;

  depth++;

  type_ids = ctf_dynhash_lookup (d->cd_output_mapping, hval);
  if (!type_ids)
    {
      ctf_err_warn (output, 0, ECTF_INTERNAL,
		    _("looked up type kind by nonexistent hash %s"), hval);
      return ctf_set_errno (output, ECTF_INTERNAL);
    }

  /* Have we seen this type before?  */

  if (!ctf_dynset_exists (already_visited, hval, NULL))
    {
      /* Mark as already-visited immediately, to eliminate the possibility of
	 cycles: but remember we have not actually visited it yet for the
	 upcoming call to the visit_fun.  (All our callers handle cycles
	 properly themselves, so we can just abort them aggressively as soon as
	 we find ourselves in one.)  */

      visited = 0;
      if (ctf_dynset_cinsert (already_visited, hval) < 0)
	{
	  ctf_err_warn (output, 0, ENOMEM,
			_("out of memory tracking already-visited types"));
	  return ctf_set_errno (output, ENOMEM);
	}
    }

  /* If this type is marked conflicted, traverse members and call
     ctf_dedup_rwalk_output_mapping_once on all the unique ones: otherwise, just
     pick a random one and use it.  */

  if (!ctf_dynset_exists (d->cd_conflicting_types, hval, NULL))
    {
      id = ctf_dynset_lookup_any (type_ids);
      if (!ctf_assert (output, id))
	return -1;

      return ctf_dedup_rwalk_one_output_mapping (output, inputs, ninputs,
						 parents, already_visited,
						 visited, id, hval, visit_fun,
						 arg, depth);
    }

  while ((err = ctf_dynset_next (type_ids, &i, &id)) == 0)
    {
      int ret;

      ret = ctf_dedup_rwalk_one_output_mapping (output, inputs, ninputs,
						parents, already_visited,
						visited, id, hval,
						visit_fun, arg, depth);
      if (ret < 0)
	{
	  ctf_next_destroy (i);
	  return ret;				/* errno is set for us.  */
	}
    }
  if (err != ECTF_NEXT_END)
    {
      ctf_err_warn (output, 0, err, _("cannot walk conflicted type"));
      return ctf_set_errno (output, err);
    }

  return 0;
}

typedef struct ctf_sort_om_cb_arg
{
  ctf_dict_t **inputs;
  uint32_t ninputs;
  ctf_dedup_t *d;
} ctf_sort_om_cb_arg_t;

/* Sort the output mapping into order: types first appearing in earlier inputs
   first, parents preceding children: if types first appear in the same input,
   sort those with earlier ctf_id_t's first.  */
static int
sort_output_mapping (const ctf_next_hkv_t *one, const ctf_next_hkv_t *two,
		     void *arg_)
{
  ctf_sort_om_cb_arg_t *arg = (ctf_sort_om_cb_arg_t *) arg_;
  ctf_dedup_t *d = arg->d;
  const char *one_hval = (const char *) one->hkv_key;
  const char *two_hval = (const char *) two->hkv_key;
  void *one_gid, *two_gid;
  uint32_t one_ninput;
  uint32_t two_ninput;
  ctf_dict_t *one_fp;
  ctf_dict_t *two_fp;
  ctf_id_t one_type;
  ctf_id_t two_type;

  one_gid = ctf_dynhash_lookup (d->cd_output_first_gid, one_hval);
  two_gid = ctf_dynhash_lookup (d->cd_output_first_gid, two_hval);

  one_ninput = CTF_DEDUP_GID_TO_INPUT (one_gid);
  two_ninput = CTF_DEDUP_GID_TO_INPUT (two_gid);

  one_type = CTF_DEDUP_GID_TO_TYPE (one_gid);
  two_type = CTF_DEDUP_GID_TO_TYPE (two_gid);

  /* It's kind of hard to smuggle an assertion failure out of here.  */
  assert (one_ninput < arg->ninputs && two_ninput < arg->ninputs);

  one_fp = arg->inputs[one_ninput];
  two_fp = arg->inputs[two_ninput];

  /* Parents before children.  */

  if (!(one_fp->ctf_flags & LCTF_CHILD)
      && (two_fp->ctf_flags & LCTF_CHILD))
    return -1;
  else if ((one_fp->ctf_flags & LCTF_CHILD)
      && !(two_fp->ctf_flags & LCTF_CHILD))
    return 1;

  /* ninput order, types appearing in earlier TUs first.  */

  if (one_ninput < two_ninput)
    return -1;
  else if (two_ninput < one_ninput)
    return 1;

  /* Same TU.  Earliest ctf_id_t first.  They cannot be the same.  */

  assert (one_type != two_type);
  if (one_type < two_type)
    return -1;
  else
    return 1;
}

/* The public entry point to ctf_dedup_rwalk_output_mapping, above.  */
static int
ctf_dedup_walk_output_mapping (ctf_dict_t *output, ctf_dict_t **inputs,
			       uint32_t ninputs, uint32_t *parents,
			       int (*visit_fun) (const char *hval,
						 ctf_dict_t *output,
						 ctf_dict_t **inputs,
						 uint32_t ninputs,
						 uint32_t *parents,
						 int already_visited,
						 ctf_dict_t *input,
						 ctf_id_t type,
						 void *id,
						 int depth,
						 void *arg),
			       void *arg)
{
  ctf_dynset_t *already_visited;
  ctf_next_t *i = NULL;
  ctf_sort_om_cb_arg_t sort_arg;
  int err;
  void *k;

  if ((already_visited = ctf_dynset_create (htab_hash_string,
					    htab_eq_string,
					    NULL)) == NULL)
    return ctf_set_errno (output, ENOMEM);

  sort_arg.inputs = inputs;
  sort_arg.ninputs = ninputs;
  sort_arg.d = &output->ctf_dedup;

  while ((err = ctf_dynhash_next_sorted (output->ctf_dedup.cd_output_mapping,
					 &i, &k, NULL, sort_output_mapping,
					 &sort_arg)) == 0)
    {
      const char *hval = (const char *) k;

      err = ctf_dedup_rwalk_output_mapping (output, inputs, ninputs, parents,
					    already_visited, hval, visit_fun,
					    arg, 0);
      if (err < 0)
	{
	  ctf_next_destroy (i);
	  goto err;				/* errno is set for us.  */
	}
    }
  if (err != ECTF_NEXT_END)
    {
      ctf_err_warn (output, 0, err, _("cannot recurse over output mapping"));
      ctf_set_errno (output, err);
      goto err;
    }
  ctf_dynset_destroy (already_visited);

  return 0;
 err:
  ctf_dynset_destroy (already_visited);
  return -1;
}

/* Possibly synthesise a synthetic forward in TARGET to subsitute for a
   conflicted per-TU type ID in INPUT with hash HVAL.  Return its CTF ID, or 0
   if none was needed.  */
static ctf_id_t
ctf_dedup_maybe_synthesize_forward (ctf_dict_t *output, ctf_dict_t *target,
				    ctf_dict_t *input, ctf_id_t id,
				    const char *hval)
{
  ctf_dedup_t *od = &output->ctf_dedup;
  ctf_dedup_t *td = &target->ctf_dedup;
  int kind;
  int fwdkind;
  const char *name = ctf_type_name_raw (input, id);
  const char *decorated;
  void *v;
  ctf_id_t emitted_forward;

  if (!ctf_dynset_exists (od->cd_conflicting_types, hval, NULL)
      || target->ctf_flags & LCTF_CHILD
      || name[0] == '\0'
      || (((kind = ctf_type_kind_unsliced (input, id)) != CTF_K_STRUCT
	   && kind != CTF_K_UNION && kind != CTF_K_FORWARD)))
    return 0;

  fwdkind = ctf_type_kind_forwarded (input, id);

  ctf_dprintf ("Using synthetic forward for conflicted struct/union with "
	       "hval %s\n", hval);

  if (!ctf_assert (output, name))
    return CTF_ERR;

  if ((decorated = ctf_decorate_type_name (output, name, fwdkind)) == NULL)
    return CTF_ERR;

  if (!ctf_dynhash_lookup_kv (td->cd_output_emission_conflicted_forwards,
			      decorated, NULL, &v))
    {
      if ((emitted_forward = ctf_add_forward (target, CTF_ADD_ROOT, name,
					      fwdkind)) == CTF_ERR)
	{
	  ctf_set_errno (output, ctf_errno (target));
	  return CTF_ERR;
	}

      if (ctf_dynhash_cinsert (td->cd_output_emission_conflicted_forwards,
			       decorated, (void *) (uintptr_t)
			       emitted_forward) < 0)
	{
	  ctf_set_errno (output, ENOMEM);
	  return CTF_ERR;
	}
    }
  else
    emitted_forward = (ctf_id_t) (uintptr_t) v;

  ctf_dprintf ("Cross-TU conflicted struct: passing back forward, %lx\n",
	       emitted_forward);

  return emitted_forward;
}

/* Map a GID in some INPUT dict, in the form of an input number and a ctf_id_t,
   into a GID in a target output dict.  If it returns 0, this is the
   unimplemented type, and the input type must have been 0.  The OUTPUT dict is
   assumed to be the parent of the TARGET, if it is not the TARGET itself.

   Returns CTF_ERR on failure.  Responds to an incoming CTF_ERR as an 'id' by
   returning CTF_ERR, to simplify callers.  Errors are always propagated to the
   input, even if they relate to the target, for the same reason.  (Target
   errors are expected to be very rare.)

   If the type in question is a citation of a conflicted type in a different TU,
   emit a forward of the right type in its place (if not already emitted), and
   record that forward in cd_output_emission_conflicted_forwards.  This avoids
   the need to replicate the entire type graph below this point in the current
   TU (an appalling waste of space).

   TODO: maybe replace forwards in the same TU with their referents?  Might
   make usability a bit better.  */

static ctf_id_t
ctf_dedup_id_to_target (ctf_dict_t *output, ctf_dict_t *target,
			ctf_dict_t **inputs, uint32_t ninputs,
			uint32_t *parents, ctf_dict_t *input, int input_num,
			ctf_id_t id)
{
  ctf_dedup_t *od = &output->ctf_dedup;
  ctf_dedup_t *td = &target->ctf_dedup;
  ctf_dict_t *err_fp = input;
  const char *hval;
  void *target_id;
  ctf_id_t emitted_forward;

  /* The target type of an error is an error.  */
  if (id == CTF_ERR)
    return CTF_ERR;

  /* The unimplemented type's ID never changes.  */
  if (!id)
    {
      ctf_dprintf ("%i/%lx: unimplemented type\n", input_num, id);
      return 0;
    }

  ctf_dprintf ("Mapping %i/%lx to target %p (%s)\n", input_num,
	       id, (void *) target, ctf_link_input_name (target));

  /* If the input type is in the parent type space, and this is a child, reset
     the input to the parent (which must already have been emitted, since
     emission of parent dicts happens before children).  */
  if ((input->ctf_flags & LCTF_CHILD) && (LCTF_TYPE_ISPARENT (input, id)))
    {
      if (!ctf_assert (output, parents[input_num] <= ninputs))
	return -1;
      input = inputs[parents[input_num]];
      input_num = parents[input_num];
    }

  hval = ctf_dynhash_lookup (od->cd_type_hashes,
			     CTF_DEDUP_GID (output, input_num, id));

  if (!ctf_assert (output, hval && td->cd_output_emission_hashes))
    return -1;

  /* If this type is a conflicted tagged structure, union, or forward,
     substitute a synthetic forward instead, emitting it if need be.  Only do
     this if the target is in the parent dict: if it's in the child dict, we can
     just point straight at the thing itself.  Of course, we might be looking in
     the child dict right now and not find it and have to look in the parent, so
     we have to do this check twice.  */

  emitted_forward = ctf_dedup_maybe_synthesize_forward (output, target,
							input, id, hval);
  switch (emitted_forward)
    {
    case 0: /* No forward needed.  */
      break;
    case -1:
      ctf_set_errno (err_fp, ctf_errno (output));
      ctf_err_warn (err_fp, 0, 0, _("cannot add synthetic forward for type "
				    "%i/%lx"), input_num, id);
      return -1;
    default:
      return emitted_forward;
    }

  ctf_dprintf ("Looking up %i/%lx, hash %s, in target\n", input_num, id, hval);

  target_id = ctf_dynhash_lookup (td->cd_output_emission_hashes, hval);
  if (!target_id)
    {
      /* Must be in the parent, so this must be a child, and they must not be
	 the same dict.  */
      ctf_dprintf ("Checking shared parent for target\n");
      if (!ctf_assert (output, (target != output)
		       && (target->ctf_flags & LCTF_CHILD)))
	return -1;

      target_id = ctf_dynhash_lookup (od->cd_output_emission_hashes, hval);

      emitted_forward = ctf_dedup_maybe_synthesize_forward (output, output,
							    input, id, hval);
      switch (emitted_forward)
	{
	case 0: /* No forward needed.  */
	  break;
	case -1:
	  ctf_err_warn (err_fp, 0, ctf_errno (output),
			_("cannot add synthetic forward for type %i/%lx"),
			input_num, id);
	  return ctf_set_errno (err_fp, ctf_errno (output));
	default:
	  return emitted_forward;
	}
    }
  if (!ctf_assert (output, target_id))
    return -1;
  return (ctf_id_t) (uintptr_t) target_id;
}

/* Emit a single deduplicated TYPE with the given HVAL, located in a given
   INPUT, with the given (G)ID, into the shared OUTPUT or a
   possibly-newly-created per-CU dict.  All the types this type depends upon
   have already been emitted.  (This type itself may also have been emitted.)

   If the ARG is 1, this is a CU-mapped deduplication round mapping many
   ctf_dict_t's into precisely one: conflicting types should be marked
   non-root-visible.  If the ARG is 0, conflicting types go into per-CU
   dictionaries stored in the input's ctf_dedup.cd_output: otherwise, everything
   is emitted directly into the output.  No struct/union members are emitted.

   Optimization opportunity: trace the ancestry of non-root-visible types and
   elide all that neither have a root-visible type somewhere towards their root,
   nor have the type visible via any other route (the function info section,
   data object section, backtrace section etc).  */

static int
ctf_dedup_emit_type (const char *hval, ctf_dict_t *output, ctf_dict_t **inputs,
		     uint32_t ninputs, uint32_t *parents, int already_visited,
		     ctf_dict_t *input, ctf_id_t type, void *id, int depth,
		     void *arg)
{
  ctf_dedup_t *d = &output->ctf_dedup;
  int kind = ctf_type_kind_unsliced (input, type);
  const char *name;
  ctf_dict_t *target = output;
  ctf_dict_t *real_input;
  const ctf_type_t *tp;
  int input_num = CTF_DEDUP_GID_TO_INPUT (id);
  int output_num = (uint32_t) -1;		/* 'shared' */
  int cu_mapped = *(int *)arg;
  int isroot = 1;
  int is_conflicting;

  ctf_next_t *i = NULL;
  ctf_id_t new_type;
  ctf_id_t ref;
  ctf_id_t maybe_dup = 0;
  ctf_encoding_t ep;
  const char *errtype;
  int emission_hashed = 0;

  /* We don't want to re-emit something we've already emitted.  */

  if (already_visited)
    return 0;

  ctf_dprintf ("%i: Emitting type with hash %s from %s: determining target\n",
	       depth, hval, ctf_link_input_name (input));

  /* Conflicting types go into a per-CU output dictionary, unless this is a
     CU-mapped run.  The import is not refcounted, since it goes into the
     ctf_link_outputs dict of the output that is its parent.  */
  is_conflicting = ctf_dynset_exists (d->cd_conflicting_types, hval, NULL);

  if (is_conflicting && !cu_mapped)
    {
      ctf_dprintf ("%i: Type %s in %i/%lx is conflicted: "
		   "inserting into per-CU target.\n",
		   depth, hval, input_num, type);

      if (input->ctf_dedup.cd_output)
	target = input->ctf_dedup.cd_output;
      else
	{
	  int err;

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

	  ctf_import_unref (target, output);
	  if (ctf_cuname (input) != NULL)
	    ctf_cuname_set (target, ctf_cuname (input));
	  else
	    ctf_cuname_set (target, "unnamed-CU");
	  ctf_parent_name_set (target, _CTF_SECTION);

	  input->ctf_dedup.cd_output = target;
	  input->ctf_link_in_out = target;
	  target->ctf_link_in_out = input;
	}
      output_num = input_num;
    }

  real_input = input;
  if ((tp = ctf_lookup_by_id (&real_input, type)) == NULL)
    {
      ctf_err_warn (output, 0, ctf_errno (input),
		    _("%s: lookup failure for type %lx"),
		    ctf_link_input_name (real_input), type);
      return ctf_set_errno (output, ctf_errno (input));
    }

  name = ctf_strraw (real_input, tp->ctt_name);

  /* Hide conflicting types, if we were asked to: also hide if a type with this
     name already exists and is not a forward.  */
  if (cu_mapped && is_conflicting)
    isroot = 0;
  else if (name
	   && (maybe_dup = ctf_lookup_by_rawname (target, kind, name)) != 0)
    {
      if (ctf_type_kind (target, maybe_dup) != CTF_K_FORWARD)
	isroot = 0;
    }

  ctf_dprintf ("%i: Emitting type with hash %s (%s), into target %i/%p\n",
	       depth, hval, name ? name : "", input_num, (void *) target);

  if (!target->ctf_dedup.cd_output_emission_hashes)
    if ((target->ctf_dedup.cd_output_emission_hashes
	 = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
			      NULL, NULL)) == NULL)
      goto oom_hash;

  if (!target->ctf_dedup.cd_output_emission_conflicted_forwards)
    if ((target->ctf_dedup.cd_output_emission_conflicted_forwards
	 = ctf_dynhash_create (ctf_hash_string, ctf_hash_eq_string,
			      NULL, NULL)) == NULL)
      goto oom_hash;

  switch (kind)
    {
    case CTF_K_UNKNOWN:
      /* These are types that CTF cannot encode, marked as such by the
	 compiler.  */
      errtype = _("unknown type");
      if ((new_type = ctf_add_unknown (target, isroot, name)) == CTF_ERR)
	goto err_target;
      break;
    case CTF_K_FORWARD:
      /* This will do nothing if the type to which this forwards already exists,
	 and will be replaced with such a type if it appears later.  */

      errtype = _("forward");
      if ((new_type = ctf_add_forward (target, isroot, name,
				       ctf_type_kind_forwarded (input, type)))
	  == CTF_ERR)
	goto err_target;
      break;

    case CTF_K_FLOAT:
    case CTF_K_INTEGER:
      errtype = _("float/int");
      if (ctf_type_encoding (input, type, &ep) < 0)
	goto err_input;				/* errno is set for us.  */
      if ((new_type = ctf_add_encoded (target, isroot, name, &ep, kind))
	  == CTF_ERR)
	goto err_target;
      break;

    case CTF_K_ENUM:
      {
	int val;
	errtype = _("enum");
	if ((new_type = ctf_add_enum (target, isroot, name)) == CTF_ERR)
	  goto err_input;				/* errno is set for us.  */

	while ((name = ctf_enum_next (input, type, &i, &val)) != NULL)
	  {
	    if (ctf_add_enumerator (target, new_type, name, val) < 0)
	      {
		ctf_err_warn (target, 0, ctf_errno (target),
			      _("%s (%i): cannot add enumeration value %s "
				"from input type %lx"),
			      ctf_link_input_name (input), input_num, name,
			      type);
		ctf_next_destroy (i);
		return ctf_set_errno (output, ctf_errno (target));
	      }
	  }
	if (ctf_errno (input) != ECTF_NEXT_END)
	  goto err_input;
	break;
      }

    case CTF_K_TYPEDEF:
      errtype = _("typedef");

      ref = ctf_type_reference (input, type);
      if ((ref = ctf_dedup_id_to_target (output, target, inputs, ninputs,
					 parents, input, input_num,
					 ref)) == CTF_ERR)
	goto err_input;				/* errno is set for us.  */

      if ((new_type = ctf_add_typedef (target, isroot, name, ref)) == CTF_ERR)
	goto err_target;			/* errno is set for us.  */
      break;

    case CTF_K_VOLATILE:
    case CTF_K_CONST:
    case CTF_K_RESTRICT:
    case CTF_K_POINTER:
      errtype = _("pointer or cvr-qual");

      ref = ctf_type_reference (input, type);
      if ((ref = ctf_dedup_id_to_target (output, target, inputs, ninputs,
					 parents, input, input_num,
					 ref)) == CTF_ERR)
	goto err_input;				/* errno is set for us.  */

      if ((new_type = ctf_add_reftype (target, isroot, ref, kind)) == CTF_ERR)
	goto err_target;			/* errno is set for us.  */
      break;

    case CTF_K_SLICE:
      errtype = _("slice");

      if (ctf_type_encoding (input, type, &ep) < 0)
	goto err_input;				/* errno is set for us.  */

      ref = ctf_type_reference (input, type);
      if ((ref = ctf_dedup_id_to_target (output, target, inputs, ninputs,
					 parents, input, input_num,
					 ref)) == CTF_ERR)
	goto err_input;

      if ((new_type = ctf_add_slice (target, isroot, ref, &ep)) == CTF_ERR)
	goto err_target;
      break;

    case CTF_K_ARRAY:
      {
	ctf_arinfo_t ar;

	errtype = _("array info");
	if (ctf_array_info (input, type, &ar) < 0)
	  goto err_input;

	ar.ctr_contents = ctf_dedup_id_to_target (output, target, inputs,
						  ninputs, parents, input,
						  input_num, ar.ctr_contents);
	ar.ctr_index = ctf_dedup_id_to_target (output, target, inputs, ninputs,
					       parents, input, input_num,
					       ar.ctr_index);

	if (ar.ctr_contents == CTF_ERR || ar.ctr_index == CTF_ERR)
	  goto err_input;

	if ((new_type = ctf_add_array (target, isroot, &ar)) == CTF_ERR)
	  goto err_target;

	break;
      }

    case CTF_K_FUNCTION:
      {
	ctf_funcinfo_t fi;
	ctf_id_t *args;
	uint32_t j;

	errtype = _("function");
	if (ctf_func_type_info (input, type, &fi) < 0)
	  goto err_input;

	fi.ctc_return = ctf_dedup_id_to_target (output, target, inputs, ninputs,
						parents, input, input_num,
						fi.ctc_return);
	if (fi.ctc_return == CTF_ERR)
	  goto err_input;

	if ((args = calloc (fi.ctc_argc, sizeof (ctf_id_t))) == NULL)
	  {
	    ctf_set_errno (input, ENOMEM);
	    goto err_input;
	  }

	errtype = _("function args");
	if (ctf_func_type_args (input, type, fi.ctc_argc, args) < 0)
	  {
	    free (args);
	    goto err_input;
	  }

	for (j = 0; j < fi.ctc_argc; j++)
	  {
	    args[j] = ctf_dedup_id_to_target (output, target, inputs, ninputs,
					      parents, input, input_num,
					      args[j]);
	    if (args[j] == CTF_ERR)
	      goto err_input;
	  }

	if ((new_type = ctf_add_function (target, isroot,
					  &fi, args)) == CTF_ERR)
	  {
	    free (args);
	    goto err_target;
	  }
	free (args);
	break;
      }

    case CTF_K_STRUCT:
    case CTF_K_UNION:
      {
	size_t size = ctf_type_size (input, type);
	void *out_id;
	/* Insert the structure itself, so other types can refer to it.  */

	errtype = _("structure/union");
	if (kind == CTF_K_STRUCT)
	  new_type = ctf_add_struct_sized (target, isroot, name, size);
	else
	  new_type = ctf_add_union_sized (target, isroot, name, size);

	if (new_type == CTF_ERR)
	  goto err_target;

	out_id = CTF_DEDUP_GID (output, output_num, new_type);
	ctf_dprintf ("%i: Noting need to emit members of %p -> %p\n", depth,
		     id, out_id);
	/* Record the need to emit the members of this structure later.  */
	if (ctf_dynhash_insert (d->cd_emission_struct_members, id, out_id) < 0)
	  {
	    ctf_set_errno (target, errno);
	    goto err_target;
	  }
	break;
      }
    default:
      ctf_err_warn (output, 0, ECTF_CORRUPT, _("%s: unknown type kind for "
					       "input type %lx"),
		    ctf_link_input_name (input), type);
      return ctf_set_errno (output, ECTF_CORRUPT);
    }

  if (!emission_hashed
      && new_type != 0
      && ctf_dynhash_cinsert (target->ctf_dedup.cd_output_emission_hashes,
			      hval, (void *) (uintptr_t) new_type) < 0)
    {
      ctf_err_warn (output, 0, ENOMEM, _("out of memory tracking deduplicated "
					 "global type IDs"));
	return ctf_set_errno (output, ENOMEM);
    }

  if (!emission_hashed && new_type != 0)
    ctf_dprintf ("%i: Inserted %s, %i/%lx -> %lx into emission hash for "
		 "target %p (%s)\n", depth, hval, input_num, type, new_type,
		 (void *) target, ctf_link_input_name (target));

  return 0;

 oom_hash:
  ctf_err_warn (output, 0, ENOMEM, _("out of memory creating emission-tracking "
				     "hashes"));
  return ctf_set_errno (output, ENOMEM);

 err_input:
  ctf_err_warn (output, 0, ctf_errno (input),
		_("%s (%i): while emitting deduplicated %s, error getting "
		  "input type %lx"), ctf_link_input_name (input),
		input_num, errtype, type);
  return ctf_set_errno (output, ctf_errno (input));
 err_target:
  ctf_err_warn (output, 0, ctf_errno (target),
		_("%s (%i): while emitting deduplicated %s, error emitting "
		  "target type from input type %lx"),
		ctf_link_input_name (input), input_num,
		errtype, type);
  return ctf_set_errno (output, ctf_errno (target));
}

/* Traverse the cd_emission_struct_members and emit the members of all
   structures and unions.  All other types are emitted and complete by this
   point.  */

static int
ctf_dedup_emit_struct_members (ctf_dict_t *output, ctf_dict_t **inputs,
			       uint32_t ninputs, uint32_t *parents)
{
  ctf_dedup_t *d = &output->ctf_dedup;
  ctf_next_t *i = NULL;
  void *input_id, *target_id;
  int err;
  ctf_dict_t *err_fp, *input_fp;
  int input_num;
  ctf_id_t err_type;

  while ((err = ctf_dynhash_next (d->cd_emission_struct_members, &i,
				  &input_id, &target_id)) == 0)
    {
      ctf_next_t *j = NULL;
      ctf_dict_t *target;
      uint32_t target_num;
      ctf_id_t input_type, target_type;
      ssize_t offset;
      ctf_id_t membtype;
      const char *name;

      input_num = CTF_DEDUP_GID_TO_INPUT (input_id);
      input_fp = inputs[input_num];
      input_type = CTF_DEDUP_GID_TO_TYPE (input_id);

      /* The output is either -1 (for the shared, parent output dict) or the
	 number of the corresponding input.  */
      target_num = CTF_DEDUP_GID_TO_INPUT (target_id);
      if (target_num == (uint32_t) -1)
	target = output;
      else
	{
	  target = inputs[target_num]->ctf_dedup.cd_output;
	  if (!ctf_assert (output, target))
	    {
	      err_fp = output;
	      err_type = input_type;
	      goto err_target;
	    }
	}
      target_type = CTF_DEDUP_GID_TO_TYPE (target_id);

      while ((offset = ctf_member_next (input_fp, input_type, &j, &name,
					&membtype, 0)) >= 0)
	{
	  err_fp = target;
	  err_type = target_type;
	  if ((membtype = ctf_dedup_id_to_target (output, target, inputs,
						  ninputs, parents, input_fp,
						  input_num,
						  membtype)) == CTF_ERR)
	    {
	      ctf_next_destroy (j);
	      goto err_target;
	    }

	  if (name == NULL)
	    name = "";
#ifdef ENABLE_LIBCTF_HASH_DEBUGGING
	  ctf_dprintf ("Emitting %s, offset %zi\n", name, offset);
#endif
	  if (ctf_add_member_offset (target, target_type, name,
				     membtype, offset) < 0)
	    {
	      ctf_next_destroy (j);
	      goto err_target;
	    }
	}
      if (ctf_errno (input_fp) != ECTF_NEXT_END)
	{
	  err = ctf_errno (input_fp);
	  ctf_next_destroy (i);
	  goto iterr;
	}
    }
  if (err != ECTF_NEXT_END)
    goto iterr;

  return 0;
 err_target:
  ctf_next_destroy (i);
  ctf_err_warn (output, 0, ctf_errno (err_fp),
		_("%s (%i): error emitting members for structure type %lx"),
		ctf_link_input_name (input_fp), input_num, err_type);
  return ctf_set_errno (output, ctf_errno (err_fp));
 iterr:
  ctf_err_warn (output, 0, err, _("iteration failure emitting "
				  "structure members"));
  return ctf_set_errno (output, err);
}

/* Emit deduplicated types into the outputs.  The shared type repository is
   OUTPUT, on which the ctf_dedup function must have already been called.  The
   PARENTS array contains the INPUTS index of the parent dict for every child
   dict at the corresponding index in the INPUTS (for non-child dicts, the value
   is undefined).

   Return an array of fps with content emitted into them (starting with OUTPUT,
   which is the parent of all others, then all the newly-generated outputs).

   If CU_MAPPED is set, this is a first pass for a link with a non-empty CU
   mapping: only one output will result.  */

ctf_dict_t **
ctf_dedup_emit (ctf_dict_t *output, ctf_dict_t **inputs, uint32_t ninputs,
		uint32_t *parents, uint32_t *noutputs, int cu_mapped)
{
  size_t num_outputs = 1;		/* Always at least one output: us.  */
  ctf_dict_t **outputs;
  ctf_dict_t **walk;
  size_t i;

  ctf_dprintf ("Triggering emission.\n");
  if (ctf_dedup_walk_output_mapping (output, inputs, ninputs, parents,
				     ctf_dedup_emit_type, &cu_mapped) < 0)
    return NULL;				/* errno is set for us.  */

  ctf_dprintf ("Populating struct members.\n");
  if (ctf_dedup_emit_struct_members (output, inputs, ninputs, parents) < 0)
    return NULL;				/* errno is set for us.  */

  for (i = 0; i < ninputs; i++)
    {
      if (inputs[i]->ctf_dedup.cd_output)
	num_outputs++;
    }

  if (!ctf_assert (output, !cu_mapped || (cu_mapped && num_outputs == 1)))
    return NULL;

  if ((outputs = calloc (num_outputs, sizeof (ctf_dict_t *))) == NULL)
    {
      ctf_err_warn (output, 0, ENOMEM,
		    _("out of memory allocating link outputs array"));
      ctf_set_errno (output, ENOMEM);
      return NULL;
    }
  *noutputs = num_outputs;

  walk = outputs;
  *walk = output;
  output->ctf_refcnt++;
  walk++;

  for (i = 0; i < ninputs; i++)
    {
      if (inputs[i]->ctf_dedup.cd_output)
	{
	  *walk = inputs[i]->ctf_dedup.cd_output;
	  inputs[i]->ctf_dedup.cd_output = NULL;
	  walk++;
	}
    }

  return outputs;
}

/* Determine what type SRC_FP / SRC_TYPE was emitted as in the FP, which
   must be the shared dict or have it as a parent: return 0 if none.  The SRC_FP
   must be a past input to ctf_dedup.  */

ctf_id_t
ctf_dedup_type_mapping (ctf_dict_t *fp, ctf_dict_t *src_fp, ctf_id_t src_type)
{
  ctf_dict_t *output = NULL;
  ctf_dedup_t *d;
  int input_num;
  void *num_ptr;
  void *type_ptr;
  int found;
  const char *hval;

  /* It is an error (an internal error in the caller, in ctf-link.c) to call
     this with an FP that is not a per-CU output or shared output dict, or with
     a SRC_FP that was not passed to ctf_dedup as an input; it is an internal
     error in ctf-dedup for the type passed not to have been hashed, though if
     the src_fp is a child dict and the type is not a child type, it will have
     been hashed under the GID corresponding to the parent.  */

  if (fp->ctf_dedup.cd_type_hashes != NULL)
    output = fp;
  else if (fp->ctf_parent && fp->ctf_parent->ctf_dedup.cd_type_hashes != NULL)
    output = fp->ctf_parent;
  else
    {
      ctf_set_errno (fp, ECTF_INTERNAL);
      ctf_err_warn (fp, 0, ECTF_INTERNAL,
		    _("dict %p passed to ctf_dedup_type_mapping is not a "
		      "deduplicated output"), (void *) fp);
      return CTF_ERR;
    }

  if (src_fp->ctf_parent && ctf_type_isparent (src_fp, src_type))
    src_fp = src_fp->ctf_parent;

  d = &output->ctf_dedup;

  found = ctf_dynhash_lookup_kv (d->cd_input_nums, src_fp, NULL, &num_ptr);
  if (!ctf_assert (output, found != 0))
    return CTF_ERR;				/* errno is set for us.  */
  input_num = (uintptr_t) num_ptr;

  hval = ctf_dynhash_lookup (d->cd_type_hashes,
			     CTF_DEDUP_GID (output, input_num, src_type));

  if (!ctf_assert (output, hval != NULL))
    return CTF_ERR;				/* errno is set for us.  */

  /* The emission hashes may be unset if this dict was created after
     deduplication to house variables or other things that would conflict if
     stored in the shared dict.  */
  if (fp->ctf_dedup.cd_output_emission_hashes)
    if (ctf_dynhash_lookup_kv (fp->ctf_dedup.cd_output_emission_hashes, hval,
			       NULL, &type_ptr))
      return (ctf_id_t) (uintptr_t) type_ptr;

  if (fp->ctf_parent)
    {
      ctf_dict_t *pfp = fp->ctf_parent;
      if (pfp->ctf_dedup.cd_output_emission_hashes)
	if (ctf_dynhash_lookup_kv (pfp->ctf_dedup.cd_output_emission_hashes,
				   hval, NULL, &type_ptr))
	  return (ctf_id_t) (uintptr_t) type_ptr;
    }

  return 0;
}
