[DTrace-devel] [PATCH 01/17] Revert "Remove drti.o and related support code."

Eugene Loh eugene.loh at oracle.com
Thu Sep 15 15:43:08 UTC 2022


On 9/15/22 09:30, Kris Van Hees via DTrace-devel wrote:

> 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>

And just to be sure... per other discussion, since this patch introduces 
regressions, it should be accompanied (immediately followed) by the 
"emit into subdirectory" patch, maybe labeled 15/17 in this series".

>> ---
>>   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
> _______________________________________________
> 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