summaryrefslogtreecommitdiff
path: root/cddl
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-05-15 20:03:57 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-05-15 20:03:57 +0000
commit5273cdc3288beb49c82db58721e105ca54504923 (patch)
tree43e7f0446cc23ae7e6984b136aaa7f61a7a3228a /cddl
parent4fe2ee2d27fd6897ab0965a4174363dc9ba8f9f5 (diff)
downloadsrc-test2-5273cdc3288beb49c82db58721e105ca54504923.tar.gz
src-test2-5273cdc3288beb49c82db58721e105ca54504923.zip
Notes
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c14
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c140
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c8
3 files changed, 55 insertions, 107 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
index a4e325671f9f..3d1d976bd3dd 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c
@@ -462,18 +462,8 @@ dof_add_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
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;
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
index 1da91f003591..1120a6947c0b 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
@@ -239,7 +239,7 @@ prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep)
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): MIPS not implemented\n",
@@ -257,15 +257,6 @@ prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep)
/* XXX */
printf("%s:%s(%d): RISC-V not implemented\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
@@ -274,7 +265,7 @@ prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep)
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++;
@@ -291,11 +282,7 @@ prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep)
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++;
@@ -452,18 +439,8 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
#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
@@ -472,7 +449,7 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
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++;
@@ -489,11 +466,7 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
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++;
@@ -801,16 +774,15 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
}
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) {
@@ -820,20 +792,12 @@ dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
*(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__)
@@ -1245,7 +1209,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
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;
@@ -1382,12 +1346,13 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
* 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>
*
@@ -1425,16 +1390,13 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
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;
@@ -1470,12 +1432,12 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
}
/*
- * 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) {
/*
@@ -1524,9 +1486,11 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
shdr_sym.sh_size += nsym * symsize;
(void) gelf_update_shdr(scn_sym, &shdr_sym);
+ osym = isym;
nsym += isym;
} else {
dt_strtab_destroy(strtab);
+ continue;
}
/*
@@ -1585,8 +1549,11 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
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;
@@ -1596,37 +1563,30 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
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++;
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
index 29138746cfd9..7cf352d4d505 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
@@ -545,9 +545,7 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
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 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
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_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
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;