[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