Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146787548
D9374.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D9374.id.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D9374: Use PC-relative relocations for USDT probe offsets on x86
Attached
Detach File
Event Timeline
Log In to Comment