for (i = 0; i < fp->ctf_nsyms; i++)
     {
       char *str;
-      char *bit;
+      char *bit = NULL;
       const char *err;
       const char *sym_name;
       ctf_funcinfo_t fi;
       ctf_id_t type;
-      size_t j;
-      ctf_id_t *args;
 
       if ((type = ctf_func_info (state->cds_fp, i, &fi)) == CTF_ERR)
        switch (ctf_errno (state->cds_fp))
          case ECTF_NOFUNCDAT:
            continue;
          }
-      if ((args = calloc (fi.ctc_argc, sizeof (ctf_id_t))) == NULL)
-       return (ctf_set_errno (fp, ENOMEM));
 
-      /* Return type.  */
-      if ((str = ctf_type_aname (state->cds_fp, type)) == NULL)
+      /* Return type and all args.  */
+      if ((bit = ctf_type_aname (state->cds_fp, type)) == NULL)
        {
          err = "look up return type";
          goto err;
        }
 
-      str = str_append (str, " ");
-
-      /* Function name.  */
+      /* Replace in the returned string, dropping in the function name.  */
 
       sym_name = ctf_lookup_symbol_name (fp, i);
-      if (sym_name[0] == '\0')
+      if (sym_name[0] != '\0')
        {
-         if (asprintf (&bit, "0x%lx ", (unsigned long) i) < 0)
-           goto oom;
-       }
-      else
-       {
-         if (asprintf (&bit, "%s (0x%lx) ", sym_name, (unsigned long) i) < 0)
+         char *retstar;
+         char *new_bit;
+         char *walk;
+
+         new_bit = malloc (strlen (bit) + 1 + strlen (sym_name));
+         if (!new_bit)
            goto oom;
-       }
-      str = str_append (str, bit);
-      str = str_append (str, " (");
-      free (bit);
 
-      /* Function arguments.  */
+         /* See ctf_type_aname.  */
+         retstar = strstr (bit, "(*) (");
+         if (!ctf_assert (fp, retstar))
+           goto assert_err;
+         retstar += 2;                 /* After the '*' */
 
-      if (ctf_func_args (state->cds_fp, i, fi.ctc_argc, args) < 0)
-       {
-         err = "look up argument type";
-         goto err;
-       }
+         /* C is not good at search-and-replace.  */
+         walk = new_bit;
+         memcpy (walk, bit, retstar - bit);
+         walk += (retstar - bit);
+         strcpy (walk, sym_name);
+         walk += strlen (sym_name);
+         strcpy (walk, retstar);
 
-      for (j = 0; j < fi.ctc_argc; j++)
-       {
-         if ((bit = ctf_type_aname (state->cds_fp, args[j])) == NULL)
-           {
-             err = "look up argument type name";
-             goto err;
-           }
-         str = str_append (str, bit);
-         if ((j < fi.ctc_argc - 1) || (fi.ctc_flags & CTF_FUNC_VARARG))
-           str = str_append (str, ", ");
          free (bit);
+         bit = new_bit;
        }
 
-      if (fi.ctc_flags & CTF_FUNC_VARARG)
-       str = str_append (str, "...");
-      str = str_append (str, ")");
+      if (asprintf (&str, "Symbol 0x%lx: %s", (unsigned long) i, bit) < 0)
+       goto oom;
+      free (bit);
 
-      free (args);
       ctf_dump_append (state, str);
       continue;
 
+    err:
+      ctf_err_warn (fp, 1, "Cannot %s dumping function type for "
+                   "symbol 0x%li: %s", err, (unsigned long) i,
+                   ctf_errmsg (ctf_errno (state->cds_fp)));
+      free (bit);
+      return -1;               /* errno is set for us.  */
+
     oom:
-      free (args);
-      free (str);
+      free (bit);
       return (ctf_set_errno (fp, errno));
-    err:
-      ctf_dprintf ("Cannot %s dumping function type for symbol 0x%li: %s\n",
-                  err, (unsigned long) i,
-                  ctf_errmsg (ctf_errno (state->cds_fp)));
-      free (args);
-      free (str);
+
+    assert_err:
+      free (bit);
       return -1;               /* errno is set for us.  */
     }
   return 0;
 
              ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
              break;
            case CTF_K_FUNCTION:
-             ctf_decl_sprintf (&cd, "()");
+             {
+               size_t i;
+               ctf_funcinfo_t fi;
+               ctf_id_t *argv = NULL;
+
+               if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
+                 goto err;             /* errno is set for us.  */
+
+               if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
+                 {
+                   ctf_set_errno (rfp, errno);
+                   goto err;
+                 }
+
+               if (ctf_func_type_args (rfp, cdp->cd_type,
+                                       fi.ctc_argc, argv) < 0)
+                 goto err;             /* errno is set for us.  */
+
+               ctf_decl_sprintf (&cd, "(*) (");
+               for (i = 0; i < fi.ctc_argc; i++)
+                 {
+                   char *arg = ctf_type_aname (rfp, argv[i]);
+
+                   if (arg == NULL)
+                     goto err;         /* errno is set for us.  */
+                   ctf_decl_sprintf (&cd, "%s", arg);
+                   free (arg);
+
+                   if ((i < fi.ctc_argc - 1)
+                       || (fi.ctc_flags & CTF_FUNC_VARARG))
+                     ctf_decl_sprintf (&cd, ", ");
+                 }
+
+               if (fi.ctc_flags & CTF_FUNC_VARARG)
+                 ctf_decl_sprintf (&cd, "...");
+               ctf_decl_sprintf (&cd, ")");
+
+               free (argv);
+               break;
+
+             err:
+               free (argv);
+               ctf_decl_fini (&cd);
+               return NULL;
+             }
              break;
            case CTF_K_STRUCT:
            case CTF_K_FORWARD: