[DTrace-devel] [PATCH 3/4] Report missing BPF dlib symbols as a proper compiler error
Kris Van Hees
kris.van.hees at oracle.com
Wed Jun 10 08:23:32 PDT 2020
If a BPF dlib symbol was not found in the bpf_dlib.o object, a SEGV
would occur because the compiler would try to dereference a NULL
pointer. This patch adds proper error handling for this case and
also fixes a few error handling cases where a goto was done to the
wrong label.
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
libdtrace/dt_cc.c | 53 +++++++++++++++++++++++++++++++-------------
libdtrace/dt_dlibs.c | 16 ++++++++-----
libdtrace/dt_impl.h | 2 +-
3 files changed, 49 insertions(+), 22 deletions(-)
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index 2b687bb0..67834790 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -2181,7 +2181,7 @@ out:
return (err ? NULL : rv);
}
-static uint_t
+static int
dt_link_layout(dtrace_hdl_t *dtp, const dtrace_difo_t *dp, uint_t *insc,
uint_t *relc)
{
@@ -2195,6 +2195,7 @@ dt_link_layout(dtrace_hdl_t *dtp, const dtrace_difo_t *dp, uint_t *insc,
char *name = &dp->dtdo_strtab[rp->dofr_name];
dt_ident_t *idp = dt_dlib_get_func(dtp, name);
dtrace_difo_t *rdp;
+ int ipc;
if (idp == NULL || /* not found */
idp->di_kind != DT_IDENT_SYMBOL || /* not external sym */
@@ -2203,14 +2204,19 @@ dt_link_layout(dtrace_hdl_t *dtp, const dtrace_difo_t *dp, uint_t *insc,
idp->di_flags |= DT_IDFLG_REF;
- rdp = dt_dlib_get_func_difo(idp);
- idp->di_id = dt_link_layout(dtp, rdp, insc, relc);
+ rdp = dt_dlib_get_func_difo(dtp, idp);
+ if (rdp == NULL)
+ return -1;
+ ipc = dt_link_layout(dtp, rdp, insc, relc);
+ if (ipc == -1)
+ return -1;
+ idp->di_id = ipc;
}
return pc;
}
-static uint_t
+static int
dt_link_construct(dtrace_hdl_t *dtp, dtrace_difo_t *dp,
const dtrace_difo_t *sdp, dt_strtab_t *stab,
uint_t *pcp, uint_t *rcp)
@@ -2280,6 +2286,7 @@ dt_link_construct(dtrace_hdl_t *dtp, dtrace_difo_t *dp,
char *name = &sdp->dtdo_strtab[rp->dofr_name];
dt_ident_t *idp = dt_dlib_get_func(dtp, name);
dtrace_difo_t *rdp;
+ int ipc;
if (idp == NULL || /* not found */
idp->di_kind != DT_IDENT_SYMBOL || /* not external sym */
@@ -2288,15 +2295,20 @@ dt_link_construct(dtrace_hdl_t *dtp, dtrace_difo_t *dp,
idp->di_flags |= DT_IDFLG_REF;
- rdp = dt_dlib_get_func_difo(idp);
- idp->di_id = dt_link_construct(dtp, dp, rdp, stab, pcp, rcp);
+ rdp = dt_dlib_get_func_difo(dtp, idp);
+ if (rdp == NULL)
+ return -1;
+ ipc = dt_link_construct(dtp, dp, rdp, stab, pcp, rcp);
+ if (ipc == -1)
+ return -1;
+ idp->di_id = ipc;
nrp->dofr_data = idp->di_id; /* set value */
}
return pc;
}
-static uint_t
+static void
dt_link_resolve(dtrace_hdl_t *dtp, dtrace_difo_t *dp)
{
struct bpf_insn *buf = dp->dtdo_buf;
@@ -2330,29 +2342,32 @@ dt_link_stmt(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp,
uint_t insc = 0;
uint_t relc = 0;
dtrace_difo_t *dp = sdp->dtsd_action->dtad_difo;
- dtrace_difo_t *fdp;
+ dtrace_difo_t *fdp = NULL;
dt_strtab_t *stab;
+ int rc;
/*
* Determine the layout of the final (linked) DIFO, and calculate the
* total isntruction and relocation record counts..
*/
- dt_link_layout(dtp, dp, &insc, &relc);
+ rc = dt_link_layout(dtp, dp, &insc, &relc);
dt_dlib_reset(dtp, B_TRUE);
+ if (rc == -1)
+ goto fail;
/*
* Allocate memory for constructing the final DIFO.
*/
fdp = dt_zalloc(dtp, sizeof(dtrace_difo_t));
if (fdp == NULL)
- goto fail;
+ goto nomem;
fdp->dtdo_buf = dt_calloc(dtp, insc, sizeof(struct bpf_insn));
if (fdp->dtdo_buf == NULL)
- goto fail;
+ goto nomem;
fdp->dtdo_len = insc;
fdp->dtdo_breltab = dt_calloc(dtp, relc, sizeof(dof_relodesc_t));
if (fdp->dtdo_breltab == NULL)
- goto fail;
+ goto nomem;
fdp->dtdo_brelen = relc;
/*
@@ -2362,10 +2377,12 @@ dt_link_stmt(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp,
insc = relc = 0;
stab = dt_strtab_create(BUFSIZ);
if (stab == NULL)
- goto fail;
+ goto nomem;
- dt_link_construct(dtp, fdp, dp, stab, &insc, &relc);
+ rc = dt_link_construct(dtp, fdp, dp, stab, &insc, &relc);
dt_dlib_reset(dtp, B_FALSE);
+ if (rc == -1)
+ goto fail;
/*
* Replace the program DIFO instruction buffer, BPF relocation table,
@@ -2386,7 +2403,7 @@ dt_link_stmt(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp,
if (dp->dtdo_strlen > 0) {
dp->dtdo_strtab = dt_zalloc(dtp, dp->dtdo_strlen);
if (dp->dtdo_strtab == NULL)
- goto fail;
+ goto nomem;
dt_strtab_write(stab, (dt_strtab_write_f *)dt_strtab_copystr,
dp->dtdo_strtab);
} else
@@ -2410,7 +2427,11 @@ fail:
dt_free(dtp, fdp);
}
- return dt_set_errno(dtp, EDT_NOMEM);
+ return rc;
+
+nomem:
+ rc = dt_set_errno(dtp, EDT_NOMEM);
+ goto fail;
}
static int
diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
index 4bf8e29b..4a8dd00e 100644
--- a/libdtrace/dt_dlibs.c
+++ b/libdtrace/dt_dlibs.c
@@ -222,10 +222,16 @@ dt_dlib_get_var(dtrace_hdl_t *dtp, const char *name)
* Return the DIFO for an external symbol.
*/
dtrace_difo_t *
-dt_dlib_get_func_difo(const dt_ident_t *idp)
+dt_dlib_get_func_difo(dtrace_hdl_t *dtp, const dt_ident_t *idp)
{
assert(idp->di_kind == DT_IDENT_SYMBOL);
- assert(idp->di_data != NULL);
+
+ if (idp->di_data == NULL) {
+ dt_dlib_error(dtp, D_IDENT_UNDEF, "dlib symbol %s not found",
+ idp->di_name);
+ dt_set_errno(dtp, EDT_COMPILER);
+ return NULL;
+ }
return ((dt_bpf_func_t *)idp->di_data)->difo;
}
@@ -358,7 +364,7 @@ get_symbols(dtrace_hdl_t *dtp, Elf *elf, int syms_idx, int strs_idx,
name = elf_strptr(elf, strs_idx, sym.st_name);
if (name == NULL) {
dt_dlib_error(dtp, 0, "BPF ELF: no symbol name");
- goto err;;
+ goto err;
}
if (sym.st_shndx == text_idx) {
@@ -485,7 +491,7 @@ get_symbols(dtrace_hdl_t *dtp, Elf *elf, int syms_idx, int strs_idx,
scn = elf_getscn(elf, text_idx);
if ((text = elf_getdata(scn, NULL)) == NULL) {
dt_dlib_error(dtp, 0, "BPF ELF: no .text data\n");
- goto out;
+ goto err;
}
for (idx = 0; idx < symc; idx++) {
@@ -531,7 +537,7 @@ get_symbols(dtrace_hdl_t *dtp, Elf *elf, int syms_idx, int strs_idx,
scn = elf_getscn(elf, relo_idx);
if ((data = elf_getdata(scn, NULL)) == NULL) {
dt_dlib_error(dtp, 0, "BPF ELF: no relocation data");
- goto out;
+ goto err;
}
/*
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index 34c3435d..40603ea8 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -760,7 +760,7 @@ extern void dt_dlib_init(dtrace_hdl_t *dtp);
extern dt_ident_t *dt_dlib_get_func(dtrace_hdl_t *, const char *);
extern dt_ident_t *dt_dlib_get_map(dtrace_hdl_t *, const char *);
extern dt_ident_t *dt_dlib_get_var(dtrace_hdl_t *, const char *);
-extern dtrace_difo_t *dt_dlib_get_func_difo(const dt_ident_t *);
+extern dtrace_difo_t *dt_dlib_get_func_difo(dtrace_hdl_t *, const dt_ident_t *);
extern void dt_dlib_reset(dtrace_hdl_t *dtp, boolean_t);
extern int dt_load_libs(dtrace_hdl_t *dtp);
--
2.26.0
More information about the DTrace-devel
mailing list