struct objfile *of = ccp->of;
ctf_dict_t *dict = ccp->dict;
struct type *type, *rettype, *atype;
- ctf_funcinfo_t cfi;
- uint32_t argc;
+ ctf_func_type_flags_t cflags;
+ ctf_id_t cret;
+ ctf_id_t *argv;
+ size_t argc;
type = type_allocator (of, language_c).new_type ();
type->set_code (TYPE_CODE_FUNC);
- if (ctf_func_type_info (dict, tid, &cfi) < 0)
+ if ((argv = ctf_func_type (dict, tid, &cret, &cflags, &argc)) == NULL)
{
const char *fname = ctf_type_name_raw (dict, tid);
error (_("Error getting function type info: %s"),
fname == nullptr ? "noname" : fname);
}
- rettype = fetch_tid_type (ccp, cfi.ctc_return);
+ rettype = fetch_tid_type (ccp, cret);
type->set_target_type (rettype);
set_type_align (type, ctf_type_align (dict, tid));
/* Set up function's arguments. */
- argc = cfi.ctc_argc;
type->set_num_fields (argc);
- if ((cfi.ctc_flags & CTF_FUNC_VARARG) != 0)
+ if ((cflags & CTF_FUNC_VARARG) != 0)
type->set_has_varargs (true);
if (argc != 0)
{
- std::vector<ctf_id_t> argv (argc);
- if (ctf_func_type_args (dict, tid, argc, argv.data ()) == CTF_ERR)
- return nullptr;
-
type->alloc_fields (argc);
struct type *void_type = builtin_type (of)->builtin_void;
/* If failed to find the argument type, fill it with void_type. */
type->field (iparam).set_type (void_type);
}
}
-
+ free (argv);
return set_tid_type (of, tid, type);
}
size_t ctr_nelems; /* Number of elements. */
} ctf_arinfo_t;
-typedef struct ctf_funcinfo
-{
- ctf_id_t ctc_return; /* Function return type. */
- size_t ctc_argc; /* Number of typed arguments to function. */
- uint32_t ctc_flags; /* Function attributes (see below). */
-} ctf_funcinfo_t;
-
typedef struct ctf_enum_value /* The value of an enumerator. Can just be
cast to an int/int64 if you like. */
{
unsigned long snapshot_id; /* Snapshot id at time of snapshot. */
} ctf_snapshot_id_t;
-#define CTF_FUNC_VARARG 0x1 /* Function arguments end with varargs. */
+typedef enum ctf_func_type_flags
+ {
+ CTF_FUNC_VARARG = 0x1 /* Function arguments end with varargs. */
+ } ctf_func_type_flags_t;
/* Functions that return a ctf_id_t use the following value to indicate failure.
ctf_errno can be used to obtain an error code. Functions that return
extern int ctf_version (int ctf_version_, size_t btf_hdr_len,
ctf_btf_mode_t btf_mode);
-/* Given a symbol table index corresponding to a function symbol, return info on
- the type of a given function's arguments or return value, or its parameter
- names. Vararg functions have a final arg with CTF_FUNC_VARARG on in
- ctc_flags. */
+/* Given a type ID relating to a function type or function linkage type, return
+ an array of arg types, and optionally in the RET argument the return type
+ too. Vararg functions set CTF_FUNC_VARARG in the optional FLAG argument. The
+ NARGS arg gives the length of the array (optional because it will always
+ have the same value when you call both ctf_func_type and ctf_func_arg_names,
+ so you only need to get it from one of them). */
-extern int ctf_func_info (ctf_dict_t *, unsigned long, ctf_funcinfo_t *);
-extern int ctf_func_args (ctf_dict_t *, unsigned long, uint32_t, ctf_id_t *);
-extern int ctf_func_arg_names (ctf_dict_t *, unsigned long, uint32_t, const char **);
+extern ctf_id_t *ctf_func_type (ctf_dict_t *, ctf_id_t, ctf_id_t *ret_type,
+ ctf_func_type_flags_t *flags, size_t *nargs);
-/* As above, but for CTF_K_FUNCTION or CTF_K_FUNC_LINKAGE types in CTF dicts. */
+/* Likewise, for the argument names. */
-extern int ctf_func_type_info (ctf_dict_t *, ctf_id_t, ctf_funcinfo_t *);
-extern int ctf_func_type_args (ctf_dict_t *, ctf_id_t, uint32_t, ctf_id_t *);
-extern int ctf_func_type_arg_names (ctf_dict_t *, ctf_id_t, uint32_t,
- const char **);
+extern const char **ctf_func_arg_names (ctf_dict_t *, ctf_id_t, size_t *nargs);
/* Get the linkage of a CTF_K_FUNC_LINKAGE or variable. */
/* ctf_add_function adds an unnamed function with a bundle of arguments and a
return type. ctf_add_function_linkage provides a function with a name
and linkage, which is one of the CTF_FUNC_LINKAGE_* constants. */
-extern ctf_id_t ctf_add_function (ctf_dict_t *, uint32_t,
- const ctf_funcinfo_t *, const ctf_id_t *,
- const char **arg_names);
+
+extern ctf_id_t ctf_add_function (ctf_dict_t *fp, uint32_t flag,
+ ctf_id_t ret_type, ctf_func_type_flags_t flags,
+ const ctf_id_t *argv, const char **arg_names,
+ size_t nargs);
+
extern ctf_id_t ctf_add_function_linkage (ctf_dict_t *, uint32_t,
ctf_id_t, const char *,
ctf_linkages_t linkage);
case CTF_K_FUNCTION:
{
- ctf_funcinfo_t fi;
+ ctf_id_t *args;
+ size_t nargs;
- if (ctf_func_type_info (fp, func_type, &fi) < 0)
+ if ((args = ctf_func_type (fp, func_type, NULL, NULL,
+ &nargs)) == NULL)
return -1; /* errno is set for us. */
+ free (args);
- if ((size_t) component_idx >= fi.ctc_argc)
+ if ((size_t) component_idx >= nargs)
return (ctf_set_typed_errno (fp, ECTF_BADCOMPONENT));
break;
}
ctf_id_t
-ctf_add_function (ctf_dict_t *fp, uint32_t flag,
- const ctf_funcinfo_t *ctc, const ctf_id_t *argv,
- const char **arg_names)
+ctf_add_function (ctf_dict_t *fp, uint32_t flag, ctf_id_t ret_type,
+ ctf_func_type_flags_t flags, const ctf_id_t *argv,
+ const char **arg_names, size_t nargs)
{
ctf_dtdef_t *dtd;
uint32_t vlen;
ctf_dict_t *tmp = fp;
size_t i;
- if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
- || (ctc->ctc_argc != 0 && argv == NULL))
+ if ((flags & ~CTF_FUNC_VARARG) != 0 || (nargs != 0 && argv == NULL))
return (ctf_set_typed_errno (fp, EINVAL));
- vlen = ctc->ctc_argc;
+ vlen = nargs;
/* UPTODO: CTF_K_BIG prefix for big functions? */
if (vlen > 0xffff)
return (ctf_set_typed_errno (fp, EOVERFLOW));
- if (ctc->ctc_flags & CTF_FUNC_VARARG)
+ if (flags & CTF_FUNC_VARARG)
vlen++; /* Add trailing zero to indicate varargs (see below). */
- if (ctc->ctc_return != 0
- && ctf_lookup_by_id (&tmp, ctc->ctc_return, NULL) == NULL)
+ if (ret_type != 0
+ && ctf_lookup_by_id (&tmp, ret_type, NULL) == NULL)
return CTF_ERR; /* errno is set for us. */
- for (i = 0; i < ctc->ctc_argc; i++)
+ for (i = 0; i < nargs; i++)
{
tmp = fp;
if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i], NULL) == NULL)
vdat = (ctf_param_t *) dtd->dtd_vlen;
- for (i = 0; i < ctc->ctc_argc; i++)
+ for (i = 0; i < nargs; i++)
{
vdat[i].cfp_name = ctf_str_add (fp, arg_names[i]);
vdat[i].cfp_type = (uint32_t) argv[i];
}
dtd->dtd_data->ctt_info = CTF_TYPE_INFO (CTF_K_FUNCTION, 0, vlen);
- dtd->dtd_data->ctt_type = (uint32_t) ctc->ctc_return;
+ dtd->dtd_data->ctt_type = (uint32_t) ret_type;
- if (ctc->ctc_flags & CTF_FUNC_VARARG)
+ if (flags & CTF_FUNC_VARARG)
{
vdat[vlen - 1].cfp_type = 0; /* Add trailing zero to indicate varargs. */
vdat[vlen - 1].cfp_name = 0;
/* UPTODO: FUNC_LINKAGE, DATASEC, VAR, *TAG */
case CTF_K_FUNCTION:
{
- ctf_funcinfo_t fi;
+ ctf_func_type_flags_t flags;
+ ctf_id_t ret;
ctf_id_t *argv;
+ size_t nargs;
const char **arg_names;
size_t i;
- if (ctf_func_type_info (src_fp, src_type, &fi) < 0)
+ if ((argv = ctf_func_type (src_fp, src_type, &ret, &flags, &nargs)) == NULL)
return CTF_ERR; /* errno is set for us. */
- fi.ctc_return = ctf_add_type_internal (dst_fp, src_fp,
- src_tp->ctt_type,
- proc_tracking_fp);
+ ret = ctf_add_type_internal (dst_fp, src_fp, ret, proc_tracking_fp);
- if (fi.ctc_return == CTF_ERR)
- return CTF_ERR; /* errno is set for us. */
-
- if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
- {
- ctf_set_errno (src_fp, errno);
- return CTF_ERR;
- }
-
- if (ctf_func_type_args (src_fp, src_type, fi.ctc_argc, argv) < 0)
+ if (ret == CTF_ERR)
{
free (argv);
- return CTF_ERR; /* errno is set for us. */
+ return CTF_ERR; /* errno is set for us. */
}
- for (i = 0; i < fi.ctc_argc; i++)
+ for (i = 0; i < nargs; i++)
{
argv[i] = ctf_add_type_internal (dst_fp, src_fp,
argv[i],
}
}
- if ((arg_names = calloc (fi.ctc_argc, sizeof (const char **))) == NULL)
- {
- free (argv);
- free (arg_names);
- return CTF_ERR; /* errno is set for us. */
- }
-
- if (ctf_func_type_arg_names (src_fp, src_type, fi.ctc_argc,
- arg_names) < 0)
+ if ((arg_names = ctf_func_arg_names (src_fp, src_type, NULL)) == NULL)
{
free (argv);
- free (arg_names);
return CTF_ERR; /* errno is set for us. */
}
- dst_type = ctf_add_function (dst_fp, flag, &fi, argv, arg_names);
+ dst_type = ctf_add_function (dst_fp, flag, ret, flags, argv, arg_names,
+ nargs);
free (argv);
free (arg_names);
break;
}
case CTF_K_FUNCTION:
{
- ctf_funcinfo_t fi;
+ ctf_id_t ret;
ctf_id_t *args;
+ size_t nargs;
+ ctf_func_type_flags_t func_flags;
const char **arg_names;
uint32_t j;
- if (ctf_func_type_info (input, type, &fi) < 0)
+ if ((args = ctf_func_type (input, type, &ret, &func_flags,
+ &nargs)) == NULL)
{
- whaterr = N_("error getting func type info");
+ whaterr = N_("error getting func arg info");
goto input_err;
}
if ((hval = ctf_dedup_hash_type (fp, input, inputs, input_num,
- fi.ctc_return, flags, depth,
+ ret, flags, depth,
populate_fun)) == NULL)
{
- whaterr = N_("error getting func return type");
+ whaterr = N_("error hashing 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),
+ ctf_dedup_sha1_add (&hash, &nargs, sizeof (nargs), "func nargs", depth);
+ ctf_dedup_sha1_add (&hash, &func_flags, sizeof (func_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 ((args = calloc (fi.ctc_argc, sizeof (ctf_id_t))) == NULL)
- {
- err = ENOMEM;
- whaterr = N_("error doing memory allocation");
- goto err;
- }
-
- if ((arg_names = calloc (fi.ctc_argc, sizeof (const char **))) == NULL)
- {
- free (args);
- err = ENOMEM;
- whaterr = N_("error doing memory allocation");
- goto err;
- }
-
- if ((ctf_func_type_args (input, type, fi.ctc_argc, args) < 0)
- || (ctf_func_type_arg_names (input, type, fi.ctc_argc, arg_names) < 0))
+ if ((arg_names = ctf_func_arg_names (input, type, NULL)) == NULL)
{
free (args);
- free (arg_names);
- whaterr = N_("error getting func arg info");
+ whaterr = N_("error getting func arg names");
goto input_err;
}
- for (j = 0; j < fi.ctc_argc; j++)
+ for (j = 0; j < nargs; j++)
{
ctf_dedup_sha1_add (&hash, arg_names[j], strlen (arg_names[j]) + 1,
"func arg name", depth);
case CTF_K_FUNCTION:
{
- ctf_funcinfo_t fi;
+ size_t nargs;
+ ctf_id_t func_ret;
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)
+ if ((args = ctf_func_type (fp, type, &func_ret, NULL, &nargs)) == NULL)
{
- whaterr = N_("error doing memory allocation");
+ whaterr = N_("error during func args lookup");
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;
- }
+ CTF_TYPE_WALK (func_ret, err, N_("error during func return type walk"));
- for (j = 0; j < fi.ctc_argc; j++)
+ for (j = 0; j < nargs; j++)
CTF_TYPE_WALK (args[j], err_free_args,
N_("error during func arg type walk"));
free (args);
case CTF_K_FUNCTION:
{
- ctf_funcinfo_t fi;
+ size_t nargs;
+ ctf_id_t ret;
ctf_id_t *args;
+ ctf_func_type_flags_t func_flags;
const char **arg_names;
uint32_t j;
errtype = _("function");
- if (ctf_func_type_info (input, type, &fi) < 0)
+ if ((args = ctf_func_type (input, type, &ret, &func_flags,
+ &nargs)) == NULL)
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)
+ ret = ctf_dedup_id_to_target (output, target, inputs, ninputs,
+ parents, input, input_num, ret);
+ if (ret == CTF_ERR)
{
free (args);
goto err_input;
}
- for (j = 0; j < fi.ctc_argc; j++)
+ for (j = 0; j < nargs; 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 ((arg_names = calloc (fi.ctc_argc, sizeof (const char **))) == NULL)
- {
- ctf_set_errno (input, ENOMEM);
- goto err_input;
+ {
+ free (args);
+ goto err_input;
+ }
}
errtype = _("function arg names");
- if (ctf_func_type_arg_names (input, type, fi.ctc_argc, arg_names) < 0)
+ if ((arg_names = ctf_func_arg_names (input, type, NULL)) == NULL)
{
free (args);
- free (arg_names);
goto err_input;
}
- if ((new_type = ctf_add_function (target, isroot,
- &fi, args, arg_names)) == CTF_ERR)
+ if ((new_type = ctf_add_function (target, isroot, ret, func_flags, args,
+ arg_names, nargs)) == CTF_ERR)
{
free (args);
free (arg_names);
case CTF_K_FUNCTION:
{
size_t i;
- ctf_funcinfo_t fi;
- ctf_id_t *argv = NULL;
+ ctf_id_t ret;
+ size_t nargs;
+ ctf_id_t *argv;
+ ctf_func_type_flags_t flags;
const char **arg_names = NULL;
- if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
+ if ((argv = ctf_func_type (rfp, cdp->cd_type, &ret, &flags, &nargs)) == NULL)
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 ((arg_names = calloc (fi.ctc_argc, sizeof (const char *))) == 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. */
-
- if (ctf_func_type_arg_names (rfp, cdp->cd_type,
- fi.ctc_argc, arg_names) < 0)
+ if ((arg_names = ctf_func_arg_names (rfp, cdp->cd_type, NULL)) == NULL)
goto err; /* errno is set for us. */
ctf_decl_sprintf (&cd, "(*) (");
- for (i = 0; i < fi.ctc_argc; i++)
+ for (i = 0; i < nargs; i++)
{
char *arg = ctf_type_aname (rfp, argv[i]);
? arg_names[i] : "");
free (arg);
- if ((i < fi.ctc_argc - 1)
- || (fi.ctc_flags & CTF_FUNC_VARARG))
+ if ((i < nargs - 1)
+ || (flags & CTF_FUNC_VARARG))
ctf_decl_sprintf (&cd, ", ");
}
- if (fi.ctc_flags & CTF_FUNC_VARARG)
+ if (flags & CTF_FUNC_VARARG)
ctf_decl_sprintf (&cd, "...");
ctf_decl_sprintf (&cd, ")");
free (argv);
+ free (arg_names);
break;
err:
case CTF_K_FUNC_LINKAGE:
case CTF_K_FUNCTION:
{
- ctf_funcinfo_t fi;
ctf_id_t *args;
+ size_t nargs;
ctf_id_t argtype;
- if (ctf_func_type_info (fp, ref, &fi) < 0)
+ if ((args = ctf_func_type (fp, ref, NULL, NULL, &nargs)) == NULL)
return CTF_ERR; /* errno is set for us. */
- if (component_idx + 1 > (ssize_t) fi.ctc_argc)
+ if (component_idx + 1 > (ssize_t) nargs)
break;
- if ((args = malloc ((component_idx + 1) * sizeof (ctf_id_t))) == NULL)
- return (ctf_set_typed_errno (fp, ENOMEM));
-
- if (ctf_func_type_args (fp, ref, component_idx + 1, args))
- {
- free (args);
- return CTF_ERR; /* errno is set for us. */
- }
argtype = args[component_idx];
free (args);
return argtype;
return CTF_INFO_KFLAG (tp->ctt_info);
}
-/* Given a type ID relating to a function type, return info on return types and
- arg counts for that function. */
+/* Common code for ctf_func_type_*: arg checking, func arg vararg handling
+ etc. */
-int
-ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
+static const ctf_param_t *
+ctf_func_type_common (ctf_dict_t **fp, ctf_id_t type, size_t *nargs,
+ const ctf_type_t **suffix)
{
- ctf_dict_t *ofp = fp;
- const ctf_type_t *tp, *suffix;
+ ctf_dict_t *ofp = *fp;
+ const ctf_type_t *tp;
ctf_kind_t kind;
unsigned char *vlen;
const ctf_param_t *args;
- if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
- return -1; /* errno is set for us. */
+ if ((type = ctf_type_resolve (*fp, type)) == CTF_ERR)
+ return NULL; /* errno is set for us. */
- if (ctf_type_kind (fp, type) == CTF_K_FUNC_LINKAGE)
- type = ctf_type_reference (fp, type);
+ if (ctf_type_kind (*fp, type) == CTF_K_FUNC_LINKAGE)
+ type = ctf_type_reference (*fp, type);
- if ((tp = ctf_lookup_by_id (&fp, type, &suffix)) == NULL)
- return -1; /* errno is set for us. */
+ if ((tp = ctf_lookup_by_id (fp, type, suffix)) == NULL)
+ return NULL; /* errno is set for us. */
- kind = LCTF_KIND (fp, tp);
+ kind = LCTF_KIND (*fp, tp);
if (kind != CTF_K_FUNCTION)
- return (ctf_set_errno (ofp, ECTF_NOTFUNC));
-
- fip->ctc_return = suffix->ctt_type;
- fip->ctc_flags = 0;
-
- vlen = ctf_vlen (fp, type, tp, &fip->ctc_argc);
- args = (const ctf_param_t *) vlen;
-
- if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1].cfp_type == 0)
{
- fip->ctc_flags |= CTF_FUNC_VARARG;
- fip->ctc_argc--;
+ ctf_set_errno (ofp, ECTF_NOTFUNC);
+ return NULL;
}
+ vlen = ctf_vlen (*fp, type, tp, nargs);
+ args = (const ctf_param_t *) vlen;
- return 0;
-}
+ if (*nargs != 0 && args[*nargs - 1].cfp_type == 0)
+ (*nargs)--;
-/* Given a type ID relating to a function type, return the arguments for the
- function. */
+ return args;
+}
-int
-ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
+/* Given a type ID relating to a function type, return an array of arg types,
+ and optionally in the RET argument the return type too. The optional FLAGS
+ argument may contain CTF_FUNC_* flags; the NARGS arg gives the length of
+ the array. */
+ctf_id_t *
+ctf_func_type (ctf_dict_t *fp, ctf_id_t type, ctf_id_t *ret_type,
+ ctf_func_type_flags_t *flags, size_t *nargs)
{
- const ctf_type_t *tp;
+ ctf_dict_t *ofp = fp;
+ const ctf_type_t *suffix;
const ctf_param_t *args;
- unsigned char *vlen;
- ctf_funcinfo_t f;
+ ctf_id_t *ret_args;
+ size_t n_args;
+ size_t i;
- if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
- return -1; /* errno is set for us. */
+ if ((args = ctf_func_type_common (&fp, type, &n_args, &suffix)) == NULL)
+ return NULL; /* errno is set for us. */
- if (ctf_type_kind (fp, type) == CTF_K_FUNC_LINKAGE)
- type = ctf_type_reference (fp, type);
+ if (ret_type)
+ *ret_type = suffix->ctt_type;
- if (ctf_func_type_info (fp, type, &f) < 0)
- return -1; /* errno is set for us. */
+ if (flags)
+ *flags = 0;
- if ((tp = ctf_lookup_by_id (&fp, type, NULL)) == NULL)
- return -1; /* errno is set for us. */
+ if (n_args != 0 && args[n_args - 1].cfp_type == 0 && flags)
+ *flags |= CTF_FUNC_VARARG;
- vlen = ctf_vlen (fp, type, tp, NULL);
- args = (const ctf_param_t *) vlen;
+ if (nargs)
+ *nargs = n_args;
+
+ if ((ret_args = calloc (n_args, sizeof (ctf_id_t))) == NULL)
+ {
+ ctf_set_errno (ofp, ENOMEM);
+ return NULL;
+ }
- for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
- *argv++ = (args++)->cfp_type;
+ for (i = 0; i < n_args; i++)
+ ret_args[i] = args[i].cfp_type;
- return 0;
+ return ret_args;
}
/* Given a type ID relating to a function type, return the argument names for
the function. */
-
-int
-ctf_func_type_arg_names (ctf_dict_t *fp, ctf_id_t type, uint32_t argc,
- const char **arg_names)
+const char **
+ctf_func_arg_names (ctf_dict_t *fp, ctf_id_t type, size_t *nargs)
{
- const ctf_type_t *tp;
+ ctf_dict_t *ofp = fp;
const ctf_param_t *args;
- unsigned char *vlen;
- ctf_funcinfo_t f;
+ const char **ret;
+ size_t n_args;
+ size_t i;
- if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
- return -1; /* errno is set for us. */
+ if ((args = ctf_func_type_common (&fp, type, &n_args, NULL)) == NULL)
+ return NULL; /* errno is set for us. */
- if (ctf_type_kind (fp, type) == CTF_K_FUNC_LINKAGE)
- type = ctf_type_reference (fp, type);
+ if (nargs)
+ *nargs = n_args;
- if (ctf_func_type_info (fp, type, &f) < 0)
- return -1; /* errno is set for us. */
-
- if ((tp = ctf_lookup_by_id (&fp, type, NULL)) == NULL)
- return -1; /* errno is set for us. */
-
- vlen = ctf_vlen (fp, type, tp, NULL);
- args = (const ctf_param_t *) vlen;
+ if ((ret = calloc (n_args, sizeof (const char *))) == NULL)
+ {
+ ctf_set_errno (ofp, ENOMEM);
+ return NULL;
+ }
- for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
- *arg_names++ = ctf_strptr (fp, (args++)->cfp_name);
+ for (i = 0; i < n_args; i++)
+ ret[i] = ctf_strptr (fp, args[i].cfp_name);
- return 0;
+ return ret;
}
/* Get the linkage of a CTF_K_FUNC_LINKAGE or variable. */
ctf_errmsg;
ctf_version;
- ctf_func_type_info;
- ctf_func_type_args;
- ctf_func_type_arg_names;
+ ctf_func_type;
+ ctf_func_arg_names;
ctf_lookup_by_name;
ctf_lookup_by_kind;
ctf_encoding_t long_encoding = { CTF_INT_SIGNED, 0, sizeof (long) };
ctf_encoding_t void_encoding = { CTF_INT_SIGNED, 0, 0 };
ctf_encoding_t foo;
- ctf_funcinfo_t fi;
ctf_id_t bar;
int err;
if (ctf_add_variable (parent, "base", base) < 0)
goto child_err;
- fi.ctc_return = void_id;
- fi.ctc_argc = 0;
- fi.ctc_flags = 0;
- if ((function = ctf_add_function (child, CTF_ADD_ROOT, &fi, NULL)) == CTF_ERR)
+ if ((function = ctf_add_function (child, CTF_ADD_ROOT, void_id, NULL, NULL, 0)) == CTF_ERR)
goto child_err;
- desc = "func info lookup of non-function";
- if ((ctf_func_type_info (child, base, &fi)) != CTF_ERR)
- no_prop_err ();
- check_prop_err (child, parent, ECTF_NOTFUNC);
-
- desc = "func args lookup of non-function";
- if ((ctf_func_type_args (child, base, 0, &bar)) != CTF_ERR)
+ desc = "func type lookup of non-function";
+ if ((bar = ctf_func_type (child, base, NULL, NULL, NULL)) != CTF_ERR)
no_prop_err ();
check_prop_err (child, parent, ECTF_NOTFUNC);
+ free (bar);
/* Swap the insides of "parent" and "wrong" so we get a parent dict with
different types than it had. */
no_prop_err ();
check_prop_err (child, parent, ECTF_NONREPRESENTABLE);
- desc = "func info lookup of nonrepresentable function";
- if ((ctf_func_type_info (child, base, &fi)) != CTF_ERR)
- no_prop_err ();
- check_prop_err (child, parent, ECTF_NONREPRESENTABLE);
-
- desc = "func args lookup of nonrepresentable function";
- if ((ctf_func_type_args (child, base, 0, &bar)) != CTF_ERR)
+ desc = "func lookup of nonrepresentable function";
+ if ((bar = ctf_func_type_args (child, base, NULL, NULL, NULL)) != CTF_ERR)
no_prop_err ();
check_prop_err (child, parent, ECTF_NONREPRESENTABLE);
+ free (bar);
desc = "child slice addition";
if ((slice = ctf_add_slice (child, CTF_ADD_ROOT, base, &foo)) != CTF_ERR)
ctf_id_t first_child_type = 1;
ctf_membinfo_t memb;
ctf_arinfo_t ar;
- ctf_funcinfo_t func;
- ctf_funcinfo_t pfunc, cfunc;
- ctf_id_t args[2], pargs[2], cargs[2];
+ ctf_id_t args[2];
printf ("Testing with %s, %s parent\n", empty_parent ? "empty" : "nonempty",
unserialized_parent ? "unserialized" : "serialized");
goto parent_add_err;
first_child_type++;
- func.ctc_argc = 2;
- func.ctc_flags = 0;
- func.ctc_return = pprovint;
args[0] = pptr;
args[1] = parray;
- if ((pfunction = ctf_add_function (parent, CTF_ADD_ROOT, &func, args)) == CTF_ERR)
+ if ((pfunction = ctf_add_function (parent, CTF_ADD_ROOT, pprovint, 0, args, 2)) == CTF_ERR)
goto parent_add_err;
first_child_type++;
}
if (ctf_add_member (child, ctype2, "pfunc", pfunction, CTF_NEXT_MEMBER) < 0)
goto child_add_memb_err;
- func.ctc_argc = 2;
- func.ctc_flags = 0;
- func.ctc_return = pprovint;
args[0] = pptr;
args[1] = parray;
- if ((cfunction = ctf_add_function (parent, CTF_ADD_ROOT, &func, args)) == CTF_ERR)
+ if ((cfunction = ctf_add_function (parent, CTF_ADD_ROOT, pprovint, 0, args, 2)) == CTF_ERR)
goto child_add_err;
first_child_type++;
if (!empty_parent)
{
+ size_t pnargs, cnargs;
+ ctf_func_type_flags_t pflags, cflags;
+ ctf_id_t pret, cret;
+ ctf_id_t *pargs, *cargs;
+
if (ctf_member_info (child, ctype2, "a", &memb) < 0)
goto memb_err;
goto func_err;
cfunction = memb.ctm_type;
- if (ctf_func_type_info (child, pfunction, &pfunc) < 0 ||
- ctf_func_type_info (child, cfunction, &cfunc) < 0)
+ if ((pargs = ctf_func_type (child, pfunction, &pret, &pflags, &pnargs)) == NULL
+ || (cargs = ctf_func_type (child, cfunction, &cret, &cflags, &cnargs)) == NULL)
{
- fprintf (stderr, "func info lookup failed: %s\n", ctf_errmsg (ctf_errno (child)));
+ fprintf (stderr, "func arg lookup failed: %s\n", ctf_errmsg (ctf_errno (child)));
exit (1);
}
- if (memcmp (&pfunc, &cfunc, sizeof (pfunc)) != 0)
+ if (pnargs != cnargs || pflags != cflags || pret != cret)
{
fprintf (stderr, "parent and child funcs differ\n");
exit (1);
}
- if (ctf_type_kind (child, pfunc.ctc_return) != CTF_K_INTEGER)
+ if (ctf_type_kind (child, pret) != CTF_K_INTEGER)
{
fprintf (stderr, "func return type lookup yielded kind %x, not %x\n", ctf_type_kind (child, pfunc.ctc_return), CTF_K_INTEGER);
exit (1);
}
- /* This isn't a type ID, so we're not really expecting problems here, but if
- there are problems, rather an error message than a buffer overrun. */
- if (pfunc.ctc_argc != 2)
+ if (pnargs != 2 || cnargs != 2)
{
- fprintf (stderr, "func has %i args, not 2\n", pfunc.ctc_argc);
- exit (1);
- }
-
- if (ctf_func_type_args (child, pfunction, pfunc.ctc_argc, pargs) < 0 ||
- ctf_func_type_args (child, cfunction, cfunc.ctc_argc, cargs) < 0)
- {
- fprintf (stderr, "func arg lookup failed: %s\n", ctf_errmsg (ctf_errno (child)));
+ fprintf (stderr, "funcs have (%i, %i) args, not 2\n", pnargs, cnargs);
exit (1);
}
ctf_id_t func, func2, func3, base, base2, base3;
ctf_encoding_t e = { CTF_INT_SIGNED, 0, sizeof (long) };
ctf_id_t dummy = 0;
- ctf_funcinfo_t fi;
ctf_next_t *i = NULL;
ctf_id_t symtype;
const char *symname;
fi.ctc_return = base;
fi.ctc_argc = 0;
fi.ctc_flags = 0;
- if (((func = ctf_add_function (fp, CTF_ADD_ROOT, &fi, &dummy)) == CTF_ERR) ||
- ((func2 = ctf_add_function (fp, CTF_ADD_ROOT, &fi, &dummy)) == CTF_ERR) ||
- ((func3 = ctf_add_function (fp, CTF_ADD_ROOT, &fi, &dummy)) == CTF_ERR))
+ if (((func = ctf_add_function (fp, CTF_ADD_ROOT, base, 0, &dummy, 0)) == CTF_ERR) ||
+ ((func2 = ctf_add_function (fp, CTF_ADD_ROOT, base, 0, &dummy, 0)) == CTF_ERR) ||
+ ((func3 = ctf_add_function (fp, CTF_ADD_ROOT, base, 0, &dummy, 0)) == CTF_ERR))
goto create_types_err;
/* Add some function and data symbols. We intentionally add the symbols in