Deleted Added
full compact
36a37,38
> #include <libelf.h>
> #include <gelf.h>
55a58
> #if defined(sun)
56a60
> #endif
59a64
> #if defined(sun)
61c66,67
< static boolean_t dof_init_debug = B_FALSE; /* From DTRACE_DOF_INIT_DEBUG */
---
> #endif
> static boolean_t dof_init_debug = B_TRUE; /* From DTRACE_DOF_INIT_DEBUG */
85a92,121
> #if !defined(sun)
> static void
> fixsymbol(Elf *e, Elf_Data *data, size_t idx, int nprobes, char *buf,
> dof_sec_t *sec, int *fixedprobes, char *dofstrtab)
> {
> GElf_Sym sym;
> char *s;
> unsigned char *funcname;
> dof_probe_t *prb;
> int j = 0;
> int ndx;
>
> while (gelf_getsym(data, j++, &sym) != NULL) {
> prb = (dof_probe_t *)(buf + sec->dofs_offset);
>
> for (ndx = nprobes; ndx; ndx--, prb += 1) {
> funcname = dofstrtab + prb->dofpr_func;
> s = elf_strptr(e, idx, sym.st_name);
> if (strcmp(s, funcname) == 0) {
> dprintf(1, "fixing %s() symbol\n", s);
> prb->dofpr_addr = sym.st_value;
> (*fixedprobes)++;
> }
> }
> if (*fixedprobes == nprobes)
> break;
> }
> }
> #endif
>
94a131
> #if defined(sun)
95a133,135
> #else
> dof_hdr_t *dof = NULL;
> #endif
102d141
< #if defined(sun)
103a143
> #if defined(sun)
106d145
< struct link_map *lmp;
107a147,148
> dof_sec_t *sec;
> size_t i;
110a152,163
> #if !defined(sun)
> Elf *e;
> Elf_Scn *scn = NULL;
> Elf_Data *symtabdata = NULL, *dynsymdata = NULL;
> GElf_Shdr shdr;
> int efd, nprobes;
> char *s;
> size_t shstridx, symtabidx = 0, dynsymidx = 0;
> unsigned char *dofstrtab = NULL;
> unsigned char *buf;
> int fixedprobes = 0;
> #endif
129a183
>
133a188,222
> #if !defined(sun)
> elf_version(EV_CURRENT);
> if ((efd = open(lmp->l_name, O_RDONLY, 0)) < 0) {
> dprintf(1, "couldn't open file for reading\n");
> return;
> }
> if ((e = elf_begin(efd, ELF_C_READ, NULL)) == NULL) {
> dprintf(1, "elf_begin failed\n");
> close(efd);
> return;
> }
> elf_getshdrstrndx(e, &shstridx);
> dof = NULL;
> while ((scn = elf_nextscn(e, scn)) != NULL) {
> gelf_getshdr(scn, &shdr);
> if (shdr.sh_type == SHT_SYMTAB) {
> symtabidx = shdr.sh_link;
> symtabdata = elf_getdata(scn, NULL);
> } else if (shdr.sh_type == SHT_DYNSYM) {
> dynsymidx = shdr.sh_link;
> dynsymdata = elf_getdata(scn, NULL);
> } 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;
> }
> }
> }
> if (dof == NULL) {
> dprintf(1, "SUNW_dof section not found\n");
> elf_end(e);
> close(efd);
> return;
> }
> #endif
161c250
<
---
> #if defined(sun)
174a264,266
> #else
> return;
> #endif
176c268,322
<
---
> #if !defined(sun)
> /*
> * We need to fix the base address of each probe since this wasn't
> * done by ld(1). (ld(1) needs to grow support for parsing the
> * SUNW_dof section).
> *
> * The complexity of this is not that great. The first for loop
> * iterates over the sections inside the DOF file. There are usually
> * 10 sections here. We asume the STRTAB section comes first and the
> * PROBES section comes after. Since we are only interested in fixing
> * data inside the PROBES section we quit the for loop after processing
> * the PROBES section. It's usually the case that the first section
> * is the STRTAB section and the second section is the PROBES section,
> * so this for loop is not meaningful when doing complexity analysis.
> *
> * After finding the probes section, we iterate over the symbols
> * in the symtab section. When we find a symbol name that matches
> * the probe function name, we fix it. If we have fixed all the
> * probes, we exit all the loops and we are done.
> * The number of probes is given by the variable 'nprobes' and this
> * depends entirely on the user, but some optimizations were done.
> *
> * 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);
> 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)
> 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");
> }
> #endif
179c325
< else
---
> else {
180a327,330
> #if !defined(sun)
> gen = dh.gen;
> #endif
> }
182a333,336
> #if !defined(sun)
> elf_end(e);
> (void) close(efd);
> #endif
201c355
< if ((gen = ioctl(fd, DTRACEHIOC_REMOVE, gen)) == -1)
---
> if ((gen = ioctl(fd, DTRACEHIOC_REMOVE, &gen)) == -1)