Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Feb 2015 03:54:55 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r278934 - in head: cddl/contrib/opensolaris/lib/libdtrace/common share/mk
Message-ID:  <201502180354.t1I3stA4009326@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Wed Feb 18 03:54:54 2015
New Revision: 278934
URL: https://svnweb.freebsd.org/changeset/base/278934

Log:
  Remove drti.o's dependency on libelf. This makes it possible to add DTrace
  probes to userland programs and libraries without also needing to link
  libelf.
  
  dtrace -G places the __SUNW_dof symbol at the beginning of the DOF (DTrace
  probe and provider metdata) section in the generated object file; drti.o
  now just uses this symbol to locate the section. A complication occurs
  when multiple dtrace-generated object files are linked together, since the
  __SUNW_dof symbol defined in each file is global. This is handled by
  using objcopy(1) to convert __SUNW_dof to a local symbol once drti.o has
  been linked with the generated object file. Upstream, this is done using a
  linker feature not present in GNU ld.
  
  Differential Revision:	https://reviews.freebsd.org/D1757
  Reviewed by:	rpaulo
  MFC after:	1 month
  Relnotes:	yes

Modified:
  head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
  head/share/mk/bsd.dep.mk

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c	Wed Feb 18 03:46:43 2015	(r278933)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c	Wed Feb 18 03:54:54 2015	(r278934)
@@ -36,7 +36,6 @@
 #include <string.h>
 #include <errno.h>
 #include <libelf.h>
-#include <gelf.h>
 
 /*
  * In Solaris 10 GA, the only mechanism for communicating helper information
@@ -62,9 +61,7 @@ static const char *olddevname = "/device
 
 static const char *modname;	/* Name of this load object */
 static int gen;			/* DOF helper generation */
-#ifdef illumos
 extern dof_hdr_t __SUNW_dof;	/* DOF defined in the .SUNW_dof section */
-#endif
 static boolean_t dof_init_debug = B_FALSE;	/* From DTRACE_DOF_INIT_DEBUG */
 
 static void
@@ -99,11 +96,7 @@ static void dtrace_dof_init(void) __attr
 static void
 dtrace_dof_init(void)
 {
-#ifdef illumos
 	dof_hdr_t *dof = &__SUNW_dof;
-#else
-	dof_hdr_t *dof = NULL;
-#endif
 #ifdef _LP64
 	Elf64_Ehdr *elf;
 #else
@@ -118,17 +111,6 @@ dtrace_dof_init(void)
 #endif
 	int fd;
 	const char *p;
-#ifndef illumos
-	Elf *e;
-	Elf_Scn *scn = NULL;
-	Elf_Data *dofdata = NULL;
-	dof_hdr_t *dof_next = NULL;
-	GElf_Shdr shdr;
-	int efd;
-	char *s;
-	size_t shstridx;
-	uint64_t aligned_filesz;
-#endif
 
 	if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL)
 		return;
@@ -152,42 +134,6 @@ dtrace_dof_init(void)
 		modname = lmp->l_name;
 	else
 		modname++;
-#ifndef illumos
-	elf_version(EV_CURRENT);
-	if ((efd = open(lmp->l_name, O_RDONLY, 0)) < 0) {
-		dprintf(1, "couldn't open file for reading\n");
-		return;
-	}
-	if ((e = elf_begin(efd, ELF_C_READ, NULL)) == NULL) {
-		dprintf(1, "elf_begin failed\n");
-		close(efd);
-		return;
-	}
-	elf_getshdrstrndx(e, &shstridx);
-	dof = NULL;
-	while ((scn = elf_nextscn(e, scn)) != NULL) {
-		gelf_getshdr(scn, &shdr);
-		if (shdr.sh_type == SHT_SUNW_dof) {
-			s = elf_strptr(e, shstridx, shdr.sh_name);
-			if (s != NULL && strcmp(s, ".SUNW_dof") == 0) {
-				dofdata = elf_getdata(scn, NULL);
-				dof = dofdata->d_buf;
-				break;
-			}
-		}
-	}
-	if (dof == NULL) {
-		dprintf(1, "SUNW_dof section not found\n");
-		elf_end(e);
-		close(efd);
-		return;
-	}
-
-	while ((char *) dof < (char *) dofdata->d_buf + dofdata->d_size) {
-		aligned_filesz = (shdr.sh_addralign == 0 ? dof->dofh_filesz :
-		    roundup2(dof->dofh_filesz, shdr.sh_addralign));
-		dof_next = (void *) ((char *) dof + aligned_filesz);
-#endif
 
 	if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 ||
 	    dof->dofh_ident[DOF_ID_MAG1] != DOF_MAG_MAG1 ||
@@ -237,21 +183,12 @@ dtrace_dof_init(void)
 		dprintf(1, "DTrace ioctl failed for DOF at %p", dof);
 	else {
 		dprintf(1, "DTrace ioctl succeeded for DOF at %p\n", dof);
-#ifndef illumos
+#ifdef __FreeBSD__
 		gen = dh.gen;
 #endif
 	}
 
 	(void) close(fd);
-
-#ifndef illumos
-		/* End of while loop */
-		dof = dof_next;
-	}
-
-	elf_end(e);
-	(void) close(efd);
-#endif
 }
 
 #ifdef illumos

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h	Wed Feb 18 03:46:43 2015	(r278933)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h	Wed Feb 18 03:54:54 2015	(r278934)
@@ -275,6 +275,9 @@ struct dtrace_hdl {
 	int dt_cpp_argc;	/* count of initialized cpp(1) arguments */
 	int dt_cpp_args;	/* size of dt_cpp_argv[] array */
 	char *dt_ld_path;	/* pathname of ld(1) to invoke if needed */
+#ifdef __FreeBSD__
+	char *dt_objcopy_path;	/* pathname of objcopy(1) to invoke if needed */
+#endif
 	dt_list_t dt_lib_path;	/* linked-list forming library search path */
 	uint_t dt_lazyload;	/* boolean:  set via -xlazyload */
 	uint_t dt_droptags;	/* boolean:  set via -xdroptags */

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c	Wed Feb 18 03:46:43 2015	(r278933)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c	Wed Feb 18 03:54:54 2015	(r278934)
@@ -281,7 +281,11 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION_
 	sym->st_value = 0;
 	sym->st_size = dof->dofh_filesz;
 	sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT);
+#ifdef illumos
 	sym->st_other = 0;
+#else
+	sym->st_other = ELF32_ST_VISIBILITY(STV_HIDDEN);
+#endif
 	sym->st_shndx = ESHDR_DOF;
 	sym++;
 
@@ -471,7 +475,11 @@ prepare_elf64(dtrace_hdl_t *dtp, const d
 	sym->st_value = 0;
 	sym->st_size = dof->dofh_filesz;
 	sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
+#ifdef illumos
 	sym->st_other = 0;
+#else
+	sym->st_other = ELF64_ST_VISIBILITY(STV_HIDDEN);
+#endif
 	sym->st_shndx = ESHDR_DOF;
 	sym++;
 
@@ -711,11 +719,7 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_
 
 	shp = &elf_file.shdr[ESHDR_DOF];
 	shp->sh_name = 11; /* DTRACE_SHSTRTAB64[11] = ".SUNW_dof" */
-#ifdef illumos
 	shp->sh_flags = SHF_ALLOC;
-#else
-	shp->sh_flags = SHF_WRITE | SHF_ALLOC;
-#endif
 	shp->sh_type = SHT_SUNW_dof;
 	shp->sh_offset = off;
 	shp->sh_size = dof->dofh_filesz;
@@ -1874,7 +1878,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, d
 #endif
 
 		(void) snprintf(drti, sizeof (drti), "/usr/lib%s/dtrace/drti.o",
-		    use_32 ? "32":"");
+		    use_32 ? "32" : "");
 
 		len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile,
 		    drti) + 1;
@@ -1885,26 +1889,61 @@ dtrace_program_link(dtrace_hdl_t *dtp, d
 		    drti);
 #endif
 		if ((status = system(cmd)) == -1) {
-			ret = dt_link_error(dtp, NULL, -1, NULL,
+			ret = dt_link_error(dtp, NULL, fd, NULL,
 			    "failed to run %s: %s", dtp->dt_ld_path,
 			    strerror(errno));
 			goto done;
 		}
 
 		if (WIFSIGNALED(status)) {
-			ret = dt_link_error(dtp, NULL, -1, NULL,
+			ret = dt_link_error(dtp, NULL, fd, NULL,
 			    "failed to link %s: %s failed due to signal %d",
 			    file, dtp->dt_ld_path, WTERMSIG(status));
 			goto done;
 		}
 
 		if (WEXITSTATUS(status) != 0) {
-			ret = dt_link_error(dtp, NULL, -1, NULL,
+			ret = dt_link_error(dtp, NULL, fd, NULL,
 			    "failed to link %s: %s exited with status %d\n",
 			    file, dtp->dt_ld_path, WEXITSTATUS(status));
 			goto done;
 		}
 		(void) close(fd); /* release temporary file */
+
+#ifdef __FreeBSD__
+		/*
+		 * Now that we've linked drti.o, reduce the global __SUNW_dof
+		 * symbol to a local symbol. This is needed to so that multiple
+		 * generated object files (for different providers, for
+		 * instance) can be linked together. This is accomplished using
+		 * the -Blocal flag with Sun's linker, but GNU ld doesn't appear
+		 * to have an equivalent option.
+		 */
+		asprintf(&cmd, "%s --localize-hidden %s", dtp->dt_objcopy_path,
+		    file);
+		if ((status = system(cmd)) == -1) {
+			ret = dt_link_error(dtp, NULL, -1, NULL,
+			    "failed to run %s: %s", dtp->dt_objcopy_path,
+			    strerror(errno));
+			free(cmd);
+			goto done;
+		}
+		free(cmd);
+
+		if (WIFSIGNALED(status)) {
+			ret = dt_link_error(dtp, NULL, -1, NULL,
+			    "failed to link %s: %s failed due to signal %d",
+			    file, dtp->dt_objcopy_path, WTERMSIG(status));
+			goto done;
+		}
+
+		if (WEXITSTATUS(status) != 0) {
+			ret = dt_link_error(dtp, NULL, -1, NULL,
+			    "failed to link %s: %s exited with status %d\n",
+			    file, dtp->dt_objcopy_path, WEXITSTATUS(status));
+			goto done;
+		}
+#endif
 	} else {
 		(void) close(fd);
 	}

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c	Wed Feb 18 03:46:43 2015	(r278933)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c	Wed Feb 18 03:54:54 2015	(r278934)
@@ -785,6 +785,7 @@ const char *_dtrace_defld = "/usr/ccs/bi
 #else
 const char *_dtrace_defcpp = "cpp"; /* default cpp(1) to invoke */
 const char *_dtrace_defld = "ld";   /* default ld(1) to invoke */
+const char *_dtrace_defobjcopy = "objcopy"; /* default objcopy(1) to invoke */
 #endif
 
 const char *_dtrace_libdir = "/usr/lib/dtrace"; /* default library directory */
@@ -1185,6 +1186,9 @@ alloc:
 	dtp->dt_cpp_argc = 1;
 	dtp->dt_cpp_args = 1;
 	dtp->dt_ld_path = strdup(_dtrace_defld);
+#ifdef __FreeBSD__
+	dtp->dt_objcopy_path = strdup(_dtrace_defobjcopy);
+#endif
 	dtp->dt_provmod = provmod;
 	dtp->dt_vector = vector;
 	dtp->dt_varg = arg;
@@ -1193,6 +1197,9 @@ alloc:
 
 	if (dtp->dt_mods == NULL || dtp->dt_provs == NULL ||
 	    dtp->dt_procs == NULL || dtp->dt_ld_path == NULL ||
+#ifdef __FreeBSD__
+	    dtp->dt_objcopy_path == NULL ||
+#endif
 	    dtp->dt_cpp_path == NULL || dtp->dt_cpp_argv == NULL)
 		return (set_open_errno(dtp, errp, EDT_NOMEM));
 
@@ -1673,6 +1680,9 @@ dtrace_close(dtrace_hdl_t *dtp)
 	free(dtp->dt_cpp_argv);
 	free(dtp->dt_cpp_path);
 	free(dtp->dt_ld_path);
+#ifdef __FreeBSD__
+	free(dtp->dt_objcopy_path);
+#endif
 
 	free(dtp->dt_mods);
 	free(dtp->dt_provs);

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c	Wed Feb 18 03:46:43 2015	(r278933)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c	Wed Feb 18 03:54:54 2015	(r278934)
@@ -280,6 +280,28 @@ dt_opt_ld_path(dtrace_hdl_t *dtp, const 
 	return (0);
 }
 
+#ifdef __FreeBSD__
+static int
+dt_opt_objcopy_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
+{
+	char *objcopy;
+
+	if (arg == NULL)
+		return (dt_set_errno(dtp, EDT_BADOPTVAL));
+
+	if (dtp->dt_pcb != NULL)
+		return (dt_set_errno(dtp, EDT_BADOPTCTX));
+
+	if ((objcopy = strdup(arg)) == NULL)
+		return (dt_set_errno(dtp, EDT_NOMEM));
+
+	free(dtp->dt_objcopy_path);
+	dtp->dt_objcopy_path = objcopy;
+
+	return (0);
+}
+#endif
+
 /*ARGSUSED*/
 static int
 dt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
@@ -960,6 +982,9 @@ static const dt_option_t _dtrace_ctoptio
 	{ "linkmode", dt_opt_linkmode },
 	{ "linktype", dt_opt_linktype },
 	{ "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },
+#ifdef __FreeBSD__
+	{ "objcopypath", dt_opt_objcopy_path },
+#endif
 	{ "pgmax", dt_opt_pgmax },
 	{ "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
 	{ "setenv", dt_opt_setenv, 1 },

Modified: head/share/mk/bsd.dep.mk
==============================================================================
--- head/share/mk/bsd.dep.mk	Wed Feb 18 03:46:43 2015	(r278933)
+++ head/share/mk/bsd.dep.mk	Wed Feb 18 03:54:54 2015	(r278934)
@@ -121,10 +121,7 @@ ${_YC:R}.o: ${_YC}
 .endfor
 
 # DTrace probe definitions
-# libelf is currently needed for drti.o
 .if ${SRCS:M*.d}
-LDADD+=		-lelf
-DPADD+=		${LIBELF}
 CFLAGS+=	-I${.OBJDIR}
 .endif
 .for _DSRC in ${SRCS:M*.d:N*/*}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502180354.t1I3stA4009326>