[DTrace-devel] [PATCH 01/17] Revert "Remove drti.o and related support code."
Nick Alcock
nick.alcock at oracle.com
Wed Aug 10 22:06:53 UTC 2022
We're going to start using drti again, so bring it back.
This reverts commit 1e45252a1e1c9a2ab35e03558dc4e5bbf63ad0d8.
---
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
More information about the DTrace-devel
mailing list