[DTrace-devel] [PATCH 01/17] Revert "Remove drti.o and related support code."
Kris Van Hees
kris.van.hees at oracle.com
Thu Sep 15 13:30:25 UTC 2022
On Wed, Aug 10, 2022 at 11:06:53PM +0100, Nick Alcock via DTrace-devel wrote:
> We're going to start using drti again, so bring it back.
>
> This reverts commit 1e45252a1e1c9a2ab35e03558dc4e5bbf63ad0d8.
This patch is missing the Signed-off-by: ....
I'll add it and include:
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
> Makefunctions | 2 +-
> libdtrace/Build | 26 ++++++
> libdtrace/drti-vers | 1 +
> libdtrace/drti.c | 193 ++++++++++++++++++++++++++++++++++++++++++++
> libdtrace/dt_link.c | 22 +++--
> 5 files changed, 236 insertions(+), 8 deletions(-)
> create mode 100644 libdtrace/drti-vers
> create mode 100644 libdtrace/drti.c
>
> diff --git a/Makefunctions b/Makefunctions
> index 4909c0c91959..5945768bf983 100644
> --- a/Makefunctions
> +++ b/Makefunctions
> @@ -90,7 +90,7 @@ endef
> # Syntax: $(call dof-template,primary,filename-without-dir)
>
> define dof-template
> -$(dof-name): $(src-name) $(objdir)/run-dtrace $(foreach source,$($(1)_SOURCES),$(call obj-name,$(1),$(source))) $(filter-out $(dof-name),$(foreach dep,$(filter %.o,$($(1)_DEPS)),$(call obj-name,$(1),$(dep)))) $(other-dlib-targets)
> +$(dof-name): $(src-name) $(objdir)/run-dtrace $(foreach source,$($(1)_SOURCES),$(call obj-name,$(1),$(source))) $(filter-out $(dof-name),$(foreach dep,$(filter %.o,$($(1)_DEPS)),$(call obj-name,$(1),$(dep)))) $(other-dlib-targets) $(DRTI_OBJ)
> $(call describe-target,GENDOF,$(src-name))
> $(objdir)/run-dtrace -x nolibs -G -o $(dof-name) -s $(src-name) $(foreach source,$($(1)_SOURCES),$(call obj-name,$(1),$(source))) $(filter-out $(dof-name),$(foreach dep,$(filter %.o,$($(1)_DEPS)),$(call obj-name,$(1),$(dep))))
> endef
> diff --git a/libdtrace/Build b/libdtrace/Build
> index f1ee0d1c9a22..bc24fdd6d36d 100644
> --- a/libdtrace/Build
> +++ b/libdtrace/Build
> @@ -145,6 +145,7 @@ override other-dlib-targets = $(foreach kernel,$(SHORTKERNELS), \
> $(objdir)/dlibs/.dir.stamp:
> mkdir -p $(objdir)/dlibs $(foreach kernel,$(SHORTKERNELS),$(objdir)/dlibs/$(kernel))
> @touch $(objdir)/dlibs/.dir.stamp
> + ln -sf ../../$(libdtrace-build_DIR)/drti-vers $(objdir)/dlibs
>
> define dlib-kernel-ver-template
> $(objdir)/dlibs/$(shell printf %s $(1) | sed -e 's/^\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*$$/\1.\2.\3/')/%.d: override SHORTKERNELVER := $(shell printf %s $(1) | sed -e 's/^\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*$$/\1.\2.\3/' | awk -F. '{ print $$1 * 1000 * 1000 + $$2 * 1000 + $$3 }')
> @@ -202,6 +203,25 @@ PHONIES += dlibs
> TARGETS += dlibs
> dlibs: $(m4-dlib-targets) $(other-dlib-targets)
>
> +PHONIES += objs
> +TARGETS += objs
> +BUILD_DRTI_OBJ = $(objdir)/drti.o
> +DRTI_OBJ = $(objdir)/dlibs/drti.o
> +BUILD_DRTI32_OBJ = $(objdir)/drti32.o
> +DRTI32_OBJ = $(if $(NATIVE_BITNESS_ONLY),,$(objdir)/dlibs/drti32.o)
> +
> +objs: $(DRTI_OBJ) $(DRTI32_OBJ)
> +$(BUILD_DRTI_OBJ): $(libdtrace-build_DIR)drti.c
> + $(call describe-target,CC,$<)
> + $(CC) $(filter-out --coverage,$(CFLAGS)) -fPIC $(CPPFLAGS) $(libdtrace-build_CPPFLAGS) -MP -MMD -c -o $@ $<
> +$(DRTI_OBJ): $(BUILD_DRTI_OBJ) $(objdir)/dlibs/.dir.stamp
> + ln -sf $(BUILD_DRTI_OBJ) $(DRTI_OBJ)
> +$(BUILD_DRTI32_OBJ): $(libdtrace-build_DIR)drti.c
> + $(call describe-target,CC-32,$<)
> + $(CC) $(filter-out --coverage,$(CFLAGS)) -m32 -fPIC $(CPPFLAGS) $(libdtrace-build_CPPFLAGS) -MP -MMD -c -o $@ $<
> +$(DRTI32_OBJ): $(BUILD_DRTI32_OBJ) $(objdir)/dlibs/.dir.stamp
> + ln -sf $(BUILD_DRTI32_OBJ) $(DRTI32_OBJ)
> +
> # Custom substitutions.
>
> # Though we use errno.h, the sensitive dependency is linux/errno.h,
> @@ -236,6 +256,12 @@ install::
> ln -sf libdtrace.so.$(libdtrace_VERSION) $(INSTLIBDIR)/$(libdtrace_SONAME)
> $(call describe-install-target,$(INSTLIBDIR),$(libdtrace_TARGET).so)
> ln -sf libdtrace.so.$(libdtrace_VERSION) $(INSTLIBDIR)/$(libdtrace_TARGET).so
> + $(call describe-install-target,$(INSTLIBDIR)/dtrace,$(DRTI_OBJ))
> + install -m 644 $(DRTI_OBJ) $(INSTLIBDIR)/dtrace
> + $(call describe-install-target,$(INSTLIBDIR)/dtrace,$(DRTI32_OBJ))
> + $(if $(NATIVE_BITNESS_ONLY),,install -m 644 $(DRTI32_OBJ) $(INSTLIBDIR)/dtrace)
> + $(call describe-install-target,$(INSTLIBDIR)/dtrace,drti-vers)
> + install -m 644 $(objdir)/dlibs/drti-vers $(INSTLIBDIR)/dtrace
> for kernel in $(SHORTKERNELS); do \
> $(call describe-expanded-install-target,$(INSTLIBDIR)/dtrace/$$kernel,$(WORKING_DLIBS)) \
> mkdir -p $(INSTLIBDIR)/dtrace/$$kernel && \
> diff --git a/libdtrace/drti-vers b/libdtrace/drti-vers
> new file mode 100644
> index 000000000000..8862dc291df1
> --- /dev/null
> +++ b/libdtrace/drti-vers
> @@ -0,0 +1 @@
> +{ local: *; };
> diff --git a/libdtrace/drti.c b/libdtrace/drti.c
> new file mode 100644
> index 000000000000..cabc316b0a00
> --- /dev/null
> +++ b/libdtrace/drti.c
> @@ -0,0 +1,193 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
> + * Licensed under the Universal Permissive License v 1.0 as shown at
> + * http://oss.oracle.com/licenses/upl.
> + */
> +
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <dlfcn.h>
> +#include <link.h>
> +#include <sys/dtrace.h>
> +#include <sys/compiler.h>
> +#include <sys/ioctl.h>
> +
> +#include <gelf.h>
> +
> +#include <limits.h>
> +#include <stdarg.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <errno.h>
> +
> +/*
> + * In Solaris 10 GA, the only mechanism for communicating helper information
> + * is through the DTrace helper pseudo-device node in /devices; there is
> + * no /dev link. Because of this, USDT providers and helper actions don't
> + * work inside of non-global zones. This issue was addressed by adding
> + * the /dev and having this initialization code use that /dev link. If the
> + * /dev link doesn't exist it falls back to looking for the /devices node
> + * as this code may be embedded in a binary which runs on Solaris 10 GA.
> + *
> + * Users may set the following environment variables to affect the way
> + * helper initialization takes place:
> + *
> + * DTRACE_DOF_INIT_DEBUG enable debugging output
> + * DTRACE_DOF_INIT_DISABLE disable helper loading
> + * DTRACE_DOF_INIT_DEVNAME set the path to the helper node
> + */
> +
> +static const char *devname = "/dev/dtrace/helper";
> +
> +static const char *modname; /* Name of this load object */
> +static int gen; /* DOF helper generation */
> +extern dof_hdr_t __SUNW_dof; /* DOF defined in the .SUNW_dof section */
> +static boolean_t dof_init_debug = B_FALSE; /* From DTRACE_DOF_INIT_DEBUG */
> +
> +_dt_constructor_(dtrace_dof_init)
> +static void
> +dtrace_dof_init(void)
> +{
> + dof_hdr_t *dof = &__SUNW_dof;
> +#ifdef _LP64
> + Elf64_Ehdr *elf;
> +#else
> + Elf32_Ehdr *elf;
> +#endif
> + dof_helper_t dh;
> + struct link_map *lmp = NULL;
> + Lmid_t lmid = -1;
> + int fd;
> + const char *p;
> +#if 1
> + char mfn[PATH_MAX]; /* "/proc/<pid>/maps" */
> + char str[4096]; /* read buffer */
> + FILE *fp;
> + struct link_map fmap = { 0x0, };
> +#endif
> +
> + if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL)
> + return;
> +
> + if (getenv("DTRACE_DOF_INIT_DEBUG") != NULL)
> + dof_init_debug = B_TRUE;
> +
> + if ((p = getenv("DTRACE_DOF_INIT_DEVNAME")) != NULL)
> + devname = p;
> +
> + if ((fd = open(devname, O_RDWR)) < 0) {
> + if (dof_init_debug)
> + dprintf(2, "DRTI: Failed to open helper device %s\n",
> + devname);
> + return;
> + }
> +
> +#if 0
> + if (dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &lmp) == -1) {
> + dprintf(2, "DRTI: Couldn't discover module name or address.\n");
> + goto out;
> + }
> +
> + if (dlinfo(RTLD_SELF, RTLD_DI_LMID, &lmid) == -1) {
> + dprintf(2, "DRTI: Couldn't discover link map ID.\n");
> + goto out;
> + }
> +#else
> + lmid = 0; /* We need a way to determine this. */
> +
> + snprintf(mfn, sizeof(mfn), "/proc/%d/maps", getpid());
> + if ((fp = fopen(mfn, "re")) == NULL) {
> + dprintf(2, "DRTI: Failed to open maps file.\n");
> + goto out;
> + }
> + while (fgets(str, sizeof(str), fp) != NULL) {
> + uintptr_t start, end;
> + char *p = str, *q;
> +
> + start = strtoul(p, &p, 16);
> + if (*p != '-')
> + continue;
> +
> + end = strtoul(++p, &p, 16);
> +
> + if (start > (uintptr_t)dtrace_dof_init ||
> + (uintptr_t)dtrace_dof_init > end)
> + continue;
> +
> + if ((p = strrchr(str, ' ')) == NULL)
> + continue;
> + if ((q = strchr(p, '\n')) != NULL)
> + *q = '\0';
> +
> + fmap.l_addr = start;
> + fmap.l_name = p + 1;
> + lmp = &fmap;
> +
> + break;
> + }
> + fclose(fp);
> +#endif
> + if (_dt_unlikely_(lmp == NULL)) {
> + dprintf(2, "DRTI: Couldn't discover module name or address.\n");
> + goto out;
> + }
> +
> + if ((modname = strrchr(lmp->l_name, '/')) == NULL)
> + modname = lmp->l_name;
> + else
> + modname++;
> +
> + if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 ||
> + dof->dofh_ident[DOF_ID_MAG1] != DOF_MAG_MAG1 ||
> + dof->dofh_ident[DOF_ID_MAG2] != DOF_MAG_MAG2 ||
> + dof->dofh_ident[DOF_ID_MAG3] != DOF_MAG_MAG3) {
> + dprintf(2, "DRTI: .SUNW_dof section corrupt in %s.\n",
> + lmp->l_name);
> + goto out;
> + }
> +
> + elf = (void *)lmp->l_addr;
> +
> + dh.dofhp_dof = (uintptr_t)dof;
> + dh.dofhp_addr = elf->e_type == ET_DYN ? lmp->l_addr : 0;
> +
> + if (lmid == 0) {
> + (void) snprintf(dh.dofhp_mod, sizeof (dh.dofhp_mod),
> + "%s", modname);
> + } else {
> + (void) snprintf(dh.dofhp_mod, sizeof (dh.dofhp_mod),
> + "LM%lu`%s", lmid, modname);
> + }
> +
> + if ((gen = ioctl(fd, DTRACEHIOC_ADDDOF, &dh)) == -1)
> + dprintf(2, "DRTI: Ioctl failed for DOF at %p\n", (void *)dof);
> + else if (dof_init_debug)
> + dprintf(2, "DRTI: Ioctl OK for DOF at %p (gen %d)\n",
> + (void *)dof, gen);
> +
> + out:
> + close(fd);
> +}
> +
> +_dt_destructor_(dtrace_dof_fini)
> +static void
> +dtrace_dof_fini(void)
> +{
> + int fd;
> +
> + if ((fd = open(devname, O_RDWR | O_CLOEXEC)) < 0) {
> + if (dof_init_debug)
> + dprintf(2, "DRTI: Failed to open helper device %s\n",
> + devname);
> + return;
> + }
> +
> + if ((gen = ioctl(fd, DTRACEHIOC_REMOVE, gen)) == -1)
> + dprintf(2, "DRTI: Ioctl failed to remove DOF (gen %d)\n", gen);
> + else if (dof_init_debug)
> + dprintf(2, "DRTI: Ioctl removed DOF (gen %d)\n", gen);
> +
> + close(fd);
> +}
> diff --git a/libdtrace/dt_link.c b/libdtrace/dt_link.c
> index 187f8d89d693..766b97420db3 100644
> --- a/libdtrace/dt_link.c
> +++ b/libdtrace/dt_link.c
> @@ -1570,6 +1570,7 @@ int
> dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
> const char *file, int objc, char *const objv[])
> {
> + char drti[PATH_MAX], symvers[PATH_MAX];
> dof_hdr_t *dof;
> int fd, status, i, cur;
> char *cmd;
> @@ -1634,8 +1635,8 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
>
> /*
> * Create a temporary file and then unlink it if we're going to
> - * link later. We can still refer to it in child processes as
> - * /dev/fd/<fd>.
> + * combine it with drti.o later. We can still refer to it in child
> + * processes as /dev/fd/<fd>.
> */
> if ((fd = open64(file, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1)
> return dt_link_error(dtp, NULL, -1, NULL,
> @@ -1681,7 +1682,8 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
> "failed to write %s: %s", file, strerror(errno));
>
> if (!dtp->dt_lazyload) {
> - const char *fmt = "%s%s -o %s -r /dev/fd/%d";
> + dt_dirpath_t *libdir = dt_list_next(&dtp->dt_lib_path);
> + const char *fmt = "%s%s -o %s -r --version-script=%s /dev/fd/%d %s";
> const char *emu;
>
> /*
> @@ -1690,19 +1692,25 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
> */
>
> if (dtp->dt_oflags & DTRACE_O_ILP32) {
> + snprintf(drti, sizeof (drti), "%s/drti32.o", libdir->dir_path);
> #if defined(__sparc)
> emu = " -m elf32_sparc";
> #elif defined(__i386) || defined(__amd64)
> emu = " -m elf_i386";
> #endif
> - } else
> + } else {
> + snprintf(drti, sizeof (drti), "%s/drti.o", libdir->dir_path);
> emu = "";
> + }
> + snprintf(symvers, sizeof (symvers), "%s/drti-vers", libdir->dir_path);
> +
> + len = snprintf(NULL, 0, fmt, dtp->dt_ld_path, emu, file,
> + symvers, fd, drti) + 1;
>
> - len = snprintf(NULL, 0, fmt, dtp->dt_ld_path, emu, file, fd) +
> - 1;
> cmd = alloca(len);
>
> - snprintf(cmd, len, fmt, dtp->dt_ld_path, emu, file, fd);
> + (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, emu, file,
> + symvers, fd, drti);
>
> if ((status = system(cmd)) == -1) {
> ret = dt_link_error(dtp, NULL, -1, NULL,
> --
> 2.37.1.265.g363c192786.dirty
>
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
More information about the DTrace-devel
mailing list