Blame vmware_vmss.c

Packit bf408e
/*
Packit bf408e
 * vmware_vmss.c
Packit bf408e
 *
Packit bf408e
 * Copyright (c) 2015 VMware, Inc.
Packit bf408e
 * Copyright (c) 2018 Red Hat Inc.
Packit bf408e
 *
Packit bf408e
 * This program is free software; you can redistribute it and/or modify
Packit bf408e
 * it under the terms of the GNU General Public License as published by
Packit bf408e
 * the Free Software Foundation; either version 2 of the License, or
Packit bf408e
 * (at your option) any later version.
Packit bf408e
 *
Packit bf408e
 * This program is distributed in the hope that it will be useful,
Packit bf408e
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit bf408e
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit bf408e
 * GNU General Public License for more details.
Packit bf408e
 *
Packit bf408e
 * Authors: Dyno Hongjun Fu <hfu@vmware.com>
Packit bf408e
 *          Sergio Lopez <slp@redhat.com>
Packit bf408e
 */
Packit bf408e
Packit bf408e
#include "defs.h"
Packit bf408e
#include "vmware_vmss.h"
Packit bf408e
Packit bf408e
#define LOGPRX "vmw: "
Packit bf408e
Packit Service 2d41f0
vmssdata vmss = { 0 };
Packit bf408e
Packit bf408e
int
Packit bf408e
is_vmware_vmss(char *filename)
Packit bf408e
{
Packit bf408e
	struct cptdumpheader hdr;
Packit bf408e
	FILE *fp;
Packit bf408e
Packit bf408e
        if ((fp = fopen(filename, "r")) == NULL) {
Packit bf408e
		error(INFO, LOGPRX"Failed to open '%s': [Error %d] %s\n",
Packit bf408e
		      filename, errno, strerror(errno));
Packit bf408e
		return FALSE;
Packit bf408e
        }
Packit bf408e
Packit bf408e
	if (fread(&hdr, sizeof(cptdumpheader), 1, fp) != 1) {
Packit bf408e
		error(INFO, LOGPRX"Failed to read '%s': [Error %d] %s\n",
Packit bf408e
		      filename, errno, strerror(errno));
Packit bf408e
		fclose(fp);
Packit bf408e
		return FALSE;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	fclose(fp);
Packit bf408e
Packit bf408e
	if (hdr.id != CPTDUMP_OLD_MAGIC_NUMBER &&
Packit bf408e
	    hdr.id != CPTDUMP_MAGIC_NUMBER &&
Packit bf408e
	    hdr.id != CPTDUMP_PARTIAL_MAGIC_NUMBER &&
Packit bf408e
	    hdr.id != CPTDUMP_RESTORED_MAGIC_NUMBER &&
Packit bf408e
	    hdr.id != CPTDUMP_NORESTORE_MAGIC_NUMBER) {
Packit bf408e
		if (CRASHDEBUG(1))
Packit bf408e
			error(INFO, LOGPRX"Unrecognized .vmss file (magic %x).\n", hdr.id);
Packit bf408e
		return FALSE;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	return TRUE;
Packit bf408e
}
Packit bf408e
Packit bf408e
int
Packit bf408e
vmware_vmss_init(char *filename, FILE *ofp)
Packit bf408e
{
Packit bf408e
	cptdumpheader hdr;
Packit bf408e
	cptgroupdesc *grps = NULL;
Packit bf408e
	unsigned grpsize;
Packit bf408e
	unsigned i;
Packit bf408e
	FILE *fp = NULL;
Packit bf408e
	int result = TRUE;
Packit bf408e
Packit bf408e
	if (!machine_type("X86") && !machine_type("X86_64")) {
Packit bf408e
		error(INFO,
Packit bf408e
		      LOGPRX"Invalid or unsupported host architecture for .vmss file: %s\n",
Packit bf408e
		      MACHINE_TYPE);
Packit bf408e
		result = FALSE;
Packit bf408e
		goto exit;
Packit bf408e
	}
Packit bf408e
Packit bf408e
        if ((fp = fopen(filename, "r")) == NULL) {
Packit bf408e
		error(INFO, LOGPRX"Failed to open '%s': %s [Error %d] %s\n",
Packit bf408e
		      filename, errno, strerror(errno));
Packit bf408e
		result = FALSE;
Packit bf408e
		goto exit;
Packit bf408e
        }
Packit bf408e
Packit bf408e
	if (fread(&hdr, sizeof(cptdumpheader), 1, fp) != 1) {
Packit bf408e
		error(INFO, LOGPRX"Failed to read '%s': %s [Error %d] %s\n",
Packit bf408e
                      filename, errno, strerror(errno));
Packit bf408e
		result = FALSE;
Packit bf408e
		goto exit;
Packit bf408e
	}
Packit bf408e
	DEBUG_PARSE_PRINT((ofp, LOGPRX"Header: id=%x version=%d numgroups=%d\n",
Packit bf408e
			   hdr.id, hdr.version, hdr.numgroups));
Packit bf408e
Packit bf408e
	vmss.cpt64bit = (hdr.id != CPTDUMP_OLD_MAGIC_NUMBER);
Packit bf408e
	DEBUG_PARSE_PRINT((ofp, LOGPRX"Checkpoint is %d-bit\n", vmss.cpt64bit ? 64 : 32));
Packit bf408e
	if (!vmss.cpt64bit) {
Packit bf408e
		error(INFO, LOGPRX"Not implemented for 32-bit VMSS file!\n");
Packit bf408e
		result = FALSE;
Packit bf408e
		goto exit;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	grpsize = hdr.numgroups * sizeof (cptgroupdesc);
Packit bf408e
	grps = (cptgroupdesc *) malloc(grpsize * sizeof(cptgroupdesc));
Packit bf408e
	if (grps == NULL) {
Packit bf408e
		error(INFO, LOGPRX"Failed to allocate memory! [Error %d] %s\n",
Packit bf408e
                      errno, strerror(errno));
Packit bf408e
		result = FALSE;
Packit bf408e
		goto exit;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	if (fread(grps, sizeof(cptgroupdesc), grpsize, fp) != grpsize) {
Packit bf408e
		error(INFO, LOGPRX"Failed to read '%s': [Error %d] %s\n",
Packit bf408e
		      filename, errno, strerror(errno));
Packit bf408e
		result = FALSE;
Packit bf408e
		goto exit;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	for (i = 0; i < hdr.numgroups; i++) {
Packit bf408e
		if (fseek(fp, grps[i].position, SEEK_SET) == -1) {
Packit bf408e
			error(INFO, LOGPRX"Bad offset of VMSS Group['%s'] in '%s' at %#llx.\n",
Packit bf408e
			      grps[i].name, filename, (ulonglong)grps[i].position);
Packit bf408e
			continue;
Packit bf408e
		}
Packit bf408e
		DEBUG_PARSE_PRINT((ofp, LOGPRX"Group: %-20s offset=%#llx size=0x%#llx.\n",
Packit bf408e
				  grps[i].name, (ulonglong)grps[i].position, (ulonglong)grps[i].size));
Packit bf408e
Packit bf408e
		if (strcmp(grps[i].name, "memory") != 0 &&
Packit bf408e
		    (strcmp(grps[i].name, "cpu") != 0 || !machine_type("X86_64"))) {
Packit bf408e
			continue;
Packit bf408e
		}
Packit bf408e
Packit bf408e
		for (;;) {
Packit bf408e
			uint16_t tag;
Packit bf408e
			char name[TAG_NAMELEN_MASK + 1];
Packit bf408e
			unsigned nameLen;
Packit bf408e
			unsigned nindx;
Packit bf408e
			int idx[3];
Packit bf408e
			unsigned j;
Packit bf408e
			int nextgroup = FALSE;
Packit bf408e
Packit bf408e
			if (fread(&tag, sizeof(tag), 1, fp) != 1) {
Packit bf408e
				error(INFO, LOGPRX"Cannot read tag.\n");
Packit bf408e
				break;
Packit bf408e
			}
Packit bf408e
			if (tag == NULL_TAG)
Packit bf408e
				break;
Packit bf408e
Packit bf408e
			nameLen = TAG_NAMELEN(tag);
Packit bf408e
			if (fread(name, nameLen, 1, fp) != 1) {
Packit bf408e
				error(INFO, LOGPRX"Cannot read tag name.\n");
Packit bf408e
				break;
Packit bf408e
			}
Packit bf408e
			name[nameLen] = 0;
Packit bf408e
			DEBUG_PARSE_PRINT((ofp, LOGPRX"\t Item %20s", name));
Packit bf408e
Packit bf408e
			nindx = TAG_NINDX(tag);
Packit bf408e
			if (nindx > 3) {
Packit bf408e
				error(INFO, LOGPRX"Too many indexes %d (> 3).\n", nindx);
Packit bf408e
				break;
Packit bf408e
			}
Packit bf408e
			idx[0] = idx[1] = idx[2] = NO_INDEX;
Packit bf408e
			for (j= 0; j < nindx; j++) {
Packit bf408e
				if (fread(&idx[j], sizeof(idx[0]), 1, fp) != 1) {
Packit bf408e
					error(INFO, LOGPRX"Cannot read index.\n");
Packit bf408e
					nextgroup = TRUE;
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				DEBUG_PARSE_PRINT((ofp, "[%d]", idx[j]));
Packit bf408e
			}
Packit Service 2d41f0
			if (nextgroup) {
Packit Service 2d41f0
				DEBUG_PARSE_PRINT((ofp, "\n"));
Packit bf408e
				break;
Packit Service 2d41f0
			}
Packit bf408e
Packit bf408e
			if (IS_BLOCK_TAG(tag)) {
Packit bf408e
				uint64_t nbytes;
Packit bf408e
				uint64_t blockpos;
Packit bf408e
				uint64_t nbytesinmem;
Packit bf408e
				int compressed = IS_BLOCK_COMPRESSED_TAG(tag);
Packit bf408e
				uint16_t padsize;
Packit bf408e
Packit bf408e
				if (fread(&nbytes, sizeof(nbytes), 1, fp) != 1) {
Packit bf408e
					error(INFO, LOGPRX"Cannot read block size.\n");
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				if (fread(&nbytesinmem, sizeof(nbytesinmem), 1, fp) != 1) {
Packit bf408e
					error(INFO, LOGPRX"Cannot read block memory size.\n");
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				if (fread(&padsize, sizeof(padsize), 1, fp) != 1) {
Packit bf408e
					error(INFO, LOGPRX"Cannot read block padding size.\n");
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				if ((blockpos = ftell(fp)) == -1) {
Packit bf408e
					error(INFO, LOGPRX"Cannot determine location within VMSS file.\n");
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				blockpos += padsize;
Packit bf408e
Packit bf408e
				if (strcmp(name, "Memory") == 0) {
Packit bf408e
					/* The things that we really care about...*/
Packit bf408e
					vmss.memoffset = blockpos;
Packit bf408e
					vmss.memsize = nbytesinmem;
Packit bf408e
					vmss.separate_vmem = FALSE;
Packit bf408e
					DEBUG_PARSE_PRINT((ofp, "\t=> %sBLOCK: position=%#llx size=%#llx memsize=%#llx\n",
Packit bf408e
							   compressed ? "COMPRESSED " : "",
Packit bf408e
							   (ulonglong)blockpos, (ulonglong)nbytes, (ulonglong)nbytesinmem));
Packit bf408e
Packit bf408e
					if (compressed) {
Packit bf408e
						error(INFO, LOGPRX"Cannot handle compressed memory dump yet!\n");
Packit bf408e
						result = FALSE;
Packit bf408e
						goto exit;
Packit bf408e
					}
Packit bf408e
Packit bf408e
					if (fseek(fp, blockpos + nbytes, SEEK_SET) == -1) {
Packit bf408e
						error(INFO, LOGPRX"Cannot seek past block at %#llx.\n",
Packit bf408e
						      (ulonglong)(blockpos + nbytes));
Packit bf408e
						break;
Packit bf408e
					}
Packit bf408e
				} else if (strcmp(name, "gpregs") == 0 &&
Packit bf408e
					   nbytes == VMW_GPREGS_SIZE &&
Packit bf408e
					   idx[0] < vmss.num_vcpus) {
Packit bf408e
					int cpu = idx[0];
Packit bf408e
					if (fread(vmss.regs64[cpu], VMW_GPREGS_SIZE, 1, fp) != 1) {
Packit bf408e
						error(INFO, LOGPRX"Failed to read '%s': [Error %d] %s\n",
Packit bf408e
						      filename, errno, strerror(errno));
Packit bf408e
						break;
Packit bf408e
					}
Packit Service 2d41f0
					DEBUG_PARSE_PRINT((ofp, "\n"));
Packit bf408e
					vmss.vcpu_regs[cpu] |= REGS_PRESENT_GPREGS;
Packit bf408e
				} else if (strcmp(name, "CR64") == 0 &&
Packit bf408e
					   nbytes == VMW_CR64_SIZE &&
Packit bf408e
					   idx[0] < vmss.num_vcpus) {
Packit bf408e
					int cpu = idx[0];
Packit Service 2d41f0
					DEBUG_PARSE_PRINT((ofp, "\t=> "));
Packit bf408e
					if (fread(&vmss.regs64[cpu]->cr[0], VMW_CR64_SIZE, 1, fp) != 1) {
Packit bf408e
						error(INFO, LOGPRX"Failed to read '%s': [Error %d] %s\n",
Packit bf408e
						      filename, errno, strerror(errno));
Packit bf408e
						break;
Packit bf408e
					}
Packit Service 2d41f0
					for (j = 0; j < VMW_CR64_SIZE / 8; j++)
Packit Service 2d41f0
						DEBUG_PARSE_PRINT((ofp, "%s%016llX", j ? " " : "",
Packit Service 2d41f0
								(ulonglong)vmss.regs64[cpu]->cr[j]));
Packit Service 2d41f0
					DEBUG_PARSE_PRINT((ofp, "\n"));
Packit bf408e
					vmss.vcpu_regs[cpu] |= REGS_PRESENT_CRS;
Packit bf408e
				} else if (strcmp(name, "IDTR") == 0 &&
Packit bf408e
					   nbytes == VMW_IDTR_SIZE &&
Packit bf408e
					   idx[0] < vmss.num_vcpus) {
Packit bf408e
					int cpu = idx[0];
Packit bf408e
					uint64_t idtr;
Packit bf408e
					if (fseek(fp, blockpos + 2, SEEK_SET) == -1) {
Packit bf408e
						error(INFO, LOGPRX"Cannot seek past block at %#llx.\n",
Packit bf408e
						      (ulonglong)(blockpos + 2));
Packit bf408e
						break;
Packit bf408e
					}
Packit bf408e
					if (fread(&idtr, sizeof(idtr), 1, fp) != 1) {
Packit bf408e
						error(INFO, LOGPRX"Failed to read '%s': [Error %d] %s\n",
Packit bf408e
						      filename, errno, strerror(errno));
Packit bf408e
						break;
Packit bf408e
					}
Packit Service 2d41f0
					DEBUG_PARSE_PRINT((ofp, "\n"));
Packit bf408e
					vmss.regs64[cpu]->idtr = idtr;
Packit bf408e
					vmss.vcpu_regs[cpu] |= REGS_PRESENT_IDTR;
Packit bf408e
				} else {
Packit bf408e
					if (fseek(fp, blockpos + nbytes, SEEK_SET) == -1) {
Packit bf408e
						error(INFO, LOGPRX"Cannot seek past block at %#llx.\n",
Packit bf408e
						      (ulonglong)(blockpos + nbytes));
Packit bf408e
						break;
Packit bf408e
					}
Packit Service 2d41f0
					DEBUG_PARSE_PRINT((ofp, "\n"));
Packit bf408e
				}
Packit bf408e
			} else {
Packit bf408e
				union {
Packit bf408e
					uint8_t val[TAG_VALSIZE_MASK];
Packit bf408e
					uint32_t val32;
Packit bf408e
					uint64_t val64;
Packit bf408e
				} u;
Packit bf408e
				unsigned k;
Packit bf408e
				unsigned valsize = TAG_VALSIZE(tag);
Packit bf408e
				uint64_t blockpos = ftell(fp);
Packit bf408e
Packit bf408e
				DEBUG_PARSE_PRINT((ofp, "\t=> position=%#llx size=%#x: ", (ulonglong)blockpos, valsize));
Packit bf408e
				if (fread(u.val, sizeof(u.val[0]), valsize, fp) != valsize) {
Packit bf408e
					error(INFO, LOGPRX"Cannot read item.\n");
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				for (k = 0; k < valsize; k++) {
Packit bf408e
					/* Assume Little Endian */
Packit bf408e
					DEBUG_PARSE_PRINT((ofp, "%02X", u.val[valsize - k - 1]));
Packit bf408e
				}
Packit bf408e
Packit bf408e
				if (strcmp(grps[i].name, "memory") == 0) {
Packit bf408e
					if (strcmp(name, "regionsCount") == 0) {
Packit bf408e
						vmss.regionscount = u.val32;
Packit bf408e
					}
Packit bf408e
				        if (strcmp(name, "regionPageNum") == 0) {
Packit bf408e
						vmss.regions[idx[0]].startpagenum = u.val32;
Packit bf408e
					}
Packit bf408e
					if (strcmp(name, "regionPPN") == 0) {
Packit bf408e
						vmss.regions[idx[0]].startppn = u.val32;
Packit bf408e
					}
Packit bf408e
					if (strcmp(name, "regionSize") == 0) {
Packit bf408e
						vmss.regions[idx[0]].size = u.val32;
Packit bf408e
					}
Packit bf408e
					if (strcmp(name, "align_mask") == 0) {
Packit bf408e
						vmss.alignmask = u.val32;
Packit bf408e
					}
Packit bf408e
				} else if (strcmp(grps[i].name, "cpu") == 0) {
Packit bf408e
					if (strcmp(name, "cpu:numVCPUs") == 0) {
Packit bf408e
						if (vmss.regs64 != NULL) {
Packit bf408e
							error(INFO, LOGPRX"Duplicated cpu:numVCPUs entry.\n");
Packit bf408e
							break;
Packit bf408e
						}
Packit bf408e
Packit bf408e
						vmss.num_vcpus = u.val32;
Packit bf408e
						vmss.regs64 = malloc(vmss.num_vcpus * sizeof(void *));
Packit bf408e
						vmss.vcpu_regs = malloc(vmss.num_vcpus * sizeof(uint32_t));
Packit bf408e
Packit bf408e
						for (k = 0; k < vmss.num_vcpus; k++) {
Packit bf408e
							vmss.regs64[k] = malloc(sizeof(vmssregs64));
Packit bf408e
							memset(vmss.regs64[k], 0, sizeof(vmssregs64));
Packit bf408e
							vmss.vcpu_regs[k] = 0;
Packit bf408e
						}
Packit bf408e
					} else if (strcmp(name, "rax") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rax = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RAX;
Packit bf408e
					} else if (strcmp(name, "rcx") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rcx = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RCX;
Packit bf408e
					} else if (strcmp(name, "rdx") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rdx = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RDX;
Packit bf408e
					} else if (strcmp(name, "rbx") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rbx = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RBX;
Packit bf408e
					} else if (strcmp(name, "rbp") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rbp = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RBP;
Packit bf408e
					} else if (strcmp(name, "rsp") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rsp = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RSP;
Packit bf408e
					} else if (strcmp(name, "rsi") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rsi = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RSI;
Packit bf408e
					} else if (strcmp(name, "rdi") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rdi = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RDI;
Packit bf408e
					} else if (strcmp(name, "r8") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->r8 = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_R8;
Packit bf408e
					} else if (strcmp(name, "r9") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->r9 = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_R9;
Packit bf408e
					} else if (strcmp(name, "r10") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->r10 = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_R10;
Packit bf408e
					} else if (strcmp(name, "r11") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->r11 = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_R11;
Packit bf408e
					} else if (strcmp(name, "r12") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->r12 = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_R12;
Packit bf408e
					} else if (strcmp(name, "r13") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->r13 = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_R13;
Packit bf408e
					} else if (strcmp(name, "r14") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->r14 = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_R14;
Packit bf408e
					} else if (strcmp(name, "r15") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->r15 = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_R15;
Packit bf408e
					} else if (strcmp(name, "CR64") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						switch (idx[1]) {
Packit bf408e
							case 0:
Packit bf408e
								vmss.regs64[cpu]->cr[0] = u.val64;
Packit bf408e
								vmss.vcpu_regs[cpu] |= REGS_PRESENT_CR0;
Packit bf408e
								break;
Packit bf408e
							case 1:
Packit bf408e
								vmss.regs64[cpu]->cr[1] = u.val64;
Packit bf408e
								vmss.vcpu_regs[cpu] |= REGS_PRESENT_CR1;
Packit bf408e
								break;
Packit bf408e
							case 2:
Packit bf408e
								vmss.regs64[cpu]->cr[2] = u.val64;
Packit bf408e
								vmss.vcpu_regs[cpu] |= REGS_PRESENT_CR2;
Packit bf408e
								break;
Packit bf408e
							case 3:
Packit bf408e
								vmss.regs64[cpu]->cr[3] = u.val64;
Packit bf408e
								vmss.vcpu_regs[cpu] |= REGS_PRESENT_CR3;
Packit bf408e
								break;
Packit bf408e
							case 4:
Packit bf408e
								vmss.regs64[cpu]->cr[4] = u.val64;
Packit bf408e
								vmss.vcpu_regs[cpu] |= REGS_PRESENT_CR4;
Packit bf408e
								break;
Packit bf408e
						}
Packit bf408e
					} else if (strcmp(name, "IDTR") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						if (idx[1] == 1)
Packit bf408e
							vmss.regs64[cpu]->idtr = u.val32;
Packit bf408e
						else if (idx[1] == 2) {
Packit bf408e
							vmss.regs64[cpu]->idtr |= (uint64_t) u.val32 << 32;
Packit bf408e
							vmss.vcpu_regs[cpu] |= REGS_PRESENT_IDTR;
Packit bf408e
						}
Packit bf408e
					} else if (strcmp(name, "rip") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rip = u.val64;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RIP;
Packit bf408e
					} else if (strcmp(name, "eflags") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rflags |= u.val32;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RFLAGS;
Packit bf408e
					} else if (strcmp(name, "EFLAGS") == 0) {
Packit bf408e
						int cpu = idx[0];
Packit bf408e
						vmss.regs64[cpu]->rflags |= u.val32;
Packit bf408e
						vmss.vcpu_regs[cpu] |= REGS_PRESENT_RFLAGS;
Packit bf408e
					}
Packit bf408e
				}
Packit bf408e
Packit bf408e
				DEBUG_PARSE_PRINT((ofp, "\n"));
Packit bf408e
			}
Packit bf408e
		}
Packit bf408e
	}
Packit bf408e
Packit bf408e
Packit bf408e
	if (vmss.memsize == 0) {
Packit bf408e
		char *vmem_filename, *p;
Packit bf408e
Packit bf408e
		fprintf(ofp, LOGPRX"Memory dump is not part of this vmss file.\n");
Packit bf408e
		fclose(fp);
Packit bf408e
		fp = NULL;
Packit bf408e
Packit bf408e
		fprintf(ofp, LOGPRX"Try to locate the companion vmem file ...\n");
Packit bf408e
		/* check the companion vmem file */
Packit bf408e
		vmem_filename = strdup(filename);
Packit bf408e
		p = vmem_filename + strlen(vmem_filename) - 4;
Packit bf408e
		if (strcmp(p, "vmss") != 0 && strcmp(p, "vmsn") != 0) {
Packit bf408e
			free(vmem_filename);
Packit bf408e
			result = FALSE;
Packit bf408e
			goto exit;
Packit bf408e
		}
Packit bf408e
		strcpy(p, "vmem");
Packit bf408e
		if ((fp = fopen(vmem_filename, "r")) == NULL) {
Packit bf408e
			error(INFO, LOGPRX"%s: %s\n", vmem_filename, strerror(errno));
Packit bf408e
			free(vmem_filename);
Packit bf408e
			result = FALSE;
Packit bf408e
			goto exit;
Packit bf408e
		}
Packit bf408e
		fseek(fp, 0L, SEEK_END);
Packit bf408e
		vmss.memsize = ftell(fp);
Packit bf408e
		fseek(fp, 0L, SEEK_SET);
Packit bf408e
Packit bf408e
		vmss.separate_vmem = TRUE;
Packit bf408e
		vmss.filename = filename;
Packit bf408e
Packit bf408e
		fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename);
Packit bf408e
		free(vmem_filename);
Packit bf408e
	}
Packit bf408e
Packit bf408e
	vmss.dfp = fp;
Packit bf408e
Packit bf408e
exit:
Packit bf408e
	if (grps)
Packit bf408e
		free(grps);
Packit bf408e
Packit bf408e
	if (!result && fp)
Packit bf408e
		fclose(fp);
Packit bf408e
Packit bf408e
	return result;
Packit bf408e
}
Packit bf408e
Packit bf408e
uint vmware_vmss_page_size(void)
Packit bf408e
{
Packit bf408e
	return VMW_PAGE_SIZE;
Packit bf408e
}
Packit bf408e
Packit bf408e
int
Packit bf408e
read_vmware_vmss(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
Packit bf408e
{
Packit bf408e
	uint64_t pos = paddr;
Packit bf408e
Packit bf408e
	if (vmss.regionscount > 0) {
Packit bf408e
		/* Memory is divided into regions and there are holes between them. */
Packit bf408e
		uint32_t ppn = (uint32_t) (pos >> VMW_PAGE_SHIFT);
Packit bf408e
	        int i;
Packit bf408e
Packit bf408e
		for (i = 0; i < vmss.regionscount; i++) {
Packit Service 2d41f0
			uint32_t hole;
Packit Service 2d41f0
Packit bf408e
			if (ppn < vmss.regions[i].startppn)
Packit bf408e
				break;
Packit bf408e
Packit bf408e
			/* skip holes. */
Packit Service 2d41f0
			hole = vmss.regions[i].startppn - vmss.regions[i].startpagenum;
Packit Service 2d41f0
			pos -= (uint64_t)hole << VMW_PAGE_SHIFT;
Packit bf408e
		}
Packit bf408e
	}
Packit bf408e
Packit bf408e
	if (pos + cnt > vmss.memsize) {
Packit bf408e
		error(INFO, LOGPRX"Read beyond the end of file! paddr=%#lx cnt=%d\n",
Packit bf408e
		      paddr, cnt);
Packit bf408e
	}
Packit bf408e
Packit bf408e
	pos += vmss.memoffset;
Packit bf408e
        if (fseek(vmss.dfp, pos, SEEK_SET) != 0)
Packit bf408e
		return SEEK_ERROR;
Packit bf408e
Packit bf408e
	if (fread(bufptr, 1, cnt, vmss.dfp) != cnt)
Packit bf408e
		return READ_ERROR;
Packit bf408e
Packit bf408e
	return cnt;
Packit bf408e
}
Packit bf408e
Packit bf408e
int
Packit bf408e
write_vmware_vmss(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
Packit bf408e
{
Packit bf408e
	return SEEK_ERROR;
Packit bf408e
}
Packit bf408e
Packit bf408e
void
Packit bf408e
vmware_vmss_display_regs(int cpu, FILE *ofp)
Packit bf408e
{
Packit bf408e
	if (cpu >= vmss.num_vcpus)
Packit bf408e
		return;
Packit bf408e
Packit bf408e
	if (machine_type("X86_64")) {
Packit bf408e
		fprintf(ofp,
Packit bf408e
		    "	 RIP: %016llx  RSP: %016llx  RFLAGS: %08llx\n"
Packit bf408e
		    "	 RAX: %016llx  RBX: %016llx  RCX: %016llx\n"
Packit bf408e
		    "	 RDX: %016llx  RSI: %016llx  RDI: %016llx\n"
Packit bf408e
		    "	 RBP: %016llx   R8: %016llx   R9: %016llx\n"
Packit bf408e
		    "	 R10: %016llx  R11: %016llx  R12: %016llx\n"
Packit bf408e
		    "	 R13: %016llx  R14: %016llx  R15: %016llx\n",
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->rip,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->rsp,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->rflags,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->rax,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->rbx,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->rcx,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->rdx,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->rsi,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->rdi,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->rbp,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->r8,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->r9,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->r10,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->r11,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->r12,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->r13,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->r14,
Packit bf408e
		    (ulonglong)vmss.regs64[cpu]->r15
Packit bf408e
		);
Packit bf408e
	}
Packit bf408e
}
Packit bf408e
Packit bf408e
void
Packit bf408e
get_vmware_vmss_regs(struct bt_info *bt, ulong *ipp, ulong *spp)
Packit bf408e
{
Packit bf408e
	ulong ip, sp;
Packit bf408e
Packit bf408e
	ip = sp = 0;
Packit bf408e
Packit bf408e
	if (bt->tc->processor >= vmss.num_vcpus ||
Packit bf408e
	    vmss.regs64 == NULL ||
Packit bf408e
	    vmss.vcpu_regs[bt->tc->processor] != REGS_PRESENT_ALL) {
Packit bf408e
		machdep->get_stack_frame(bt, ipp, spp);
Packit bf408e
		return;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	if (!is_task_active(bt->task)) {
Packit bf408e
		machdep->get_stack_frame(bt, ipp, spp);
Packit bf408e
		return;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	bt->flags |= BT_DUMPFILE_SEARCH;
Packit bf408e
	if (machine_type("X86_64"))
Packit bf408e
		machdep->get_stack_frame(bt, ipp, spp);
Packit bf408e
	else if (machine_type("X86"))
Packit bf408e
		get_netdump_regs_x86(bt, ipp, spp);
Packit bf408e
	if (bt->flags & BT_DUMPFILE_SEARCH)
Packit bf408e
		return;
Packit bf408e
Packit bf408e
	ip = (ulong)vmss.regs64[bt->tc->processor]->rip;
Packit bf408e
	sp = (ulong)vmss.regs64[bt->tc->processor]->rsp;
Packit bf408e
	if (is_kernel_text(ip) &&
Packit bf408e
	    (((sp >= GET_STACKBASE(bt->task)) &&
Packit bf408e
	      (sp < GET_STACKTOP(bt->task))) ||
Packit bf408e
	     in_alternate_stack(bt->tc->processor, sp))) {
Packit bf408e
		*ipp = ip;
Packit bf408e
		*spp = sp;
Packit bf408e
		bt->flags |= BT_KERNEL_SPACE;
Packit bf408e
		return;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	if (!is_kernel_text(ip) &&
Packit bf408e
	    in_user_stack(bt->tc->task, sp))
Packit bf408e
		bt->flags |= BT_USER_SPACE;
Packit bf408e
}
Packit bf408e
Packit bf408e
int
Packit bf408e
vmware_vmss_memory_dump(FILE *ofp)
Packit bf408e
{
Packit bf408e
	cptdumpheader hdr;
Packit bf408e
	cptgroupdesc *grps = NULL;
Packit bf408e
	unsigned grpsize;
Packit bf408e
	unsigned i;
Packit bf408e
	int result = TRUE;
Packit bf408e
	FILE *fp = vmss.dfp;
Packit bf408e
Packit bf408e
	if (vmss.separate_vmem) {
Packit bf408e
	        if ((fp = fopen(vmss.filename, "r")) == NULL) {
Packit bf408e
			error(INFO, LOGPRX"Failed to open '%s': %s [Error %d] %s\n",
Packit bf408e
			      vmss.filename, errno, strerror(errno));
Packit bf408e
			return FALSE;
Packit bf408e
		}
Packit bf408e
	}
Packit bf408e
Packit bf408e
	if (fseek(fp, 0, SEEK_SET) != 0) {
Packit bf408e
		fprintf(ofp, "Error seeking to position 0.\n");
Packit bf408e
		fclose(fp);
Packit bf408e
		return FALSE;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	if (fread(&hdr, sizeof(cptdumpheader), 1, fp) != 1) {
Packit bf408e
		fprintf(ofp, "Failed to read vmss file: [Error %d] %s\n",
Packit bf408e
			errno, strerror(errno));
Packit bf408e
		fclose(fp);
Packit bf408e
		return FALSE;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	fprintf(ofp, "vmware_vmss:\n");
Packit bf408e
	fprintf(ofp, "    Header: id=%x version=%d numgroups=%d\n",
Packit bf408e
		hdr.id, hdr.version, hdr.numgroups);
Packit bf408e
Packit bf408e
	vmss.cpt64bit = (hdr.id != CPTDUMP_OLD_MAGIC_NUMBER);
Packit bf408e
	fprintf(ofp, "    Checkpoint is %d-bit\n", vmss.cpt64bit ? 64 : 32);
Packit bf408e
Packit bf408e
	grpsize = hdr.numgroups * sizeof (cptgroupdesc);
Packit bf408e
	grps = (cptgroupdesc *) malloc(grpsize * sizeof(cptgroupdesc));
Packit bf408e
	if (grps == NULL) {
Packit bf408e
		fprintf(ofp, "Failed to allocate memory! [Error %d] %s\n",
Packit bf408e
			errno, strerror(errno));
Packit bf408e
		fclose(fp);
Packit bf408e
		return FALSE;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	if (fread(grps, sizeof(cptgroupdesc), grpsize, fp) != grpsize) {
Packit bf408e
		fprintf(ofp, "Failed to read vmss file: [Error %d] %s\n",
Packit bf408e
			errno, strerror(errno));
Packit bf408e
		result = FALSE;
Packit bf408e
		goto exit;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	for (i = 0; i < hdr.numgroups; i++) {
Packit bf408e
		if (fseek(fp, grps[i].position, SEEK_SET) == -1) {
Packit bf408e
			fprintf(ofp, "Bad offset of VMSS Group['%s'] in vmss file at %#llx.\n",
Packit bf408e
				grps[i].name, (ulonglong)grps[i].position);
Packit bf408e
			continue;
Packit bf408e
		}
Packit bf408e
		fprintf(ofp, "\nGroup: %s offset=%#llx size=0x%#llx\n",
Packit bf408e
			grps[i].name, (ulonglong)grps[i].position, (ulonglong)grps[i].size);
Packit bf408e
Packit bf408e
		for (;;) {
Packit bf408e
			uint16_t tag;
Packit bf408e
			char name[TAG_NAMELEN_MASK + 1];
Packit bf408e
			unsigned nameLen;
Packit bf408e
			unsigned nindx;
Packit bf408e
			int idx[3];
Packit bf408e
			unsigned j;
Packit bf408e
			int nextgroup = FALSE;
Packit bf408e
Packit bf408e
			if (fread(&tag, sizeof(tag), 1, fp) != 1) {
Packit bf408e
				fprintf(ofp, "Cannot read tag.\n");
Packit bf408e
				break;
Packit bf408e
			}
Packit bf408e
			if (tag == NULL_TAG)
Packit bf408e
				break;
Packit bf408e
Packit bf408e
			nameLen = TAG_NAMELEN(tag);
Packit bf408e
			if (fread(name, nameLen, 1, fp) != 1) {
Packit bf408e
				fprintf(ofp, "Cannot read tag name.\n");
Packit bf408e
				break;
Packit bf408e
			}
Packit bf408e
			name[nameLen] = 0;
Packit bf408e
			fprintf(ofp, "    Item %20s", name);
Packit bf408e
Packit bf408e
			nindx = TAG_NINDX(tag);
Packit bf408e
			if (nindx > 3) {
Packit bf408e
				fprintf(ofp, "Too many indexes %d (> 3).\n", nindx);
Packit bf408e
				break;
Packit bf408e
			}
Packit bf408e
			idx[0] = idx[1] = idx[2] = NO_INDEX;
Packit bf408e
			for (j= 0; j < 3; j++) {
Packit bf408e
				if (j < nindx) {
Packit bf408e
					if (fread(&idx[j], sizeof(idx[0]), 1, fp) != 1) {
Packit bf408e
						fprintf(ofp, "Cannot read index.\n");
Packit bf408e
						nextgroup = TRUE;
Packit bf408e
						break;
Packit bf408e
					}
Packit bf408e
					fprintf(ofp, "[%d]", idx[j]);
Packit bf408e
				} else
Packit bf408e
					fprintf(ofp, "   ");
Packit bf408e
			}
Packit bf408e
		       if (nextgroup)
Packit bf408e
				break;
Packit bf408e
Packit bf408e
			if (IS_BLOCK_TAG(tag)) {
Packit bf408e
				uint64_t nbytes;
Packit bf408e
				uint64_t blockpos;
Packit bf408e
				uint64_t nbytesinmem;
Packit bf408e
				int compressed = IS_BLOCK_COMPRESSED_TAG(tag);
Packit bf408e
				uint16_t padsize;
Packit bf408e
				unsigned k, l;
Packit bf408e
				char byte;
Packit bf408e
Packit bf408e
				if (fread(&nbytes, sizeof(nbytes), 1, fp) != 1) {
Packit bf408e
					fprintf(ofp, "Cannot read block size.\n");
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				if (fread(&nbytesinmem, sizeof(nbytesinmem), 1, fp) != 1) {
Packit bf408e
					fprintf(ofp, "Cannot read block memory size.\n");
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				if (fread(&padsize, sizeof(padsize), 1, fp) != 1) {
Packit bf408e
					fprintf(ofp, "Cannot read block padding size.\n");
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				if ((blockpos = ftell(fp)) == -1) {
Packit bf408e
					fprintf(ofp, "Cannot determine location within VMSS file.\n");
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				blockpos += padsize;
Packit bf408e
Packit bf408e
				fprintf(ofp, " => %sBLOCK: position=%#llx size=%#llx memsize=%#llx\n",
Packit bf408e
					compressed ? "COMPRESSED " : "",
Packit bf408e
					(ulonglong)blockpos, (ulonglong)nbytes, (ulonglong)nbytesinmem);
Packit bf408e
Packit bf408e
				if (nbytes && nbytes <= MAX_BLOCK_DUMP && !compressed) {
Packit bf408e
					fprintf(ofp, "Hex dump: \n");
Packit bf408e
					l = 0;
Packit bf408e
					for (k = 0; k < nbytes; k++) {
Packit bf408e
						if (fread(&byte, 1, 1, fp) != 1) {
Packit bf408e
							fprintf(ofp, "Cannot read byte.\n");
Packit bf408e
							result = FALSE;
Packit bf408e
							goto exit;
Packit bf408e
						}
Packit bf408e
Packit bf408e
						fprintf(ofp, " %02hhX", byte);
Packit bf408e
Packit bf408e
						if (l++ == 15) {
Packit bf408e
							fprintf(ofp, "\n");
Packit bf408e
							l = 0;
Packit bf408e
						}
Packit bf408e
					}
Packit bf408e
					if (l)
Packit bf408e
						fprintf(ofp, "\n\n");
Packit bf408e
					else
Packit bf408e
						fprintf(ofp, "\n");
Packit bf408e
				} else {
Packit bf408e
					if (fseek(fp, blockpos + nbytes, SEEK_SET) == -1) {
Packit bf408e
						fprintf(ofp, "Cannot seek past block at %#llx.\n",
Packit bf408e
							(ulonglong)(blockpos + nbytes));
Packit bf408e
						result = FALSE;
Packit bf408e
						goto exit;
Packit bf408e
					}
Packit bf408e
				}
Packit bf408e
			} else {
Packit bf408e
				union {
Packit bf408e
					uint8_t val[TAG_VALSIZE_MASK];
Packit bf408e
					uint32_t val32;
Packit bf408e
					uint64_t val64;
Packit bf408e
				} u;
Packit bf408e
				unsigned k;
Packit bf408e
				unsigned valsize = TAG_VALSIZE(tag);
Packit bf408e
				uint64_t blockpos = ftell(fp);
Packit bf408e
Packit bf408e
				fprintf(ofp, " => position=%#llx size=%#x: ",
Packit bf408e
					(ulonglong)blockpos, valsize);
Packit bf408e
Packit bf408e
				if (fread(u.val, sizeof(u.val[0]), valsize, fp) != valsize) {
Packit bf408e
					fprintf(ofp, "Cannot read item.\n");
Packit bf408e
					break;
Packit bf408e
				}
Packit bf408e
				for (k = 0; k < valsize; k++) {
Packit bf408e
					/* Assume Little Endian */
Packit bf408e
					fprintf(ofp, "%02X", u.val[valsize - k - 1]);
Packit bf408e
				}
Packit bf408e
Packit bf408e
Packit bf408e
				fprintf(ofp, "\n");
Packit bf408e
			}
Packit bf408e
		}
Packit bf408e
	}
Packit bf408e
Packit bf408e
exit:
Packit bf408e
	if (vmss.separate_vmem)
Packit bf408e
		fclose(fp);
Packit bf408e
	if (grps)
Packit bf408e
		free(grps);
Packit bf408e
Packit bf408e
	return result;
Packit bf408e
}
Packit bf408e
Packit bf408e
void
Packit bf408e
dump_registers_for_vmss_dump(void)
Packit bf408e
{
Packit bf408e
	int i;
Packit bf408e
	vmssregs64 *regs;
Packit bf408e
Packit bf408e
	if (!machine_type("X86_64")) {
Packit bf408e
		fprintf(fp, "-r option not supported on this dumpfile type\n");
Packit bf408e
		return;
Packit bf408e
	}
Packit bf408e
Packit bf408e
	for (i = 0; i < vmss.num_vcpus; i++) {
Packit bf408e
		regs = vmss.regs64[i];
Packit bf408e
Packit bf408e
		if (i)
Packit bf408e
			fprintf(fp, "\n");
Packit bf408e
Packit bf408e
		fprintf(fp, "CPU %d:\n", i);
Packit bf408e
Packit bf408e
		if (vmss.vcpu_regs[i] != REGS_PRESENT_ALL) {
Packit bf408e
			fprintf(fp, "Missing registers for this CPU: 0x%x\n", vmss.vcpu_regs[i]);
Packit bf408e
			continue;
Packit bf408e
		}
Packit bf408e
Packit bf408e
		fprintf(fp, "  RAX: %016llx  RBX: %016llx  RCX: %016llx\n",
Packit bf408e
			(ulonglong)regs->rax, (ulonglong)regs->rbx, (ulonglong)regs->rcx);
Packit bf408e
		fprintf(fp, "  RDX: %016llx  RSI: %016llx  RDI: %016llx\n",
Packit bf408e
			(ulonglong)regs->rdx, (ulonglong)regs->rsi, (ulonglong)regs->rdi);
Packit bf408e
		fprintf(fp, "  RSP: %016llx  RBP: %016llx   R8: %016llx\n",
Packit bf408e
			(ulonglong)regs->rsp, (ulonglong)regs->rbp, (ulonglong)regs->r8);
Packit bf408e
		fprintf(fp, "   R9: %016llx  R10: %016llx  R11: %016llx\n",
Packit bf408e
			(ulonglong)regs->r9, (ulonglong)regs->r10, (ulonglong)regs->r11);
Packit bf408e
		fprintf(fp, "  R12: %016llx  R13: %016llx  R14: %016llx\n",
Packit bf408e
			(ulonglong)regs->r12, (ulonglong)regs->r13, (ulonglong)regs->r14);
Packit bf408e
		fprintf(fp, "  R15: %016llx  RIP: %016llx  RFLAGS: %08llx\n",
Packit bf408e
			(ulonglong)regs->r15, (ulonglong)regs->rip, (ulonglong)regs->rflags);
Packit bf408e
		fprintf(fp, "  IDT: base: %016llx\n",
Packit bf408e
			(ulonglong)regs->idtr);
Packit bf408e
		fprintf(fp, "  CR0: %016llx  CR1: %016llx  CR2: %016llx\n",
Packit bf408e
			(ulonglong)regs->cr[0], (ulonglong)regs->cr[1], (ulonglong)regs->cr[2]);
Packit bf408e
		fprintf(fp, "  CR3: %016llx  CR4: %016llx\n",
Packit bf408e
			(ulonglong)regs->cr[3], (ulonglong)regs->cr[4]);
Packit bf408e
	}
Packit bf408e
}
Packit bf408e
Packit bf408e
int
Packit bf408e
vmware_vmss_valid_regs(struct bt_info *bt)
Packit bf408e
{
Packit bf408e
	if (vmss.vcpu_regs[bt->tc->processor] == REGS_PRESENT_ALL)
Packit bf408e
		return TRUE;
Packit bf408e
Packit bf408e
	return FALSE;
Packit bf408e
}
Packit bf408e
Packit bf408e
int
Packit Service 2d41f0
vmware_vmss_get_nr_cpus(void)
Packit Service 2d41f0
{
Packit Service 2d41f0
	return vmss.num_vcpus;
Packit Service 2d41f0
}
Packit Service 2d41f0
Packit Service 2d41f0
int
Packit Service 2d41f0
vmware_vmss_get_cr3_cr4_idtr(int cpu, ulong *cr3, ulong *cr4, ulong *idtr)
Packit bf408e
{
Packit Service 2d41f0
	if (cpu >= vmss.num_vcpus || vmss.vcpu_regs[cpu] != REGS_PRESENT_ALL)
Packit bf408e
		return FALSE;
Packit bf408e
Packit Service 2d41f0
	*cr3 = vmss.regs64[cpu]->cr[3];
Packit Service 2d41f0
	*cr4 = vmss.regs64[cpu]->cr[4];
Packit Service 2d41f0
	*idtr = vmss.regs64[cpu]->idtr;
Packit bf408e
Packit bf408e
	return TRUE;
Packit bf408e
}
Packit bf408e
Packit bf408e
int
Packit bf408e
vmware_vmss_phys_base(ulong *phys_base)
Packit bf408e
{
Packit bf408e
	*phys_base = vmss.phys_base;
Packit bf408e
Packit bf408e
	return TRUE;
Packit bf408e
}
Packit bf408e
Packit bf408e
int
Packit bf408e
vmware_vmss_set_phys_base(ulong phys_base)
Packit bf408e
{
Packit bf408e
	vmss.phys_base = phys_base;
Packit bf408e
Packit bf408e
	return TRUE;
Packit bf408e
}