From b325e69c9282072ea3b203319017abc400db4771 Mon Sep 17 00:00:00 2001 From: rpaulo Date: Sat, 21 Aug 2010 11:50:53 +0000 Subject: Add libdtrace support for tracing userland programs. Summary of changes: * Implement a compatibility shim between Solaris libproc and our libproc and remove several ifdefs because of this. * Port the drti to FreeBSD. * Implement the missing DOODAD sections * Link with libproc and librtld_db * Support for ustack, jstack and uregs (by sson@) * Misc bugfixing When writing the SUWN_dof section, we had to resort to building the ELF file layout by "hand". This is the job of libelf, but our libelf doesn't support this yet. When libelf is fixed, we can remove the code under #ifdef BROKEN_LIBELF. Sponsored by: The FreeBSD Foundation --- cddl/contrib/opensolaris/cmd/dtrace/dtrace.c | 24 ++- .../opensolaris/lib/libdtrace/common/drti.c | 168 +++++++++++++++++- .../lib/libdtrace/common/dt_aggregate.c | 9 +- .../opensolaris/lib/libdtrace/common/dt_consume.c | 27 +-- .../opensolaris/lib/libdtrace/common/dt_link.c | 193 +++++++++++++++++++-- .../opensolaris/lib/libdtrace/common/dt_open.c | 14 +- .../opensolaris/lib/libdtrace/common/dt_pid.c | 83 +++------ .../opensolaris/lib/libdtrace/common/dt_proc.c | 154 ++++++++-------- .../opensolaris/lib/libdtrace/common/dt_proc.h | 2 - .../opensolaris/lib/libdtrace/common/dt_subr.c | 10 +- .../opensolaris/lib/libdtrace/common/dtrace.h | 3 + .../opensolaris/lib/libdtrace/i386/dt_isadep.c | 44 +++++ cddl/lib/libdtrace/Makefile | 16 +- cddl/lib/libdtrace/libproc_compat.h | 62 +++++++ cddl/lib/libdtrace/regs_x86.d | 121 +++++++++++++ 15 files changed, 712 insertions(+), 218 deletions(-) create mode 100644 cddl/lib/libdtrace/libproc_compat.h create mode 100644 cddl/lib/libdtrace/regs_x86.d (limited to 'cddl') diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c index 2580e63..63721ab 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c @@ -773,19 +773,27 @@ compile_str(dtrace_cmd_t *dcp) static void prochandler(struct ps_prochandle *P, const char *msg, void *arg) { -fatal("DOODAD in function %s, file %s, line %d\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD +#if defined(sun) const psinfo_t *prp = Ppsinfo(P); int pid = Pstatus(P)->pr_pid; char name[SIG2STR_MAX]; +#else + int wstatus = proc_getwstat(P); + int pid = proc_getpid(P); +#endif if (msg != NULL) { notice("pid %d: %s\n", pid, msg); return; } +#if defined(sun) switch (Pstate(P)) { +#else + switch (proc_state(P)) { +#endif case PS_UNDEAD: +#if defined(sun) /* * Ideally we would like to always report pr_wstat here, but it * isn't possible given current /proc semantics. If we grabbed @@ -798,9 +806,20 @@ fatal("DOODAD in function %s, file %s, line %d\n",__FUNCTION__,__FILE__,__LINE__ notice("pid %d terminated by %s\n", pid, proc_signame(WTERMSIG(prp->pr_wstat), name, sizeof (name))); +#else + if (WIFSIGNALED(wstatus)) { + notice("pid %d terminated by %d\n", pid, + WTERMSIG(wstatus)); +#endif +#if defined(sun) } else if (prp != NULL && WEXITSTATUS(prp->pr_wstat) != 0) { notice("pid %d exited with status %d\n", pid, WEXITSTATUS(prp->pr_wstat)); +#else + } else if (WEXITSTATUS(wstatus) != 0) { + notice("pid %d exited with status %d\n", + pid, WEXITSTATUS(wstatus)); +#endif } else { notice("pid %d has exited\n", pid); } @@ -812,7 +831,6 @@ fatal("DOODAD in function %s, file %s, line %d\n",__FUNCTION__,__FILE__,__LINE__ g_pslive--; break; } -#endif } /*ARGSUSED*/ diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c index 1ae8283..bce8038 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include /* * In Solaris 10 GA, the only mechanism for communicating helper information @@ -53,12 +55,16 @@ */ static const char *devnamep = "/dev/dtrace/helper"; +#if defined(sun) static const char *olddevname = "/devices/pseudo/dtrace@0:helper"; +#endif static const char *modname; /* Name of this load object */ static int gen; /* DOF helper generation */ +#if defined(sun) extern dof_hdr_t __SUNW_dof; /* DOF defined in the .SUNW_dof section */ -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 */ static void dprintf(int debug, const char *fmt, ...) @@ -83,6 +89,36 @@ dprintf(int debug, const char *fmt, ...) va_end(ap); } +#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 + #if defined(sun) #pragma init(dtrace_dof_init) #else @@ -92,22 +128,39 @@ static void dtrace_dof_init(void) __attribute__ ((constructor)); static void dtrace_dof_init(void) { +#if defined(sun) dof_hdr_t *dof = &__SUNW_dof; +#else + dof_hdr_t *dof = NULL; +#endif #ifdef _LP64 Elf64_Ehdr *elf; #else Elf32_Ehdr *elf; #endif dof_helper_t dh; -#if defined(sun) Link_map *lmp; +#if defined(sun) Lmid_t lmid; #else - struct link_map *lmp; u_long lmid = 0; + dof_sec_t *sec; + size_t i; #endif int fd; const char *p; +#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 if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL) return; @@ -127,10 +180,46 @@ dtrace_dof_init(void) } #endif + if ((modname = strrchr(lmp->l_name, '/')) == NULL) modname = lmp->l_name; else modname++; +#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 if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 || dof->dofh_ident[DOF_ID_MAG1] != DOF_MAG_MAG1 || @@ -158,7 +247,7 @@ dtrace_dof_init(void) if ((fd = open64(devnamep, O_RDWR)) < 0) { dprintf(1, "failed to open helper device %s", devnamep); - +#if defined(sun) /* * If the device path wasn't explicitly set, try again with * the old device path. @@ -172,14 +261,79 @@ dtrace_dof_init(void) dprintf(1, "failed to open helper device %s", devnamep); return; } +#else + return; +#endif } - +#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 if ((gen = ioctl(fd, DTRACEHIOC_ADDDOF, &dh)) == -1) dprintf(1, "DTrace ioctl failed for DOF at %p", dof); - else + else { dprintf(1, "DTrace ioctl succeeded for DOF at %p\n", dof); +#if !defined(sun) + gen = dh.gen; +#endif + } (void) close(fd); +#if !defined(sun) + elf_end(e); + (void) close(efd); +#endif } #if defined(sun) @@ -198,7 +352,7 @@ dtrace_dof_fini(void) return; } - if ((gen = ioctl(fd, DTRACEHIOC_REMOVE, gen)) == -1) + if ((gen = ioctl(fd, DTRACEHIOC_REMOVE, &gen)) == -1) dprintf(1, "DTrace ioctl failed to remove DOF (%d)\n", gen); else dprintf(1, "DTrace ioctl removed DOF (%d)\n", gen); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c index ac32f76..f6c9622 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c @@ -36,6 +36,7 @@ #include #else #include +#include #endif #include @@ -264,11 +265,7 @@ dt_aggregate_usym(dtrace_hdl_t *dtp, uint64_t *data) dt_proc_lock(dtp, P); -#if defined(sun) if (Plookup_by_addr(P, *pc, NULL, 0, &sym) == 0) -#else - if (proc_addr2sym(P, *pc, NULL, 0, &sym) == 0) -#endif *pc = sym.st_value; dt_proc_unlock(dtp, P); @@ -291,11 +288,7 @@ dt_aggregate_umod(dtrace_hdl_t *dtp, uint64_t *data) dt_proc_lock(dtp, P); -#if defined(sun) if ((map = Paddr_to_map(P, *pc)) != NULL) -#else - if ((map = proc_addr2map(P, *pc)) != NULL) -#endif *pc = map->pr_vaddr; dt_proc_unlock(dtp, P); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c index c8ac6b0..911478e 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c @@ -34,6 +34,9 @@ #include #endif #include +#if !defined(sun) +#include +#endif #define DT_MASK_LO 0x00000000FFFFFFFFULL @@ -952,17 +955,9 @@ dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format, if ((err = dt_printf(dtp, fp, "%*s", indent, "")) < 0) break; -#if defined(sun) if (P != NULL && Plookup_by_addr(P, pc[i], -#else - if (P != NULL && proc_addr2sym(P, pc[i], -#endif name, sizeof (name), &sym) == 0) { -#if defined(sun) (void) Pobjname(P, pc[i], objname, sizeof (objname)); -#else - (void) proc_objname(P, pc[i], objname, sizeof (objname)); -#endif if (pc[i] > sym.st_value) { (void) snprintf(c, sizeof (c), @@ -973,12 +968,8 @@ dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format, "%s`%s", dt_basename(objname), name); } } else if (str != NULL && str[0] != '\0' && str[0] != '@' && -#if defined(sun) (P != NULL && ((map = Paddr_to_map(P, pc[i])) == NULL || (map->pr_mflags & MA_WRITE)))) { -#else - (P != NULL && ((map = proc_addr2map(P, pc[i])) == NULL))) { -#endif /* * If the current string pointer in the string table * does not point to an empty string _and_ the program @@ -994,11 +985,7 @@ dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format, */ (void) snprintf(c, sizeof (c), "%s", str); } else { -#if defined(sun) if (P != NULL && Pobjname(P, pc[i], objname, -#else - if (P != NULL && proc_objname(P, pc[i], objname, -#endif sizeof (objname)) != 0) { (void) snprintf(c, sizeof (c), "%s`0x%llx", dt_basename(objname), (u_longlong_t)pc[i]); @@ -1068,11 +1055,7 @@ dt_print_usym(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, dtrace_actkind_t act) dt_proc_lock(dtp, P); -#if defined(sun) if (Plookup_by_addr(P, pc, NULL, 0, &sym) == 0) -#else - if (proc_addr2sym(P, pc, NULL, 0, &sym) == 0) -#endif pc = sym.st_value; dt_proc_unlock(dtp, P); @@ -1115,11 +1098,7 @@ dt_print_umod(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr) if (P != NULL) dt_proc_lock(dtp, P); /* lock handle while we perform lookups */ -#if defined(sun) if (P != NULL && Pobjname(P, pc, objname, sizeof (objname)) != 0) { -#else - if (P != NULL && proc_objname(P, pc, objname, sizeof (objname)) != 0) { -#endif (void) snprintf(c, sizeof (c), "%s", dt_basename(objname)); } else { (void) snprintf(c, sizeof (c), "0x%llx", (u_longlong_t)pc); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c index aa78658..0b8899a 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c @@ -51,6 +51,9 @@ #include #else #include +#include +#include +#include #endif #include #include @@ -412,7 +415,6 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep) s = &dofs[dofrh->dofr_tgtsec]; for (j = 0; j < nrel; j++) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); #ifdef DOODAD #if defined(__arm__) /* XXX */ @@ -1519,14 +1521,29 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) off = rela.r_offset - fsym.st_value; if (dt_modtext(dtp, data_tgt->d_buf, eprobe, - &rela, &off) != 0) { + &rela, &off) != 0) goto err; - } if (dt_probe_define(pvp, prp, s, r, off, eprobe) != 0) { return (dt_link_error(dtp, elf, fd, bufs, "failed to allocate space for probe")); } +#if !defined(sun) + /* + * Our linker doesn't understand the SUNW_IGNORE ndx and + * will try to use this relocation when we build the + * final executable. Since we are done processing this + * relocation, mark it as inexistant and let libelf + * remove it from the file. + * If this wasn't done, we would have garbage added to + * the executable file as the symbol is going to be + * change from UND to ABS. + */ + rela.r_offset = 0; + rela.r_info = 0; + rela.r_addend = 0; + (void) gelf_update_rela(data_rel, i, &rela); +#endif mod = 1; (void) elf_flagdata(data_tgt, ELF_C_SET, ELF_F_DIRTY); @@ -1538,13 +1555,13 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) * already been processed by an earlier link * invocation. */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD +#if !defined(sun) +#define SHN_SUNW_IGNORE SHN_ABS +#endif if (rsym.st_shndx != SHN_SUNW_IGNORE) { rsym.st_shndx = SHN_SUNW_IGNORE; (void) gelf_update_sym(data_sym, ndx, &rsym); } -#endif } } @@ -1554,6 +1571,9 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); (void) elf_end(elf); (void) close(fd); +#if !defined(sun) + if (nsym > 0) +#endif while ((pair = bufs) != NULL) { bufs = pair->dlp_next; dt_free(dtp, pair->dlp_str); @@ -1574,6 +1594,19 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, { #if !defined(sun) char tfile[PATH_MAX]; + Elf *e; + Elf_Scn *scn; + Elf_Data *data; + GElf_Shdr shdr; + int efd; + size_t stridx; + unsigned char *buf; + char *s; + int loc; + GElf_Ehdr ehdr; + Elf_Scn *scn0; + GElf_Shdr shdr0; + uint64_t off, rc; #endif char drti[PATH_MAX]; dof_hdr_t *dof; @@ -1697,12 +1730,17 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, (void) unlink(file); #endif +#if defined(sun) if (dtp->dt_oflags & DTRACE_O_LP64) status = dump_elf64(dtp, dof, fd); else status = dump_elf32(dtp, dof, fd); if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) { +#else + /* We don't write the ELF header, just the DOF section */ + if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz) { +#endif return (dt_link_error(dtp, NULL, -1, NULL, "failed to write %s: %s", file, strerror(errno))); } @@ -1726,7 +1764,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, fd, drti); #else - const char *fmt = "%s -o %s -r %s %s"; + const char *fmt = "%s -o %s -r %s"; #if defined(__amd64__) /* @@ -1748,11 +1786,14 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile, drti) + 1; +#if !defined(sun) + len *= 2; +#endif cmd = alloca(len); - (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, tfile, drti); + (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, + drti); #endif - if ((status = system(cmd)) == -1) { ret = dt_link_error(dtp, NULL, -1, NULL, "failed to run %s: %s", dtp->dt_ld_path, @@ -1760,8 +1801,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, goto done; } - (void) close(fd); /* release temporary file */ - if (WIFSIGNALED(status)) { ret = dt_link_error(dtp, NULL, -1, NULL, "failed to link %s: %s failed due to signal %d", @@ -1775,6 +1814,138 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, file, dtp->dt_ld_path, WEXITSTATUS(status)); goto done; } +#if !defined(sun) +#define BROKEN_LIBELF + /* + * FreeBSD's ld(1) is not instructed to interpret and add + * correctly the SUNW_dof section present in tfile. + * We use libelf to add this section manually and hope the next + * ld invocation won't remove it. + */ + elf_version(EV_CURRENT); + if ((efd = open(file, O_RDWR, 0)) < 0) { + ret = dt_link_error(dtp, NULL, -1, NULL, + "failed to open file %s: %s", + file, strerror(errno)); + goto done; + } + if ((e = elf_begin(efd, ELF_C_RDWR, NULL)) == NULL) { + close(efd); + ret = dt_link_error(dtp, NULL, -1, NULL, + "failed to open elf file: %s", + elf_errmsg(elf_errno())); + goto done; + } + /* + * Add the string '.SUWN_dof' to the shstrtab section. + */ +#ifdef BROKEN_LIBELF + elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT); +#endif + elf_getshdrstrndx(e, &stridx); + scn = elf_getscn(e, stridx); + gelf_getshdr(scn, &shdr); + data = elf_newdata(scn); + data->d_off = shdr.sh_size; + data->d_buf = ".SUNW_dof"; + data->d_size = 10; + data->d_type = ELF_T_BYTE; + loc = shdr.sh_size; + shdr.sh_size += data->d_size; + gelf_update_shdr(scn, &shdr); +#ifdef BROKEN_LIBELF + off = shdr.sh_offset; + rc = shdr.sh_offset + shdr.sh_size; + gelf_getehdr(e, &ehdr); + if (ehdr.e_shoff > off) { + off = ehdr.e_shoff + ehdr.e_shnum * ehdr.e_shentsize; + rc = roundup(rc, 8); + ehdr.e_shoff = rc; + gelf_update_ehdr(e, &ehdr); + rc += ehdr.e_shnum * ehdr.e_shentsize; + } + for (;;) { + scn0 = NULL; + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + gelf_getshdr(scn, &shdr); + if (shdr.sh_type == SHT_NOBITS || + shdr.sh_offset < off) + continue; + /* Find the immediately adjcent section. */ + if (scn0 == NULL || + shdr.sh_offset < shdr0.sh_offset) { + scn0 = scn; + gelf_getshdr(scn0, &shdr0); + } + } + if (scn0 == NULL) + break; + /* Load section data to work around another bug */ + elf_getdata(scn0, NULL); + /* Update section header, assure section alignment */ + off = shdr0.sh_offset + shdr0.sh_size; + rc = roundup(rc, shdr0.sh_addralign); + shdr0.sh_offset = rc; + gelf_update_shdr(scn0, &shdr0); + rc += shdr0.sh_size; + } + if (elf_update(e, ELF_C_WRITE) < 0) { + ret = dt_link_error(dtp, NULL, -1, NULL, + "failed to add append the shstrtab section: %s", + elf_errmsg(elf_errno())); + elf_end(e); + close(efd); + goto done; + } + elf_end(e); + e = elf_begin(efd, ELF_C_RDWR, NULL); +#endif + /* + * Construct the .SUNW_dof section. + */ + scn = elf_newscn(e); + data = elf_newdata(scn); + buf = mmap(NULL, dof->dofh_filesz, PROT_READ, MAP_SHARED, + fd, 0); + if (buf == MAP_FAILED) { + ret = dt_link_error(dtp, NULL, -1, NULL, + "failed to mmap buffer %s", strerror(errno)); + elf_end(e); + close(efd); + goto done; + } + data->d_buf = buf; + data->d_align = 4; + data->d_size = dof->dofh_filesz; + data->d_version = EV_CURRENT; + gelf_getshdr(scn, &shdr); + shdr.sh_name = loc; + shdr.sh_flags = SHF_ALLOC; + /* + * Actually this should be SHT_SUNW_dof, but FreeBSD's ld(1) + * will remove this 'unknown' section when we try to create an + * executable using the object we are modifying, so we stop + * playing by the rules and use SHT_PROGBITS. + * Also, note that our drti has modifications to handle this. + */ + shdr.sh_type = SHT_PROGBITS; + shdr.sh_addralign = 4; + gelf_update_shdr(scn, &shdr); + if (elf_update(e, ELF_C_WRITE) < 0) { + ret = dt_link_error(dtp, NULL, -1, NULL, + "failed to add the SUNW_dof section: %s", + elf_errmsg(elf_errno())); + munmap(buf, dof->dofh_filesz); + elf_end(e); + close(efd); + goto done; + } + munmap(buf, dof->dofh_filesz); + elf_end(e); + close(efd); +#endif + (void) close(fd); /* release temporary file */ } else { (void) close(fd); } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c index ec8bce8..a8070e6 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c @@ -283,10 +283,8 @@ static const dt_ident_t _dtrace_globals[] = { DT_VERS_1_5, &dt_idops_func, "string(int, void *)" }, { "ipl", DT_IDENT_SCALAR, 0, DIF_VAR_IPL, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "uint_t" }, -#if defined(sun) { "jstack", DT_IDENT_ACTFUNC, 0, DT_ACT_JSTACK, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "stack(...)" }, -#endif { "lltostr", DT_IDENT_FUNC, 0, DIF_SUBR_LLTOSTR, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "string(int64_t)" }, { "lquantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_LQUANTIZE, @@ -465,8 +463,10 @@ static const dt_ident_t _dtrace_globals[] = { #if defined(sun) { "uaddr", DT_IDENT_ACTFUNC, 0, DT_ACT_UADDR, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, +#endif { "ucaller", DT_IDENT_SCALAR, 0, DIF_VAR_UCALLER, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_type, "uint64_t" }, +#if defined(sun) { "ufunc", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, #endif @@ -475,6 +475,7 @@ static const dt_ident_t _dtrace_globals[] = { #if defined(sun) { "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, +#endif { "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_regs, NULL }, { "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0, @@ -482,6 +483,7 @@ static const dt_ident_t _dtrace_globals[] = { { "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_type, "uint32_t" }, +#if defined(sun) { "usym", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, #endif @@ -760,9 +762,7 @@ int _dtrace_argmax = 32; /* default maximum number of probe arguments */ int _dtrace_debug = 0; /* debug messages enabled (off) */ const char *const _dtrace_version = DT_VERS_STRING; /* API version string */ -#if defined(sun) int _dtrace_rdvers = RD_VERSION; /* rtld_db feature version */ -#endif typedef struct dt_fdlist { int *df_fds; /* array of provider driver file descriptors */ @@ -780,12 +780,10 @@ _dtrace_init(void) { _dtrace_debug = getenv("DTRACE_DEBUG") != NULL; -#if defined(sun) for (; _dtrace_rdvers > 0; _dtrace_rdvers--) { if (rd_init(_dtrace_rdvers) == RD_OK) break; } -#endif #if defined(__i386__) /* make long doubles 64 bits -sson */ (void) fpsetprec(FP_PE); @@ -1102,7 +1100,11 @@ alloc: bzero(dtp, sizeof (dtrace_hdl_t)); dtp->dt_oflags = flags; +#if defined(sun) dtp->dt_prcmode = DT_PROC_STOP_PREINIT; +#else + dtp->dt_prcmode = DT_PROC_STOP_POSTINIT; +#endif dtp->dt_linkmode = DT_LINK_KERNEL; dtp->dt_linktype = DT_LTYP_ELF; dtp->dt_xlatemode = DT_XL_STATIC; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c index a754d9c..52b0eb9 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c @@ -40,6 +40,9 @@ #include #include #include +#if !defined(sun) +#include +#endif typedef struct dt_pid_probe { dtrace_hdl_t *dpp_dtp; @@ -142,7 +145,6 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) pp->dpp_obj); if (!isdash && gmatch("return", pp->dpp_name)) { -#ifdef DOODAD if (dt_pid_create_return_probe(pp->dpp_pr, dtp, ftp, symp, pp->dpp_stret) < 0) { return (dt_pid_error(dtp, pcb, dpr, ftp, @@ -150,20 +152,17 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) "for '%s': %s", func, dtrace_errmsg(dtp, dtrace_errno(dtp)))); } -#endif nmatches++; } if (!isdash && gmatch("entry", pp->dpp_name)) { -#ifdef DOODAD if (dt_pid_create_entry_probe(pp->dpp_pr, dtp, ftp, symp) < 0) { return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_CREATEFAIL, "failed to create entry probe " "for '%s': %s", func, dtrace_errmsg(dtp, dtrace_errno(dtp)))); } -#endif nmatches++; } @@ -182,10 +181,8 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) (u_longlong_t)off, func)); } -#ifdef DOODAD err = dt_pid_create_offset_probe(pp->dpp_pr, pp->dpp_dtp, ftp, symp, off); -#endif if (err == DT_PROC_ERR) { return (dt_pid_error(dtp, pcb, dpr, ftp, @@ -203,7 +200,6 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) nmatches++; } else if (glob && !isdash) { -#ifdef DOODAD if (dt_pid_create_glob_offset_probes(pp->dpp_pr, pp->dpp_dtp, ftp, symp, pp->dpp_name) < 0) { return (dt_pid_error(dtp, pcb, dpr, ftp, @@ -211,7 +207,6 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) "failed to create offset probes in '%s': %s", func, dtrace_errmsg(dtp, dtrace_errno(dtp)))); } -#endif nmatches++; } @@ -279,7 +274,6 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) pp->dpp_obj = obj; else pp->dpp_obj++; - #if defined(sun) if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret1", &sym, NULL) == 0) @@ -305,25 +299,10 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) else pp->dpp_stret[3] = 0; #else - if (proc_name2sym(pp->dpp_pr, obj, ".stret1", &sym) == 0) - pp->dpp_stret[0] = sym.st_value; - else - pp->dpp_stret[0] = 0; - - if (proc_name2sym(pp->dpp_pr, obj, ".stret2", &sym) == 0) - pp->dpp_stret[1] = sym.st_value; - else - pp->dpp_stret[1] = 0; - - if (proc_name2sym(pp->dpp_pr, obj, ".stret4", &sym) == 0) - pp->dpp_stret[2] = sym.st_value; - else - pp->dpp_stret[2] = 0; - - if (proc_name2sym(pp->dpp_pr, obj, ".stret8", &sym) == 0) - pp->dpp_stret[3] = sym.st_value; - else - pp->dpp_stret[3] = 0; + pp->dpp_stret[0] = 0; + pp->dpp_stret[1] = 0; + pp->dpp_stret[2] = 0; + pp->dpp_stret[3] = 0; #endif dt_dprintf("%s stret %llx %llx %llx %llx\n", obj, @@ -345,12 +324,8 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) * just fail silently in the hopes that some other object will * contain the desired symbol. */ -#if defined(sun) if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, pp->dpp_func, &sym, NULL) != 0) { -#else - if (proc_name2sym(pp->dpp_pr, obj, pp->dpp_func, &sym) != 0) { -#endif if (strcmp("-", pp->dpp_func) == 0) { sym.st_name = 0; sym.st_info = @@ -390,16 +365,11 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) return (0); #endif -#if defined(sun) (void) Plookup_by_addr(pp->dpp_pr, sym.st_value, pp->dpp_func, -#else - (void) proc_addr2sym(pp->dpp_pr, sym.st_value, pp->dpp_func, -#endif DTRACE_FUNCNAMELEN, &sym); return (dt_pid_per_sym(pp, &sym, pp->dpp_func)); } else { -#ifdef DOODAD uint_t nmatches = pp->dpp_nmatches; if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_SYMTAB, @@ -415,7 +385,6 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1) return (1); } -#endif } return (0); @@ -459,14 +428,16 @@ dt_pid_mod_filt(void *arg, const prmap_t *pmp, const char *obj) static const prmap_t * dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) { -#ifdef DOODAD char m[MAXPATHLEN]; +#if defined(sun) Lmid_t lmid = PR_LMID_EVERY; - const char *obj; +#else + Lmid_t lmid = 0; #endif + const char *obj; const prmap_t *pmp; -#ifdef DOODAD +#if defined(sun) /* * Pick apart the link map from the library name. */ @@ -487,10 +458,14 @@ dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) } else { obj = pdp->dtpd_mod; } +#else + obj = pdp->dtpd_mod; +#endif if ((pmp = Plmid_to_map(P, lmid, obj)) == NULL) return (NULL); +#if defined(sun) (void) Pobjname(P, pmp->pr_vaddr, m, sizeof (m)); if ((obj = strrchr(m, '/')) == NULL) obj = &m[0]; @@ -498,11 +473,9 @@ dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) obj++; (void) Plmid(P, pmp->pr_vaddr, &lmid); +#endif dt_pid_objname(pdp->dtpd_mod, sizeof (pdp->dtpd_mod), lmid, obj); -#else -pmp = NULL; -#endif return (pmp); } @@ -544,13 +517,8 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, pp.dpp_mod = pdp->dtpd_mod; (void) strcpy(pdp->dtpd_mod, "a.out"); } else if (strisglob(pp.dpp_mod) || -#if defined(sun) (aout = Pname_to_map(pp.dpp_pr, "a.out")) == NULL || (pmp = Pname_to_map(pp.dpp_pr, pp.dpp_mod)) == NULL || -#else - (aout = proc_name2map(pp.dpp_pr, "a.out")) == NULL || - (pmp = proc_name2map(pp.dpp_pr, pp.dpp_mod)) == NULL || -#endif aout->pr_vaddr != pmp->pr_vaddr) { return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_LIB, "only the a.out module is valid with the " @@ -569,7 +537,6 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, * to iterate over each module and compare its name against the * pattern. An empty module name is treated as '*'. */ -#ifdef DOODAD if (strisglob(pp.dpp_mod)) { ret = Pobject_iter(pp.dpp_pr, dt_pid_mod_filt, &pp); } else { @@ -590,7 +557,6 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, ret = dt_pid_per_mod(&pp, pmp, obj); } } -#endif return (ret); } @@ -616,12 +582,8 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) * run the code to instantiate these providers. */ for (i = 0; i < 2; i++) { -#if defined(sun) if (Pxlookup_by_name(P, PR_LMID_EVERY, oname, syms[i], &sym, &sip) != 0) { -#else - if (proc_name2sym(P, oname, syms[i], &sym) != 0) { -#endif continue; } @@ -632,13 +594,11 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) dt_dprintf("lookup of %s succeeded for %s\n", syms[i], mname); -#ifdef DOODAD if (Pread(P, &e_type, sizeof (e_type), pmp->pr_vaddr + offsetof(Elf64_Ehdr, e_type)) != sizeof (e_type)) { dt_dprintf("read of ELF header failed"); continue; } -#endif dh.dofhp_dof = sym.st_value; dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr; @@ -650,7 +610,7 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) 0, mname); #endif -#ifdef DOODAD +#if defined(sun) if (fd == -1 && (fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) { dt_dprintf("pr_open of helper device failed: %s\n", @@ -663,7 +623,7 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) #endif } -#ifdef DOODAD +#if defined(sun) if (fd != -1) (void) pr_close(P, fd); #endif @@ -679,9 +639,9 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, int ret = 0; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); - -#ifdef DOODAD +#if defined(sun) (void) Pupdate_maps(P); +#endif if (Pobject_iter(P, dt_pid_usdt_mapping, P) != 0) { ret = -1; (void) dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_USDT, @@ -692,7 +652,6 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, (int)proc_getpid(P), strerror(errno)); #endif } -#endif /* * Put the module name in its canonical form. diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c index 13f5a1a..664a122 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c @@ -89,10 +89,15 @@ #include #include +#if !defined(sun) +#include +#include +#define SYS_forksys SYS_fork +#endif + #define IS_SYS_EXEC(w) (w == SYS_execve) #define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_forksys) -#ifdef DOODAD static dt_bkpt_t * dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data) { @@ -114,53 +119,62 @@ dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data) return (dbp); } -#endif static void dt_proc_bpdestroy(dt_proc_t *dpr, int delbkpts) { -#if defined(sun) int state = Pstate(dpr->dpr_proc); -#else - int state = proc_state(dpr->dpr_proc); -#endif dt_bkpt_t *dbp, *nbp; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = nbp) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD if (delbkpts && dbp->dbp_active && state != PS_LOST && state != PS_UNDEAD) { (void) Pdelbkpt(dpr->dpr_proc, dbp->dbp_addr, dbp->dbp_instr); } -#endif nbp = dt_list_next(dbp); dt_list_delete(&dpr->dpr_bps, dbp); dt_free(dpr->dpr_hdl, dbp); } } -#ifdef DOODAD static void dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr) { +#if defined(sun) const lwpstatus_t *psp = &Pstatus(dpr->dpr_proc)->pr_lwp; +#else + unsigned long pc; +#endif dt_bkpt_t *dbp; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); +#if !defined(sun) + proc_regget(dpr->dpr_proc, REG_PC, &pc); + proc_bkptregadj(&pc); +#endif + for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = dt_list_next(dbp)) { +#if defined(sun) if (psp->pr_reg[R_PC] == dbp->dbp_addr) break; +#else + if (pc == dbp->dbp_addr) + break; +#endif } if (dbp == NULL) { dt_dprintf("pid %d: spurious breakpoint wakeup for %lx\n", +#if defined(sun) (int)dpr->dpr_pid, (ulong_t)psp->pr_reg[R_PC]); +#else + (int)dpr->dpr_pid, pc); +#endif return; } @@ -170,7 +184,6 @@ dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr) dbp->dbp_func(dtp, dpr, dbp->dbp_data); (void) Pxecbkpt(dpr->dpr_proc, dbp->dbp_instr); } -#endif static void dt_proc_bpenable(dt_proc_t *dpr) @@ -181,12 +194,9 @@ dt_proc_bpenable(dt_proc_t *dpr) for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = dt_list_next(dbp)) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD if (!dbp->dbp_active && Psetbkpt(dpr->dpr_proc, dbp->dbp_addr, &dbp->dbp_instr) == 0) dbp->dbp_active = B_TRUE; -#endif } dt_dprintf("breakpoints enabled\n"); @@ -201,12 +211,9 @@ dt_proc_bpdisable(dt_proc_t *dpr) for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = dt_list_next(dbp)) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD if (dbp->dbp_active && Pdelbkpt(dpr->dpr_proc, dbp->dbp_addr, dbp->dbp_instr) == 0) dbp->dbp_active = B_FALSE; -#endif } dt_dprintf("breakpoints disabled\n"); @@ -279,7 +286,6 @@ dt_proc_bpmain(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *fname) dt_proc_stop(dpr, DT_PROC_STOP_MAIN); } -#if defined(sun) static void dt_proc_rdevent(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *evname) { @@ -336,7 +342,12 @@ dt_proc_rdwatch(dt_proc_t *dpr, rd_event_e event, const char *evname) } (void) dt_proc_bpcreate(dpr, rdn.u.bptaddr, +#if defined(sun) (dt_bkpt_f *)dt_proc_rdevent, (void *)evname); +#else + /* XXX ugly */ + (dt_bkpt_f *)dt_proc_rdevent, __DECONST(void *, evname)); +#endif } /* @@ -346,25 +357,34 @@ dt_proc_rdwatch(dt_proc_t *dpr, rd_event_e event, const char *evname) static void dt_proc_attach(dt_proc_t *dpr, int exec) { +#if defined(sun) const pstatus_t *psp = Pstatus(dpr->dpr_proc); +#endif rd_err_e err; GElf_Sym sym; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); if (exec) { +#if defined(sun) if (psp->pr_lwp.pr_errno != 0) return; /* exec failed: nothing needs to be done */ +#endif dt_proc_bpdestroy(dpr, B_FALSE); +#if defined(sun) Preset_maps(dpr->dpr_proc); +#endif } - if ((dpr->dpr_rtld = Prd_agent(dpr->dpr_proc)) != NULL && (err = rd_event_enable(dpr->dpr_rtld, B_TRUE)) == RD_OK) { +#if defined(sun) dt_proc_rdwatch(dpr, RD_PREINIT, "RD_PREINIT"); +#endif dt_proc_rdwatch(dpr, RD_POSTINIT, "RD_POSTINIT"); +#if defined(sun) dt_proc_rdwatch(dpr, RD_DLACTIVITY, "RD_DLACTIVITY"); +#endif } else { dt_dprintf("pid %d: failed to enable rtld events: %s\n", (int)dpr->dpr_pid, dpr->dpr_rtld ? rd_errstr(err) : @@ -406,6 +426,8 @@ dt_proc_attach(dt_proc_t *dpr, int exec) static void dt_proc_waitrun(dt_proc_t *dpr) { +printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); +#ifdef DOODAD struct ps_prochandle *P = dpr->dpr_proc; const lwpstatus_t *psp = &Pstatus(P)->pr_lwp; @@ -455,8 +477,8 @@ dt_proc_waitrun(dt_proc_t *dpr) } (void) pthread_mutex_lock(&dpr->dpr_lock); -} #endif +} typedef struct dt_proc_control_data { dtrace_hdl_t *dpcd_hdl; /* DTrace handle */ @@ -533,35 +555,26 @@ dt_proc_control(void *arg) (void) Psysexit(P, SYS_forksys, B_TRUE); Psync(P); /* enable all /proc changes */ +#endif dt_proc_attach(dpr, B_FALSE); /* enable rtld breakpoints */ /* * If PR_KLC is set, we created the process; otherwise we grabbed it. * Check for an appropriate stop request and wait for dt_proc_continue. */ +#if defined(sun) if (Pstatus(P)->pr_flags & PR_KLC) - dt_proc_stop(dpr, DT_PROC_STOP_CREATE); - else - dt_proc_stop(dpr, DT_PROC_STOP_GRAB); - - if (Psetrun(P, 0, 0) == -1) { - dt_dprintf("pid %d: failed to set running: %s\n", - (int)dpr->dpr_pid, strerror(errno)); - } #else - /* - * If PR_KLC is set, we created the process; otherwise we grabbed it. - * Check for an appropriate stop request and wait for dt_proc_continue. - */ if (proc_getflags(P) & PR_KLC) +#endif dt_proc_stop(dpr, DT_PROC_STOP_CREATE); else dt_proc_stop(dpr, DT_PROC_STOP_GRAB); - if (proc_continue(P) != 0) + if (Psetrun(P, 0, 0) == -1) { dt_dprintf("pid %d: failed to set running: %s\n", (int)dpr->dpr_pid, strerror(errno)); -#endif + } (void) pthread_mutex_unlock(&dpr->dpr_lock); @@ -575,14 +588,16 @@ dt_proc_control(void *arg) * Pwait() (which will return immediately) and do our processing. */ while (!dpr->dpr_quit) { -#if defined(sun) const lwpstatus_t *psp; +#if defined(sun) if (write(pfd, &wstop, sizeof (wstop)) == -1 && errno == EINTR) continue; /* check dpr_quit and continue waiting */ #else /* Wait for the process to report status. */ proc_wstatus(P); + if (errno == EINTR) + continue; /* check dpr_quit and continue waiting */ #endif (void) pthread_mutex_lock(&dpr->dpr_lock); @@ -595,14 +610,13 @@ pwait_locked: } #endif -#if defined(sun) switch (Pstate(P)) { -#else - switch (proc_state(P)) { -#endif case PS_STOP: -#ifdef DOODAD +#if defined(sun) psp = &Pstatus(P)->pr_lwp; +#else + psp = proc_getlwpstatus(P); +#endif dt_dprintf("pid %d: proc stopped showing %d/%d\n", pid, psp->pr_why, psp->pr_what); @@ -644,7 +658,6 @@ pwait_locked: else if (psp->pr_why == PR_SYSEXIT && IS_SYS_EXEC(psp->pr_what)) dt_proc_attach(dpr, B_TRUE); -#endif break; case PS_LOST: @@ -667,12 +680,10 @@ pwait_locked: break; } -#if defined(sun) if (Pstate(P) != PS_UNDEAD && Psetrun(P, 0, 0) == -1) { dt_dprintf("pid %d: failed to set running: %s\n", (int)dpr->dpr_pid, strerror(errno)); } -#endif (void) pthread_mutex_unlock(&dpr->dpr_lock); } @@ -712,11 +723,7 @@ dt_proc_error(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *format, ...) va_end(ap); if (dpr->dpr_proc != NULL) -#if defined(sun) Prelease(dpr->dpr_proc, 0); -#else - proc_detach(dpr->dpr_proc, 0); -#endif dt_free(dtp, dpr); (void) dt_set_errno(dtp, EDT_COMPILER); @@ -804,7 +811,7 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P) #if defined(sun) (void) _lwp_kill(dpr->dpr_tid, SIGCANCEL); #else - (void) pthread_kill(dpr->dpr_tid, SIGUSR1); + pthread_kill(dpr->dpr_tid, SIGUSR1); #endif /* @@ -853,11 +860,7 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P) } dt_list_delete(&dph->dph_lrulist, dpr); -#if defined(sun) Prelease(dpr->dpr_proc, rflag); -#else - proc_detach(dpr->dpr_proc, rflag); -#endif dt_free(dtp, dpr); } @@ -912,18 +915,15 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop) #if defined(sun) const psinfo_t *prp = Ppsinfo(dpr->dpr_proc); int stat = prp ? prp->pr_wstat : 0; -#endif int pid = dpr->dpr_pid; - -#if defined(sun) - if (Pstate(dpr->dpr_proc) == PS_LOST) { #else - if (proc_state(dpr->dpr_proc) == PS_LOST) { + int stat = proc_getwstat(dpr->dpr_proc); + int pid = proc_getpid(dpr->dpr_proc); #endif + if (proc_state(dpr->dpr_proc) == PS_LOST) { (void) dt_proc_error(dpr->dpr_hdl, dpr, "failed to control pid %d: process exec'd " "set-id or unobservable program\n", pid); -#if defined(sun) } else if (WIFSIGNALED(stat)) { (void) dt_proc_error(dpr->dpr_hdl, dpr, "failed to control pid %d: process died " @@ -932,7 +932,6 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop) (void) dt_proc_error(dpr->dpr_hdl, dpr, "failed to control pid %d: process exited " "with status %d\n", pid, WEXITSTATUS(stat)); -#endif } err = ESRCH; /* cause grab() or create() to fail */ @@ -965,30 +964,25 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv, #if defined(sun) if ((dpr->dpr_proc = Pcreate(file, argv, &err, NULL, 0)) == NULL) { +#else + if ((err = proc_create(file, argv, pcf, child_arg, + &dpr->dpr_proc)) != 0) { +#endif return (dt_proc_error(dtp, dpr, "failed to execute %s: %s\n", file, Pcreate_error(err))); } dpr->dpr_hdl = dtp; +#if defined(sun) dpr->dpr_pid = Pstatus(dpr->dpr_proc)->pr_pid; - - (void) Punsetflags(dpr->dpr_proc, PR_RLC); - (void) Psetflags(dpr->dpr_proc, PR_KLC); #else - (void) proc_clearflags(dpr->dpr_proc, PR_RLC); - (void) proc_setflags(dpr->dpr_proc, PR_KLC); - if ((err = proc_create(file, argv, pcf, child_arg, &dpr->dpr_proc)) != 0) - return (dt_proc_error(dtp, dpr, - "failed to execute %s: %s\n", file, strerror(err))); - dpr->dpr_hdl = dtp; dpr->dpr_pid = proc_getpid(dpr->dpr_proc); #endif -#if defined(sun) + (void) Punsetflags(dpr->dpr_proc, PR_RLC); + (void) Psetflags(dpr->dpr_proc, PR_KLC); + if (dt_proc_create_thread(dtp, dpr, dtp->dt_prcmode) != 0) -#else - if (dt_proc_create_thread(dtp, dpr, DT_PROC_STOP_IDLE) != 0) -#endif return (NULL); /* dt_proc_error() has been called for us */ dpr->dpr_hash = dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)]; @@ -1046,25 +1040,18 @@ dt_proc_grab(dtrace_hdl_t *dtp, pid_t pid, int flags, int nomonitor) #if defined(sun) if ((dpr->dpr_proc = Pgrab(pid, flags, &err)) == NULL) { +#else + if ((err = proc_attach(pid, flags, &dpr->dpr_proc)) != 0) { +#endif return (dt_proc_error(dtp, dpr, "failed to grab pid %d: %s\n", (int)pid, Pgrab_error(err))); } -#else - if ((err = proc_attach(pid, flags, &dpr->dpr_proc)) != 0) - return (dt_proc_error(dtp, dpr, - "failed to grab pid %d: %s\n", (int) pid, strerror(err))); -#endif dpr->dpr_hdl = dtp; dpr->dpr_pid = pid; -#if defined(sun) (void) Punsetflags(dpr->dpr_proc, PR_KLC); (void) Psetflags(dpr->dpr_proc, PR_RLC); -#else - (void) proc_clearflags(dpr->dpr_proc, PR_KLC); - (void) proc_setflags(dpr->dpr_proc, PR_RLC); -#endif /* * If we are attempting to grab the process without a monitor @@ -1185,12 +1172,13 @@ dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv, dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target"); struct ps_prochandle *P = dt_proc_create(dtp, file, argv, pcf, child_arg); - if (P != NULL && idp != NULL && idp->di_id == 0) + if (P != NULL && idp != NULL && idp->di_id == 0) { #if defined(sun) idp->di_id = Pstatus(P)->pr_pid; /* $target = created pid */ #else idp->di_id = proc_getpid(P); /* $target = created pid */ #endif + } return (P); } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h index b469f55..d1fc765 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h @@ -44,9 +44,7 @@ typedef struct dt_proc { dtrace_hdl_t *dpr_hdl; /* back pointer to libdtrace handle */ struct ps_prochandle *dpr_proc; /* proc handle for libproc calls */ char dpr_errmsg[BUFSIZ]; /* error message */ -#if defined(sun) rd_agent_t *dpr_rtld; /* rtld handle for librtld_db calls */ -#endif pthread_mutex_t dpr_lock; /* lock for manipulating dpr_hdl */ pthread_cond_t dpr_cv; /* cond for dpr_stop/quit/done */ pid_t dpr_pid; /* pid of process */ diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c index ca35e77..f4eadbc 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c @@ -40,6 +40,7 @@ #include #else #include +#include #endif #include #include @@ -963,13 +964,8 @@ dtrace_uaddr2str(dtrace_hdl_t *dtp, pid_t pid, dt_proc_lock(dtp, P); -#if defined(sun) if (Plookup_by_addr(P, addr, name, sizeof (name), &sym) == 0) { (void) Pobjname(P, addr, objname, sizeof (objname)); -#else - if (proc_addr2sym(P, addr, name, sizeof (name), &sym) == 0) { - (void) proc_objname(P, addr, objname, sizeof (objname)); -#endif obj = dt_basename(objname); @@ -979,11 +975,7 @@ dtrace_uaddr2str(dtrace_hdl_t *dtp, pid_t pid, } else { (void) snprintf(c, sizeof (c), "%s`%s", obj, name); } -#if defined(sun) } else if (Pobjname(P, addr, objname, sizeof (objname)) != 0) { -#else - } else if (proc_objname(P, addr, objname, sizeof (objname)) != 0) { -#endif (void) snprintf(c, sizeof (c), "%s`0x%llx", dt_basename(objname), addr); } else { diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h index 00b32ee..13c2776 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h @@ -34,6 +34,9 @@ #include #include #include +#if !defined(sun) +#include +#endif #ifdef __cplusplus extern "C" { diff --git a/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c b/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c index c1484a4..ad1c032 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c @@ -35,6 +35,12 @@ #include +#if !defined(sun) +#define PR_MODEL_ILP32 1 +#define PR_MODEL_LP64 2 +#include +#endif + #define DT_POPL_EBP 0x5d #define DT_RET 0xc3 #define DT_RET16 0xc2 @@ -78,8 +84,17 @@ dt_pid_has_jump_table(struct ps_prochandle *P, dtrace_hdl_t *dtp, { ulong_t i; int size; +#if defined(sun) pid_t pid = Pstatus(P)->pr_pid; char dmodel = Pstatus(P)->pr_dmodel; +#else + pid_t pid = proc_getpid(P); +#if __i386__ + char dmodel = PR_MODEL_ILP32; +#elif __amd64__ + char dmodel = PR_MODEL_LP64; +#endif +#endif /* * Take a pass through the function looking for a register-dependant @@ -98,6 +113,7 @@ dt_pid_has_jump_table(struct ps_prochandle *P, dtrace_hdl_t *dtp, return (1); } +#ifdef notyet /* * Register-dependant jmp instructions start with a 0xff byte * and have the modrm.reg field set to 4. They can have an @@ -110,6 +126,7 @@ dt_pid_has_jump_table(struct ps_prochandle *P, dtrace_hdl_t *dtp, ftp->ftps_func, i); return (1); } +#endif } return (0); @@ -123,8 +140,17 @@ dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, uint8_t *text; ulong_t i, end; int size; +#if defined(sun) pid_t pid = Pstatus(P)->pr_pid; char dmodel = Pstatus(P)->pr_dmodel; +#else + pid_t pid = proc_getpid(P); +#if __i386__ + char dmodel = PR_MODEL_ILP32; +#elif __amd64__ + char dmodel = PR_MODEL_LP64; +#endif +#endif /* * We allocate a few extra bytes at the end so we don't have to check @@ -275,8 +301,17 @@ dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, uint8_t *text; ulong_t i; int size; +#if defined(sun) pid_t pid = Pstatus(P)->pr_pid; char dmodel = Pstatus(P)->pr_dmodel; +#else + pid_t pid = proc_getpid(P); +#if __i386__ + char dmodel = PR_MODEL_ILP32; +#elif __amd64__ + char dmodel = PR_MODEL_LP64; +#endif +#endif if ((text = malloc(symp->st_size)) == NULL) { dt_dprintf("mr sparkle: malloc() failed\n"); @@ -349,8 +384,17 @@ dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp, uint8_t *text; int size; ulong_t i, end = symp->st_size; +#if defined(sun) pid_t pid = Pstatus(P)->pr_pid; char dmodel = Pstatus(P)->pr_dmodel; +#else + pid_t pid = proc_getpid(P); +#if __i386__ + char dmodel = PR_MODEL_ILP32; +#elif __amd64__ + char dmodel = PR_MODEL_LP64; +#endif +#endif ftp->ftps_type = DTFTP_OFFSETS; ftp->ftps_pc = (uintptr_t)symp->st_value; diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile index 7e500c7..2cc9564 100644 --- a/cddl/lib/libdtrace/Makefile +++ b/cddl/lib/libdtrace/Makefile @@ -18,6 +18,7 @@ SRCS= dt_aggregate.c \ dt_grammar.y \ dt_handle.c \ dt_ident.c \ + dt_isadep.c \ dt_inttab.c \ dt_lex.l \ dt_link.c \ @@ -41,7 +42,8 @@ SRCS= dt_aggregate.c \ dt_subr.c \ dt_work.c \ dt_xlator.c \ - gmatch.c + gmatch.c \ + dis_tables.c DSRCS= errno.d \ psinfo.d \ @@ -50,7 +52,8 @@ DSRCS= errno.d \ WARNS?= 1 -CFLAGS+= -I${.OBJDIR} \ +CFLAGS+= -I${.OBJDIR} -I${.CURDIR} \ + -I${.CURDIR}/../../../sys/cddl/dev/dtrace/${MACHINE_ARCH} \ -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \ -I${.CURDIR}/../../../cddl/compat/opensolaris/include \ -I${OPENSOLARIS_USR_DISTDIR}/head \ @@ -61,14 +64,21 @@ CFLAGS+= -I${.OBJDIR} \ #CFLAGS+= -DYYDEBUG .if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" -CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel +CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel -DDIS_MEM +.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/i386 +.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/${MACHINE_ARCH} .elif ${MACHINE_ARCH} == "sparc64" CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc +.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/sparc .else # temporary hack CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel .endif +.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" +DSRCS+= regs_x86.d +.endif + LFLAGS+=-l YFLAGS+=-d diff --git a/cddl/lib/libdtrace/libproc_compat.h b/cddl/lib/libdtrace/libproc_compat.h new file mode 100644 index 0000000..a561157 --- /dev/null +++ b/cddl/lib/libdtrace/libproc_compat.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Rui Paulo under sponsorship from the + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * Compatibility functions between Solaris libproc and FreeBSD libproc. + * Functions sorted alphabetically. + */ +#define PR_LMID_EVERY 0 +#define Psetrun(p, a1, a2) proc_continue((p)) +#define Pxlookup_by_addr(p, a, n, s, sym, i) \ + proc_addr2sym(p, a, n, s, sym) +#define Pxlookup_by_name(p, l, s1, s2, sym, a) \ + proc_name2sym((p), (s1), (s2), (sym)) +#define Paddr_to_map proc_addr2map +#define Pcreate_error strerror +#define Pdelbkpt proc_bkptdel +#define Pgrab_error strerror +#define Plmid_to_map(p, l, o) proc_obj2map((p), (o)) +#define Plookup_by_addr proc_addr2sym +#define Pname_to_map proc_name2map +#define Pobject_iter proc_iter_objs +#define Pobjname proc_objname +#define Pread proc_read +#define Prd_agent proc_rdagent +#define Prelease proc_detach +#define Psetbkpt proc_bkptset +#define Psetflags proc_setflags +#define Pstate proc_state +#define Pstate proc_state +#define Psymbol_iter_by_addr proc_iter_symbyaddr +#define Punsetflags proc_clearflags +#define Pupdate_maps(p) do { } while (0) +#define Pupdate_syms proc_updatesyms +#define Pxecbkpt proc_bkptexec diff --git a/cddl/lib/libdtrace/regs_x86.d b/cddl/lib/libdtrace/regs_x86.d new file mode 100644 index 0000000..7dce197 --- /dev/null +++ b/cddl/lib/libdtrace/regs_x86.d @@ -0,0 +1,121 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Portions Copyright 2009 Stacey Son sson@FreeBSD.org + * + * $FreeBSD$ + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "@(#)regs.d.in 1.1 04/09/28 SMI" + +inline int R_GS = 0; +#pragma D binding "1.0" R_GS +inline int R_FS = 1; +#pragma D binding "1.0" R_FS +inline int R_ES = 2; +#pragma D binding "1.0" R_ES +inline int R_DS = 3; +#pragma D binding "1.0" R_DS + +inline int R_EDI = 4; +#pragma D binding "1.0" R_EDI +inline int R_ESI = 5; +#pragma D binding "1.0" R_ESI +inline int R_EBP = 6; +#pragma D binding "1.0" R_EBP +inline int R_ESP = 7; +#pragma D binding "1.0" R_ESP +inline int R_EBX = 8; +#pragma D binding "1.0" R_EBX +inline int R_EDX = 9; +#pragma D binding "1.0" R_EDX +inline int R_ECX = 10; +#pragma D binding "1.0" R_ECX +inline int R_EAX = 11; +#pragma D binding "1.0" R_EAX + +inline int R_TRAPNO = 12; +#pragma D binding "1.0" R_TRAPNO +inline int R_ERR = 13; +#pragma D binding "1.0" R_ERR +inline int R_EIP = 14; +#pragma D binding "1.0" R_EIP +inline int R_CS = 15; +#pragma D binding "1.0" R_CS +inline int R_EFL = 16; +#pragma D binding "1.0" R_EFL +inline int R_UESP = 17; +#pragma D binding "1.0" R_UESP +inline int R_SS = 18; +#pragma D binding "1.0" R_SS + +inline int R_PC = R_EIP; +#pragma D binding "1.0" R_PC +inline int R_SP = R_UESP; +#pragma D binding "1.0" R_SP +inline int R_PS = R_EFL; +#pragma D binding "1.0" R_PS +inline int R_R0 = R_EAX; +#pragma D binding "1.0" R_R0 +inline int R_R1 = R_EBX; +#pragma D binding "1.0" R_R1 + +inline int R_RSP = 18 + 1 + 20; +#pragma D binding "1.0" R_RSP +inline int R_RFL = 18 + 1 + 19; +#pragma D binding "1.0" R_RFL +inline int R_RIP = 18 + 1 + 17; +#pragma D binding "1.0" R_RIP +inline int R_RAX = 18 + 1 + 14; +#pragma D binding "1.0" R_RAX +inline int R_RCX = 18 + 1 + 13; +#pragma D binding "1.0" R_RCX +inline int R_RDX = 18 + 1 + 12; +#pragma D binding "1.0" R_RDX +inline int R_RBX = 18 + 1 + 11; +#pragma D binding "1.0" R_RBX +inline int R_RBP = 18 + 1 + 10; +#pragma D binding "1.0" R_RBP +inline int R_RSI = 18 + 1 + 9; +#pragma D binding "1.0" R_RSI +inline int R_RDI = 18 + 1 + 8; +#pragma D binding "1.0" R_RDI +inline int R_R8 = 18 + 1 + 7; +#pragma D binding "1.0" R_R8 +inline int R_R9 = 18 + 1 + 6; +#pragma D binding "1.0" R_R9 +inline int R_R10 = 18 + 1 + 5; +#pragma D binding "1.0" R_R10 +inline int R_R11 = 18 + 1 + 4; +#pragma D binding "1.0" R_R11 +inline int R_R12 = 18 + 1 + 3; +#pragma D binding "1.0" R_R12 +inline int R_R13 = 18 + 1 + 2; +#pragma D binding "1.0" R_R13 +inline int R_R14 = 18 + 1 + 1; +#pragma D binding "1.0" R_R14 +inline int R_R15 = 18 + 1 + 0; +#pragma D binding "1.0" R_R15 + -- cgit v1.1