static int dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) { struct ps_prochandle *P = data; GElf_Sym sym; prsyminfo_t sip; dof_helper_t dh; GElf_Half e_type; const char *mname; const char *syms[] = { "___SUNW_dof", "__SUNW_dof" }; int i, fd = -1; /* * The symbol ___SUNW_dof is for lazy-loaded DOF sections, and * __SUNW_dof is for actively-loaded DOF sections. We try to force * in both types of DOF section since the process may not yet have * run the code to instantiate these providers. */ for (i = 0; i < 2; i++) { if (Pxlookup_by_name(P, PR_LMID_EVERY, oname, syms[i], &sym, &sip) != 0) { continue; } if ((mname = strrchr(oname, '/')) == NULL) mname = oname; else mname++; dt_dprintf("lookup of %s succeeded for %s\n", syms[i], mname); 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; } dh.dofhp_dof = sym.st_value; dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr; dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod), sip.prs_lmid, mname); if (fd == -1 && (fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) { dt_dprintf("pr_open of helper device failed: %s\n", strerror(errno)); return (-1); /* errno is set for us */ } if (pr_ioctl(P, fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)) < 0) dt_dprintf("DOF was rejected for %s\n", dh.dofhp_mod); } if (fd != -1) (void) pr_close(P, fd); return (0); }
int main(int argc, const char *argv[]) { int ifd, ofd, perr, toread, ret; struct ps_prochandle *p; GElf_Sym sym; prsyminfo_t si; char buf[1024]; if (argc != 3) { fprintf(stderr, "pdump: <infile> <outfile>\n"); return (1); } ifd = open(argv[1], O_RDONLY); if (ifd < 0) { fprintf(stderr, "failed to open: %s: %s\n", argv[1], strerror(errno)); return (1); } ofd = open(argv[2], O_RDWR | O_CREAT | O_TRUNC); if (ofd < 0) { fprintf(stderr, "failed to open: %s: %s\n", argv[1], strerror(errno)); return (1); } p = Pfgrab_core(ifd, NULL, &perr); if (p == NULL) { fprintf(stderr, "failed to grab core file\n"); return (1); } if (Pxlookup_by_name(p, NULL, "a.out", g_sym, &sym, &si) != 0) { fprintf(stderr, "failed to lookup symobl %s\n", g_sym); return (0); } while (sym.st_size > 0) { toread = MIN(sym.st_size, sizeof (buf)); ret = Pread(p, buf, toread, sym.st_value); if (ret < 0) { fprintf(stderr, "failed to Pread...\n"); return (1); } if (ret != 0) ret = write(ofd, buf, ret); if (ret < 0) { fprintf(stderr, "failed to write to output file %s\n", strerror(errno)); } sym.st_size -= ret; sym.st_value += ret; } return (0); }
/* * Common code for enabling events associated with the run-time linker after * attaching to a process or after a victim process completes an exec(2). */ static void dt_proc_attach(dt_proc_t *dpr, int exec) { const pstatus_t *psp = Pstatus(dpr->dpr_proc); rd_err_e err; GElf_Sym sym; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); if (exec) { if (psp->pr_lwp.pr_errno != 0) return; /* exec failed: nothing needs to be done */ dt_proc_bpdestroy(dpr, B_FALSE); Preset_maps(dpr->dpr_proc); } if ((dpr->dpr_rtld = Prd_agent(dpr->dpr_proc)) != NULL && (err = rd_event_enable(dpr->dpr_rtld, B_TRUE)) == RD_OK) { dt_proc_rdwatch(dpr, RD_PREINIT, "RD_PREINIT"); dt_proc_rdwatch(dpr, RD_POSTINIT, "RD_POSTINIT"); dt_proc_rdwatch(dpr, RD_DLACTIVITY, "RD_DLACTIVITY"); } else { dt_dprintf("pid %d: failed to enable rtld events: %s\n", (int)dpr->dpr_pid, dpr->dpr_rtld ? rd_errstr(err) : "rtld_db agent initialization failed"); } Pupdate_maps(dpr->dpr_proc); if (Pxlookup_by_name(dpr->dpr_proc, LM_ID_BASE, "a.out", "main", &sym, NULL) == 0) { (void) dt_proc_bpcreate(dpr, (uintptr_t)sym.st_value, (dt_bkpt_f *)dt_proc_bpmain, "a.out`main"); } else { dt_dprintf("pid %d: failed to find a.out`main: %s\n", (int)dpr->dpr_pid, strerror(errno)); } }
static int /*ARGSUSED*/ lookup_cb(void *data, const prmap_t *pmp, const char *object) { lookup_cb_arg_t *lcap = (lookup_cb_arg_t *)data; prsyminfo_t si; GElf_Sym sym; if (Pxlookup_by_name(lcap->lca_ph, LM_ID_BASE, object, "dlsym", &sym, &si) != 0) return (0); if (sym.st_shndx == SHN_UNDEF) return (0); /* * XXX: we should be more paranoid and verify that the symbol * we just looked up is libdl.so.2`dlsym */ lcap->lca_ptr = (caddr_t)(uintptr_t)sym.st_value; return (1); }
static void *Ploopcreate(LPVOID args) { STARTUPINFO si; PROCESS_INFORMATION pi; DEBUG_EVENT dbg; DWORD cont; BOOL wow = 0; DWORD Options = SymGetOptions(), excep, size = 0; TCHAR pszFilename[MAX_PATH+1]; struct proc_uc *tmp = args; struct ps_prochandle *P = tmp->ps; int first_execp = 0; char *s, targs[256], *ctmp; char *const *argv = tmp->args; int len; ctmp = targs; while (*argv != NULL) { len = strlen(*argv); sprintf(ctmp, "%s ", *argv); ctmp = ctmp + len + 1; argv++; } *ctmp = '\0'; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); if(!CreateProcess( NULL, // module name targs, // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE DEBUG_ONLY_THIS_PROCESS, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { pthread_mutex_lock(&P->mutex); P->status = PS_STOP; P->flags = CREATE_FAILED; pthread_cond_signal(&P->cond); pthread_mutex_unlock(&P->mutex); return NULL; } P->pid = pi.dwProcessId; P->tid = pi.dwThreadId; P->wstat = 0; P->exitcode = 0; P->event = CreateEvent(NULL,FALSE,FALSE,NULL); P->dll_load_order = 1; #if __amd64__ /* There seems to be a bug in 64 bit version of dbghelp.dll * when SYMOPT_DEFERRED_LOADS is set, * dtrace -n "pid$target:kernel32::entry, pid$target:KernelBase::entry" -c test.exe, * when SymEnumSymbols (Psymbol_iter_by_addr) is called on this two dll, * the second call (KernelBase) will enumerate the * symbols from the previous enumurated (kernel32) dll (from the first call). * This behaviour is not present in 32 bit. */ Options &= ~SYMOPT_DEFERRED_LOADS; #endif SymSetOptions(Options|SYMOPT_INCLUDE_32BIT_MODULES|SYMOPT_DEBUG); while (1) { if (WaitForDebugEvent(&dbg, INFINITE) == 0) { return NULL; } cont = DBG_CONTINUE; pthread_mutex_lock(&P->mutex); switch (dbg.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: P->phandle = dbg.u.CreateProcessInfo.hProcess; P->thandle = dbg.u.CreateProcessInfo.hThread; if ((SymInitialize(P->phandle, 0, FALSE) == FALSE)) { dprintf("SymInitialize failed: %d\n", GetLastError()); break; } s = GetFileNameFromHandle(dbg.u.CreateProcessInfo.hFile, pszFilename); addmodule(P, dbg.u.CreateProcessInfo.hFile, s, dbg.u.CreateProcessInfo.lpBaseOfImage, PE_TYPE_EXE, P->dll_load_order); size = GetFileSize(dbg.u.CreateProcessInfo.hFile, NULL); if (size == INVALID_FILE_SIZE) { size = 0; } if (SymLoadModuleEx(P->phandle, dbg.u.CreateProcessInfo.hFile, s, NULL, (ULONG_PTR) dbg.u.CreateProcessInfo.lpBaseOfImage, size, NULL, 0) == 0) { dprintf("SymLoadModule64 failed for %s:%d\n", s, GetLastError()); break; } #if __amd64__ if (Is32bitProcess(P->phandle)) { P->model = PR_MODEL_ILP32; wow = 1; } else P->model = PR_MODEL_ILP64; #else P->model = PR_MODEL_ILP32; #endif P->status = PS_STOP; P->msg.type = 0; CloseHandle(dbg.u.CreateProcessInfo.hFile); pthread_cond_signal(&P->cond); break; case CREATE_THREAD_DEBUG_EVENT: P->status = PS_RUN; P->msg.type = 0; break; case LOAD_DLL_DEBUG_EVENT: s = GetFileNameFromHandle(dbg.u.LoadDll.hFile, pszFilename); if (first_execp == 2) { P->dll_load_order++; } addmodule(P, dbg.u.LoadDll.hFile, s, dbg.u.LoadDll.lpBaseOfDll, PE_TYPE_DLL, P->dll_load_order); size = GetFileSize(dbg.u.LoadDll.hFile, NULL); if (size == INVALID_FILE_SIZE) { size = 0; } #if __amd64__ /* Not tracing 64 bit dlls for 32 bit process */ if (P->model == PR_MODEL_ILP32 && is64bitmodule(dbg.u.LoadDll.lpBaseOfDll, s)) { CloseHandle(dbg.u.LoadDll.hFile ); break; } #endif if (SymLoadModuleEx(P->phandle, dbg.u.LoadDll.hFile, s, NULL, (ULONG_PTR) dbg.u.LoadDll.lpBaseOfDll, size, NULL, 0) == FALSE) { dprintf("SymLoadModule64 dailed for %s:%d\n", s, GetLastError()); break; } CloseHandle(dbg.u.LoadDll.hFile ); P->status = PS_STOP; P->msg.type = RD_DLACTIVITY; break; case UNLOAD_DLL_DEBUG_EVENT: if (SymUnloadModule64(P->phandle, (ULONG_PTR) dbg.u.UnloadDll.lpBaseOfDll) == FALSE) { dprintf("SymUnloadModule64 failed-Imagebase %p:%d\n", dbg.u.UnloadDll.lpBaseOfDll, GetLastError()); break; } delmodule(P, (ULONG64) dbg.u.UnloadDll.lpBaseOfDll); P->status = PS_RUN; P->msg.type = RD_DLACTIVITY; break; case EXIT_PROCESS_DEBUG_EVENT: P->exitcode = dbg.u.ExitProcess.dwExitCode; P->status = PS_UNDEAD; P->msg.type = RD_NONE; break; case EXIT_THREAD_DEBUG_EVENT: P->status = PS_RUN; P->msg.type = 0; break; case EXCEPTION_DEBUG_EVENT: switch(excep = dbg.u.Exception.ExceptionRecord.ExceptionCode) { case EXCEPTION_BREAKPOINT: case 0x4000001F: /* WOW64 exception breakpoint */ /* NOTE: Dtrace sets a BP at main (entry point of the process), which is implemented * with Psetbkpt, Pdelbkpt & Pexecbkpt. But I have implemnted it here. */ if ((excep == EXCEPTION_BREAKPOINT && first_execp == 0 && wow == 0) || (excep == 0x4000001F && first_execp == 0 && wow == 1) ) { SYMBOL_INFO *Symbol; GElf_Sym sym; ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; Symbol = (SYMBOL_INFO *) buffer; Symbol->SizeOfStruct= sizeof(SYMBOL_INFO ); Symbol->MaxNameLen = MAX_SYM_NAME; if (Pxlookup_by_name(P, LM_ID_BASE, "a.out", "main", &sym, NULL) != 0 && Pxlookup_by_name(P, LM_ID_BASE, "a.out", "WinMain", &sym, NULL) != 0) { dprintf("failed to find entry point (main):%d\n", GetLastError()); break; } if (setbkpt(P, (uintptr_t) sym.st_value) != 0) { dprintf("failed to set breakpoint for %s at address %p\n", Symbol->Name, Symbol->Address); break; } first_execp = 1; P->status = PS_RUN; P->msg.type = 0; break; } if (dbg.u.Exception.ExceptionRecord.ExceptionAddress != (PVOID) P->addr) { dprintf("expecting execption at %p:but recived from %p\n", P->addr, dbg.u.Exception.ExceptionRecord.ExceptionAddress); P->status = PS_RUN; cont = DBG_EXCEPTION_NOT_HANDLED; break; } if (delbkpt(P, P->addr) != 0) { dprintf("failed to delete brk point at %p:(main)\n", P->addr); break; } if (adjbkpt(P, wow) != 0) { dprintf("failed to normalize brk point (main)\n"); break; } first_execp = 2; P->status = PS_STOP; P->msg.type = RD_MAININIT; break;/* if (first_execp == 0) { P->status = PS_STOP; P->msg.type = RD_MAININIT; first_execp = 2; } else { P->status = PS_RUN; cont = DBG_EXCEPTION_NOT_HANDLED; } break;*/ default: if (dbg.u.Exception.dwFirstChance == 0) P->wstat = dbg.u.Exception.ExceptionRecord.ExceptionCode; P->status = PS_RUN; cont = DBG_EXCEPTION_NOT_HANDLED; break; } break; default: P->status = PS_RUN; dprintf("Debug Event not processed: %d\n", dbg.dwDebugEventCode); break; } if (P->status != PS_RUN) SetEvent(P->event); while (P->status == PS_STOP) pthread_cond_wait(&P->cond, &P->mutex); pthread_mutex_unlock(&P->mutex); ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, cont); } }
static int dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) { dt_pid_probe_t *pp = arg; dtrace_hdl_t *dtp = pp->dpp_dtp; dt_pcb_t *pcb = pp->dpp_pcb; dt_proc_t *dpr = pp->dpp_dpr; GElf_Sym sym; if (obj == NULL) return (0); #if defined(sun) (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid); #endif if ((pp->dpp_obj = strrchr(obj, '/')) == NULL) 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) pp->dpp_stret[0] = sym.st_value; else pp->dpp_stret[0] = 0; if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret2", &sym, NULL) == 0) pp->dpp_stret[1] = sym.st_value; else pp->dpp_stret[1] = 0; if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret4", &sym, NULL) == 0) pp->dpp_stret[2] = sym.st_value; else pp->dpp_stret[2] = 0; if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret8", &sym, NULL) == 0) pp->dpp_stret[3] = sym.st_value; else pp->dpp_stret[3] = 0; #else 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, (u_longlong_t)pp->dpp_stret[0], (u_longlong_t)pp->dpp_stret[1], (u_longlong_t)pp->dpp_stret[2], (u_longlong_t)pp->dpp_stret[3]); /* * If pp->dpp_func contains any globbing meta-characters, we need * to iterate over the symbol table and compare each function name * against the pattern. */ if (!strisglob(pp->dpp_func)) { /* * If we fail to lookup the symbol, try interpreting the * function as the special "-" function that indicates that the * probe name should be interpreted as a absolute virtual * address. If that fails and we were matching a specific * function in a specific module, report the error, otherwise * just fail silently in the hopes that some other object will * contain the desired symbol. */ if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, pp->dpp_func, &sym, NULL) != 0) { if (strcmp("-", pp->dpp_func) == 0) { sym.st_name = 0; sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_FUNC); sym.st_other = 0; sym.st_value = 0; #if defined(sun) sym.st_size = Pstatus(pp->dpp_pr)->pr_dmodel == PR_MODEL_ILP32 ? -1U : -1ULL; #else sym.st_size = ~((Elf64_Xword) 0); #endif } else if (!strisglob(pp->dpp_mod)) { return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_FUNC, "failed to lookup '%s' in module '%s'", pp->dpp_func, pp->dpp_mod)); } else { return (0); } } /* * Only match defined functions of non-zero size. */ if (GELF_ST_TYPE(sym.st_info) != STT_FUNC || sym.st_shndx == SHN_UNDEF || sym.st_size == 0) return (0); /* * We don't instrument PLTs -- they're dynamically rewritten, * and, so, inherently dicey to instrument. */ #ifdef DOODAD if (Ppltdest(pp->dpp_pr, sym.st_value) != NULL) return (0); #endif (void) Plookup_by_addr(pp->dpp_pr, sym.st_value, pp->dpp_func, DTRACE_FUNCNAMELEN, &sym); return (dt_pid_per_sym(pp, &sym, pp->dpp_func)); } else { uint_t nmatches = pp->dpp_nmatches; if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_SYMTAB, BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1) return (1); if (nmatches == pp->dpp_nmatches) { /* * If we didn't match anything in the PR_SYMTAB, try * the PR_DYNSYM. */ if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_DYNSYM, BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1) return (1); } } return (0); }
uintptr_t la_pltexit(Elf32_Sym *symp, uint_t symndx, uintptr_t *refcookie, uintptr_t *defcookie, uintptr_t retval) #endif { #if !defined(_LP64) const char *sym_name = (const char *)symp->st_name; #endif sigset_t omask; char buf[256]; GElf_Sym sym; prsyminfo_t si; ctf_file_t *ctfp; ctf_funcinfo_t finfo; char *defname = (char *)(*defcookie); char *refname = (char *)(*refcookie); abilock(&omask); if (pidout) (void) fprintf(ABISTREAM, "%7u:", (unsigned int)getpid()); if (retval == 0) { if (verbose_list == NULL) { (void) fprintf(ABISTREAM, "<- %-8s -> %8s:%s()\n", refname, defname, sym_name); (void) fflush(ABISTREAM); } abiunlock(&omask); return (retval); } if ((ctfp = Pname_to_ctf(proc_hdl, defname)) == NULL) goto fail; if (Pxlookup_by_name(proc_hdl, PR_LMID_EVERY, defname, sym_name, &sym, &si) != 0) goto fail; if (ctf_func_info(ctfp, si.prs_id, &finfo) == CTF_ERR) goto fail; if (verbose_list != NULL) { if (check_intlist(verbose_list, sym_name) != 0) { (void) type_name(ctfp, finfo.ctc_return, buf, sizeof (buf)); (void) fprintf(ABISTREAM, "\treturn = (%s) ", buf); print_value(ctfp, finfo.ctc_return, retval); (void) fprintf(ABISTREAM, "\n"); (void) fprintf(ABISTREAM, "<- %-8s -> %8s:%s()", refname, defname, sym_name); (void) fprintf(ABISTREAM, " = 0x%p\n", (void *)retval); } } else { (void) fprintf(ABISTREAM, "<- %-8s -> %8s:%s()", refname, defname, sym_name); (void) fprintf(ABISTREAM, " = 0x%p\n", (void *)retval); } (void) fflush(ABISTREAM); abiunlock(&omask); return (retval); fail: if (verbose_list != NULL) { if (check_intlist(verbose_list, sym_name) != 0) { (void) fprintf(ABISTREAM, "\treturn = 0x%p\n", (void *)retval); (void) fprintf(ABISTREAM, "<- %-8s -> %8s:%s()", refname, defname, sym_name); (void) fprintf(ABISTREAM, " = 0x%p\n", (void *)retval); } } else { (void) fprintf(ABISTREAM, "<- %-8s -> %8s:%s()", refname, defname, sym_name); (void) fprintf(ABISTREAM, " = 0x%p\n", (void *)retval); } (void) fflush(ABISTREAM); abiunlock(&omask); return (retval); }
uintptr_t la_i86_pltenter(Elf32_Sym *symp, uint_t symndx, uintptr_t *refcookie, uintptr_t *defcookie, La_i86_regs *regset, uint_t *sb_flags) #endif { char *defname = (char *)(*defcookie); char *refname = (char *)(*refcookie); sigset_t omask; #if !defined(_LP64) char const *sym_name = (char const *)symp->st_name; #endif char buf[256]; GElf_Sym sym; prsyminfo_t si; ctf_file_t *ctfp; ctf_funcinfo_t finfo; int argc; ctf_id_t argt[NUM_ARGS]; ulong_t argv[NUM_ARGS]; int i; char *sep = ""; ctf_id_t type, rtype; int kind; abilock(&omask); if (pidout) (void) fprintf(ABISTREAM, "%7u:", (unsigned int)getpid()); if ((ctfp = Pname_to_ctf(proc_hdl, defname)) == NULL) goto fail; if (Pxlookup_by_name(proc_hdl, PR_LMID_EVERY, defname, sym_name, &sym, &si) != 0) goto fail; if (ctf_func_info(ctfp, si.prs_id, &finfo) == CTF_ERR) goto fail; (void) type_name(ctfp, finfo.ctc_return, buf, sizeof (buf)); (void) fprintf(ABISTREAM, "-> %-8s -> %8s:%s %s(", refname, defname, buf, sym_name); /* * According to bug in la_pltexit(), it can't return * if the type is just a struct/union. So, if the return * type is a struct/union, la_pltexit() should be off. */ rtype = ctf_type_resolve(ctfp, finfo.ctc_return); type = ctf_type_reference(ctfp, rtype); rtype = ctf_type_resolve(ctfp, type); kind = ctf_type_kind(ctfp, rtype); if ((kind == CTF_K_STRUCT || kind == CTF_K_UNION) && strpbrk(buf, "*") == NULL) *sb_flags |= LA_SYMB_NOPLTEXIT; argc = MIN(sizeof (argt) / sizeof (argt[0]), finfo.ctc_argc); (void) ctf_func_args(ctfp, si.prs_id, argc, argt); argv[0] = GETARG0(regset); if (argc > 1) argv[1] = GETARG1(regset); if (argc > 2) argv[2] = GETARG2(regset); if (argc > 3) argv[3] = GETARG3(regset); if (argc > 4) argv[4] = GETARG4(regset); if (argc > 5) argv[5] = GETARG5(regset); if (argc > 6) { for (i = 6; i < argc; i++) argv[i] = GETARG_6NUP(i, regset); } for (i = 0; i < argc; i++) { (void) type_name(ctfp, argt[i], buf, sizeof (buf)); (void) fprintf(ABISTREAM, "%s%s = ", sep, buf); rtype = ctf_type_resolve(ctfp, argt[i]); type = ctf_type_reference(ctfp, rtype); rtype = ctf_type_resolve(ctfp, type); kind = ctf_type_kind(ctfp, rtype); if (kind == CTF_K_STRUCT || kind == CTF_K_UNION) (void) fprintf(ABISTREAM, "0x%p", (void *)argv[i]); else print_value(ctfp, argt[i], argv[i]); sep = ", "; } if (finfo.ctc_flags & CTF_FUNC_VARARG) (void) fprintf(ABISTREAM, "%s...", sep); else if (argc == 0) (void) fprintf(ABISTREAM, "void"); if ((*sb_flags & LA_SYMB_NOPLTEXIT) != 0) (void) fprintf(ABISTREAM, ") ** ST\n"); else (void) fprintf(ABISTREAM, ")\n"); if (verbose_list != NULL && check_intlist(verbose_list, sym_name) != 0) { for (i = 0; i < argc; i++) { (void) type_name(ctfp, argt[i], buf, sizeof (buf)); (void) fprintf(ABISTREAM, "\targ%d = (%s) ", i, buf); print_value(ctfp, argt[i], argv[i]); (void) fprintf(ABISTREAM, "\n"); } if ((*sb_flags & LA_SYMB_NOPLTEXIT) != 0) { if (kind == CTF_K_STRUCT) (void) fprintf(ABISTREAM, "\treturn = (struct), apptrace " "will not trace the return\n"); else (void) fprintf(ABISTREAM, "\treturn = (union), apptrace " "will not trace the return\n"); } } (void) fflush(ABISTREAM); abiunlock(&omask); return (symp->st_value); fail: (void) fprintf(ABISTREAM, "-> %-8s -> %8s:%s(0x%lx, 0x%lx, 0x%lx) ** NR\n", refname, defname, sym_name, (ulong_t)GETARG0(regset), (ulong_t)GETARG1(regset), (ulong_t)GETARG2(regset)); *sb_flags |= LA_SYMB_NOPLTEXIT; (void) fflush(ABISTREAM); abiunlock(&omask); return (symp->st_value); }
static int dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) { struct ps_prochandle *P = data; GElf_Sym sym; #if defined(sun) prsyminfo_t sip; GElf_Half e_type; #endif dof_helper_t dh; const char *mname; const char *syms[] = { "___SUNW_dof", "__SUNW_dof" }; int i; #if defined(windows) HANDLE fd = NULL; DWORD ret, gen; #endif #if !defined(sun) dof_hdr_t hdr; #endif /* * The symbol ___SUNW_dof is for lazy-loaded DOF sections, and * __SUNW_dof is for actively-loaded DOF sections. We try to force * in both types of DOF section since the process may not yet have * run the code to instantiate these providers. */ for (i = 0; i < 2; i++) { if (Pxlookup_by_name(P, PR_LMID_EVERY, oname, syms[i], &sym, NULL) != 0) { continue; } if ((mname = strrchr(oname, '/')) == NULL) mname = oname; else mname++; dt_dprintf("lookup of %s succeeded for %s\n", syms[i], mname); #if 0 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; } dh.dofhp_dof = sym.st_value; dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr; #endif #if !defined(sun) dh.dofhp_addr = 0; dh.dofhp_dof = (uintptr_t) sym.st_value;; dh.dofhp_pid = Ppid(P); dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod), 0, mname); if (fd == NULL && (fd = CreateFile("\\\\.\\DtraceHelper", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == NULL) { dt_dprintf("open of helper device failed: %s\n", strerror(errno)); return (-1); /* errno is set for us */ } if ((DeviceIoControl(fd, DTRACEHIOC_ADDDOF, &dh, 0, &gen, 0, &ret, NULL)) == 0) dt_dprintf("DOF was rejected for %s\n", dh.dofhp_mod); else dt_dprintf("DOF was success for %s\n", dh.dofhp_mod); #else dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod), sip.prs_lmid, mname); if (fd == -1 && (fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) { dt_dprintf("pr_open of helper device failed: %s\n", strerror(errno)); return (-1); /* errno is set for us */ } if (pr_ioctl(P, fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)) < 0) dt_dprintf("DOF was rejected for %s\n", dh.dofhp_mod); #endif } #if defined(sun) if (fd != -1) (void) pr_close(P, fd); #else if (fd != 0) CloseHandle(fd); #endif return (0); }