Skip to content

Instantly share code, notes, and snippets.

@indutny
Created February 24, 2014 10:01
Show Gist options
  • Save indutny/d3fee964995eea206fb3 to your computer and use it in GitHub Desktop.
Save indutny/d3fee964995eea206fb3 to your computer and use it in GitHub Desktop.
commit c46786f47483e7fc218727aa52cf6b2278a45053
Author: Fedor Indutny <fedor.indutny@gmail.com>
Date: Mon Feb 17 01:16:13 2014 +0400
dtrace: proper symbol fixup and import in drti
Application may contain multiple DOFs, merged into one ._SUNW_dof ELF
section. Process all of them and fix symbols only in those ones that
actaully define a provider. Use proper strtab for resolving symbols.
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
index 3b4a38c..e47cfb4d 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2013 Voxer Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -144,7 +145,8 @@ dtrace_dof_init(void)
Lmid_t lmid;
#else
u_long lmid = 0;
- dof_sec_t *sec;
+ dof_sec_t *sec, *secstart, *dofstrtab, *dofprobes;
+ dof_provider_t *dofprovider;
size_t i;
#endif
int fd;
@@ -152,12 +154,13 @@ dtrace_dof_init(void)
#if !defined(sun)
Elf *e;
Elf_Scn *scn = NULL;
- Elf_Data *symtabdata = NULL, *dynsymdata = NULL;
+ Elf_Data *symtabdata = NULL, *dynsymdata = NULL, *dofdata = NULL;
+ dof_hdr_t *dof_next = NULL;
GElf_Shdr shdr;
int efd, nprobes;
char *s;
+ char *dofstrtabraw;
size_t shstridx, symtabidx = 0, dynsymidx = 0;
- unsigned char *dofstrtab = NULL;
unsigned char *buf;
int fixedprobes = 0;
#endif
@@ -209,7 +212,9 @@ dtrace_dof_init(void)
} else if (shdr.sh_type == SHT_PROGBITS) {
s = elf_strptr(e, shstridx, shdr.sh_name);
if (s && strcmp(s, ".SUNW_dof") == 0) {
- dof = elf_getdata(scn, NULL)->d_buf;
+ dofdata = elf_getdata(scn, NULL);
+ dof = dofdata->d_buf;
+ break;
}
}
}
@@ -219,6 +224,9 @@ dtrace_dof_init(void)
close(efd);
return;
}
+
+ while ((char *) dof < (char *) dofdata->d_buf + dofdata->d_size) {
+ dof_next = (void *) ((char *) dof + dof->dofh_filesz);
#endif
if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 ||
@@ -290,34 +298,49 @@ dtrace_dof_init(void)
* We are assuming the number of probes is less than the number of
* symbols (libc can have 4k symbols, for example).
*/
- sec = (dof_sec_t *)(dof + 1);
+ secstart = sec = (dof_sec_t *)(dof + 1);
buf = (char *)dof;
for (i = 0; i < dof->dofh_secnum; i++, sec++) {
- if (sec->dofs_type == DOF_SECT_STRTAB)
- dofstrtab = (unsigned char *)(buf + sec->dofs_offset);
- else if (sec->dofs_type == DOF_SECT_PROBES && dofstrtab)
+ if (sec->dofs_type != DOF_SECT_PROVIDER)
+ continue;
+
+ dofprovider = (void *) (buf + sec->dofs_offset);
+ dofstrtab = secstart + dofprovider->dofpv_strtab;
+ dofprobes = secstart + dofprovider->dofpv_probes;
+
+ if (dofstrtab->dofs_type != DOF_SECT_STRTAB) {
+ fprintf(stderr, "WARNING: expected STRTAB section, but got %d\n",
+ dofstrtab->dofs_type);
break;
-
- }
- nprobes = sec->dofs_size / sec->dofs_entsize;
- fixsymbol(e, symtabdata, symtabidx, nprobes, buf, sec, &fixedprobes,
- dofstrtab);
- if (fixedprobes != nprobes) {
- /*
- * If we haven't fixed all the probes using the
- * symtab section, look inside the dynsym
- * section.
- */
- fixsymbol(e, dynsymdata, dynsymidx, nprobes, buf, sec,
- &fixedprobes, dofstrtab);
- }
- if (fixedprobes != nprobes) {
- fprintf(stderr, "WARNING: number of probes "
- "fixed does not match the number of "
- "defined probes (%d != %d, "
- "respectively)\n", fixedprobes, nprobes);
- fprintf(stderr, "WARNING: some probes might "
- "not fire or your program might crash\n");
+ }
+ if (dofprobes->dofs_type != DOF_SECT_PROBES) {
+ fprintf(stderr, "WARNING: expected PROBES section, but got %d\n",
+ dofprobes->dofs_type);
+ break;
+ }
+
+ dprintf(1, "found provider %p\n", dofprovider);
+ dofstrtabraw = (char *)(buf + dofstrtab->dofs_offset);
+ nprobes = dofprobes->dofs_size / dofprobes->dofs_entsize;
+ fixsymbol(e, symtabdata, symtabidx, nprobes, buf, dofprobes, &fixedprobes,
+ dofstrtabraw);
+ if (fixedprobes != nprobes) {
+ /*
+ * If we haven't fixed all the probes using the
+ * symtab section, look inside the dynsym
+ * section.
+ */
+ fixsymbol(e, dynsymdata, dynsymidx, nprobes, buf, dofprobes,
+ &fixedprobes, dofstrtabraw);
+ }
+ if (fixedprobes != nprobes) {
+ fprintf(stderr, "WARNING: number of probes "
+ "fixed does not match the number of "
+ "defined probes (%d != %d, "
+ "respectively)\n", fixedprobes, nprobes);
+ fprintf(stderr, "WARNING: some probes might "
+ "not fire or your program might crash\n");
+ }
}
#endif
if ((gen = ioctl(fd, DTRACEHIOC_ADDDOF, &dh)) == -1)
@@ -330,7 +353,12 @@ dtrace_dof_init(void)
}
(void) close(fd);
+
#if !defined(sun)
+ /* End of while loop */
+ dof = dof_next;
+ }
+
elf_end(e);
(void) close(efd);
#endif
@No9
Copy link

No9 commented Jan 16, 2015

Hi @indutny
Had a look at this patch on the new Digital Ocean 10.1
This patch seems to be in 10.1 as I mentioned here
https://twitter.com/dhigit9/status/519884077378580480

But I am getting
dtrace DOF node: .SUNW_dof section corrupt

On node v0.10.35

Are these patches meant to address this problem?
https://svnweb.freebsd.org/base/head/cddl/contrib/opensolaris/lib/lib0dtrace/common/drti.c?pathrev=276250&view=log&r1=276250&log_pagestart=0

Tried io.js 1.0.1 and that failed to build anything so Ill report that as a separate issue

@No9
Copy link

No9 commented Jan 16, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment