Add .gitignore file
[s390-tools.git] / vmconvert / vm_dump.cpp
blobeb5366f79be43e937ded3399d9f8c2f2bbbf5c06
1 /*
2 * vm_dump.cpp
3 * vmdump classes:
4 * - VMDump
5 * - VMDumpClassic
6 * - VMDump64
7 * - VMDump64Big
8 * - VMDump32
10 * Copyright IBM Corp. 2004, 2006.
12 * Author(s): Michael Holzheu
15 #include <time.h>
16 #include <ctype.h>
17 #include "vm_dump.h"
19 Dump::DumpType
20 VMDump::getDumpType(const char* inputFileName)
22 FILE* fh;
23 struct _fmbk fmbk;
24 struct _fir_basic fir;
25 char fmbk_id[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
26 char msg[200];
28 fh = fopen(inputFileName,"r");
29 if(!fh) {
30 sprintf(msg,"Could not open '%s'",inputFileName);
31 throw DumpErrnoException(msg);
34 /* Record 2: fmbk */
35 dump_seek(fh,0x1000,SEEK_SET);
36 if(fread(&fmbk,sizeof(fmbk),1,fh) != 1) {
37 if(ferror(fh)) {
38 sprintf(msg,"Could not read header of vmdump '%s'",
39 inputFileName);
40 fclose(fh);
41 throw DumpErrnoException(msg);
42 } else{
43 sprintf(msg,"Input file '%s' is not a vmdump",
44 inputFileName);
45 fclose(fh);
46 throw DumpException(msg);
50 /* Check if this is a vmdump */
51 if(memcmp(fmbk.id, fmbk_id, 8) != 0) {
52 fclose(fh);
53 sprintf(msg,"Input file '%s' is not a vmdump",inputFileName);
54 throw DumpException(msg);
57 /* Record 3-7: fir */
58 dump_seek(fh,(fmbk.rec_nr_fir-1)* 0x1000,SEEK_SET);
59 if(fread(&fir,sizeof(fir),1,fh) != 1) {
60 if(ferror(fh)) {
61 sprintf(msg,"Could not read header of vmdump '%s'",
62 inputFileName);
63 fclose(fh);
64 throw DumpErrnoException(msg);
66 else{
67 sprintf(msg,"Could not read header of vmdump '%s'",
68 inputFileName);
69 fclose(fh);
70 throw DumpException(msg);
73 fclose(fh);
74 if(fir.fir_format == 0) {
75 return DT_VM32;
76 } else if(fir.fir_format == 0x02) {/*XXX && (fir.dump_format == 0x1))*/
77 return DT_VM64_BIG;
78 } else if(fir.fir_format == 0x82) {
79 return DT_VM64;
80 } else {
81 return DT_UNKNOWN;
85 VMDump::VMDump(const char *fileName) : Dump(fileName, "rb")
87 char fmbk_id[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
89 ebcdicAsciiConv = iconv_open("ISO-8859-1", "EBCDIC-US");
91 /* Record 1: adsrRecord */
93 dump_seek(fh,0,SEEK_SET);
94 dump_read(&adsrRecord,sizeof(adsrRecord),1,fh);
96 if(debug) {
97 char buf[1024];
98 int i;
100 dump_seek(fh,adsrRecord.sec3_offset,SEEK_SET);
101 dump_read(buf, adsrRecord.sec3_len,1,fh);
102 ebcAsc(buf,adsrRecord.sec3_len);
103 for(i=0; i < adsrRecord.sec3_len; i++) {
104 if((buf[i]==0) || iscntrl(buf[i]))
105 buf[i]=' ';
107 buf[adsrRecord.sec3_len]=0;
108 printf("symptom string1: %s\n",buf);
111 /* Record 2: fmbk */
113 dump_seek(fh,0x1000,SEEK_SET);
114 dump_read(&fmbkRecord,sizeof(fmbkRecord),1,fh);
116 /* Check if this is a vmdump */
117 if(memcmp(fmbkRecord.id, fmbk_id, 8) != 0) {
118 throw DumpException("Input file is not a vmdump");
121 /* Record 3-7: fir records read by subclasses */
123 /* Record 8: albk */
125 dump_seek(fh,(fmbkRecord.rec_nr_access-1)*0x1000 ,SEEK_SET);
126 dump_read(&albkRecord,sizeof(albkRecord),1,fh);
130 struct timeval
131 VMDump::getDumpTime(void) const
133 struct timeval rc;
134 s390TodToTimeval(adsrRecord.tod,&rc);
135 return rc;
138 void
139 VMDump::printDebug(void)
141 struct timeval time;
142 s390TodToTimeval(adsrRecord.tod,&time);
143 char buf[1024];
145 /* adsr */
147 printf("time : %s\n",ctime(&time.tv_sec));
148 printf("stat1 : %x\n",adsrRecord.record_status_flag1);
149 printf("stat2 : %x\n",adsrRecord.record_status_flag2);
150 printf("sec 2 len: %i\n",adsrRecord.sec2_len);
151 printf("sec 2.1 len: %i/%i\n",adsrRecord.sec2_1_len,
152 adsrRecord.sec2_1_offset);
153 printf("sec 3 len: %i/%i\n",adsrRecord.sec3_len,
154 adsrRecord.sec3_offset);
155 printf("sec 4 len: %i/%i\n",adsrRecord.sec4_len,
156 adsrRecord.sec4_offset);
157 printf("sec 5 len: %i/%i\n",adsrRecord.sec5_len,
158 adsrRecord.sec5_offset);
159 printf("sec 6 len: %i/%i\n",adsrRecord.sec6_len,
160 adsrRecord.sec6_offset);
162 /* fmbk */
164 ebcAsc(fmbkRecord.id,sizeof(fmbkRecord.id));
165 fmbkRecord.id[7] = 0;
166 printf("id : %s\n",fmbkRecord.id);
167 printf("fir rec nr: %i\n",fmbkRecord.rec_nr_fir);
168 printf("vec rec nr: %i\n",fmbkRecord.rec_nr_vector);
169 printf("access rec nr: %i\n",fmbkRecord.rec_nr_access);
172 /* albk */
174 memcpy(buf,albkRecord.id,sizeof(albkRecord.id));
175 ebcAsc(buf,sizeof(albkRecord.id));
176 buf[8]=0;
177 printf("ALBK id : %s\n",buf);
179 /* asibk */
182 memcpy(buf,asibkRecord.id,sizeof(asibkRecord.id));
183 ebcAsc(buf,sizeof(asibkRecord.id));
184 asibkRecord.id[8]=0;
185 printf("ASIBK id : %s\n",buf);
186 printf("storage : %x\n",asibkRecord.storage_size_2GB);
187 printf("bitmapsrecs : %i\n",asibkRecord.nr_of_recs_of_first_bit_map);
191 void
192 VMDump::printInfo(void)
194 struct timeval time;
195 s390TodToTimeval(adsrRecord.tod,&time);
197 fprintf(stderr, " date........: %s",ctime(&time.tv_sec));
201 VMDump::seekMem(uint64_t offset)
203 if(offset != 0) {
204 return -1;
206 pageOffset = 0;
207 return 0;
210 void
211 VMDump::readMem(char* buf, int size)
213 int i;
215 if(pageOffset == 0)
216 dump_seek(fh, memoryStartRecord, SEEK_SET);
218 if(size % 0x1000 != 0) {
219 throw(DumpException("internal error: VMDump::readMem() "\
220 "can only handle sizes which are multiples of page size"));
223 for(i = 0; i < size; i += 0x1000) {
224 if(testPage(pageOffset)) {
225 dump_read(buf + i, 0x1000,1,fh);
226 } else {
227 memset(buf + i, 0, 0x1000);
229 pageOffset += 1;
233 VMDump::~VMDump(void)
237 /*****************************************************************************/
238 /* VMDumpClassic: traditional 32/64 bit vmdump (before z/VM 5.2) */
239 /*****************************************************************************/
241 VMDumpClassic::VMDumpClassic(const char *fileName) : VMDump(fileName)
243 int storageKeyPages,bitMapPages;
245 pageOffset = 0;
247 /* Record 9: asibk */
249 dump_seek(fh,fmbkRecord.rec_nr_access * 0x1000,SEEK_SET);
250 dump_read(&asibkRecord,sizeof(asibkRecord),1,fh);
252 /* Record 10: bitmaps */
254 dump_seek(fh,(fmbkRecord.rec_nr_access + 1)* 0x1000 ,SEEK_SET);
255 bitmap = new char[asibkRecord.storage_size_2GB / (0x1000 * 8)];
256 dump_read(bitmap,asibkRecord.storage_size_2GB / (0x1000*8),1,fh);
258 bitMapPages=asibkRecord.storage_size_2GB / (0x1000 * 8);
259 if(bitMapPages % 0x1000 != 0)
260 bitMapPages = bitMapPages/0x1000 + 1;
261 else
262 bitMapPages = bitMapPages/0x1000;
264 storageKeyPages=asibkRecord.storage_size_2GB / 0x1000;
265 if(storageKeyPages % 0x1000 != 0) {
266 storageKeyPages = storageKeyPages/0x1000 + 1;
267 } else {
268 storageKeyPages = storageKeyPages/0x1000;
271 /* skip storage keys */
273 memoryStartRecord = (fmbkRecord.rec_nr_access + 1) *0x1000 /* 0x9000 */
274 + (bitMapPages + storageKeyPages)*0x1000;
275 if(debug) {
276 printf("Mem Offset: %llx\n",(long long)memoryStartRecord);
280 void
281 VMDumpClassic::printInfo(void)
283 VMDump::printInfo();
284 fprintf(stderr, " storage.....: %i MB\n",
285 asibkRecord.storage_size_2GB/(1024*1024));
288 VMDumpClassic::~VMDumpClassic(void)
290 delete bitmap;
294 /*****************************************************************************/
295 /* VMDump32: 32 bit vmdump */
296 /*****************************************************************************/
298 VMDump32::VMDump32(const char* filename) : VMDumpClassic(filename)
300 int i;
302 if(!fh) {
303 return;
306 dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
307 dump_read(&fir32Record,sizeof(fir32Record),1,fh);
309 fir32OtherRecords = new _fir_other_32[fir32Record.online_cpus];
310 for(i=0; i < fir32Record.online_cpus; i++) {
311 /* fir other */
312 dump_read(&fir32OtherRecords[i],sizeof(fir32OtherRecords[i]),1,
313 fh);
315 if(debug)
316 printDebug();
319 RegisterContent32
320 VMDump32::getRegisterContent(void)
322 RegisterContent32 rc;
323 RegisterSet32 rs;
324 int cpu;
326 /* First CPU */
328 memcpy(&rs.gprs, &fir32Record.gprs, sizeof(rs.gprs));
329 memcpy(&rs.crs, &fir32Record.crs, sizeof(rs.crs));
330 memcpy(&rs.acrs, &fir32Record.acrs, sizeof(rs.acrs));
331 memcpy(&rs.psw, &fir32Record.psw, sizeof(rs.psw));
332 memcpy(&rs.prefix, &fir32Record.prefix, sizeof(rs.prefix));
333 memcpy(&rs.fprs, &fir32Record.fprs, sizeof(rs.fprs));
334 memcpy(&rs.cpuTimer, &fir32Record.cpu_timer, sizeof(rs.cpuTimer));
335 memcpy(&rs.clkCmp, &fir32Record.clock_cmp, sizeof(rs.clkCmp));
337 rc.addRegisterSet(rs);
339 /* other online cpus */
341 for(cpu = 0; cpu < fir32Record.online_cpus; cpu++) {
342 memcpy(&rs.gprs, &fir32OtherRecords[cpu].gprs, sizeof(rs.gprs));
343 memcpy(&rs.crs, &fir32OtherRecords[cpu].crs, sizeof(rs.crs));
344 memcpy(&rs.acrs, &fir32OtherRecords[cpu].acrs, sizeof(rs.acrs));
345 /* no psw for ESA vmdumps */
346 rs.psw[0] = 0xdeadbeef;
347 rs.psw[1] = 0xdeadbeef;
348 memcpy(&rs.prefix, &fir32OtherRecords[cpu].prefix,
349 sizeof(rs.prefix));
350 memcpy(&rs.fprs, &fir32OtherRecords[cpu].fprs, sizeof(rs.fprs));
351 memcpy(&rs.cpuTimer, &fir32OtherRecords[cpu].cpu_timer,
352 sizeof(rs.cpuTimer));
353 memcpy(&rs.clkCmp, &fir32OtherRecords[cpu].clock_cmp,
354 sizeof(rs.clkCmp));
355 rc.addRegisterSet(rs);
357 return rc;
361 void
362 VMDump32::printDebug(void)
364 int i;
365 VMDump::printDebug();
366 printf("prefix: %x\n",fir32Record.prefix);
367 printf("cpus: %x\n",fir32Record.online_cpus);
368 printf("psw: %08x %08x\n",fir32Record.psw[0],fir32Record.psw[1]);
370 for(i=0; i < fir32Record.online_cpus; i++) {
371 /* fir other */
372 printf("prefix (%i): %x\n",i,fir32OtherRecords[i].prefix);
376 void
377 VMDump32::printInfo(void)
379 fprintf(stderr, "vmdump information:\n");
380 fprintf(stderr, " architecture: 32 bit\n");
381 VMDumpClassic::printInfo();
382 fprintf(stderr, " cpus........: %x\n",fir32Record.online_cpus + 1);
386 VMDump32::~VMDump32(void)
388 delete fir32OtherRecords;
392 /*****************************************************************************/
393 /* VMDump64: 64 bit vmdump for old vmdump format (z/VM < 5.2) */
394 /*****************************************************************************/
396 VMDump64::VMDump64(const char* filename) : VMDumpClassic(filename)
398 int i;
400 if(!fh) {
401 return;
404 dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
405 dump_read(&fir64Record,sizeof(fir64Record),1,fh);
407 fir64OtherRecords = new _fir_other_64[fir64Record.online_cpus];
408 for(i=0; i < fir64Record.online_cpus; i++) {
409 /* fir other */
410 dump_read(&fir64OtherRecords[i],sizeof(fir64OtherRecords[i]),1,
411 fh);
413 if(debug)
414 printDebug();
417 void
418 VMDump64::printDebug(void)
420 int i;
421 VMDump::printDebug();
422 printf("prefix: %x\n",fir64Record.prefix);
423 printf("cpus: %x\n",fir64Record.online_cpus);
424 printf("psw: %016llx %016llx\n",(long long)fir64Record.psw[0],
425 (long long)fir64Record.psw[1]);
427 for(i=0; i < fir64Record.online_cpus; i++) {
428 /* fir other */
429 printf("prefix (%i): %x\n",i,fir64OtherRecords[i].prefix);
433 void
434 VMDump64::printInfo(void)
436 fprintf(stderr, "vmdump information:\n");
437 fprintf(stderr, " architecture: 64 bit\n");
438 VMDumpClassic::printInfo();
439 fprintf(stderr, " cpus........: %x\n",fir64Record.online_cpus + 1);
443 RegisterContent64
444 VMDump64::getRegisterContent(void)
446 RegisterContent64 rc;
447 RegisterSet64 rs;
448 int cpu;
450 /* First CPU */
452 memcpy(&rs.gprs, &fir64Record.gprs, sizeof(rs.gprs));
453 memcpy(&rs.crs, &fir64Record.crs, sizeof(rs.crs));
454 memcpy(&rs.acrs, &fir64Record.acrs, sizeof(rs.acrs));
455 memcpy(&rs.psw, &fir64Record.psw, sizeof(rs.psw));
456 memcpy(&rs.prefix, &fir64Record.prefix, sizeof(rs.prefix));
457 memcpy(&rs.fprs, &fir64Record.fprs, sizeof(rs.fprs));
458 memcpy(&rs.cpuTimer, &fir64Record.cpu_timer, sizeof(rs.cpuTimer));
459 memcpy(&rs.clkCmp, &fir64Record.clock_cmp, sizeof(rs.clkCmp));
460 memcpy(&rs.fpCr, &fir64Record.fp_cntrl_reg, sizeof(rs.fpCr));
462 rc.addRegisterSet(rs);
464 /* other online cpus */
466 for(cpu = 0; cpu < fir64Record.online_cpus; cpu++) {
467 memcpy(&rs.gprs, &fir64OtherRecords[cpu].gprs, sizeof(rs.gprs));
468 memcpy(&rs.crs, &fir64OtherRecords[cpu].crs, sizeof(rs.crs));
469 memcpy(&rs.acrs, &fir64OtherRecords[cpu].acrs, sizeof(rs.acrs));
470 memcpy(&rs.psw, &fir64OtherRecords[cpu].psw, sizeof(rs.psw));
471 memcpy(&rs.prefix, &fir64OtherRecords[cpu].prefix,
472 sizeof(rs.prefix));
473 memcpy(&rs.fprs, &fir64OtherRecords[cpu].fprs, sizeof(rs.fprs));
474 memcpy(&rs.cpuTimer, &fir64OtherRecords[cpu].cpu_timer,
475 sizeof(rs.cpuTimer));
476 memcpy(&rs.clkCmp, &fir64OtherRecords[cpu].clock_cmp,
477 sizeof(rs.clkCmp));
478 memcpy(&rs.fpCr, &fir64OtherRecords[cpu].fp_cntrl_reg,
479 sizeof(rs.fpCr));
480 rc.addRegisterSet(rs);
482 return rc;
485 VMDump64::~VMDump64(void)
487 delete fir64OtherRecords;
490 /*****************************************************************************/
491 /* VMDump64Big: 64 bit vmdump with new big storage dump format */
492 /*****************************************************************************/
494 VMDump64Big::VMDump64Big(const char* filename) : VMDump(filename)
496 int i,j;
497 uint64_t pageNum, nrDumpedPages;
499 if(!fh) {
500 return;
503 /* Record 9: asibk */
505 dump_seek(fh,fmbkRecord.rec_nr_access * 0x1000,SEEK_SET);
506 dump_read(&asibkRecordNew,sizeof(asibkRecordNew),1,fh);
508 /* Record 10: bitmaps: */
509 /* Read all bitmap pages and setup bitmap array */
511 pageNum = 0;
512 nrDumpedPages = asibkRecordNew.storage_size_def_store / 0x1000;
513 memoryStartRecord = (fmbkRecord.rec_nr_access + 1) * 0x1000;
514 bitmap = new char[asibkRecordNew.storage_size_def_store/(0x1000 * 8)];
515 if(!bitmap) {
516 throw(DumpErrnoException("out of memory"));
518 memset(bitmap,0,asibkRecordNew.storage_size_def_store/(0x1000 * 8));
520 dump_seek(fh,(fmbkRecord.rec_nr_access + 1)* 0x1000 ,SEEK_SET);
522 do {
523 char bmIndexPage[0x1000];
524 dump_read(bmIndexPage,sizeof(bmIndexPage),1,fh);
525 memoryStartRecord += 0x1000;
526 for(i=0; i < 0x1000; i++) {
527 if(testBitmapPage(bmIndexPage,i)) {
528 char bmPage[0x1000];
529 dump_read(bmPage,sizeof(bmPage),1,fh);
530 memoryStartRecord += 0x1000;
531 for(j = 0; j < 0x1000; j++) {
532 if(testBitmapKeyPage(bmPage, j)) {
533 setPageBit(pageNum);
535 pageNum++;
536 if(pageNum == nrDumpedPages) {
537 goto all_bitmaps_read;
540 } else {
541 pageNum += 0x1000; // empty pages
544 } while (pageNum < nrDumpedPages);
546 all_bitmaps_read:
548 if(debug)
549 printf("Mem Offset: %llx\n",(long long)memoryStartRecord);
551 dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
552 dump_read(&fir64Record,sizeof(fir64Record),1,fh);
554 fir64OtherRecords = new _fir_other_64[fir64Record.online_cpus];
555 for(i=0; i < fir64Record.online_cpus; i++) {
556 /* fir other */
557 dump_read(&fir64OtherRecords[i],sizeof(fir64OtherRecords[i]),1,
558 fh);
560 if(debug)
561 printDebug();
564 void
565 VMDump64Big::printDebug(void)
567 int i;
568 VMDump::printDebug();
569 printf("prefix: %x\n",fir64Record.prefix);
570 printf("cpus: %x\n",fir64Record.online_cpus);
571 printf("psw: %016llx %016llx\n",(long long)fir64Record.psw[0],
572 (long long)fir64Record.psw[1]);
574 for(i=0; i < fir64Record.online_cpus; i++) {
575 /* fir other */
576 printf("prefix (%i): %x\n",i,fir64OtherRecords[i].prefix);
580 void
581 VMDump64Big::printInfo(void)
583 fprintf(stderr, "vmdump information:\n");
584 fprintf(stderr, " architecture: 64 bit (big)\n");
585 fprintf(stderr, " storage.....: %lli MB\n",
586 (long long)asibkRecordNew.storage_size_def_store / (1024*1024));
587 VMDump::printInfo();
588 fprintf(stderr, " cpus........: %x\n",fir64Record.online_cpus + 1);
592 RegisterContent64
593 VMDump64Big::getRegisterContent(void)
595 RegisterContent64 rc;
596 RegisterSet64 rs;
597 int cpu;
599 /* First CPU */
601 memcpy(&rs.gprs, &fir64Record.gprs, sizeof(rs.gprs));
602 memcpy(&rs.crs, &fir64Record.crs, sizeof(rs.crs));
603 memcpy(&rs.acrs, &fir64Record.acrs, sizeof(rs.acrs));
604 memcpy(&rs.psw, &fir64Record.psw, sizeof(rs.psw));
605 memcpy(&rs.prefix, &fir64Record.prefix, sizeof(rs.prefix));
606 memcpy(&rs.fprs, &fir64Record.fprs, sizeof(rs.fprs));
607 memcpy(&rs.cpuTimer, &fir64Record.cpu_timer, sizeof(rs.cpuTimer));
608 memcpy(&rs.clkCmp, &fir64Record.clock_cmp, sizeof(rs.clkCmp));
609 memcpy(&rs.fpCr, &fir64Record.fp_cntrl_reg, sizeof(rs.fpCr));
611 rc.addRegisterSet(rs);
613 /* other online cpus */
615 for(cpu = 0; cpu < fir64Record.online_cpus; cpu++) {
616 memcpy(&rs.gprs, &fir64OtherRecords[cpu].gprs, sizeof(rs.gprs));
617 memcpy(&rs.crs, &fir64OtherRecords[cpu].crs, sizeof(rs.crs));
618 memcpy(&rs.acrs, &fir64OtherRecords[cpu].acrs, sizeof(rs.acrs));
619 memcpy(&rs.psw, &fir64OtherRecords[cpu].psw, sizeof(rs.psw));
620 memcpy(&rs.prefix, &fir64OtherRecords[cpu].prefix, sizeof(rs.prefix));
621 memcpy(&rs.fprs, &fir64OtherRecords[cpu].fprs, sizeof(rs.fprs));
622 memcpy(&rs.cpuTimer, &fir64OtherRecords[cpu].cpu_timer, sizeof(rs.cpuTimer));
623 memcpy(&rs.clkCmp, &fir64OtherRecords[cpu].clock_cmp, sizeof(rs.clkCmp));
624 memcpy(&rs.fpCr, &fir64OtherRecords[cpu].fp_cntrl_reg, sizeof(rs.fpCr));
625 rc.addRegisterSet(rs);
627 return rc;
630 VMDump64Big::~VMDump64Big(void)
632 delete bitmap;
633 delete fir64OtherRecords;