Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Sep 2020 12:41:02 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r365566 - in stable/12/cddl: contrib/opensolaris/lib/libdtrace/common usr.sbin/dtrace/tests/tools
Message-ID:  <202009101241.08ACf2cY049587@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Thu Sep 10 12:41:01 2020
New Revision: 365566
URL: https://svnweb.freebsd.org/changeset/base/365566

Log:
  MFC r364438, r364440, r364483:
  Enable creation of static userspace probes in incremental builds.

Modified:
  stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
  stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.c
  stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.h
  stable/12/cddl/usr.sbin/dtrace/tests/tools/exclude.sh
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
==============================================================================
--- stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c	Thu Sep 10 12:01:35 2020	(r365565)
+++ stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c	Thu Sep 10 12:41:01 2020	(r365566)
@@ -770,6 +770,7 @@ dt_symtab_lookup(Elf_Data *data_sym, int start, int en
 #define	DT_OP_RET		0xd65f03c0
 #define	DT_OP_CALL26		0x94000000
 #define	DT_OP_JUMP26		0x14000000
+#define	DT_REL_NONE		R_AARCH64_NONE
 
 static int
 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
@@ -828,7 +829,8 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, 
 	return (0);
 }
 #elif defined(__arm__)
-/* XXX */
+#define	DT_REL_NONE		R_ARM_NONE
+
 static int
 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
     uint32_t *off)
@@ -838,7 +840,8 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, 
 	return (-1);
 }
 #elif defined(__mips__)
-/* XXX */
+#define	DT_REL_NONE		R_MIPS_NONE
+
 static int
 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
     uint32_t *off)
@@ -858,7 +861,8 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, 
 #define DT_IS_BRANCH(inst)	((inst & 0xfc000000) == 0x48000000)
 #define DT_IS_BL(inst)	(DT_IS_BRANCH(inst) && (inst & 0x01))
 
-/* XXX */
+#define	DT_REL_NONE		R_PPC_NONE
+
 static int
 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
     uint32_t *off)
@@ -875,7 +879,8 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, 
 	 * We only know about some specific relocation types.
 	 */
 	if (GELF_R_TYPE(rela->r_info) != R_PPC_REL24 &&
-	    GELF_R_TYPE(rela->r_info) != R_PPC_PLTREL24)
+	    GELF_R_TYPE(rela->r_info) != R_PPC_PLTREL24 &&
+	    GELF_R_TYPE(rela->r_info) != R_PPC_NONE)
 		return (-1);
 
 	/*
@@ -929,7 +934,7 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, 
 	return (0);
 }
 #elif defined(__riscv)
-/* XXX */
+#define	DT_REL_NONE		R_RISCV_NONE
 static int
 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
     uint32_t *off)
@@ -949,6 +954,8 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, 
 #define	DT_OP_XOR_EAX_0		0x33
 #define	DT_OP_XOR_EAX_1		0xc0
 
+#define	DT_REL_NONE		R_386_NONE
+
 static int
 dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
     uint32_t *off)
@@ -971,7 +978,8 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, 
 	 * x86 architectures.
 	 */
 	if (GELF_R_TYPE(rela->r_info) != R_386_PC32 &&
-	    GELF_R_TYPE(rela->r_info) != R_386_PLT32)
+	    GELF_R_TYPE(rela->r_info) != R_386_PLT32 &&
+	    GELF_R_TYPE(rela->r_info) != R_386_NONE)
 		return (-1);
 
 	/*
@@ -1267,6 +1275,11 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *e
 		 * We take a first pass through all the relocations to
 		 * populate our string table and count the number of extra
 		 * symbols we'll require.
+		 *
+		 * We also handle the case where the object has already been
+		 * processed, to support incremental rebuilds.  Relocations
+		 * of interest are converted to type NONE, but all information
+		 * needed to reconstruct the output DOF is retained.
 		 */
 		strtab = dt_strtab_create(1);
 		nsym = 0;
@@ -1274,7 +1287,6 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *e
 		istr = data_str->d_size;
 
 		for (i = 0; i < shdr_rel.sh_size / shdr_rel.sh_entsize; i++) {
-
 			if (shdr_rel.sh_type == SHT_RELA) {
 				if (gelf_getrela(data_rel, i, &rela) == NULL)
 					continue;
@@ -1339,7 +1351,12 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *e
 			    objkey, s);
 
 			if (dt_strtab_index(strtab, p) == -1) {
-				nsym++;
+				/*
+				 * Do not add new symbols if this object file
+				 * has already been processed.
+				 */
+				if (GELF_R_TYPE(rela.r_info) != DT_REL_NONE)
+					nsym++;
 				(void) dt_strtab_insert(strtab, p);
 			}
 
@@ -1347,13 +1364,14 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *e
 		}
 
 		/*
-		 * If any probes were found, allocate the additional space for
-		 * the symbol table and string table, copying the old data into
-		 * the new buffers, and marking the buffers as dirty. We inject
-		 * those newly allocated buffers into the libelf data
+		 * If any new probes were found, allocate the additional space
+		 * for the symbol table and string table, copying the old data
+		 * into the new buffers, and marking the buffers as dirty. We
+		 * inject those newly allocated buffers into the libelf data
 		 * structures, but are still responsible for freeing them once
 		 * we're done with the elf handle.
 		 */
+		osym = isym;
 		if (nsym > 0) {
 			/*
 			 * The first byte of the string table is reserved for
@@ -1405,9 +1423,8 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *e
 			shdr_sym.sh_size += nsym * symsize;
 			(void) gelf_update_shdr(scn_sym, &shdr_sym);
 
-			osym = isym;
 			nsym += isym;
-		} else {
+		} else if (dt_strtab_empty(strtab)) {
 			dt_strtab_destroy(strtab);
 			continue;
 		}
@@ -1417,7 +1434,6 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *e
 		 * modifications described above.
 		 */
 		for (i = 0; i < shdr_rel.sh_size / shdr_rel.sh_entsize; i++) {
-
 			if (shdr_rel.sh_type == SHT_RELA) {
 				if (gelf_getrela(data_rel, i, &rela) == NULL)
 					continue;
@@ -1484,32 +1500,51 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *e
 
 				bind = GELF_ST_BIND(fsym.st_info) == STB_WEAK ?
 				    STB_WEAK : STB_GLOBAL;
-
-				/*
-				 * Emit an alias for the symbol. It needs to be
-				 * non-preemptible so that .SUNW_dof relocations
-				 * may be resolved at static link time. Aliases
-				 * of weak symbols are given a non-unique name
-				 * so that they may be merged by the linker.
-				 */
-				dsym = fsym;
-				dsym.st_name = istr;
-				dsym.st_info = GELF_ST_INFO(bind, STT_FUNC);
-				dsym.st_other = GELF_ST_VISIBILITY(STV_HIDDEN);
-				(void) gelf_update_sym(data_sym, isym, &dsym);
-				r = (char *) data_str->d_buf + istr;
 				s = (char *) data_str->d_buf + fsym.st_name;
-				if (bind == STB_WEAK)
-					istr += sprintf(r, dt_weaksymfmt,
-					    dt_symprefix, s);
-				else
-					istr += sprintf(r, dt_symfmt,
-					    dt_symprefix, objkey, s);
-				istr++;
-				isym++;
-				assert(isym <= nsym);
-			} else
+				if (GELF_R_TYPE(rela.r_info) != DT_REL_NONE) {
+					/*
+					 * Emit an alias for the symbol. It
+					 * needs to be non-preemptible so that
+					 * .SUNW_dof relocations may be resolved
+					 * at static link time. Aliases of weak
+					 * symbols are given a non-unique name
+					 * so that they may be merged by the
+					 * linker.
+					 */
+					dsym = fsym;
+					dsym.st_name = istr;
+					dsym.st_info = GELF_ST_INFO(bind,
+					    STT_FUNC);
+					dsym.st_other =
+					    GELF_ST_VISIBILITY(STV_HIDDEN);
+					(void) gelf_update_sym(data_sym, isym,
+					    &dsym);
+					isym++;
+					assert(isym <= nsym);
+
+					r = (char *) data_str->d_buf + istr;
+					if (bind == STB_WEAK) {
+						istr += sprintf(r,
+						    dt_weaksymfmt, dt_symprefix,
+						    s);
+					} else {
+						istr += sprintf(r, dt_symfmt,
+						    dt_symprefix, objkey, s);
+					}
+					istr++;
+				} else {
+					if (bind == STB_WEAK) {
+						(void) asprintf(&r,
+						    dt_weaksymfmt, dt_symprefix,
+						    s);
+					} else {
+						(void) asprintf(&r, dt_symfmt,
+						    dt_symprefix, objkey, s);
+					}
+				}
+			} else {
 				goto err;
+			}
 
 			if ((pvp = dt_provider_lookup(dtp, pname)) == NULL) {
 				return (dt_link_error(dtp, elf, fd, bufs,
@@ -1538,24 +1573,18 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *e
 			}
 
 			/*
-			 * Our linker doesn't understand the SUNW_IGNORE ndx and
-			 * will try to use this relocation when we build the
-			 * final executable. Since we are done processing this
-			 * relocation, mark it as inexistant and let libelf
-			 * remove it from the file.
-			 * If this wasn't done, we would have garbage added to
-			 * the executable file as the symbol is going to be
-			 * change from UND to ABS.
+			 * We are done with this relocation, but it must be
+			 * preserved in order to support incremental rebuilds.
 			 */
 			if (shdr_rel.sh_type == SHT_RELA) {
-				rela.r_offset = 0;
-				rela.r_info  = 0;
-				rela.r_addend = 0;
+				rela.r_info = GELF_R_INFO(
+				    GELF_R_SYM(rela.r_info), DT_REL_NONE);
 				(void) gelf_update_rela(data_rel, i, &rela);
 			} else {
 				GElf_Rel rel;
-				rel.r_offset = 0;
-				rel.r_info = 0;
+				rel.r_offset = rela.r_offset;
+				rel.r_info = GELF_R_INFO(
+				    GELF_R_SYM(rela.r_info), DT_REL_NONE);
 				(void) gelf_update_rel(data_rel, i, &rel);
 			}
 
@@ -1607,19 +1636,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *
 	char *cmd, tmp;
 	size_t len;
 	int eprobes = 0, ret = 0;
-
-	if (access(file, R_OK) == 0) {
-		fprintf(stderr, "dtrace: target object (%s) already exists. "
-		    "Please remove the target\ndtrace: object and rebuild all "
-		    "the source objects if you wish to run the DTrace\n"
-		    "dtrace: linking process again\n", file);
-		/*
-		 * Several build infrastructures run DTrace twice (e.g.
-		 * postgres) and we don't want the build to fail. Return
-		 * 0 here since this isn't really a fatal error.
-		 */
-		return (0);
-	}
 
 	/*
 	 * A NULL program indicates a special use in which we just link

Modified: stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.c
==============================================================================
--- stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.c	Thu Sep 10 12:01:35 2020	(r365565)
+++ stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.c	Thu Sep 10 12:41:01 2020	(r365566)
@@ -206,6 +206,13 @@ err:
 	return (-1);
 }
 
+boolean_t
+dt_strtab_empty(dt_strtab_t *sp)
+{
+	/* Always contains "\0". */
+	return (sp->str_nstrs == 1);
+}
+
 ssize_t
 dt_strtab_index(dt_strtab_t *sp, const char *str)
 {

Modified: stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.h
==============================================================================
--- stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.h	Thu Sep 10 12:01:35 2020	(r365565)
+++ stable/12/cddl/contrib/opensolaris/lib/libdtrace/common/dt_strtab.h	Thu Sep 10 12:41:01 2020	(r365566)
@@ -58,6 +58,7 @@ typedef ssize_t dt_strtab_write_f(const char *, size_t
 
 extern dt_strtab_t *dt_strtab_create(size_t);
 extern void dt_strtab_destroy(dt_strtab_t *);
+extern boolean_t dt_strtab_empty(dt_strtab_t *);
 extern ssize_t dt_strtab_index(dt_strtab_t *, const char *);
 extern ssize_t dt_strtab_insert(dt_strtab_t *, const char *);
 extern size_t dt_strtab_size(const dt_strtab_t *);

Modified: stable/12/cddl/usr.sbin/dtrace/tests/tools/exclude.sh
==============================================================================
--- stable/12/cddl/usr.sbin/dtrace/tests/tools/exclude.sh	Thu Sep 10 12:01:35 2020	(r365565)
+++ stable/12/cddl/usr.sbin/dtrace/tests/tools/exclude.sh	Thu Sep 10 12:41:01 2020	(r365566)
@@ -186,10 +186,6 @@ exclude EXFAIL common/usdt/tst.eliminate.ksh
 # Generated headers include <sys/sdt.h>, so _DTRACE_VERSION is always defined.
 exclude EXFAIL common/usdt/tst.nodtrace.ksh
 
-# The second dtrace -G invocation returns an error with "no probes found," which
-# makes sense to me. Not yet sure what the expected behaviour is here.
-exclude EXFAIL common/usdt/tst.static2.ksh
-
 # Uses the Solaris-specific ppriv(1).
 exclude EXFAIL common/usdt/tst.user.ksh
 



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