10 * Copyright IBM Corp. 2004, 2006.
12 * Author(s): Michael Holzheu
20 VMDump::getDumpType(const char* inputFileName
)
24 struct _fir_basic fir
;
25 char fmbk_id
[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
28 fh
= fopen(inputFileName
,"r");
30 sprintf(msg
,"Could not open '%s'",inputFileName
);
31 throw DumpErrnoException(msg
);
35 dump_seek(fh
,0x1000,SEEK_SET
);
36 if(fread(&fmbk
,sizeof(fmbk
),1,fh
) != 1) {
38 sprintf(msg
,"Could not read header of vmdump '%s'",
41 throw DumpErrnoException(msg
);
43 sprintf(msg
,"Input file '%s' is not a vmdump",
46 throw DumpException(msg
);
50 /* Check if this is a vmdump */
51 if(memcmp(fmbk
.id
, fmbk_id
, 8) != 0) {
53 sprintf(msg
,"Input file '%s' is not a vmdump",inputFileName
);
54 throw DumpException(msg
);
58 dump_seek(fh
,(fmbk
.rec_nr_fir
-1)* 0x1000,SEEK_SET
);
59 if(fread(&fir
,sizeof(fir
),1,fh
) != 1) {
61 sprintf(msg
,"Could not read header of vmdump '%s'",
64 throw DumpErrnoException(msg
);
67 sprintf(msg
,"Could not read header of vmdump '%s'",
70 throw DumpException(msg
);
74 if(fir
.fir_format
== 0) {
76 } else if(fir
.fir_format
== 0x02) {/*XXX && (fir.dump_format == 0x1))*/
78 } else if(fir
.fir_format
== 0x82) {
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
);
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
]))
107 buf
[adsrRecord
.sec3_len
]=0;
108 printf("symptom string1: %s\n",buf
);
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 */
125 dump_seek(fh
,(fmbkRecord
.rec_nr_access
-1)*0x1000 ,SEEK_SET
);
126 dump_read(&albkRecord
,sizeof(albkRecord
),1,fh
);
131 VMDump::getDumpTime(void) const
134 s390TodToTimeval(adsrRecord
.tod
,&rc
);
139 VMDump::printDebug(void)
142 s390TodToTimeval(adsrRecord
.tod
,&time
);
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
);
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
);
174 memcpy(buf
,albkRecord
.id
,sizeof(albkRecord
.id
));
175 ebcAsc(buf
,sizeof(albkRecord
.id
));
177 printf("ALBK id : %s\n",buf
);
182 memcpy(buf,asibkRecord.id,sizeof(asibkRecord.id));
183 ebcAsc(buf,sizeof(asibkRecord.id));
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);
192 VMDump::printInfo(void)
195 s390TodToTimeval(adsrRecord
.tod
,&time
);
197 fprintf(stderr
, " date........: %s",ctime(&time
.tv_sec
));
201 VMDump::seekMem(uint64_t offset
)
211 VMDump::readMem(char* buf
, int size
)
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
);
227 memset(buf
+ i
, 0, 0x1000);
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
;
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;
262 bitMapPages
= bitMapPages
/0x1000;
264 storageKeyPages
=asibkRecord
.storage_size_2GB
/ 0x1000;
265 if(storageKeyPages
% 0x1000 != 0) {
266 storageKeyPages
= storageKeyPages
/0x1000 + 1;
268 storageKeyPages
= storageKeyPages
/0x1000;
271 /* skip storage keys */
273 memoryStartRecord
= (fmbkRecord
.rec_nr_access
+ 1) *0x1000 /* 0x9000 */
274 + (bitMapPages
+ storageKeyPages
)*0x1000;
276 printf("Mem Offset: %llx\n",(long long)memoryStartRecord
);
281 VMDumpClassic::printInfo(void)
284 fprintf(stderr
, " storage.....: %i MB\n",
285 asibkRecord
.storage_size_2GB
/(1024*1024));
288 VMDumpClassic::~VMDumpClassic(void)
294 /*****************************************************************************/
295 /* VMDump32: 32 bit vmdump */
296 /*****************************************************************************/
298 VMDump32::VMDump32(const char* filename
) : VMDumpClassic(filename
)
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
++) {
312 dump_read(&fir32OtherRecords
[i
],sizeof(fir32OtherRecords
[i
]),1,
320 VMDump32::getRegisterContent(void)
322 RegisterContent32 rc
;
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
,
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
,
355 rc
.addRegisterSet(rs
);
362 VMDump32::printDebug(void)
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
++) {
372 printf("prefix (%i): %x\n",i
,fir32OtherRecords
[i
].prefix
);
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
)
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
++) {
410 dump_read(&fir64OtherRecords
[i
],sizeof(fir64OtherRecords
[i
]),1,
418 VMDump64::printDebug(void)
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
++) {
429 printf("prefix (%i): %x\n",i
,fir64OtherRecords
[i
].prefix
);
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);
444 VMDump64::getRegisterContent(void)
446 RegisterContent64 rc
;
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
,
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
,
478 memcpy(&rs
.fpCr
, &fir64OtherRecords
[cpu
].fp_cntrl_reg
,
480 rc
.addRegisterSet(rs
);
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
)
497 uint64_t pageNum
, nrDumpedPages
;
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 */
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)];
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
);
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
)) {
529 dump_read(bmPage
,sizeof(bmPage
),1,fh
);
530 memoryStartRecord
+= 0x1000;
531 for(j
= 0; j
< 0x1000; j
++) {
532 if(testBitmapKeyPage(bmPage
, j
)) {
536 if(pageNum
== nrDumpedPages
) {
537 goto all_bitmaps_read
;
541 pageNum
+= 0x1000; // empty pages
544 } while (pageNum
< nrDumpedPages
);
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
++) {
557 dump_read(&fir64OtherRecords
[i
],sizeof(fir64OtherRecords
[i
]),1,
565 VMDump64Big::printDebug(void)
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
++) {
576 printf("prefix (%i): %x\n",i
,fir64OtherRecords
[i
].prefix
);
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));
588 fprintf(stderr
, " cpus........: %x\n",fir64Record
.online_cpus
+ 1);
593 VMDump64Big::getRegisterContent(void)
595 RegisterContent64 rc
;
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
);
630 VMDump64Big::~VMDump64Big(void)
633 delete fir64OtherRecords
;