adding support for segment registers for vmware vmss dumps. Signed-off-by: Ajay Kaher <ajay.ka...@broadcom.com>
--- vmware_guestdump.c | 2 +- vmware_vmss.c | 114 +++++++++++++++++++++++++++++++++++---------- vmware_vmss.h | 92 +++++++++++++++++++++++++----------- 3 files changed, 154 insertions(+), 54 deletions(-) diff --git a/vmware_guestdump.c b/vmware_guestdump.c index 78f37fb..d515df5 100644 --- a/vmware_guestdump.c +++ b/vmware_guestdump.c @@ -320,7 +320,7 @@ vmware_guestdump_init(char *filename, FILE *ofp) goto exit; } - vmss.vcpu_regs = malloc(vmss.num_vcpus * sizeof(uint32_t)); + vmss.vcpu_regs = malloc(vmss.num_vcpus * sizeof(uint64_t)); vmss.regs64 = calloc(vmss.num_vcpus, sizeof(void *)); if (!vmss.vcpu_regs || !vmss.regs64) { error(INFO, LOGPRX"Failed to allocate memory\n"); diff --git a/vmware_vmss.c b/vmware_vmss.c index 8121ab6..1a71d02 100644 --- a/vmware_vmss.c +++ b/vmware_vmss.c @@ -317,7 +317,7 @@ vmware_vmss_init(char *filename, FILE *ofp) vmss.num_vcpus = u.val32; vmss.regs64 = malloc(vmss.num_vcpus * sizeof(void *)); - vmss.vcpu_regs = malloc(vmss.num_vcpus * sizeof(uint32_t)); + vmss.vcpu_regs = malloc(vmss.num_vcpus * sizeof(uint64_t)); for (k = 0; k < vmss.num_vcpus; k++) { vmss.regs64[k] = malloc(sizeof(vmssregs64)); @@ -432,15 +432,65 @@ vmware_vmss_init(char *filename, FILE *ofp) int cpu = idx[0]; vmss.regs64[cpu]->rflags |= u.val32; vmss.vcpu_regs[cpu] |= REGS_PRESENT_RFLAGS; + } else if (strcmp(name, "S.base64") == 0) { + int cpu = idx[0]; + int seg_index = idx[1]; + switch (seg_index) { + case SEG_FS: + vmss.regs64[cpu]->fs_base = u.val64; + vmss.vcpu_regs[cpu] |= REGS_PRESENT_FS_BASE; + break; + case SEG_GS: + vmss.regs64[cpu]->gs_base = u.val64; + vmss.vcpu_regs[cpu] |= REGS_PRESENT_GS_BASE; + break; + } + } else if (strcmp(name, "S") == 0) { + int cpu = idx[0]; + int seg_index = idx[1]; + switch (seg_index) { + case SEG_ES: + vmss.regs64[cpu]->es = u.val32; + vmss.vcpu_regs[cpu] |= REGS_PRESENT_ES; + break; + case SEG_CS: + vmss.regs64[cpu]->cs = u.val32; + vmss.vcpu_regs[cpu] |= REGS_PRESENT_CS; + break; + case SEG_SS: + vmss.regs64[cpu]->ss = u.val32; + vmss.vcpu_regs[cpu] |= REGS_PRESENT_SS; + break; + case SEG_DS: + vmss.regs64[cpu]->ds = u.val32; + vmss.vcpu_regs[cpu] |= REGS_PRESENT_DS; + break; + case SEG_FS: + vmss.regs64[cpu]->fs = u.val32; + vmss.vcpu_regs[cpu] |= REGS_PRESENT_FS; + break; + case SEG_GS: + vmss.regs64[cpu]->gs = u.val32; + vmss.vcpu_regs[cpu] |= REGS_PRESENT_GS; + break; + case SEG_LDTR: + vmss.regs64[cpu]->ldtr = u.val32; + vmss.vcpu_regs[cpu] |= REGS_PRESENT_LDTR; + break; + case SEG_TR: + vmss.regs64[cpu]->tr = u.val32; + vmss.vcpu_regs[cpu] |= REGS_PRESENT_TR; + break; + default: + error(INFO, "Unknown VMSS Segment [%d][%d]\n", cpu, seg_index); + } } } - DEBUG_PARSE_PRINT((ofp, "\n")); } } } - if (vmss.memsize == 0) { char *vmem_filename, *p; @@ -902,36 +952,50 @@ vmware_vmss_get_cpu_reg(int cpu, int regno, const char *name, int size, if (cpu >= vmss.num_vcpus) return FALSE; - /* All supported registers are 8 bytes long. */ - if (size != 8) - return FALSE; - -#define CASE(R,r) \ +#define CASE_32(R,r) \ case R##_REGNUM: \ + if (size != 4) \ + return FALSE; \ if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_##R)) \ return FALSE; \ memcpy(value, &vmss.regs64[cpu]->r, size); \ break +#define CASE_64(R,r) \ + case R##_REGNUM: \ + if (size != 8) \ + return FALSE; \ + if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_##R)) \ + return FALSE; \ + memcpy(value, &vmss.regs64[cpu]->r, size); \ + break switch (regno) { - CASE (RAX, rax); - CASE (RBX, rbx); - CASE (RCX, rcx); - CASE (RDX, rdx); - CASE (RSI, rsi); - CASE (RDI, rdi); - CASE (RBP, rbp); - CASE (RSP, rsp); - CASE (R8, r8); - CASE (R9, r9); - CASE (R10, r10); - CASE (R11, r11); - CASE (R12, r12); - CASE (R13, r13); - CASE (R14, r14); - CASE (R15, r15); - CASE (RIP, rip); + CASE_64 (RAX, rax); + CASE_64 (RBX, rbx); + CASE_64 (RCX, rcx); + CASE_64 (RDX, rdx); + CASE_64 (RSI, rsi); + CASE_64 (RDI, rdi); + CASE_64 (RBP, rbp); + CASE_64 (RSP, rsp); + CASE_64 (R8, r8); + CASE_64 (R9, r9); + CASE_64 (R10, r10); + CASE_64 (R11, r11); + CASE_64 (R12, r12); + CASE_64 (R13, r13); + CASE_64 (R14, r14); + CASE_64 (R15, r15); + CASE_64 (RIP, rip); + CASE_32 (ES, es); + CASE_32 (CS, cs); + CASE_32 (SS, ss); + CASE_32 (DS, ds); + CASE_32 (FS, fs); + CASE_32 (GS, gs); + CASE_64 (FS_BASE, fs_base); + CASE_64 (GS_BASE, gs_base); case EFLAGS_REGNUM: if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_RFLAGS)) return FALSE; diff --git a/vmware_vmss.h b/vmware_vmss.h index 01d9446..5bc0370 100644 --- a/vmware_vmss.h +++ b/vmware_vmss.h @@ -110,41 +110,77 @@ struct vmssregs64 { uint64_t r13; uint64_t r14; uint64_t r15; + uint64_t es; + uint64_t cs; + uint64_t ss; + uint64_t ds; + uint64_t fs; + uint64_t gs; + uint64_t ldtr; + uint64_t tr; + /* manually managed */ uint64_t idtr; uint64_t cr[VMW_CR64_SIZE / 8]; uint64_t rip; uint64_t rflags; + uint64_t fs_base; + uint64_t gs_base; }; typedef struct vmssregs64 vmssregs64; -#define REGS_PRESENT_RAX 1<<0 -#define REGS_PRESENT_RCX 1<<1 -#define REGS_PRESENT_RDX 1<<2 -#define REGS_PRESENT_RBX 1<<3 -#define REGS_PRESENT_RBP 1<<4 -#define REGS_PRESENT_RSP 1<<5 -#define REGS_PRESENT_RSI 1<<6 -#define REGS_PRESENT_RDI 1<<7 -#define REGS_PRESENT_R8 1<<8 -#define REGS_PRESENT_R9 1<<9 -#define REGS_PRESENT_R10 1<<10 -#define REGS_PRESENT_R11 1<<11 -#define REGS_PRESENT_R12 1<<12 -#define REGS_PRESENT_R13 1<<13 -#define REGS_PRESENT_R14 1<<14 -#define REGS_PRESENT_R15 1<<15 -#define REGS_PRESENT_IDTR 1<<16 -#define REGS_PRESENT_CR0 1<<17 -#define REGS_PRESENT_CR1 1<<18 -#define REGS_PRESENT_CR2 1<<19 -#define REGS_PRESENT_CR3 1<<20 -#define REGS_PRESENT_CR4 1<<21 -#define REGS_PRESENT_RIP 1<<22 -#define REGS_PRESENT_RFLAGS 1<<23 -#define REGS_PRESENT_GPREGS 65535 -#define REGS_PRESENT_CRS 4063232 -#define REGS_PRESENT_ALL 16777215 +typedef enum SegmentName { + SEG_ES, + SEG_CS, + SEG_SS, + SEG_DS, + SEG_FS, + SEG_GS, + SEG_LDTR, + SEG_TR, + NUM_SEGS +} SegmentName; + +#define REGS_PRESENT_RAX 1L<<0 +#define REGS_PRESENT_RCX 1L<<1 +#define REGS_PRESENT_RDX 1L<<2 +#define REGS_PRESENT_RBX 1L<<3 +#define REGS_PRESENT_RBP 1L<<4 +#define REGS_PRESENT_RSP 1L<<5 +#define REGS_PRESENT_RSI 1L<<6 +#define REGS_PRESENT_RDI 1L<<7 +#define REGS_PRESENT_R8 1L<<8 +#define REGS_PRESENT_R9 1L<<9 +#define REGS_PRESENT_R10 1L<<10 +#define REGS_PRESENT_R11 1L<<11 +#define REGS_PRESENT_R12 1L<<12 +#define REGS_PRESENT_R13 1L<<13 +#define REGS_PRESENT_R14 1L<<14 +#define REGS_PRESENT_R15 1L<<15 +#define REGS_PRESENT_IDTR 1L<<16 +#define REGS_PRESENT_CR0 1L<<17 +#define REGS_PRESENT_CR1 1L<<18 +#define REGS_PRESENT_CR2 1L<<19 +#define REGS_PRESENT_CR3 1L<<20 +#define REGS_PRESENT_CR4 1L<<21 +#define REGS_PRESENT_RIP 1L<<22 +#define REGS_PRESENT_RFLAGS 1L<<23 + +#define REGS_PRESENT_ES 1L<<24 +#define REGS_PRESENT_CS 1L<<25 +#define REGS_PRESENT_SS 1L<<26 +#define REGS_PRESENT_DS 1L<<27 +#define REGS_PRESENT_FS 1L<<28 +#define REGS_PRESENT_GS 1L<<29 +#define REGS_PRESENT_LDTR 1L<<30 +#define REGS_PRESENT_TR 1L<<31 +#define REGS_PRESENT_FS_BASE 1L<<32 +#define REGS_PRESENT_GS_BASE 1L<<33 + +#define REGS_PRESENT_GPREGS 0x000000000000FFFF +#define REGS_PRESENT_CRS 0x00000000003E0000 +#define REGS_PRESENT_SEG 0x00000003FF000000 +#define REGS_PRESENT_ALL 0x00000003FFFFFFFF #define MAX_REGIONS 3 struct vmssdata { @@ -159,7 +195,7 @@ struct vmssdata { uint64_t memsize; ulong phys_base; int separate_vmem; - uint32_t *vcpu_regs; + uint64_t *vcpu_regs; uint64_t num_vcpus; vmssregs64 **regs64; }; -- 2.40.4 -- Crash-utility mailing list -- devel@lists.crash-utility.osci.io To unsubscribe send an email to devel-le...@lists.crash-utility.osci.io https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ Contribution Guidelines: https://github.com/crash-utility/crash/wiki