Import version 1.8.3
[s390-tools.git] / vmconvert / lkcd_dump.cpp
blob3e20f9dc840a1534cd76909ee901d61cadbbb1c6
1 /*
2 * lkcd_dump.cpp
3 * lkcd dump classes:
4 * - LKCDDump
5 * - LKCDDump32
6 * - LKCDDump64
7 *
8 * Copyright IBM Corp. 2004, 2006.
9 *
10 * Author(s): Michael Holzheu
13 #include <zlib.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17 #include "lkcd_dump.h"
19 LKCDDump::LKCDDump(Dump* dump, const char* arch){
20 referenceDump = dump;
21 dumpHeader.magic_number = DUMP_MAGIC_NUMBER;
22 dumpHeader.version = DUMP_VERSION_NUMBER;
23 dumpHeader.header_size = sizeof(struct _lkcd_dump_header);
24 dumpHeader.time.tv_sec = dump->getDumpTime().tv_sec;
25 dumpHeader.time.tv_usec = dump->getDumpTime().tv_usec;
26 strcpy(dumpHeader.utsname_machine, arch);
27 dumpHeader.memory_size = dump->getMemSize();
28 dumpHeader.memory_start = 0;
29 dumpHeader.memory_end = dump->getMemSize();
30 dumpHeader.num_dump_pages = dump->getMemSize()/0x1000;
31 dumpHeader.page_size = 0x1000;
32 dumpHeader.dump_compress = DUMP_COMPRESS_GZIP;
33 dumpHeader.dump_level = DUMP_LEVEL_ALL;
36 int
37 LKCDDump::compressGZIP(const char *old, uint32_t old_size, char *n, uint32_t new_size)
39 int rc;
40 unsigned long len = old_size;
41 rc = compress((Bytef*)n, &len, (const Bytef*)old, new_size);
42 switch(rc){
43 case Z_OK:
44 rc = len;
45 break;
46 case Z_BUF_ERROR:
47 /* In this case the compressed output is bigger than */
48 /* the uncompressed */
49 rc = GZIP_NOT_COMPRESSED;
50 break;
51 case Z_MEM_ERROR:
52 throw(DumpException("gzip call failed: out of memory"));
53 case Z_DATA_ERROR:
54 throw(DumpException("gzip call failed: input data "\
55 "corrupted!"));
56 default:
57 throw(DumpException("gzip call failed: unknown error"));
59 return rc;
63 void
64 LKCDDump::writeDump(const char* fileName)
66 ProgressBar progressBar;
67 char dump_page_buf[DUMP_BUFFER_SIZE];
68 char dpcpage[DUMP_PAGE_SIZE];
69 char buf[DUMP_PAGE_SIZE];
70 char dump_header_buf[DUMP_HEADER_SIZE] = {};
71 uint32_t dp_size,dp_flags;
72 uint64_t mem_loc = 0;
73 ssize_t buf_loc = 0;
74 struct _dump_page dp;
75 int size, fd;
77 if (fileName == NULL)
78 fd = STDOUT_FILENO;
79 else {
80 fd = open(fileName, O_WRONLY | O_CREAT | O_TRUNC,
81 S_IRUSR | S_IWUSR);
82 if (fd == -1) {
83 char msg[1024];
84 sprintf(msg, "Open of dump '%s' failed.", fileName);
85 throw(DumpErrnoException(msg));
89 /* write dump header */
91 memcpy(dump_header_buf, &dumpHeader, sizeof(dumpHeader));
92 if (write(fd, dump_header_buf, sizeof(dump_header_buf)) !=
93 sizeof(dump_header_buf)) {
94 throw(DumpErrnoException("write failed"));
97 /* write memory */
99 referenceDump->seekMem(0);
101 while (mem_loc < dumpHeader.memory_size) {
102 referenceDump->readMem(buf, DUMP_PAGE_SIZE);
103 copyRegsToPage(mem_loc,buf);
105 memset(dpcpage, 0, DUMP_PAGE_SIZE);
106 /* get the new compressed page size
109 size = compressGZIP((char *)buf, DUMP_PAGE_SIZE,
110 (char *)dpcpage, DUMP_PAGE_SIZE);
112 /* if compression failed or compressed was ineffective,
113 * we write an uncompressed page
115 if (size == GZIP_NOT_COMPRESSED) {
116 dp_flags = DUMP_DH_RAW;
117 dp_size = DUMP_PAGE_SIZE;
118 } else {
119 dp_flags = DUMP_DH_COMPRESSED;
120 dp_size = size;
122 dp.address = mem_loc;
123 dp.size = dp_size;
124 dp.flags = dp_flags;
125 memcpy((void *)(dump_page_buf + buf_loc),
126 (const void *)&dp, sizeof(dp));
127 buf_loc += sizeof(dp);
128 /* copy the page of memory
130 if (dp_flags & DUMP_DH_COMPRESSED) {
131 /* copy the compressed page
133 memcpy((void *)(dump_page_buf + buf_loc),
134 (const void *)dpcpage, dp_size);
135 } else {
136 /* copy directly from memory
138 memcpy((void *)(dump_page_buf + buf_loc),
139 (const void *)buf, dp_size);
141 buf_loc += dp_size;
142 if(write(fd, dump_page_buf, buf_loc) != buf_loc){
143 throw(DumpErrnoException("write failed"));
145 buf_loc = 0;
146 mem_loc += DUMP_PAGE_SIZE;
147 progressBar.displayProgress(mem_loc/(1024*1024),
148 dumpHeader.memory_size/(1024*1024));
151 /* write end marker
154 dp.address = 0x0;
155 dp.size = DUMP_DH_END;
156 dp.flags = 0x0;
157 if(write(fd, dump_page_buf, sizeof(dp)) != sizeof(dp)){
158 throw(DumpErrnoException("write failed"));
160 fprintf(stderr, "\n");
161 if (fd != STDOUT_FILENO)
162 close(fd);
165 struct timeval
166 LKCDDump::getDumpTime(void) const
168 struct timeval rc;
169 rc.tv_sec = dumpHeader.time.tv_sec;
170 rc.tv_usec = dumpHeader.time.tv_usec;
171 return rc;
174 LKCDDump32::LKCDDump32(Dump* dump, const RegisterContent32& r)
175 : LKCDDump(dump,"s390")
177 registerContent = r;
180 void
181 LKCDDump32::copyRegsToPage(uint64_t offset, char *buf){
182 int cpu;
183 for(cpu = 0; cpu < registerContent.getNumCpus(); cpu++){
184 if(offset == registerContent.regSets[cpu].prefix){
185 memcpy(buf+0xd8,&registerContent.regSets[cpu].cpuTimer,
186 sizeof(registerContent.regSets[cpu].cpuTimer));
187 memcpy(buf+0xe0,&registerContent.regSets[cpu].clkCmp,
188 sizeof(registerContent.regSets[cpu].clkCmp));
189 memcpy(buf+0x100,&registerContent.regSets[cpu].psw,
190 sizeof(registerContent.regSets[cpu].psw));
191 memcpy(buf+0x108,&registerContent.regSets[cpu].prefix,
192 sizeof(registerContent.regSets[cpu].prefix));
193 memcpy(buf+0x120,&registerContent.regSets[cpu].acrs,
194 sizeof(registerContent.regSets[cpu].acrs));
195 memcpy(buf+0x160,&registerContent.regSets[cpu].fprs,
196 sizeof(registerContent.regSets[cpu].fprs));
197 memcpy(buf+0x180,&registerContent.regSets[cpu].gprs,
198 sizeof(registerContent.regSets[cpu].gprs));
199 memcpy(buf+0x1c0,&registerContent.regSets[cpu].crs,
200 sizeof(registerContent.regSets[cpu].crs));
205 LKCDDump64::LKCDDump64(Dump* dump, const RegisterContent64& r)
206 : LKCDDump(dump,"s390x")
208 registerContent = r;
211 void
212 LKCDDump64::copyRegsToPage(uint64_t offset, char *buf){
213 int cpu;
214 for(cpu = 0; cpu < registerContent.getNumCpus(); cpu++){
215 if(offset == (registerContent.regSets[cpu].prefix + 0x1000)){
216 memcpy(buf+0x328,&registerContent.regSets[cpu].cpuTimer,
217 sizeof(registerContent.regSets[cpu].cpuTimer));
218 memcpy(buf+0x330,&registerContent.regSets[cpu].clkCmp,
219 sizeof(registerContent.regSets[cpu].clkCmp));
220 memcpy(buf+0x300,&registerContent.regSets[cpu].psw,
221 sizeof(registerContent.regSets[cpu].psw));
222 memcpy(buf+0x318,&registerContent.regSets[cpu].prefix,
223 sizeof(registerContent.regSets[cpu].prefix));
224 memcpy(buf+0x340,&registerContent.regSets[cpu].acrs,
225 sizeof(registerContent.regSets[cpu].acrs));
226 memcpy(buf+0x200,&registerContent.regSets[cpu].fprs,
227 sizeof(registerContent.regSets[cpu].fprs));
228 memcpy(buf+0x280,&registerContent.regSets[cpu].gprs,
229 sizeof(registerContent.regSets[cpu].gprs));
230 memcpy(buf+0x380,&registerContent.regSets[cpu].crs,
231 sizeof(registerContent.regSets[cpu].crs));
232 memcpy(buf+0x31c,&registerContent.regSets[cpu].fpCr,
233 sizeof(registerContent.regSets[cpu].fpCr));