From: Kris Van Hees <kris.van.hees@oracle.com>
To: Kris Van Hees <kris.van.hees@oracle.com>
Cc: dtrace@lists.linux.dev, dtrace-devel@oss.oracle.com
Subject: Re: [PATCH] bpf, fbt: do not try to get a return value for void function return pronbes
Date: Fri, 2 Aug 2024 11:59:41 -0400 [thread overview]
Message-ID: <Zq0CbfK557g3OALy@oracle.com> (raw)
In-Reply-To: <PH8PR10MB629206C3D0CC853576B43FD5C2B32@PH8PR10MB6292.namprd10.prod.outlook.com>
v2 on the way soon - with tests
On Fri, Aug 02, 2024 at 11:58:18AM -0400, Kris Van Hees wrote:
> We were trying to access a return value for void functions, causing BPF
> verifier failures. We can determine the return type when getting the
> probe info, and set the return probe argc value accordingly. This then
> drives the code generation in the trampoline.
>
> Reported-by: Alan Maguire <alan.maguire@oracle.com>
> Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
> ---
> libdtrace/dt_btf.c | 16 ++++++++++++++++
> libdtrace/dt_btf.h | 2 ++
> libdtrace/dt_prov_fbt.c | 21 ++++++++++++---------
> 3 files changed, 30 insertions(+), 9 deletions(-)
>
> diff --git a/libdtrace/dt_btf.c b/libdtrace/dt_btf.c
> index 77366df6..e905580f 100644
> --- a/libdtrace/dt_btf.c
> +++ b/libdtrace/dt_btf.c
> @@ -980,3 +980,19 @@ dt_btf_func_argc(dtrace_hdl_t *dtp, const dt_btf_t *btf, uint32_t id)
>
> return -1;
> }
> +
> +int
> +dt_btf_func_is_void(dtrace_hdl_t *dtp, const dt_btf_t *btf, uint32_t id)
> +{
> + btf_type_t *type = dt_btf_type_by_id(dtp, btf, id);
> +
> + /* For functions, move on to the function prototype. */
> + if (BTF_INFO_KIND(type->info) == BTF_KIND_FUNC)
> + type = dt_btf_type_by_id(dtp, btf, type->type);
> +
> + if (BTF_INFO_KIND(type->info) == BTF_KIND_FUNC_PROTO &&
> + type->type == 0)
> + return 1;
> +
> + return 0;
> +}
> diff --git a/libdtrace/dt_btf.h b/libdtrace/dt_btf.h
> index a7cee464..e05b30d0 100644
> --- a/libdtrace/dt_btf.h
> +++ b/libdtrace/dt_btf.h
> @@ -25,6 +25,8 @@ extern int32_t dt_btf_lookup_name_kind(dtrace_hdl_t *, dt_btf_t *,
> const char *, uint32_t);
> extern int dt_btf_func_argc(dtrace_hdl_t *dtp, const dt_btf_t *btf,
> uint32_t id);
> +extern int dt_btf_func_is_void(dtrace_hdl_t *dtp, const dt_btf_t *btf,
> + uint32_t id);
> extern int dt_btf_get_module_ids(dtrace_hdl_t *);
> extern int dt_btf_module_fd(const dt_module_t *);
>
> diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
> index 461d5e35..80c3db20 100644
> --- a/libdtrace/dt_prov_fbt.c
> +++ b/libdtrace/dt_prov_fbt.c
> @@ -199,13 +199,15 @@ static int fprobe_trampoline(dt_pcb_t *pcb, uint_t exitlbl)
> emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
>
> /*
> + * Only try to retrieve a return value if we know we can.
> + *
> * The return value is provided by the fexit probe as an
> * argument slot past the last function argument. We can get
> * the number of function arguments using the BTF id that has
> * been stored as the tracepoint event id.
> */
> dmp = dt_module_lookup_by_name(dtp, prp->desc->mod);
> - if (dmp != NULL) {
> + if (dmp && prp->argc == 2) {
> int32_t btf_id = dt_tp_get_event_id(prp);
> int i = dt_btf_func_argc(dtp, dmp->dm_btf, btf_id);
>
> @@ -240,7 +242,9 @@ static int fprobe_probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
> dt_tp_set_event_id(prp, btf_id);
>
> if (strcmp(desc->prb, "return") == 0) {
> - argc = 2;
> + /* Void function return probes only provide 1 argument. */
> + argc = dt_btf_func_is_void(dtp, dmp->dm_btf, btf_id) ? 1 : 2;
> +
> argv = dt_calloc(dtp, argc, sizeof(dt_argdesc_t));
> if (argv == NULL)
> return dt_set_errno(dtp, EDT_NOMEM);
> @@ -250,13 +254,12 @@ static int fprobe_probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
> argv[0].native = strdup("uint64_t");
> argv[0].xlate = NULL;
>
> - /*
> - * The return type is a generic uint64_t. For void functions
> - * the value of arg1 and argv[1] is undefined.
> - */
> - argv[1].mapping = 1;
> - argv[1].native = strdup("uint64_t");
> - argv[1].xlate = NULL;
> + if (argc == 2) {
> + /* The return type is a generic uint64_t. */
> + argv[1].mapping = 1;
> + argv[1].native = strdup("uint64_t");
> + argv[1].xlate = NULL;
> + }
>
> goto done;
> }
> --
> 2.45.2
>
prev parent reply other threads:[~2024-08-02 15:59 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-02 15:58 [PATCH] bpf, fbt: do not try to get a return value for void function return pronbes Kris Van Hees
2024-08-02 15:59 ` Kris Van Hees [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Zq0CbfK557g3OALy@oracle.com \
--to=kris.van.hees@oracle.com \
--cc=dtrace-devel@oss.oracle.com \
--cc=dtrace@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.