Page MenuHomeFreeBSD

D9374.id.diff
No OneTemporary

D9374.id.diff

Index: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
===================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
@@ -462,18 +462,8 @@
dt_buf_write(dtp, &ddo->ddo_enoffs, pip->pi_enoffs,
pip->pi_nenoffs * sizeof (uint32_t), sizeof (uint32_t));
- /*
- * If pi_rname isn't set, the relocation will be against the
- * function name. If it is, the relocation will be against
- * pi_rname. This will be used if the function is scoped
- * locally so an alternate symbol is added for the purpose
- * of this relocation.
- */
- if (pip->pi_rname == NULL)
- dofr.dofr_name = dofpr.dofpr_func;
- else
- dofr.dofr_name = dof_add_string(ddo, pip->pi_rname);
- dofr.dofr_type = DOF_RELO_SETX;
+ dofr.dofr_name = dof_add_string(ddo, pip->pi_rname);
+ dofr.dofr_type = DOF_RELO_DOFREL;
dofr.dofr_offset = dt_buf_len(&ddo->ddo_probes);
dofr.dofr_data = 0;
Index: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
===================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
@@ -237,7 +237,7 @@
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset;
rel->r_info = ELF32_R_INFO(count + dep->de_global,
- R_386_32);
+ R_386_PC32);
#elif defined(__mips__)
/* XXX */
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
@@ -253,15 +253,6 @@
#elif defined(__riscv__)
/* XXX */
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
-#elif defined(__sparc)
- /*
- * Add 4 bytes to hit the low half of this 64-bit
- * big-endian address.
- */
- rel->r_offset = s->dofs_offset +
- dofr[j].dofr_offset + 4;
- rel->r_info = ELF32_R_INFO(count + dep->de_global,
- R_SPARC_32);
#else
#error unknown ISA
#endif
@@ -270,7 +261,7 @@
sym->st_value = 0;
sym->st_size = 0;
sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC);
- sym->st_other = 0;
+ sym->st_other = ELF32_ST_VISIBILITY(STV_HIDDEN);
sym->st_shndx = SHN_UNDEF;
rel++;
@@ -287,11 +278,7 @@
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++;
@@ -448,18 +435,8 @@
#elif defined(__i386) || defined(__amd64)
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset;
-#ifdef illumos
rel->r_info = ELF64_R_INFO(count + dep->de_global,
- R_AMD64_64);
-#else
- rel->r_info = ELF64_R_INFO(count + dep->de_global,
- R_X86_64_RELATIVE);
-#endif
-#elif defined(__sparc)
- rel->r_offset = s->dofs_offset +
- dofr[j].dofr_offset;
- rel->r_info = ELF64_R_INFO(count + dep->de_global,
- R_SPARC_64);
+ R_X86_64_PC64);
#else
#error unknown ISA
#endif
@@ -468,7 +445,7 @@
sym->st_value = 0;
sym->st_size = 0;
sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC);
- sym->st_other = 0;
+ sym->st_other = ELF64_ST_VISIBILITY(STV_HIDDEN);
sym->st_shndx = SHN_UNDEF;
rel++;
@@ -485,11 +462,7 @@
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++;
@@ -797,16 +770,15 @@
}
static int
-dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
- GElf_Sym *sym, int uses_funcdesc, Elf *elf)
+dt_symtab_lookup(Elf_Data *data_sym, int start, int end, uintptr_t addr,
+ uint_t shn, GElf_Sym *sym, int uses_funcdesc, Elf *elf)
{
- int i, ret = -1;
Elf64_Addr symval;
Elf_Scn *opd_scn;
Elf_Data *opd_desc;
- GElf_Sym s;
+ int i;
- for (i = 0; i < nsym && gelf_getsym(data_sym, i, sym) != NULL; i++) {
+ for (i = start; i < end && gelf_getsym(data_sym, i, sym) != NULL; i++) {
if (GELF_ST_TYPE(sym->st_info) == STT_FUNC) {
symval = sym->st_value;
if (uses_funcdesc) {
@@ -816,20 +788,12 @@
*(uint64_t*)((char *)opd_desc->d_buf + symval);
}
if ((uses_funcdesc || shn == sym->st_shndx) &&
- symval <= addr &&
- addr < symval + sym->st_size) {
- if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
- return (0);
-
- ret = 0;
- s = *sym;
- }
+ symval <= addr && addr < symval + sym->st_size)
+ return (0);
}
}
- if (ret == 0)
- *sym = s;
- return (ret);
+ return (-1);
}
#if defined(__aarch64__)
@@ -1237,7 +1201,7 @@
dt_provider_t *pvp;
dt_probe_t *prp;
uint32_t off, eclass, emachine1, emachine2;
- size_t symsize, nsym, isym, istr, len;
+ size_t symsize, osym, nsym, isym, istr, len;
key_t objkey;
dt_link_pair_t *pair, *bufs = NULL;
dt_strtab_t *strtab;
@@ -1374,12 +1338,13 @@
* target (text) section to replace the call instruction with
* one or more nops.
*
- * If the function containing the probe is locally scoped
- * (static), we create an alias used by the relocation in the
- * generated object. The alias, a new symbol, will be global
- * (so that the relocation from the generated object can be
- * resolved), and hidden (so that it is converted to a local
- * symbol at link time). Such aliases have this form:
+ * To avoid runtime overhead, the relocations added to the
+ * generated object should be resolved at static link time. We
+ * therefore create aliases for the functions that contain
+ * probes. An alias is global (so that the relocation from the
+ * generated object can be resolved), and hidden (so that its
+ * address is known at static link time). Such aliases have this
+ * form:
*
* $dtrace<key>.<function>
*
@@ -1417,16 +1382,13 @@
if (strncmp(s, dt_prefix, sizeof (dt_prefix) - 1) != 0)
continue;
- if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
- shdr_rel.sh_info, &fsym,
- (emachine1 == EM_PPC64), elf) != 0) {
+ if (dt_symtab_lookup(data_sym, 0, isym, rela.r_offset,
+ shdr_rel.sh_info, &fsym, (emachine1 == EM_PPC64),
+ elf) != 0) {
dt_strtab_destroy(strtab);
goto err;
}
- if (GELF_ST_BIND(fsym.st_info) != STB_LOCAL)
- continue;
-
if (fsym.st_name > data_str->d_size) {
dt_strtab_destroy(strtab);
goto err;
@@ -1462,12 +1424,12 @@
}
/*
- * If needed, 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.
+ * 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
+ * structures, but are still responsible for freeing them once
+ * we're done with the elf handle.
*/
if (nsym > 0) {
/*
@@ -1516,9 +1478,11 @@
shdr_sym.sh_size += nsym * symsize;
(void) gelf_update_shdr(scn_sym, &shdr_sym);
+ osym = isym;
nsym += isym;
} else {
dt_strtab_destroy(strtab);
+ continue;
}
/*
@@ -1577,8 +1541,11 @@
bcopy(s, pname, p - s);
pname[p - s] = '\0';
- if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
- shdr_rel.sh_info, &fsym,
+ if (dt_symtab_lookup(data_sym, osym, isym,
+ rela.r_offset, shdr_rel.sh_info, &fsym,
+ (emachine1 == EM_PPC64), elf) != 0 &&
+ dt_symtab_lookup(data_sym, 0, osym,
+ rela.r_offset, shdr_rel.sh_info, &fsym,
(emachine1 == EM_PPC64), elf) != 0)
goto err;
@@ -1588,37 +1555,30 @@
assert(GELF_ST_TYPE(fsym.st_info) == STT_FUNC);
/*
- * If a NULL relocation name is passed to
- * dt_probe_define(), the function name is used for the
- * relocation. The relocation needs to use a mangled
- * name if the symbol is locally scoped; the function
- * name may need to change if we've found the global
- * alias for the locally scoped symbol (we prefer
- * global symbols to locals in dt_symtab_lookup()).
+ * If this is our first time encountering this symbol,
+ * emit an alias.
*/
s = (char *)data_str->d_buf + fsym.st_name;
- r = NULL;
- if (GELF_ST_BIND(fsym.st_info) == STB_LOCAL) {
+ if (strncmp(s, dt_symprefix,
+ sizeof (dt_symprefix) - 1) != 0) {
+ u_int bind = GELF_ST_BIND(fsym.st_info);
+
dsym = fsym;
dsym.st_name = istr;
- dsym.st_info = GELF_ST_INFO(STB_GLOBAL,
- STT_FUNC);
- dsym.st_other =
- ELF64_ST_VISIBILITY(STV_ELIMINATE);
+ dsym.st_info = GELF_ST_INFO(bind == STB_LOCAL ?
+ STB_GLOBAL : 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;
- istr += 1 + sprintf(r, dt_symfmt,
- dt_symprefix, objkey, s);
+ r = (char *) data_str->d_buf + istr;
+ istr += 1 + sprintf(r, dt_symfmt, dt_symprefix, objkey,
+ s);
isym++;
assert(isym <= nsym);
-
- } else if (strncmp(s, dt_symprefix,
- strlen(dt_symprefix)) == 0) {
+ } else {
r = s;
- if ((s = strchr(s, '.')) == NULL)
- goto err;
+ s = strchr(s, '.');
+ assert(s != NULL);
s++;
}
Index: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
===================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
@@ -545,9 +545,7 @@
for (pip = prp->pr_inst; pip != NULL; pip = pip->pi_next) {
if (strcmp(pip->pi_fname, fname) == 0 &&
- ((rname == NULL && pip->pi_rname == NULL) ||
- (rname != NULL && pip->pi_rname != NULL &&
- strcmp(pip->pi_rname, rname) == 0)))
+ strcmp(pip->pi_rname, rname) == 0)
break;
}
@@ -565,7 +563,7 @@
if ((pip->pi_fname = strdup(fname)) == NULL)
goto nomem;
- if (rname != NULL && (pip->pi_rname = strdup(rname)) == NULL)
+ if ((pip->pi_rname = strdup(rname)) == NULL)
goto nomem;
pip->pi_noffs = 0;
@@ -605,7 +603,7 @@
dt_dprintf("defined probe %s %s:%s %s() +0x%x (%s)\n",
isenabled ? "(is-enabled)" : "",
pvp->pv_desc.dtvd_name, prp->pr_ident->di_name, fname, offset,
- rname != NULL ? rname : fname);
+ rname);
assert(*noffs < *maxoffs);
(*offs)[(*noffs)++] = offset;
Index: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
===================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -13917,12 +13917,13 @@
/*
* Apply the relocations from the specified 'sec' (a DOF_SECT_URELHDR) to the
- * specified DOF. At present, this amounts to simply adding 'ubase' to the
- * site of any user SETX relocations to account for load object base address.
- * In the future, if we need other relocations, this function can be extended.
+ * specified DOF. SETX relocations are computed using 'ubase', the base load
+ * address of the object containing the DOF, and DOFREL relocations are relative
+ * to the relocation offset within the DOF.
*/
static int
-dtrace_dof_relocate(dof_hdr_t *dof, dof_sec_t *sec, uint64_t ubase)
+dtrace_dof_relocate(dof_hdr_t *dof, dof_sec_t *sec, uint64_t ubase,
+ uint64_t udaddr)
{
uintptr_t daddr = (uintptr_t)dof;
dof_relohdr_t *dofr =
@@ -13960,6 +13961,7 @@
case DOF_RELO_NONE:
break;
case DOF_RELO_SETX:
+ case DOF_RELO_DOFREL:
if (r->dofr_offset >= ts->dofs_size || r->dofr_offset +
sizeof (uint64_t) > ts->dofs_size) {
dtrace_dof_error(dof, "bad relocation offset");
@@ -13971,7 +13973,11 @@
return (-1);
}
- *(uint64_t *)taddr += ubase;
+ if (r->dofr_type == DOF_RELO_SETX)
+ *(uint64_t *)taddr += ubase;
+ else
+ *(uint64_t *)taddr +=
+ udaddr + ts->dofs_offset + r->dofr_offset;
break;
default:
dtrace_dof_error(dof, "invalid relocation type");
@@ -13992,7 +13998,7 @@
*/
static int
dtrace_dof_slurp(dof_hdr_t *dof, dtrace_vstate_t *vstate, cred_t *cr,
- dtrace_enabling_t **enabp, uint64_t ubase, int noprobes)
+ dtrace_enabling_t **enabp, uint64_t ubase, uint64_t udaddr, int noprobes)
{
uint64_t len = dof->dofh_loadsz, seclen;
uintptr_t daddr = (uintptr_t)dof;
@@ -14154,7 +14160,7 @@
switch (sec->dofs_type) {
case DOF_SECT_URELHDR:
- if (dtrace_dof_relocate(dof, sec, ubase) != 0)
+ if (dtrace_dof_relocate(dof, sec, ubase, udaddr) != 0)
return (-1);
break;
}
@@ -15519,7 +15525,7 @@
}
rv = dtrace_dof_slurp(dof, &state->dts_vstate, CRED(),
- &dtrace_anon.dta_enabling, 0, B_TRUE);
+ &dtrace_anon.dta_enabling, 0, 0, B_TRUE);
if (rv == 0)
rv = dtrace_dof_options(dof, state);
@@ -16290,7 +16296,7 @@
vstate = &help->dthps_vstate;
if ((rv = dtrace_dof_slurp(dof, vstate, NULL, &enab, dhp->dofhp_addr,
- B_FALSE)) != 0) {
+ dhp->dofhp_dof, B_FALSE)) != 0) {
dtrace_dof_destroy(dof);
return (rv);
}
Index: head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
===================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
+++ head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
@@ -784,6 +784,7 @@
#define DOF_RELO_NONE 0 /* empty relocation entry */
#define DOF_RELO_SETX 1 /* relocate setx value */
+#define DOF_RELO_DOFREL 2 /* relocate DOF-relative value */
typedef struct dof_optdesc {
uint32_t dofo_option; /* option identifier */
Index: head/sys/cddl/dev/dtrace/dtrace_ioctl.c
===================================================================
--- head/sys/cddl/dev/dtrace/dtrace_ioctl.c
+++ head/sys/cddl/dev/dtrace/dtrace_ioctl.c
@@ -429,7 +429,8 @@
return (EBUSY);
}
- if (dtrace_dof_slurp(dof, vstate, td->td_ucred, &enab, 0, B_TRUE) != 0) {
+ if (dtrace_dof_slurp(dof, vstate, td->td_ucred, &enab, 0, 0,
+ B_TRUE) != 0) {
mutex_exit(&dtrace_lock);
mutex_exit(&cpu_lock);
dtrace_dof_destroy(dof);

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 6, 2:42 PM (15 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29329295
Default Alt Text
D9374.id.diff (14 KB)

Event Timeline