Permalink
Browse files

make mdb work with FreeBSD core files (kind of)

  • Loading branch information...
ahrens committed Mar 15, 2015
1 parent 356f579 commit 018e181a674cb836d62b1dcee9833c15068d7444
Showing with 140 additions and 51 deletions.
  1. +60 −38 usr/src/lib/libproc/common/Pcore.c
  2. +80 −13 usr/src/lib/libproc/common/Pcore_linux.h
@@ -395,9 +395,13 @@ note_lwpstatus(struct ps_prochandle *P, size_t nbytes)
{
lwp_info_t *lwp;
lwpstatus_t lps;
core_info_t *core = P->data;
/* XXX figure out what this struct is - nbytes==0x8c */
if (core->core_osabi == ELFOSABI_FREEBSD)
return (0);
#ifdef _LP64
core_info_t *core = P->data;
if (core->core_dmodel == PR_MODEL_ILP32) {
lwpstatus32_t l32;
@@ -439,13 +443,15 @@ note_lwpstatus(struct ps_prochandle *P, size_t nbytes)
static void
lx_prpsinfo32_to_psinfo(lx_prpsinfo32_t *p32, psinfo_t *psinfo)
{
#if 0
psinfo->pr_flag = p32->pr_flag;
psinfo->pr_pid = p32->pr_pid;
psinfo->pr_ppid = p32->pr_ppid;
psinfo->pr_uid = p32->pr_uid;
psinfo->pr_gid = p32->pr_gid;
psinfo->pr_sid = p32->pr_sid;
psinfo->pr_pgid = p32->pr_pgrp;
#endif
(void) memcpy(psinfo->pr_fname, p32->pr_fname,
sizeof (psinfo->pr_fname));
@@ -456,6 +462,7 @@ lx_prpsinfo32_to_psinfo(lx_prpsinfo32_t *p32, psinfo_t *psinfo)
static void
lx_prpsinfo64_to_psinfo(lx_prpsinfo64_t *p64, psinfo_t *psinfo)
{
#if 0
psinfo->pr_flag = p64->pr_flag;
psinfo->pr_pid = p64->pr_pid;
psinfo->pr_ppid = p64->pr_ppid;
@@ -464,6 +471,7 @@ lx_prpsinfo64_to_psinfo(lx_prpsinfo64_t *p64, psinfo_t *psinfo)
psinfo->pr_sid = p64->pr_sid;
psinfo->pr_pgid = p64->pr_pgrp;
psinfo->pr_pgid = p64->pr_pgrp;
#endif
(void) memcpy(psinfo->pr_fname, p64->pr_fname,
sizeof (psinfo->pr_fname));
@@ -510,8 +518,10 @@ note_linux_psinfo(struct ps_prochandle *P, size_t nbytes)
static void
lx_prstatus64_to_lwp(lx_prstatus64_t *prs64, lwp_info_t *lwp)
{
#if 0
LTIME_TO_TIMESPEC(lwp->lwp_status.pr_utime, prs64->pr_utime);
LTIME_TO_TIMESPEC(lwp->lwp_status.pr_stime, prs64->pr_stime);
#endif
lwp->lwp_status.pr_reg[REG_R15] = prs64->pr_reg.lxr_r15;
lwp->lwp_status.pr_reg[REG_R14] = prs64->pr_reg.lxr_r14;
@@ -539,52 +549,56 @@ lx_prstatus64_to_lwp(lx_prstatus64_t *prs64, lwp_info_t *lwp)
lwp->lwp_status.pr_reg[REG_ES] = prs64->pr_reg.lxr_es;
lwp->lwp_status.pr_reg[REG_DS] = prs64->pr_reg.lxr_ds;
#if 0
lwp->lwp_status.pr_reg[REG_GSBASE] = prs64->pr_reg.lxr_gs_base;
lwp->lwp_status.pr_reg[REG_FSBASE] = prs64->pr_reg.lxr_fs_base;
#endif
}
static void
lx_prstatus32_to_lwp(lx_prstatus32_t *prs32, lwp_info_t *lwp)
{
#if 0
LTIME_TO_TIMESPEC(lwp->lwp_status.pr_utime, prs32->pr_utime);
LTIME_TO_TIMESPEC(lwp->lwp_status.pr_stime, prs32->pr_stime);
#endif
#ifdef __amd64
lwp->lwp_status.pr_reg[REG_GS] = prs32->pr_reg.lxr_gs;
lwp->lwp_status.pr_reg[REG_FS] = prs32->pr_reg.lxr_fs;
lwp->lwp_status.pr_reg[REG_DS] = prs32->pr_reg.lxr_ds;
lwp->lwp_status.pr_reg[REG_ES] = prs32->pr_reg.lxr_es;
lwp->lwp_status.pr_reg[REG_RDI] = prs32->pr_reg.lxr_di;
lwp->lwp_status.pr_reg[REG_RSI] = prs32->pr_reg.lxr_si;
lwp->lwp_status.pr_reg[REG_RBP] = prs32->pr_reg.lxr_bp;
lwp->lwp_status.pr_reg[REG_RBX] = prs32->pr_reg.lxr_bx;
lwp->lwp_status.pr_reg[REG_RDX] = prs32->pr_reg.lxr_dx;
lwp->lwp_status.pr_reg[REG_RCX] = prs32->pr_reg.lxr_cx;
lwp->lwp_status.pr_reg[REG_RAX] = prs32->pr_reg.lxr_ax;
lwp->lwp_status.pr_reg[REG_RIP] = prs32->pr_reg.lxr_ip;
lwp->lwp_status.pr_reg[REG_CS] = prs32->pr_reg.lxr_cs;
lwp->lwp_status.pr_reg[REG_RFL] = prs32->pr_reg.lxr_flags;
lwp->lwp_status.pr_reg[REG_RSP] = prs32->pr_reg.lxr_sp;
lwp->lwp_status.pr_reg[REG_SS] = prs32->pr_reg.lxr_ss;
lwp->lwp_status.pr_reg[REG_GS] = prs32->pr_reg.fbsdr_gs;
lwp->lwp_status.pr_reg[REG_FS] = prs32->pr_reg.fbsdr_fs;
lwp->lwp_status.pr_reg[REG_DS] = prs32->pr_reg.fbsdr_ds;
lwp->lwp_status.pr_reg[REG_ES] = prs32->pr_reg.fbsdr_es;
lwp->lwp_status.pr_reg[REG_RDI] = prs32->pr_reg.fbsdr_edi;
lwp->lwp_status.pr_reg[REG_RSI] = prs32->pr_reg.fbsdr_esi;
lwp->lwp_status.pr_reg[REG_RBP] = prs32->pr_reg.fbsdr_ebp;
lwp->lwp_status.pr_reg[REG_RBX] = prs32->pr_reg.fbsdr_ebx;
lwp->lwp_status.pr_reg[REG_RDX] = prs32->pr_reg.fbsdr_edx;
lwp->lwp_status.pr_reg[REG_RCX] = prs32->pr_reg.fbsdr_ecx;
lwp->lwp_status.pr_reg[REG_RAX] = prs32->pr_reg.fbsdr_eax;
lwp->lwp_status.pr_reg[REG_RIP] = prs32->pr_reg.fbsdr_eip;
lwp->lwp_status.pr_reg[REG_CS] = prs32->pr_reg.fbsdr_cs;
lwp->lwp_status.pr_reg[REG_RFL] = prs32->pr_reg.fbsdr_eflags;
lwp->lwp_status.pr_reg[REG_RSP] = prs32->pr_reg.fbsdr_esp;
lwp->lwp_status.pr_reg[REG_SS] = prs32->pr_reg.fbsdr_ss;
#else /* __amd64 */
lwp->lwp_status.pr_reg[EBX] = prs32->pr_reg.lxr_bx;
lwp->lwp_status.pr_reg[ECX] = prs32->pr_reg.lxr_cx;
lwp->lwp_status.pr_reg[EDX] = prs32->pr_reg.lxr_dx;
lwp->lwp_status.pr_reg[ESI] = prs32->pr_reg.lxr_si;
lwp->lwp_status.pr_reg[EDI] = prs32->pr_reg.lxr_di;
lwp->lwp_status.pr_reg[EBP] = prs32->pr_reg.lxr_bp;
lwp->lwp_status.pr_reg[EAX] = prs32->pr_reg.lxr_ax;
lwp->lwp_status.pr_reg[EIP] = prs32->pr_reg.lxr_ip;
lwp->lwp_status.pr_reg[UESP] = prs32->pr_reg.lxr_sp;
lwp->lwp_status.pr_reg[DS] = prs32->pr_reg.lxr_ds;
lwp->lwp_status.pr_reg[ES] = prs32->pr_reg.lxr_es;
lwp->lwp_status.pr_reg[FS] = prs32->pr_reg.lxr_fs;
lwp->lwp_status.pr_reg[GS] = prs32->pr_reg.lxr_gs;
lwp->lwp_status.pr_reg[CS] = prs32->pr_reg.lxr_cs;
lwp->lwp_status.pr_reg[SS] = prs32->pr_reg.lxr_ss;
lwp->lwp_status.pr_reg[EFL] = prs32->pr_reg.lxr_flags;
lwp->lwp_status.pr_reg[EBX] = prs32->pr_reg.fbsdr_ebx;
lwp->lwp_status.pr_reg[ECX] = prs32->pr_reg.fbsdr_ecx;
lwp->lwp_status.pr_reg[EDX] = prs32->pr_reg.fbsdr_edx;
lwp->lwp_status.pr_reg[ESI] = prs32->pr_reg.fbsdr_esi;
lwp->lwp_status.pr_reg[EDI] = prs32->pr_reg.fbsdr_edi;
lwp->lwp_status.pr_reg[EBP] = prs32->pr_reg.fbsdr_ebp;
lwp->lwp_status.pr_reg[EAX] = prs32->pr_reg.fbsdr_eax;
lwp->lwp_status.pr_reg[EIP] = prs32->pr_reg.fbsdr_eip;
lwp->lwp_status.pr_reg[UESP] = prs32->pr_reg.fbsdr_esp;
lwp->lwp_status.pr_reg[DS] = prs32->pr_reg.fbsdr_ds;
lwp->lwp_status.pr_reg[ES] = prs32->pr_reg.fbsdr_es;
lwp->lwp_status.pr_reg[FS] = prs32->pr_reg.fbsdr_fs;
lwp->lwp_status.pr_reg[GS] = prs32->pr_reg.fbsdr_gs;
lwp->lwp_status.pr_reg[CS] = prs32->pr_reg.fbsdr_cs;
lwp->lwp_status.pr_reg[SS] = prs32->pr_reg.fbsdr_ss;
lwp->lwp_status.pr_reg[EFL] = prs32->pr_reg.fbsdr_eflags;
#endif /* !__amd64 */
}
@@ -604,12 +618,14 @@ note_linux_prstatus(struct ps_prochandle *P, size_t nbytes)
if (nbytes < sizeof (prs32) ||
read(P->asfd, &prs32, sizeof (prs32)) != nbytes)
goto err;
tid = prs32.pr_pid;
/*tid = prs32.pr_pid;*/
tid = 2;
} else {
if (nbytes < sizeof (prs64) ||
read(P->asfd, &prs64, sizeof (prs64)) != nbytes)
goto err;
tid = prs64.pr_pid;
/*tid = prs64.pr_pid;*/
tid = 2;
}
if ((lwp = lwpid2info(P, tid)) == NULL) {
@@ -639,9 +655,13 @@ note_linux_prstatus(struct ps_prochandle *P, size_t nbytes)
static int
note_psinfo(struct ps_prochandle *P, size_t nbytes)
{
#ifdef _LP64
core_info_t *core = P->data;
/* XXX figure out what this struct is - nbytes==0xd4 */
if (core->core_osabi == ELFOSABI_FREEBSD)
return (0);
#ifdef _LP64
if (core->core_dmodel == PR_MODEL_ILP32) {
psinfo32_t ps32;
@@ -2325,6 +2345,8 @@ Pfgrab_core(int core_fd, const char *aout_path, int *perr)
}
core_info->core_osabi = core.e_hdr.e_ident[EI_OSABI];
/* XXX if core_osabi is ELFOSABI_FREEBSD, then interpret as freebsd */
/*
* Because the core file may be a large file, we can't use libelf to
* read the Phdrs. We use e_phnum and e_phentsize to simplify things.
@@ -30,22 +30,18 @@ extern "C" {
/* Process Information */
typedef struct lx_prpsinfo32 {
uint8_t pr_state; /* Numeric process state */
int8_t pr_sname; /* Char for pr_state */
uint8_t pr_zomb; /* Zombie */
int8_t pr_nice; /* Nice value */
uint32_t pr_flag; /* Flags */
uint16_t pr_uid; /* User ID */
uint16_t pr_gid; /* Group ID */
int32_t pr_pid; /* Process ID */
int32_t pr_ppid; /* Parent's process ID */
int32_t pr_pgrp; /* Group ID */
int32_t pr_sid; /* Session ID */
char pr_fname[16]; /* Filename of executable */
char pr_psargs[80]; /* Initial part of arg list */
int pr_version;
u_int pr_psinfosz;
char pr_fname[17]; /* Filename of executable */
char pr_psargs[81]; /* Initial part of arg list */
} lx_prpsinfo32_t;
typedef struct lx_prpsinfo64 {
int pr_version;
u_int pr_psinfosz;
char pr_fname[17]; /* Filename of executable */
char pr_psargs[81]; /* Initial part of arg list */
#if 0
uint8_t pr_state; /* Numeric process state */
int8_t pr_sname; /* Char for pr_state */
uint8_t pr_zomb; /* Zombie */
@@ -59,9 +55,37 @@ typedef struct lx_prpsinfo64 {
int32_t pr_sid; /* Session ID */
char pr_fname[16]; /* Filename of executable */
char pr_psargs[80]; /* Initial part of arg list */
#endif
} lx_prpsinfo64_t;
typedef struct lx_amd64_regs {
int64_t lxr_r15;
int64_t lxr_r14;
int64_t lxr_r13;
int64_t lxr_r12;
int64_t lxr_r11;
int64_t lxr_r10;
int64_t lxr_r9;
int64_t lxr_r8;
int64_t lxr_rdi;
int64_t lxr_rsi;
int64_t lxr_rbp;
int64_t lxr_rbx;
int64_t lxr_rdx;
int64_t lxr_rcx;
int64_t lxr_rax;
uint32_t lxr_trapno;
uint16_t lxr_fs;
uint16_t lxr_gs;
uint32_t lxr_err;
uint16_t lxr_es;
uint16_t lxr_ds;
int64_t lxr_rip;
int64_t lxr_cs;
int64_t lxr_rflags;
int64_t lxr_rsp;
int64_t lxr_ss;
#if 0
uint64_t lxr_r15;
uint64_t lxr_r14;
uint64_t lxr_r13;
@@ -89,9 +113,30 @@ typedef struct lx_amd64_regs {
uint64_t lxr_es;
uint64_t lxr_fs;
uint64_t lxr_gs;
#endif
} lx_amd64_regs_t;
typedef struct lx_ia32_regs {
uint32_t fbsdr_fs;
uint32_t fbsdr_es;
uint32_t fbsdr_ds;
uint32_t fbsdr_edi;
uint32_t fbsdr_esi;
uint32_t fbsdr_ebp;
uint32_t fbsdr_isp;
uint32_t fbsdr_ebx;
uint32_t fbsdr_edx;
uint32_t fbsdr_ecx;
uint32_t fbsdr_eax;
uint32_t fbsdr_trapno;
uint32_t fbsdr_err;
uint32_t fbsdr_eip;
uint32_t fbsdr_cs;
uint32_t fbsdr_eflags;
uint32_t fbsdr_esp;
uint32_t fbsdr_ss;
uint32_t fbsdr_gs;
#if 0
uint32_t lxr_bx;
uint32_t lxr_cx;
uint32_t lxr_dx;
@@ -109,6 +154,7 @@ typedef struct lx_ia32_regs {
uint32_t lxr_flags;
uint32_t lxr_sp;
uint32_t lxr_ss;
#endif
} lx_ia32_regs_t;
typedef struct lx_elf_siginfo {
@@ -129,6 +175,16 @@ typedef struct lx_elf_timeval64 {
/* Thread Information */
typedef struct lx_prstatus32 {
int pr_version; /* Version number of struct (1) */
size_t pr_statussz; /* sizeof(prstatus_t) (1) */
size_t pr_gregsetsz; /* sizeof(gregset_t) (1) */
size_t pr_fpregsetsz; /* sizeof(fpregset_t) (1) */
int pr_osreldate; /* Kernel version (1) */
int pr_cursig; /* Current signal (1) */
pid_t pr_pid; /* Process ID (1) */
lx_ia32_regs_t pr_reg; /* General purpose registers (1) */
#if 0
lx_elf_siginfo_t pr_info; /* Singal Info */
uint16_t pr_cursig; /* Current signal */
uint32_t pr_sigpend; /* Set of pending signals */
@@ -143,9 +199,19 @@ typedef struct lx_prstatus32 {
lx_elf_timeval32_t pr_cstime; /* Cumulative system time */
lx_ia32_regs_t pr_reg; /* CPU registers */
uint32_t pr_fpvalid; /* True if we have fp state */
#endif
} lx_prstatus32_t;
typedef struct lx_prstatus64 {
int pr_version; /* Version number of struct (1) */
size_t pr_statussz; /* sizeof(prstatus_t) (1) */
size_t pr_gregsetsz; /* sizeof(gregset_t) (1) */
size_t pr_fpregsetsz; /* sizeof(fpregset_t) (1) */
int pr_osreldate; /* Kernel version (1) */
int pr_cursig; /* Current signal (1) */
pid_t pr_pid; /* Process ID (1) */
lx_amd64_regs_t pr_reg; /* General purpose registers (1) */
#if 0
lx_elf_siginfo_t pr_info; /* Singal Info */
uint16_t pr_cursig; /* Current signal */
uint64_t pr_sigpend; /* Set of pending signals */
@@ -160,6 +226,7 @@ typedef struct lx_prstatus64 {
lx_elf_timeval64_t pr_cstime; /* Cumulative system time */
lx_amd64_regs_t pr_reg; /* CPU registers */
uint32_t pr_fpvalid; /* True if we have fp state */
#endif
} lx_prstatus64_t;
#define LTIME_TO_TIMESPEC(dst, src) \

2 comments on commit 018e181

@ahrens

This comment has been minimized.

Show comment
Hide comment
@ahrens

ahrens Mar 15, 2015

Owner

@lovasko here's the code we worked on

Owner

ahrens replied Mar 15, 2015

@lovasko here's the code we worked on

@lovasko

This comment has been minimized.

Show comment
Hide comment
@lovasko

lovasko Mar 15, 2015

thanks 👍 I added it to the wiki page

lovasko replied Mar 15, 2015

thanks 👍 I added it to the wiki page

Please sign in to comment.