Initial s390-tools-2.0.0 import

This commit is based on the s390-tools-1.39.0 version.

Changes on top of s390-tools-1.39.0:

 - Add MIT license to all source files
 - Add LICENSE file
 - Transform REAMDE to README.md (markdown)
 - Add AUTHORS.md file
 - Add CONTRIBUTING.md file
 - Move changelog from README to CHANGELOG.md file

Reviewed-by: Stefan Haberland <sth@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
This commit is contained in:
Michael Holzheu
2017-08-07 16:13:17 +02:00
commit b627b8d8e1
647 changed files with 168974 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
include ../common.mak
lib = libvmdump.a
all: $(lib)
objects = register_content.o dump.o lkcd_dump.o register_content.o \
vmdump_convert.o vm_dump.o
$(lib): $(objects)
install: all
clean:
rm -f *.o $(lib)
+65
View File
@@ -0,0 +1,65 @@
/*
* vmdump - z/VM dump conversion library
*
* Dump base class
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "dump.h"
int debug = 0;
void s390TodToTimeval(uint64_t todval, struct timeval *xtime)
{
/* adjust todclock to 1970 */
todval -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
todval >>= 12;
xtime->tv_sec = todval / 1000000;
xtime->tv_usec = todval % 1000000;
}
Dump::Dump(const char *filename, const char *mode)
{
fh = fopen(filename, mode);
if(!fh){
throw(DumpErrnoException("Open dump file failed!"));
}
}
Dump::~Dump(void)
{
if(fh){
fclose(fh);
}
}
void ProgressBar::initProgress(void)
{
progressPercentage = -1;
}
void ProgressBar::displayProgress(uint64_t value, uint64_t maxValue)
{
char progress_bar[51];
int j;
if (progressPercentage == (int) (value * 100 / maxValue))
fprintf(stderr, "%6lld of %6lld |\r",
(long long) value, (long long) maxValue);
else { /* percent value has changed */
progressPercentage = (value * 100 / maxValue);
for (j = 0; j < progressPercentage / 2; j++)
progress_bar[j] = '#';
for (j = progressPercentage / 2; j < 50; j++)
progress_bar[j] = '-';
progress_bar[50] = 0;
fprintf(stderr, "%6lld of %6lld |%s| %3d%% \r",
(long long) value, (long long) maxValue,
progress_bar, progressPercentage);
}
}
+95
View File
@@ -0,0 +1,95 @@
/*
* vmdump - z/VM dump conversion library
*
* Dump base class
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef DUMP_H
#define DUMP_H
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
extern int debug;
class DumpException
{
public:
DumpException(void) {
msg[0] = 0;
errorCode = 0;
}
DumpException(const char *m) {
sprintf(msg, "%s", m);
errorCode = 0;
}
const char *what(void) const { return msg; }
int code(void) const { return errorCode; }
protected:
char msg[200];
int errorCode;
};
class DumpErrnoException : public DumpException
{
public:
DumpErrnoException(const char *m) {
sprintf(msg, "%s (%s)", m, strerror(errno));
errorCode = errno;
}
};
class Dump
{
public:
Dump(const char *filename, const char *mode);
Dump(void) : fh(0) {}
virtual ~Dump(void);
typedef enum {DT_VM32, DT_VM64, DT_VM64_BIG, DT_LKCD32, DT_LKCD64,
DT_UNKNOWN} DumpType;
virtual void readMem(char *buf, int size) = 0;
virtual int seekMem(uint64_t offset) = 0;
virtual uint64_t getMemSize(void) const = 0;
virtual struct timeval getDumpTime(void) const = 0;
protected:
FILE *fh;
};
class ProgressBar
{
public:
ProgressBar(void) { progressPercentage = -1; }
void initProgress(void);
void displayProgress(uint64_t value, uint64_t maxValue);
private:
int progressPercentage;
};
void s390TodToTimeval(uint64_t todval, struct timeval *xtime);
int vm_convert(const char *inputFileName, const char *outputFileName,
const char *progName);
static inline void dump_read(void *ptr, size_t size, size_t nmemb,
FILE *stream)
{
if (fread(ptr, size, nmemb, stream) != nmemb)
throw(DumpErrnoException("fread failed"));
}
static inline void dump_seek(FILE *stream, long offset, int whence)
{
if (fseek(stream, offset, whence) == -1)
throw(DumpErrnoException("fseek failed"));
}
#endif /* DUMP_H */
+261
View File
@@ -0,0 +1,261 @@
/*
* vmdump - z/VM dump conversion library
*
* LKCD dump classes: LKCDDump, LKCDDump32, LKCDDump64
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <zlib.h>
#include "lkcd_dump.h"
LKCDDump::LKCDDump(Dump* dump, const char* arch) {
referenceDump = dump;
dumpHeader.magic_number = DUMP_MAGIC_NUMBER;
dumpHeader.version = DUMP_VERSION_NUMBER;
dumpHeader.header_size = sizeof(struct _lkcd_dump_header);
dumpHeader.time.tv_sec = dump->getDumpTime().tv_sec;
dumpHeader.time.tv_usec = dump->getDumpTime().tv_usec;
strcpy(dumpHeader.utsname_machine, arch);
dumpHeader.memory_size = dump->getMemSize();
dumpHeader.memory_start = 0;
dumpHeader.memory_end = dump->getMemSize();
dumpHeader.num_dump_pages = dump->getMemSize()/0x1000;
dumpHeader.page_size = 0x1000;
dumpHeader.dump_compress = DUMP_COMPRESS_GZIP;
dumpHeader.dump_level = DUMP_LEVEL_ALL;
dumpHeaderAsm.magic_number = DUMP_ASM_MAGIC_NUMBER;
dumpHeaderAsm.version = 1;
dumpHeaderAsm.header_size = sizeof(dumpHeaderAsm);
}
int LKCDDump::compressGZIP(const char *old, uint32_t old_size, char *n,
uint32_t new_size)
{
unsigned long len = old_size;
int rc;
rc = compress((Bytef*)n, &len, (const Bytef*)old, new_size);
switch(rc) {
case Z_OK:
rc = len;
break;
case Z_BUF_ERROR:
/* In this case the compressed output is bigger than */
/* the uncompressed */
rc = GZIP_NOT_COMPRESSED;
break;
case Z_MEM_ERROR:
throw(DumpException("gzip call failed: out of memory"));
case Z_DATA_ERROR:
throw(DumpException("gzip call failed: input data " \
"corrupted!"));
default:
throw(DumpException("gzip call failed: unknown error"));
}
return rc;
}
void LKCDDump::writeDump(const char* fileName)
{
char dump_header_buf[DUMP_HEADER_SIZE] = {};
char dump_page_buf[DUMP_BUFFER_SIZE];
char dpcpage[DUMP_PAGE_SIZE];
uint32_t dp_size,dp_flags;
ProgressBar progressBar;
char buf[DUMP_PAGE_SIZE];
struct _dump_page dp;
uint64_t mem_loc = 0;
ssize_t buf_loc = 0;
int size, fd;
if (fileName == NULL) {
fd = STDOUT_FILENO;
} else {
fd = open(fileName, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR);
if (fd == -1) {
char msg[1024];
sprintf(msg, "Open of dump '%s' failed.", fileName);
throw(DumpErrnoException(msg));
}
}
/* write dump header */
memcpy(dump_header_buf, &dumpHeader, sizeof(dumpHeader));
memcpy(&dump_header_buf[sizeof(dumpHeader)], &dumpHeaderAsm,
sizeof(dumpHeaderAsm));
if (write(fd, dump_header_buf, sizeof(dump_header_buf)) !=
sizeof(dump_header_buf)) {
throw(DumpErrnoException("write failed"));
}
/* write memory */
referenceDump->seekMem(0);
while (mem_loc < dumpHeader.memory_size) {
referenceDump->readMem(buf, DUMP_PAGE_SIZE);
copyRegsToPage(mem_loc,buf);
memset(dpcpage, 0, DUMP_PAGE_SIZE);
/*
* Get the new compressed page size
*/
size = compressGZIP((char *)buf, DUMP_PAGE_SIZE,
(char *)dpcpage, DUMP_PAGE_SIZE);
/*
* If compression failed or compressed was ineffective,
* we write an uncompressed page
*/
if (size == GZIP_NOT_COMPRESSED) {
dp_flags = DUMP_DH_RAW;
dp_size = DUMP_PAGE_SIZE;
} else {
dp_flags = DUMP_DH_COMPRESSED;
dp_size = size;
}
dp.address = mem_loc;
dp.size = dp_size;
dp.flags = dp_flags;
memcpy((void *)(dump_page_buf + buf_loc),
(const void *)&dp, sizeof(dp));
buf_loc += sizeof(dp);
/*
* Copy the page of memory
*/
if (dp_flags & DUMP_DH_COMPRESSED) {
/* Copy the compressed page */
memcpy((void *)(dump_page_buf + buf_loc),
(const void *)dpcpage, dp_size);
} else {
/* Copy directly from memory */
memcpy((void *)(dump_page_buf + buf_loc),
(const void *)buf, dp_size);
}
buf_loc += dp_size;
if(write(fd, dump_page_buf, buf_loc) != buf_loc){
throw(DumpErrnoException("write failed"));
}
buf_loc = 0;
mem_loc += DUMP_PAGE_SIZE;
progressBar.displayProgress(mem_loc/(1024*1024),
dumpHeader.memory_size/(1024*1024));
}
/*
* Write end marker
*/
dp.address = 0x0;
dp.size = 0x0;
dp.flags = DUMP_DH_END;
if(write(fd, &dp, sizeof(dp)) != sizeof(dp)){
throw(DumpErrnoException("write failed"));
}
fprintf(stderr, "\n");
if (fd != STDOUT_FILENO)
close(fd);
}
struct timeval LKCDDump::getDumpTime(void) const
{
struct timeval rc;
rc.tv_sec = dumpHeader.time.tv_sec;
rc.tv_usec = dumpHeader.time.tv_usec;
return rc;
}
LKCDDump32::LKCDDump32(Dump* dump, const RegisterContent32& r)
: LKCDDump(dump,"s390")
{
unsigned int i;
dumpHeaderAsm.real_cpu_cnt = (uint32_t) r.getNumCpus();
for (i = 0; i < dumpHeaderAsm.real_cpu_cnt; i++) {
if (!r.regSets[i].prefix)
continue;
dumpHeaderAsm.lc_vec[i] = r.regSets[i].prefix;
dumpHeaderAsm.cpu_cnt++;
}
registerContent = r;
}
void LKCDDump32::copyRegsToPage(uint64_t offset, char *buf)
{
int cpu;
for(cpu = 0; cpu < registerContent.getNumCpus(); cpu++){
if(offset == registerContent.regSets[cpu].prefix){
memcpy(buf+0xd8,&registerContent.regSets[cpu].cpuTimer,
sizeof(registerContent.regSets[cpu].cpuTimer));
memcpy(buf+0xe0,&registerContent.regSets[cpu].clkCmp,
sizeof(registerContent.regSets[cpu].clkCmp));
memcpy(buf+0x100,&registerContent.regSets[cpu].psw,
sizeof(registerContent.regSets[cpu].psw));
memcpy(buf+0x108,&registerContent.regSets[cpu].prefix,
sizeof(registerContent.regSets[cpu].prefix));
memcpy(buf+0x120,&registerContent.regSets[cpu].acrs,
sizeof(registerContent.regSets[cpu].acrs));
memcpy(buf+0x160,&registerContent.regSets[cpu].fprs,
sizeof(registerContent.regSets[cpu].fprs));
memcpy(buf+0x180,&registerContent.regSets[cpu].gprs,
sizeof(registerContent.regSets[cpu].gprs));
memcpy(buf+0x1c0,&registerContent.regSets[cpu].crs,
sizeof(registerContent.regSets[cpu].crs));
}
}
}
LKCDDump64::LKCDDump64(Dump* dump, const RegisterContent64& r)
: LKCDDump(dump,"s390x")
{
unsigned int i;
dumpHeaderAsm.real_cpu_cnt = (uint32_t) r.getNumCpus();
for (i = 0; i < dumpHeaderAsm.real_cpu_cnt; i++) {
if (!r.regSets[i].prefix)
continue;
dumpHeaderAsm.lc_vec[i] = r.regSets[i].prefix;
dumpHeaderAsm.cpu_cnt++;
}
registerContent = r;
}
void LKCDDump64::copyRegsToPage(uint64_t offset, char *buf)
{
int cpu;
for(cpu = 0; cpu < registerContent.getNumCpus(); cpu++){
if(offset == (registerContent.regSets[cpu].prefix + 0x1000)){
memcpy(buf+0x328,&registerContent.regSets[cpu].cpuTimer,
sizeof(registerContent.regSets[cpu].cpuTimer));
memcpy(buf+0x330,&registerContent.regSets[cpu].clkCmp,
sizeof(registerContent.regSets[cpu].clkCmp));
memcpy(buf+0x300,&registerContent.regSets[cpu].psw,
sizeof(registerContent.regSets[cpu].psw));
memcpy(buf+0x318,&registerContent.regSets[cpu].prefix,
sizeof(registerContent.regSets[cpu].prefix));
memcpy(buf+0x340,&registerContent.regSets[cpu].acrs,
sizeof(registerContent.regSets[cpu].acrs));
memcpy(buf+0x200,&registerContent.regSets[cpu].fprs,
sizeof(registerContent.regSets[cpu].fprs));
memcpy(buf+0x280,&registerContent.regSets[cpu].gprs,
sizeof(registerContent.regSets[cpu].gprs));
memcpy(buf+0x380,&registerContent.regSets[cpu].crs,
sizeof(registerContent.regSets[cpu].crs));
memcpy(buf+0x31c,&registerContent.regSets[cpu].fpCr,
sizeof(registerContent.regSets[cpu].fpCr));
}
}
}
+149
View File
@@ -0,0 +1,149 @@
/*
* vmdump - z/VM dump conversion library
*
* LKCD dump classes: LKCDDump, LKCDDump32, LKCDDump64
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef LKCD_DUMP_H
#define LKCD_DUMP_H
#include "lib/zt_common.h"
#include "dump.h"
#include "register_content.h"
#define UTS_LEN 65
#define DUMP_BUFFER_SIZE 0x2000 /* Size of dump buffer */
/* Standard header definitions */
#define DUMP_HEADER_SIZE 0x10000
#define DUMP_MAGIC_NUMBER 0xa8190173618f23edULL /* Dump magic number */
#define DUMP_ASM_MAGIC_NUMBER 0x733339302d64756dULL /* asm magic number */
#define DUMP_VERSION_NUMBER 0x8 /* Dump version number */
#define DUMP_PANIC_LEN 0x100 /* Dump panic string length */
/* Dump levels - type specific stuff added later */
#define DUMP_LEVEL_ALL 0x10 /* Dump all memory RAM and firmware */
/* Dump compression options */
#define DUMP_COMPRESS_GZIP 0x2 /* Use GZIP compression */
/* Dump header flags */
#define DUMP_DH_RAW 0x1 /* Raw page (no compression) */
#define DUMP_DH_COMPRESSED 0x2 /* Page is compressed */
#define DUMP_DH_END 0x4 /* End marker on a full dump */
/* Dump page defines */
#define DUMP_PAGE_SHIFT 12ULL
#define DUMP_PAGE_SIZE (1ULL << DUMP_PAGE_SHIFT)
#define GZIP_NOT_COMPRESSED -1
class LKCDDump : public Dump
{
public:
LKCDDump(Dump*, const char *);
virtual ~LKCDDump(void) {}
inline virtual void readMem(char *UNUSED(buf), int UNUSED(size))
{
throw(DumpException("LKCDDump::readMem() not implemented!"));
}
inline int seekMem(uint64_t UNUSED(offset))
{
throw(DumpException("LKCDDump::seekMem() not implemented!"));
}
inline virtual uint64_t getMemSize() const
{
return dumpHeader.memory_size;
}
virtual struct timeval getDumpTime(void) const;
virtual void writeDump(const char *fileName);
virtual void copyRegsToPage(uint64_t offset, char *buf) = 0;
protected:
struct _lkcd_dump_header {
uint64_t magic_number; /* dump magic number,unique to verify */
/* dump */
uint32_t version; /* version number of this dump */
uint32_t header_size; /* size of this header */
uint32_t dump_level; /* level of this dump */
uint32_t page_size; /* page size (e.g. 4K, 8K, 16K, etc.) */
uint64_t memory_size; /* size of entire physical memory */
uint64_t memory_start; /* start of physical memory */
uint64_t memory_end; /* end of physical memory */
/* the number of dump pages in this dump specifically */
uint32_t num_dump_pages;
char panic_string[DUMP_PANIC_LEN];
/* timeval depends on machine, two long values */
struct {uint64_t tv_sec;
uint64_t tv_usec;
} time; /* the time of the system crash */
/* the NEW utsname (uname) information -- in character form */
/* we do this so we don't have to include utsname.h */
/* plus it helps us be more architecture independent */
char utsname_sysname[UTS_LEN];
char utsname_nodename[UTS_LEN];
char utsname_release[UTS_LEN];
char utsname_version[UTS_LEN];
char utsname_machine[UTS_LEN];
char utsname_domainname[UTS_LEN];
uint64_t current_task;
uint32_t dump_compress; /* compression type used in this dump */
uint32_t dump_flags; /* any additional flags */
uint32_t dump_device; /* any additional flags */
uint64_t s390_asm_magic;
uint16_t cpu_cnt;
uint32_t lowcore_ptr[512];
} __packed;
struct _lkcd_dump_header_asm {
uint64_t magic_number;
uint32_t version;
uint32_t header_size;
uint16_t cpu_cnt;
uint16_t real_cpu_cnt;
uint32_t lc_vec[512];
} __packed;
struct _dump_page {
uint64_t address; /* the address of this dump page */
uint32_t size; /* the size of this dump page */
uint32_t flags; /* flags (DUMP_COMPRESSED, DUMP_RAW */
/* or DUMP_END) */
} __packed;
struct _lkcd_dump_header dumpHeader;
struct _lkcd_dump_header_asm dumpHeaderAsm;
private:
int compressGZIP(const char *old, uint32_t old_size, char *n,
uint32_t new_size);
Dump *referenceDump;
};
class LKCDDump32 : public LKCDDump
{
public:
LKCDDump32(Dump *dump, const RegisterContent32 &rc);
virtual void copyRegsToPage(uint64_t offset, char *buf);
private:
RegisterContent32 registerContent;
};
class LKCDDump64 : public LKCDDump
{
public:
LKCDDump64(Dump *dump, const RegisterContent64 &rc);
virtual void copyRegsToPage(uint64_t offset, char *buf);
private:
RegisterContent64 registerContent;
};
#endif /* LKCD_DUMP_H */
+76
View File
@@ -0,0 +1,76 @@
/*
* vmdump - z/VM dump conversion library
*
* Register content classes
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <string.h>
#include "register_content.h"
#include "dump.h"
RegisterContent32::RegisterContent32(void)
: regSets(), nrCpus(0)
{
}
RegisterContent32::RegisterContent32(const RegisterContent32& r)
{
nrCpus = r.nrCpus;
memcpy(&regSets,&r.regSets,sizeof(regSets));
}
void RegisterContent32::addRegisterSet(const RegisterSet32& rs)
{
if(nrCpus < MAX_CPUS){
regSets[nrCpus++] = rs;
} else {
throw(DumpException("RegisterContent32::addRegisterSet - " \
"No more register sets available"));
}
}
RegisterSet32 RegisterContent32::getRegisterSet(int cpu){
if(cpu <= nrCpus){
return regSets[cpu];
} else {
throw(DumpException("RegisterContent32::getRegisterSet - " \
"No register set for cpu"));
}
}
RegisterContent64::RegisterContent64(void)
: regSets(), nrCpus(0)
{
}
RegisterContent64::RegisterContent64(const RegisterContent64& r)
{
nrCpus = r.nrCpus;
memcpy(&regSets,&r.regSets,sizeof(regSets));
}
void RegisterContent64::addRegisterSet(const RegisterSet64& rs)
{
if(nrCpus < MAX_CPUS){
regSets[nrCpus++] = rs;
} else {
throw(DumpException("RegisterContent64::addRegisterSet - " \
"No more register sets available"));
}
}
RegisterSet64 RegisterContent64::getRegisterSet(int cpu)
{
if(cpu <= nrCpus){
return regSets[cpu];
} else {
throw(DumpException("RegisterContent64::getRegisterSet - " \
"No register set for cpu"));
}
}
+73
View File
@@ -0,0 +1,73 @@
/*
* vmdump - z/VM dump conversion library
*
* Register content classes
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef REGISTER_CONTENT_H
#define REGISTER_CONTENT_H
#include <stdint.h>
#define MAX_CPUS 512
class RegisterSet64
{
public:
uint64_t gprs[16];
uint64_t crs[16];
uint32_t acrs[16];
uint64_t fprs[16];
uint32_t fpCr;
uint64_t psw[2];
uint32_t prefix;
uint64_t cpuTimer;
uint64_t clkCmp;
};
class RegisterSet32
{
public:
uint32_t gprs[16];
uint32_t crs[16];
uint32_t acrs[16];
uint64_t fprs[4];
uint32_t psw[2];
uint32_t prefix;
uint64_t cpuTimer;
uint64_t clkCmp;
};
class RegisterContent64{
public:
RegisterContent64(void);
RegisterContent64(const RegisterContent64&);
RegisterSet64 getRegisterSet(int cpu);
void addRegisterSet(const RegisterSet64&);
inline int getNumCpus(void) const { return nrCpus; }
RegisterSet64 regSets[MAX_CPUS];
private:
int nrCpus;
};
class RegisterContent32{
public:
RegisterContent32(void);
RegisterContent32(const RegisterContent32&);
RegisterSet32 getRegisterSet(int cpu);
void addRegisterSet(const RegisterSet32&);
inline int getNumCpus(void) const { return nrCpus; }
RegisterSet32 regSets[MAX_CPUS];
private:
int nrCpus;
};
#endif /* REGISTER_CONTENT_H */
+634
View File
@@ -0,0 +1,634 @@
/*
* vmdump - z/VM dump conversion library
*
* Register content classes:
* VMDump, VMDumpClassic, VMDump64, VMDump64Big, VMDump32
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <ctype.h>
#include <stdint.h>
#include <time.h>
#include "vm_dump.h"
Dump::DumpType VMDump::getDumpType(const char* inputFileName)
{
uint8_t fmbk_id[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
struct _fir_basic fir;
struct _fmbk fmbk;
struct _adsr adsr;
char msg[200];
FILE* fh;
fh = fopen(inputFileName,"r");
if (!fh) {
sprintf(msg,"Could not open '%s'",inputFileName);
throw DumpErrnoException(msg);
}
/* Record 1: adsr */
dump_read(&adsr, sizeof(adsr), 1, fh);
/* Record 2: fmbk */
dump_seek(fh, 0x1000, SEEK_SET);
if (fread(&fmbk, sizeof(fmbk), 1, fh) != 1) {
if(ferror(fh)) {
sprintf(msg,"Could not read header of vmdump '%s'",
inputFileName);
fclose(fh);
throw DumpErrnoException(msg);
} else{
sprintf(msg,"Input file '%s' is not a vmdump",
inputFileName);
fclose(fh);
throw DumpException(msg);
}
}
/* Check if this is a vmdump */
if (memcmp(fmbk.id, fmbk_id, 8) != 0 ||
adsr.dump_type != 0xe5d4c4e4d4d74040ULL) {
fclose(fh);
sprintf(msg, "Input file '%s' is not a vmdump", inputFileName);
throw DumpException(msg);
}
/* Record 3-7: fir */
dump_seek(fh, (fmbk.rec_nr_fir - 1) * 0x1000, SEEK_SET);
if(fread(&fir, sizeof(fir), 1, fh) != 1) {
if (ferror(fh)) {
sprintf(msg,"Could not read header of vmdump '%s'",
inputFileName);
fclose(fh);
throw DumpErrnoException(msg);
}
else{
sprintf(msg, "Could not read header of vmdump '%s'",
inputFileName);
fclose(fh);
throw DumpException(msg);
}
}
fclose(fh);
if (fir.fir_format == 0) {
return DT_VM32;
} else if (fir.fir_format == 0x02) {/*XXX && (fir.dump_format == 0x1))*/
return DT_VM64_BIG;
} else if (fir.fir_format == 0x82) {
return DT_VM64;
} else {
return DT_UNKNOWN;
}
}
VMDump::VMDump(const char *fileName) : Dump(fileName, "rb")
{
uint8_t fmbk_id[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
ebcdicAsciiConv = iconv_open("ISO-8859-1", "EBCDIC-US");
/* Record 1: adsrRecord */
dump_seek(fh,0,SEEK_SET);
dump_read(&adsrRecord,sizeof(adsrRecord),1,fh);
if(debug) {
char buf[1024];
int i;
fprintf(stderr, "off=%d\n", adsrRecord.sec5_offset);
dump_seek(fh, adsrRecord.sec5_offset, SEEK_SET);
dump_read(buf, adsrRecord.sec5_len, 1, fh);
ebcAsc(buf, adsrRecord.sec5_len);
for (i=0; i < adsrRecord.sec5_len; i++) {
if ((buf[i]==0) || iscntrl(buf[i]))
buf[i]=' ';
}
buf[adsrRecord.sec5_len] = 0;
printf("symptom string1: %s\n",buf);
}
/* Record 2: fmbk */
dump_seek(fh,0x1000,SEEK_SET);
dump_read(&fmbkRecord,sizeof(fmbkRecord),1,fh);
/* Check if this is a vmdump */
if(memcmp(fmbkRecord.id, fmbk_id, 8) != 0) {
throw DumpException("Input file is not a vmdump");
}
/* Record 3-7: fir records read by subclasses */
/* Record 8: albk */
dump_seek(fh,(fmbkRecord.rec_nr_access-1)*0x1000 ,SEEK_SET);
dump_read(&albkRecord,sizeof(albkRecord),1,fh);
}
struct timeval VMDump::getDumpTime(void) const
{
struct timeval rc;
s390TodToTimeval(adsrRecord.tod,&rc);
return rc;
}
void VMDump::printDebug(void)
{
struct timeval time;
char buf[1024];
s390TodToTimeval(adsrRecord.tod, &time);
/* adsr */
printf("time : %s\n", ctime(&time.tv_sec));
printf("stat1 : %x\n", adsrRecord.record_status_flag1);
printf("stat2 : %x\n", adsrRecord.record_status_flag2);
printf("sec 2 len: %i\n", adsrRecord.sec2_len);
printf("sec 2.1 len: %i/%i\n", adsrRecord.sec2_1_len,
adsrRecord.sec2_1_offset);
printf("sec 3 len: %i/%i\n", adsrRecord.sec3_len,
adsrRecord.sec3_offset);
printf("sec 4 len: %i/%i\n", adsrRecord.sec4_len,
adsrRecord.sec4_offset);
printf("sec 5 len: %i/%i\n", adsrRecord.sec5_len,
adsrRecord.sec5_offset);
printf("sec 6 len: %i/%i\n", adsrRecord.sec6_len,
adsrRecord.sec6_offset);
/* fmbk */
ebcAsc(fmbkRecord.id, sizeof(fmbkRecord.id));
fmbkRecord.id[7] = 0;
printf("id : %s\n", fmbkRecord.id);
printf("fir rec nr: %i\n", fmbkRecord.rec_nr_fir);
printf("vec rec nr: %i\n", fmbkRecord.rec_nr_vector);
printf("access rec nr: %i\n", fmbkRecord.rec_nr_access);
/* albk */
memcpy(buf, albkRecord.id, sizeof(albkRecord.id));
ebcAsc(buf, sizeof(albkRecord.id));
buf[8]=0;
printf("ALBK id : %s\n",buf);
/* asibk */
/*
XXX
memcpy(buf,asibkRecord.id,sizeof(asibkRecord.id));
ebcAsc(buf,sizeof(asibkRecord.id));
asibkRecord.id[8]=0;
printf("ASIBK id : %s\n",buf);
printf("storage : %x\n",asibkRecord.storage_size_2GB);
printf("bitmapsrecs : %i\n",asibkRecord.nr_of_recs_of_first_bit_map);
*/
}
void VMDump::printInfo(void)
{
struct timeval time;
s390TodToTimeval(adsrRecord.tod,&time);
fprintf(stderr, " date........: %s",ctime(&time.tv_sec));
}
int VMDump::seekMem(uint64_t offset)
{
if (offset != 0) {
return -1;
}
pageOffset = 0;
return 0;
}
void VMDump::readMem(char* buf, int size)
{
int i;
if (pageOffset == 0)
dump_seek(fh, memoryStartRecord, SEEK_SET);
if (size % 0x1000 != 0) {
throw(DumpException("internal error: VMDump::readMem() " \
"can only handle sizes which are multiples of page size"));
}
for(i = 0; i < size; i += 0x1000) {
if(testPage(pageOffset)) {
dump_read(buf + i, 0x1000, 1, fh);
} else {
memset(buf + i, 0, 0x1000);
}
pageOffset += 1;
}
}
VMDump::~VMDump(void)
{
}
/*****************************************************************************/
/* VMDumpClassic: traditional 32/64 bit vmdump (before z/VM 5.2) */
/*****************************************************************************/
VMDumpClassic::VMDumpClassic(const char *fileName) : VMDump(fileName)
{
int storageKeyPages,bitMapPages;
pageOffset = 0;
/* Record 9: asibk */
dump_seek(fh,fmbkRecord.rec_nr_access * 0x1000,SEEK_SET);
dump_read(&asibkRecord,sizeof(asibkRecord),1,fh);
/* Record 10: bitmaps */
dump_seek(fh,(fmbkRecord.rec_nr_access + 1)* 0x1000 ,SEEK_SET);
bitmap = new char[asibkRecord.storage_size_2GB / (0x1000 * 8)];
dump_read(bitmap,asibkRecord.storage_size_2GB / (0x1000*8),1,fh);
bitMapPages=asibkRecord.storage_size_2GB / (0x1000 * 8);
if (bitMapPages % 0x1000 != 0)
bitMapPages = bitMapPages/0x1000 + 1;
else
bitMapPages = bitMapPages/0x1000;
storageKeyPages=asibkRecord.storage_size_2GB / 0x1000;
if(storageKeyPages % 0x1000 != 0) {
storageKeyPages = storageKeyPages/0x1000 + 1;
} else {
storageKeyPages = storageKeyPages/0x1000;
}
/* Skip storage keys */
memoryStartRecord = (fmbkRecord.rec_nr_access + 1) *0x1000 /* 0x9000 */
+ (bitMapPages + storageKeyPages)*0x1000;
if(debug) {
printf("Mem Offset: %llx\n", (long long) memoryStartRecord);
}
}
void VMDumpClassic::printInfo(void)
{
VMDump::printInfo();
fprintf(stderr, " storage.....: %i MB\n",
asibkRecord.storage_size_2GB/(1024*1024));
}
VMDumpClassic::~VMDumpClassic(void)
{
delete bitmap;
}
/*****************************************************************************/
/* VMDump32: 32 bit vmdump */
/*****************************************************************************/
VMDump32::VMDump32(const char* filename) : VMDumpClassic(filename)
{
int i;
if(!fh) {
return;
}
dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
dump_read(&fir32Record,sizeof(fir32Record),1,fh);
fir32OtherRecords = new _fir_other_32[fir32Record.online_cpus];
for(i=0; i < fir32Record.online_cpus; i++) {
/* fir other */
dump_read(&fir32OtherRecords[i],sizeof(fir32OtherRecords[i]),1,
fh);
}
if(debug)
printDebug();
}
RegisterContent32 VMDump32::getRegisterContent(void)
{
RegisterContent32 rc;
RegisterSet32 rs;
int cpu;
/* First CPU */
memcpy(&rs.gprs, &fir32Record.gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir32Record.crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir32Record.acrs, sizeof(rs.acrs));
memcpy(&rs.psw, &fir32Record.psw, sizeof(rs.psw));
memcpy(&rs.prefix, &fir32Record.prefix, sizeof(rs.prefix));
memcpy(&rs.fprs, &fir32Record.fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir32Record.cpu_timer, sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir32Record.clock_cmp, sizeof(rs.clkCmp));
rc.addRegisterSet(rs);
/* Other online cpus */
for(cpu = 0; cpu < fir32Record.online_cpus; cpu++) {
memcpy(&rs.gprs, &fir32OtherRecords[cpu].gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir32OtherRecords[cpu].crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir32OtherRecords[cpu].acrs, sizeof(rs.acrs));
/* No psw for ESA vmdumps */
rs.psw[0] = 0xdeadbeef;
rs.psw[1] = 0xdeadbeef;
memcpy(&rs.prefix, &fir32OtherRecords[cpu].prefix,
sizeof(rs.prefix));
memcpy(&rs.fprs, &fir32OtherRecords[cpu].fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir32OtherRecords[cpu].cpu_timer,
sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir32OtherRecords[cpu].clock_cmp,
sizeof(rs.clkCmp));
rc.addRegisterSet(rs);
}
return rc;
}
void VMDump32::printDebug(void)
{
int i;
VMDump::printDebug();
printf("prefix: %x\n", fir32Record.prefix);
printf("cpus: %x\n", fir32Record.online_cpus);
printf("psw: %08x %08x\n", fir32Record.psw[0], fir32Record.psw[1]);
for (i=0; i < fir32Record.online_cpus; i++) {
/* fir other */
printf("prefix (%i): %x\n", i, fir32OtherRecords[i].prefix);
}
}
void
VMDump32::printInfo(void)
{
fprintf(stderr, "vmdump information:\n");
fprintf(stderr, " architecture: 32 bit\n");
VMDumpClassic::printInfo();
fprintf(stderr, " cpus........: %x\n", fir32Record.online_cpus + 1);
}
VMDump32::~VMDump32(void)
{
delete fir32OtherRecords;
}
/*****************************************************************************/
/* VMDump64: 64 bit vmdump for old vmdump format (z/VM < 5.2) */
/*****************************************************************************/
VMDump64::VMDump64(const char* filename) : VMDumpClassic(filename)
{
int i;
if(!fh) {
return;
}
dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
dump_read(&fir64Record,sizeof(fir64Record),1,fh);
fir64OtherRecords = new _fir_other_64[fir64Record.online_cpus];
for (i=0; i < fir64Record.online_cpus; i++) {
/* fir other */
dump_read(&fir64OtherRecords[i], sizeof(fir64OtherRecords[i]),
1, fh);
}
if(debug)
printDebug();
}
void VMDump64::printDebug(void)
{
int i;
VMDump::printDebug();
printf("prefix: %x\n", fir64Record.prefix);
printf("cpus: %x\n", fir64Record.online_cpus);
printf("psw: %016llx %016llx\n", (long long)fir64Record.psw[0],
(long long)fir64Record.psw[1]);
for (i=0; i < fir64Record.online_cpus; i++) {
/* fir other */
printf("prefix (%i): %x\n", i, fir64OtherRecords[i].prefix);
}
}
void VMDump64::printInfo(void)
{
fprintf(stderr, "vmdump information:\n");
fprintf(stderr, " architecture: 64 bit\n");
VMDumpClassic::printInfo();
fprintf(stderr, " cpus........: %x\n",fir64Record.online_cpus + 1);
}
RegisterContent64 VMDump64::getRegisterContent(void)
{
RegisterContent64 rc;
RegisterSet64 rs;
int cpu;
/* First CPU */
memcpy(&rs.gprs, &fir64Record.gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir64Record.crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir64Record.acrs, sizeof(rs.acrs));
memcpy(&rs.psw, &fir64Record.psw, sizeof(rs.psw));
memcpy(&rs.prefix, &fir64Record.prefix, sizeof(rs.prefix));
memcpy(&rs.fprs, &fir64Record.fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir64Record.cpu_timer, sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir64Record.clock_cmp, sizeof(rs.clkCmp));
memcpy(&rs.fpCr, &fir64Record.fp_cntrl_reg, sizeof(rs.fpCr));
rc.addRegisterSet(rs);
/* other online cpus */
for (cpu = 0; cpu < fir64Record.online_cpus; cpu++) {
memcpy(&rs.gprs, &fir64OtherRecords[cpu].gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir64OtherRecords[cpu].crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir64OtherRecords[cpu].acrs, sizeof(rs.acrs));
memcpy(&rs.psw, &fir64OtherRecords[cpu].psw, sizeof(rs.psw));
memcpy(&rs.prefix, &fir64OtherRecords[cpu].prefix,
sizeof(rs.prefix));
memcpy(&rs.fprs, &fir64OtherRecords[cpu].fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir64OtherRecords[cpu].cpu_timer,
sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir64OtherRecords[cpu].clock_cmp,
sizeof(rs.clkCmp));
memcpy(&rs.fpCr, &fir64OtherRecords[cpu].fp_cntrl_reg,
sizeof(rs.fpCr));
rc.addRegisterSet(rs);
}
return rc;
}
VMDump64::~VMDump64(void)
{
delete fir64OtherRecords;
}
/*****************************************************************************/
/* VMDump64Big: 64 bit vmdump with new big storage dump format */
/*****************************************************************************/
VMDump64Big::VMDump64Big(const char* filename) : VMDump(filename)
{
uint64_t pageNum, nrDumpedPages;
int i, j;
if(!fh) {
return;
}
/* Record 9: asibk */
dump_seek(fh, fmbkRecord.rec_nr_access * 0x1000,SEEK_SET);
dump_read(&asibkRecordNew, sizeof(asibkRecordNew), 1, fh);
/* Record 10: bitmaps: */
/* Read all bitmap pages and setup bitmap array */
pageNum = 0;
nrDumpedPages = asibkRecordNew.storage_size_def_store / 0x1000;
memoryStartRecord = (fmbkRecord.rec_nr_access + 1) * 0x1000;
bitmap = new char[asibkRecordNew.storage_size_def_store/(0x1000 * 8)];
if(!bitmap) {
throw(DumpErrnoException("out of memory"));
}
memset(bitmap,0,asibkRecordNew.storage_size_def_store/(0x1000 * 8));
dump_seek(fh,(fmbkRecord.rec_nr_access + 1)* 0x1000 ,SEEK_SET);
do {
char bmIndexPage[0x1000];
dump_read(bmIndexPage, sizeof(bmIndexPage), 1, fh);
memoryStartRecord += 0x1000;
for (i=0; i < 0x1000; i++) {
if(testBitmapPage(bmIndexPage, i)) {
char bmPage[0x1000];
dump_read(bmPage,sizeof(bmPage),1,fh);
memoryStartRecord += 0x1000;
for(j = 0; j < 0x1000; j++) {
if(testBitmapKeyPage(bmPage, j)) {
setPageBit(pageNum);
}
pageNum++;
if(pageNum == nrDumpedPages) {
goto all_bitmaps_read;
}
}
} else {
pageNum += 0x1000; /* Empty pages */
}
}
} while (pageNum < nrDumpedPages);
all_bitmaps_read:
if(debug)
printf("Mem Offset: %llx\n", (long long)memoryStartRecord);
dump_seek(fh, (fmbkRecord.rec_nr_fir-1)* 0x1000, SEEK_SET);
dump_read(&fir64Record, sizeof(fir64Record), 1, fh);
fir64OtherRecords = new _fir_other_64[fir64Record.online_cpus];
for (i=0; i < fir64Record.online_cpus; i++) {
/* fir other */
dump_read(&fir64OtherRecords[i], sizeof(fir64OtherRecords[i]),
1, fh);
}
if(debug)
printDebug();
}
void VMDump64Big::printDebug(void)
{
int i;
VMDump::printDebug();
printf("prefix: %x\n", fir64Record.prefix);
printf("cpus: %x\n", fir64Record.online_cpus);
printf("psw: %016llx %016llx\n", (long long)fir64Record.psw[0],
(long long)fir64Record.psw[1]);
for (i=0; i < fir64Record.online_cpus; i++) {
/* fir other */
printf("prefix (%i): %x\n", i, fir64OtherRecords[i].prefix);
}
}
void VMDump64Big::printInfo(void)
{
fprintf(stderr, "vmdump information:\n");
fprintf(stderr, " architecture: 64 bit (big)\n");
fprintf(stderr, " storage.....: %lli MB\n",
(long long)asibkRecordNew.storage_size_def_store / (1024*1024));
VMDump::printInfo();
fprintf(stderr, " cpus........: %x\n", fir64Record.online_cpus + 1);
}
RegisterContent64 VMDump64Big::getRegisterContent(void)
{
RegisterContent64 rc;
RegisterSet64 rs;
int cpu;
/* First CPU */
memcpy(&rs.gprs, &fir64Record.gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir64Record.crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir64Record.acrs, sizeof(rs.acrs));
memcpy(&rs.psw, &fir64Record.psw, sizeof(rs.psw));
memcpy(&rs.prefix, &fir64Record.prefix, sizeof(rs.prefix));
memcpy(&rs.fprs, &fir64Record.fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir64Record.cpu_timer, sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir64Record.clock_cmp, sizeof(rs.clkCmp));
memcpy(&rs.fpCr, &fir64Record.fp_cntrl_reg, sizeof(rs.fpCr));
rc.addRegisterSet(rs);
/* other online cpus */
for(cpu = 0; cpu < fir64Record.online_cpus; cpu++) {
memcpy(&rs.gprs, &fir64OtherRecords[cpu].gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir64OtherRecords[cpu].crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir64OtherRecords[cpu].acrs, sizeof(rs.acrs));
memcpy(&rs.psw, &fir64OtherRecords[cpu].psw, sizeof(rs.psw));
memcpy(&rs.prefix, &fir64OtherRecords[cpu].prefix,
sizeof(rs.prefix));
memcpy(&rs.fprs, &fir64OtherRecords[cpu].fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir64OtherRecords[cpu].cpu_timer,
sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir64OtherRecords[cpu].clock_cmp,
sizeof(rs.clkCmp));
memcpy(&rs.fpCr, &fir64OtherRecords[cpu].fp_cntrl_reg,
sizeof(rs.fpCr));
rc.addRegisterSet(rs);
}
return rc;
}
VMDump64Big::~VMDump64Big(void)
{
delete bitmap;
delete fir64OtherRecords;
}
+478
View File
@@ -0,0 +1,478 @@
/*
* vmdump - z/VM dump conversion library
*
* Register content classes:
* VMDump, VMDumpClassic, VMDump64, VMDump64Big, VMDump32
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
/*===========================*
* The format of an vmdump: *
*===========================*
*---------------------------*
* Symptom Record *
* (ADSR COPY) Record 1 *
*---------------------------*
* Dump File Map Record *
* (HCPDFMBK COPY) Record 2 *
*---------------------------*
* Dump File Info Record *
* (HCPDFIR COPY) Records 3-7*
*---------------------------*
* Vector Registers *
* (optional) *
*---------------------------*
* Access Lists (HCPDALBK) *
*---------------------------*
* Address Space A *
* Information and Map *
* Record (HCPASIBK) *
*---------------------------*
* Address Space A *
* Bit Maps *
*---------------------------*
* Address Space A *
* Key Maps *
*---------------------------*
* Address Space A *
* Guest Storage *
*---------------------------*
* Additional Address Spaces *
* ASIBK *
* Bit Maps *
* Key Maps *
* Guest Storage *
* *NOTE* These probably *
* aren't in a Linux guest. *
*---------------------------*
*/
#ifndef VMDUMP_H
#define VMDUMP_H
#include <iconv.h>
#include <string.h>
#include "lib/zt_common.h"
#include "dump.h"
#include "register_content.h"
class VMDump : public Dump
{
public:
VMDump(const char *filename);
virtual ~VMDump(void);
virtual void readMem(char *buf, int size);
virtual int seekMem(uint64_t offset);
virtual struct timeval getDumpTime(void) const;
void printDebug(void);
void printInfo(void);
static DumpType getDumpType(const char *);
inline int testPage(uint64_t bit) const
{
return (bitmap[bit/8] & (1 << (7-(bit % 8))));
}
inline void setPageBit(uint64_t bit) const
{
bitmap[bit/8] |= (1 << (7-(bit % 8)));
}
protected:
/* Types */
struct _adsr {
/* Section 1*/
uint16_t sr;
uint32_t cpu_model;
char cpu_serial[6];
uint32_t time_zone_conversion_factor;
uint64_t tod;
char time_stamp_str[4];
char date_str[6];
char node_name[8];
char product_id[4];
char feature_level[8];
uint8_t record_status_flag1;
uint8_t record_status_flag2;
uint64_t dump_type;
/* Section 2*/
char arch_level[2];
uint16_t sec2_len;
uint16_t sec2_1_len;
uint16_t sec2_1_offset;
uint16_t sec3_len;
uint16_t sec3_offset;
uint16_t sec4_len;
uint16_t sec4_offset;
uint16_t sec5_len;
uint16_t sec5_offset;
uint16_t sec6_len;
uint16_t sec6_offset;
} __packed;
struct _fmbk {
char id[8];
uint32_t rec_nr_fir;
uint32_t rec_nr_vector;
uint32_t rec_nr_access;
uint32_t num_acc_recs;
uint32_t num_addr_spaces;
uint32_t rec_nr_asibk;
} __packed;
struct _fir_basic {
char filler1[15];
uint8_t dump_format;/* 0x1 for big storage dump, 0x2 for cp */
/* hard abend, 0x3 for cp soft abend */
char filler2[171];
uint8_t fir_format; /* 0x2 for big esame, 0x82 for esame, */
/* 0x00 for esa */
} __packed;
struct _albk {
char id[8];
} __packed;
/* Methods */
inline void ebcAsc(char *inout, size_t len) const
{
iconv(ebcdicAsciiConv, &inout, &len, &inout, &len);
}
/* Members */
struct _adsr adsrRecord;
struct _fmbk fmbkRecord;
struct _albk albkRecord;
uint64_t memoryStartRecord;
char *bitmap;
uint64_t pageOffset;
private:
iconv_t ebcdicAsciiConv;
};
class VMDumpClassic : public VMDump
{
public:
VMDumpClassic(const char *filename);
virtual ~VMDumpClassic(void);
void printInfo(void);
inline virtual uint64_t getMemSize(void) const
{
return (uint64_t)asibkRecord.storage_size_2GB;
}
protected:
/* Types */
struct _asibk {
char id[8];
char as_token[8];
char spaceid[33];
char reserved1[3];
uint32_t storage_size_2GB;
uint32_t dcss_bitmap_first_rec;
uint32_t byte_past_highest_defined_byte;
uint64_t format_of_as;
char dump_id[100];
uint32_t nr_of_recs_of_first_bit_map;
} __packed;
/* Members */
struct _asibk asibkRecord;
};
#define MAX_BKEY_PAGES 2
class VMDump64Big : public VMDump
{
public:
VMDump64Big(const char *filename);
virtual ~VMDump64Big(void);
RegisterContent64 getRegisterContent(void);
void printDebug(void);
void printInfo(void);
inline virtual uint64_t getMemSize(void) const
{
return (uint64_t)asibkRecordNew.storage_size_def_store;
}
private:
inline int testBitmapPage(char *page, uint64_t bit) const
{
return (page[bit/8] & (1 << (7-(bit % 8))));
}
inline int testBitmapKeyPage(char *page, uint64_t bit) const
{
return (page[bit] & 0x01);
}
/* types */
struct _asibk_64_new {
char id[8];
char as_token[8];
char spaceid[33];
char reserved1[2];
uint8_t asibk_format;
char filler1[12];
uint64_t storage_size_with_dcss;
uint64_t storage_size_def_store;
char filler2[136];
uint64_t online_storage_table[8]; /* for "def store config" */
uint64_t fence1;
uint64_t requested_range_table[8];
uint64_t fence2;
uint32_t record_number_of_first_bit_map; /* XXX */
} __packed;
struct _fir_64 {
char id[8];
uint64_t reserved1;
uint64_t gprs[16];
uint32_t prefix;
char reserved2[5];
uint64_t tod;
char reserved3[8];
uint64_t cpu_timer;
char reserved4[7];
uint8_t flag;
uint8_t type;
uint8_t complete;
uint8_t fir_format; /* 0x82 for esame - 0x00 for esa */
uint8_t cont_flags;
uint8_t crypto_domain_index_reg;
uint8_t virt_cpu_info;
uint8_t arch_mode_id;
uint64_t psw[2];
uint64_t crs[16];
uint64_t fprs[16];
uint8_t reserved5;
uint64_t clock_cmp;
char reserved6[3];
uint32_t tod_programmable_reg;
uint32_t reserved_for_dvf[20];
uint32_t acrs[16];
uint32_t storage_size_2GB;
uint32_t reserved7;
uint32_t hcpsys_addr;
uint32_t reserved8;
uint64_t storage_size;
uint32_t snap_area_map_blk;
uint32_t reserved9;
char loc_mem[256];
uint16_t online_cpus;
uint16_t cpu_addr;
uint16_t section_size_vector;
uint16_t reserved10;
char asit_primary[8];
char space_id_primary[33];
char reserved12[3];
uint16_t crypto_domain_index_mask;
uint16_t reserved11;
uint32_t fp_cntrl_reg;
uint32_t reserved13;
uint64_t reserved14[16];
} __packed;
struct _fir_other_64 {
uint16_t cpu_addr;
uint16_t vector_sec_size;
uint8_t crypto_index_reg;
uint8_t virt_cpu_info;
uint16_t crypto_index_mask;
uint32_t reserved1[2];
uint64_t fprs[16];
uint64_t gprs[16];
uint64_t psw[2];
uint32_t reserved2[2];
uint32_t prefix;
uint32_t fp_cntrl_reg;
uint32_t reserved3;
uint32_t tod;
uint64_t cpu_timer;
uint64_t clock_cmp;
uint32_t reserved4[2];
uint32_t acrs[16];
uint64_t crs[16];
uint64_t mc_interrupt_code;
uint32_t reserved5;
uint32_t external_damage_code;
uint64_t mc_failing_storage_addr;
} __packed;
/* Members */
struct _asibk_64_new asibkRecordNew;
struct _fir_64 fir64Record;
struct _fir_other_64 *fir64OtherRecords;
};
class VMDump64 : public VMDumpClassic
{
public:
VMDump64(const char *filename);
virtual ~VMDump64(void);
RegisterContent64 getRegisterContent(void);
void printDebug(void);
void printInfo(void);
private:
/* Types */
struct _fir_64 {
char id[8];
uint64_t reserved1;
uint64_t gprs[16];
uint32_t prefix;
char reserved2[5];
uint64_t tod;
char reserved3[8];
uint64_t cpu_timer;
char reserved4[7];
uint8_t flag;
uint8_t type;
uint8_t complete;
uint8_t fir_format; /* 0x82 for esame - 0x00 for esa */
uint8_t cont_flags;
uint8_t crypto_domain_index_reg;
uint8_t virt_cpu_info;
uint8_t arch_mode_id;
uint64_t psw[2];
uint64_t crs[16];
uint64_t fprs[16];
uint8_t reserved5;
uint64_t clock_cmp;
char reserved6[3];
uint32_t tod_programmable_reg;
uint32_t reserved_for_dvf[20];
uint32_t acrs[16];
uint32_t storage_size_2GB;
uint32_t reserved7;
uint32_t hcpsys_addr;
uint32_t reserved8;
uint64_t storage_size;
uint32_t snap_area_map_blk;
uint32_t reserved9;
char loc_mem[256];
uint16_t online_cpus;
uint16_t cpu_addr;
uint16_t section_size_vector;
uint16_t reserved10;
char asit_primary[8];
char space_id_primary[33];
char reserved12[3];
uint16_t crypto_domain_index_mask;
uint16_t reserved11;
uint32_t fp_cntrl_reg;
uint32_t reserved13;
uint64_t reserved14[16];
} __packed;
struct _fir_other_64 {
uint16_t cpu_addr;
uint16_t vector_sec_size;
uint8_t crypto_index_reg;
uint8_t virt_cpu_info;
uint16_t crypto_index_mask;
uint32_t reserved1[2];
uint64_t fprs[16];
uint64_t gprs[16];
uint64_t psw[2];
uint32_t reserved2[2];
uint32_t prefix;
uint32_t fp_cntrl_reg;
uint32_t reserved3;
uint32_t tod;
uint64_t cpu_timer;
uint64_t clock_cmp;
uint32_t reserved4[2];
uint32_t acrs[16];
uint64_t crs[16];
uint64_t mc_interrupt_code;
uint32_t reserved5;
uint32_t external_damage_code;
uint64_t mc_failing_storage_addr;
} __packed;
/* Members */
struct _fir_64 fir64Record;
struct _fir_other_64 *fir64OtherRecords;
};
class VMDump32 : public VMDumpClassic
{
public:
VMDump32(const char *filename);
virtual ~VMDump32(void);
RegisterContent32 getRegisterContent(void);
void printDebug(void);
void printInfo(void);
private:
/* Types */
struct _fir_32 {
uint32_t gprs[16];
uint32_t crs[16];
uint64_t fprs[4];
uint64_t tod;
uint64_t cpu_timer;
uint64_t clock_cmp;
uint8_t flag;
uint8_t type;
uint8_t complete;
uint8_t fir_format;
uint32_t storage_size_2GB;
char loc_mem[256];
uint32_t prefix;
uint16_t online_cpus;
uint8_t cont_flags;
uint8_t crypto_domain_index_reg;
uint8_t virt_cpu_info;
uint8_t arch_mode_id;
uint16_t crypto_domain_index_mask;
uint32_t reserved1;
uint32_t snap_area_map_blk;
uint64_t reserved2;
uint32_t hcpsys_addr;
uint32_t reserved3[20];
uint32_t psw[2];
uint16_t cpu_addr;
uint16_t section_size_vector;
uint32_t acrs[16];
char asit_primary[8];
char space_id_primary[33];
char reserved4[131];
} __packed;
struct _fir_other_32 {
uint16_t cpu_addr;
uint16_t vector_sec_size;
uint32_t prefix;
uint8_t crypto_index_reg;
uint8_t virt_cpu_info;
uint16_t crypto_index_mask;
uint32_t reserved1;
uint64_t cpu_timer;
uint64_t clock_cmp;
uint64_t mc_interrupt_code;
uint64_t reserved2;
uint32_t mc_failing_storage_addr;
uint32_t machine_dependent_region_code;
uint32_t lixed_logout_area[4];
char reserved3[16];
uint32_t acrs[16];
uint64_t fprs[4];
uint32_t gprs[16];
uint32_t crs[16];
} __packed;
/* Members */
struct _fir_32 fir32Record;
struct _fir_other_32 *fir32OtherRecords;
};
#endif /* VMDUMP_H */
+72
View File
@@ -0,0 +1,72 @@
/*
* vmdump - z/VM dump conversion library
*
* Dump convert function: Converts VMDUMP to LKCD dump
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "lkcd_dump.h"
#include "vm_dump.h"
int vmdump_convert(const char* inputFileName, const char* outputFileName,
const char* progName)
{
/* Do the conversion */
try {
switch(VMDump::getDumpType(inputFileName)){
case Dump::DT_VM64_BIG:
{
LKCDDump64* lkcddump;
VMDump64Big* vmdump;
vmdump = new VMDump64Big(inputFileName);
vmdump->printInfo();
lkcddump = new LKCDDump64(vmdump,
vmdump->getRegisterContent());
lkcddump->writeDump(outputFileName);
delete vmdump;
delete lkcddump;
break;
}
case Dump::DT_VM64:
{
LKCDDump64* lkcddump;
VMDump64* vmdump;
vmdump = new VMDump64(inputFileName);
vmdump->printInfo();
lkcddump = new LKCDDump64(vmdump,
vmdump->getRegisterContent());
lkcddump->writeDump(outputFileName);
delete vmdump;
delete lkcddump;
break;
}
case Dump::DT_VM32:
{
LKCDDump32* lkcddump;
VMDump32* vmdump;
vmdump = new VMDump32(inputFileName);
vmdump->printInfo();
lkcddump = new LKCDDump32(vmdump,
vmdump->getRegisterContent());
lkcddump->writeDump(outputFileName);
delete vmdump;
delete lkcddump;
break;
}
default:
throw DumpException("This is not a vmdump");
}
} catch (DumpException ex) {
printf("%s: %s\n", progName, ex.what());
fflush(stdout);
return 1;
}
return 0;
}