[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