root / target-i386 / arch_dump.c @ feature-archipelago
History | View | Annotate | Download (12.4 kB)
1 | 9fecbed0 | Wen Congyang | /*
|
---|---|---|---|
2 | 9fecbed0 | Wen Congyang | * i386 memory mapping
|
3 | 9fecbed0 | Wen Congyang | *
|
4 | 9fecbed0 | Wen Congyang | * Copyright Fujitsu, Corp. 2011, 2012
|
5 | 9fecbed0 | Wen Congyang | *
|
6 | 9fecbed0 | Wen Congyang | * Authors:
|
7 | 9fecbed0 | Wen Congyang | * Wen Congyang <wency@cn.fujitsu.com>
|
8 | 9fecbed0 | Wen Congyang | *
|
9 | fc0608ac | Stefan Weil | * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
10 | fc0608ac | Stefan Weil | * See the COPYING file in the top-level directory.
|
11 | 9fecbed0 | Wen Congyang | *
|
12 | 9fecbed0 | Wen Congyang | */
|
13 | 9fecbed0 | Wen Congyang | |
14 | 9fecbed0 | Wen Congyang | #include "cpu.h" |
15 | 022c62cb | Paolo Bonzini | #include "exec/cpu-all.h" |
16 | 9c17d615 | Paolo Bonzini | #include "sysemu/dump.h" |
17 | 9fecbed0 | Wen Congyang | #include "elf.h" |
18 | 56c4bfb3 | Laszlo Ersek | #include "sysemu/memory_mapping.h" |
19 | 9fecbed0 | Wen Congyang | |
20 | 9fecbed0 | Wen Congyang | #ifdef TARGET_X86_64
|
21 | 9fecbed0 | Wen Congyang | typedef struct { |
22 | 9fecbed0 | Wen Congyang | target_ulong r15, r14, r13, r12, rbp, rbx, r11, r10; |
23 | 9fecbed0 | Wen Congyang | target_ulong r9, r8, rax, rcx, rdx, rsi, rdi, orig_rax; |
24 | 9fecbed0 | Wen Congyang | target_ulong rip, cs, eflags; |
25 | 9fecbed0 | Wen Congyang | target_ulong rsp, ss; |
26 | 9fecbed0 | Wen Congyang | target_ulong fs_base, gs_base; |
27 | 9fecbed0 | Wen Congyang | target_ulong ds, es, fs, gs; |
28 | 9fecbed0 | Wen Congyang | } x86_64_user_regs_struct; |
29 | 9fecbed0 | Wen Congyang | |
30 | 9fecbed0 | Wen Congyang | typedef struct { |
31 | 9fecbed0 | Wen Congyang | char pad1[32]; |
32 | 9fecbed0 | Wen Congyang | uint32_t pid; |
33 | 9fecbed0 | Wen Congyang | char pad2[76]; |
34 | 9fecbed0 | Wen Congyang | x86_64_user_regs_struct regs; |
35 | 9fecbed0 | Wen Congyang | char pad3[8]; |
36 | 9fecbed0 | Wen Congyang | } x86_64_elf_prstatus; |
37 | 9fecbed0 | Wen Congyang | |
38 | c72bf468 | Jens Freimann | static int x86_64_write_elf64_note(WriteCoreDumpFunction f, |
39 | 369ff018 | Andreas Färber | CPUX86State *env, int id,
|
40 | 9fecbed0 | Wen Congyang | void *opaque)
|
41 | 9fecbed0 | Wen Congyang | { |
42 | 9fecbed0 | Wen Congyang | x86_64_user_regs_struct regs; |
43 | 9fecbed0 | Wen Congyang | Elf64_Nhdr *note; |
44 | 9fecbed0 | Wen Congyang | char *buf;
|
45 | 9fecbed0 | Wen Congyang | int descsz, note_size, name_size = 5; |
46 | 9fecbed0 | Wen Congyang | const char *name = "CORE"; |
47 | 9fecbed0 | Wen Congyang | int ret;
|
48 | 9fecbed0 | Wen Congyang | |
49 | 9fecbed0 | Wen Congyang | regs.r15 = env->regs[15];
|
50 | 9fecbed0 | Wen Congyang | regs.r14 = env->regs[14];
|
51 | 9fecbed0 | Wen Congyang | regs.r13 = env->regs[13];
|
52 | 9fecbed0 | Wen Congyang | regs.r12 = env->regs[12];
|
53 | 9fecbed0 | Wen Congyang | regs.r11 = env->regs[11];
|
54 | 9fecbed0 | Wen Congyang | regs.r10 = env->regs[10];
|
55 | 9fecbed0 | Wen Congyang | regs.r9 = env->regs[9];
|
56 | 9fecbed0 | Wen Congyang | regs.r8 = env->regs[8];
|
57 | 9fecbed0 | Wen Congyang | regs.rbp = env->regs[R_EBP]; |
58 | 9fecbed0 | Wen Congyang | regs.rsp = env->regs[R_ESP]; |
59 | 9fecbed0 | Wen Congyang | regs.rdi = env->regs[R_EDI]; |
60 | 9fecbed0 | Wen Congyang | regs.rsi = env->regs[R_ESI]; |
61 | 9fecbed0 | Wen Congyang | regs.rdx = env->regs[R_EDX]; |
62 | 9fecbed0 | Wen Congyang | regs.rcx = env->regs[R_ECX]; |
63 | 9fecbed0 | Wen Congyang | regs.rbx = env->regs[R_EBX]; |
64 | 9fecbed0 | Wen Congyang | regs.rax = env->regs[R_EAX]; |
65 | 9fecbed0 | Wen Congyang | regs.rip = env->eip; |
66 | 9fecbed0 | Wen Congyang | regs.eflags = env->eflags; |
67 | 9fecbed0 | Wen Congyang | |
68 | 9fecbed0 | Wen Congyang | regs.orig_rax = 0; /* FIXME */ |
69 | 9fecbed0 | Wen Congyang | regs.cs = env->segs[R_CS].selector; |
70 | 9fecbed0 | Wen Congyang | regs.ss = env->segs[R_SS].selector; |
71 | 9fecbed0 | Wen Congyang | regs.fs_base = env->segs[R_FS].base; |
72 | 9fecbed0 | Wen Congyang | regs.gs_base = env->segs[R_GS].base; |
73 | 9fecbed0 | Wen Congyang | regs.ds = env->segs[R_DS].selector; |
74 | 9fecbed0 | Wen Congyang | regs.es = env->segs[R_ES].selector; |
75 | 9fecbed0 | Wen Congyang | regs.fs = env->segs[R_FS].selector; |
76 | 9fecbed0 | Wen Congyang | regs.gs = env->segs[R_GS].selector; |
77 | 9fecbed0 | Wen Congyang | |
78 | 9fecbed0 | Wen Congyang | descsz = sizeof(x86_64_elf_prstatus);
|
79 | 9fecbed0 | Wen Congyang | note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 + |
80 | 9fecbed0 | Wen Congyang | (descsz + 3) / 4) * 4; |
81 | 9fecbed0 | Wen Congyang | note = g_malloc(note_size); |
82 | 9fecbed0 | Wen Congyang | |
83 | 9fecbed0 | Wen Congyang | memset(note, 0, note_size);
|
84 | 9fecbed0 | Wen Congyang | note->n_namesz = cpu_to_le32(name_size); |
85 | 9fecbed0 | Wen Congyang | note->n_descsz = cpu_to_le32(descsz); |
86 | 9fecbed0 | Wen Congyang | note->n_type = cpu_to_le32(NT_PRSTATUS); |
87 | 9fecbed0 | Wen Congyang | buf = (char *)note;
|
88 | 9fecbed0 | Wen Congyang | buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4; |
89 | 9fecbed0 | Wen Congyang | memcpy(buf, name, name_size); |
90 | 9fecbed0 | Wen Congyang | buf += ((name_size + 3) / 4) * 4; |
91 | 9fecbed0 | Wen Congyang | memcpy(buf + 32, &id, 4); /* pr_pid */ |
92 | 9fecbed0 | Wen Congyang | buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong); |
93 | 9fecbed0 | Wen Congyang | memcpy(buf, ®s, sizeof(x86_64_user_regs_struct));
|
94 | 9fecbed0 | Wen Congyang | |
95 | 9fecbed0 | Wen Congyang | ret = f(note, note_size, opaque); |
96 | 9fecbed0 | Wen Congyang | g_free(note); |
97 | 9fecbed0 | Wen Congyang | if (ret < 0) { |
98 | 9fecbed0 | Wen Congyang | return -1; |
99 | 9fecbed0 | Wen Congyang | } |
100 | 9fecbed0 | Wen Congyang | |
101 | 9fecbed0 | Wen Congyang | return 0; |
102 | 9fecbed0 | Wen Congyang | } |
103 | 9fecbed0 | Wen Congyang | #endif
|
104 | 9fecbed0 | Wen Congyang | |
105 | 9fecbed0 | Wen Congyang | typedef struct { |
106 | 9fecbed0 | Wen Congyang | uint32_t ebx, ecx, edx, esi, edi, ebp, eax; |
107 | 9fecbed0 | Wen Congyang | unsigned short ds, __ds, es, __es; |
108 | 9fecbed0 | Wen Congyang | unsigned short fs, __fs, gs, __gs; |
109 | 9fecbed0 | Wen Congyang | uint32_t orig_eax, eip; |
110 | 9fecbed0 | Wen Congyang | unsigned short cs, __cs; |
111 | 9fecbed0 | Wen Congyang | uint32_t eflags, esp; |
112 | 9fecbed0 | Wen Congyang | unsigned short ss, __ss; |
113 | 9fecbed0 | Wen Congyang | } x86_user_regs_struct; |
114 | 9fecbed0 | Wen Congyang | |
115 | 9fecbed0 | Wen Congyang | typedef struct { |
116 | 9fecbed0 | Wen Congyang | char pad1[24]; |
117 | 9fecbed0 | Wen Congyang | uint32_t pid; |
118 | 9fecbed0 | Wen Congyang | char pad2[44]; |
119 | 9fecbed0 | Wen Congyang | x86_user_regs_struct regs; |
120 | 9fecbed0 | Wen Congyang | char pad3[4]; |
121 | 9fecbed0 | Wen Congyang | } x86_elf_prstatus; |
122 | 9fecbed0 | Wen Congyang | |
123 | 369ff018 | Andreas Färber | static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUX86State *env, |
124 | 9fecbed0 | Wen Congyang | int id)
|
125 | 9fecbed0 | Wen Congyang | { |
126 | 9fecbed0 | Wen Congyang | memset(prstatus, 0, sizeof(x86_elf_prstatus)); |
127 | 9fecbed0 | Wen Congyang | prstatus->regs.ebp = env->regs[R_EBP] & 0xffffffff;
|
128 | 9fecbed0 | Wen Congyang | prstatus->regs.esp = env->regs[R_ESP] & 0xffffffff;
|
129 | 9fecbed0 | Wen Congyang | prstatus->regs.edi = env->regs[R_EDI] & 0xffffffff;
|
130 | 9fecbed0 | Wen Congyang | prstatus->regs.esi = env->regs[R_ESI] & 0xffffffff;
|
131 | 9fecbed0 | Wen Congyang | prstatus->regs.edx = env->regs[R_EDX] & 0xffffffff;
|
132 | 9fecbed0 | Wen Congyang | prstatus->regs.ecx = env->regs[R_ECX] & 0xffffffff;
|
133 | 9fecbed0 | Wen Congyang | prstatus->regs.ebx = env->regs[R_EBX] & 0xffffffff;
|
134 | 9fecbed0 | Wen Congyang | prstatus->regs.eax = env->regs[R_EAX] & 0xffffffff;
|
135 | 9fecbed0 | Wen Congyang | prstatus->regs.eip = env->eip & 0xffffffff;
|
136 | 9fecbed0 | Wen Congyang | prstatus->regs.eflags = env->eflags & 0xffffffff;
|
137 | 9fecbed0 | Wen Congyang | |
138 | 9fecbed0 | Wen Congyang | prstatus->regs.cs = env->segs[R_CS].selector; |
139 | 9fecbed0 | Wen Congyang | prstatus->regs.ss = env->segs[R_SS].selector; |
140 | 9fecbed0 | Wen Congyang | prstatus->regs.ds = env->segs[R_DS].selector; |
141 | 9fecbed0 | Wen Congyang | prstatus->regs.es = env->segs[R_ES].selector; |
142 | 9fecbed0 | Wen Congyang | prstatus->regs.fs = env->segs[R_FS].selector; |
143 | 9fecbed0 | Wen Congyang | prstatus->regs.gs = env->segs[R_GS].selector; |
144 | 9fecbed0 | Wen Congyang | |
145 | 9fecbed0 | Wen Congyang | prstatus->pid = id; |
146 | 9fecbed0 | Wen Congyang | } |
147 | 9fecbed0 | Wen Congyang | |
148 | 369ff018 | Andreas Färber | static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *env, |
149 | 9fecbed0 | Wen Congyang | int id, void *opaque) |
150 | 9fecbed0 | Wen Congyang | { |
151 | 9fecbed0 | Wen Congyang | x86_elf_prstatus prstatus; |
152 | 9fecbed0 | Wen Congyang | Elf64_Nhdr *note; |
153 | 9fecbed0 | Wen Congyang | char *buf;
|
154 | 9fecbed0 | Wen Congyang | int descsz, note_size, name_size = 5; |
155 | 9fecbed0 | Wen Congyang | const char *name = "CORE"; |
156 | 9fecbed0 | Wen Congyang | int ret;
|
157 | 9fecbed0 | Wen Congyang | |
158 | 9fecbed0 | Wen Congyang | x86_fill_elf_prstatus(&prstatus, env, id); |
159 | 9fecbed0 | Wen Congyang | descsz = sizeof(x86_elf_prstatus);
|
160 | 9fecbed0 | Wen Congyang | note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 + |
161 | 9fecbed0 | Wen Congyang | (descsz + 3) / 4) * 4; |
162 | 9fecbed0 | Wen Congyang | note = g_malloc(note_size); |
163 | 9fecbed0 | Wen Congyang | |
164 | 9fecbed0 | Wen Congyang | memset(note, 0, note_size);
|
165 | 9fecbed0 | Wen Congyang | note->n_namesz = cpu_to_le32(name_size); |
166 | 9fecbed0 | Wen Congyang | note->n_descsz = cpu_to_le32(descsz); |
167 | 9fecbed0 | Wen Congyang | note->n_type = cpu_to_le32(NT_PRSTATUS); |
168 | 9fecbed0 | Wen Congyang | buf = (char *)note;
|
169 | 9fecbed0 | Wen Congyang | buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4; |
170 | 9fecbed0 | Wen Congyang | memcpy(buf, name, name_size); |
171 | 9fecbed0 | Wen Congyang | buf += ((name_size + 3) / 4) * 4; |
172 | 9fecbed0 | Wen Congyang | memcpy(buf, &prstatus, sizeof(prstatus));
|
173 | 9fecbed0 | Wen Congyang | |
174 | 9fecbed0 | Wen Congyang | ret = f(note, note_size, opaque); |
175 | 9fecbed0 | Wen Congyang | g_free(note); |
176 | 9fecbed0 | Wen Congyang | if (ret < 0) { |
177 | 9fecbed0 | Wen Congyang | return -1; |
178 | 9fecbed0 | Wen Congyang | } |
179 | 9fecbed0 | Wen Congyang | |
180 | 9fecbed0 | Wen Congyang | return 0; |
181 | 9fecbed0 | Wen Congyang | } |
182 | 9fecbed0 | Wen Congyang | |
183 | c72bf468 | Jens Freimann | int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
184 | c72bf468 | Jens Freimann | int cpuid, void *opaque) |
185 | 9fecbed0 | Wen Congyang | { |
186 | c72bf468 | Jens Freimann | X86CPU *cpu = X86_CPU(cs); |
187 | 9fecbed0 | Wen Congyang | int ret;
|
188 | 9fecbed0 | Wen Congyang | #ifdef TARGET_X86_64
|
189 | 182735ef | Andreas Färber | X86CPU *first_x86_cpu = X86_CPU(first_cpu); |
190 | 182735ef | Andreas Färber | bool lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
|
191 | 9fecbed0 | Wen Congyang | |
192 | 9fecbed0 | Wen Congyang | if (lma) {
|
193 | c72bf468 | Jens Freimann | ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, opaque); |
194 | 9fecbed0 | Wen Congyang | } else {
|
195 | 9fecbed0 | Wen Congyang | #endif
|
196 | c72bf468 | Jens Freimann | ret = x86_write_elf64_note(f, &cpu->env, cpuid, opaque); |
197 | 9fecbed0 | Wen Congyang | #ifdef TARGET_X86_64
|
198 | 9fecbed0 | Wen Congyang | } |
199 | 9fecbed0 | Wen Congyang | #endif
|
200 | 9fecbed0 | Wen Congyang | |
201 | 9fecbed0 | Wen Congyang | return ret;
|
202 | 9fecbed0 | Wen Congyang | } |
203 | 9fecbed0 | Wen Congyang | |
204 | c72bf468 | Jens Freimann | int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
|
205 | c72bf468 | Jens Freimann | int cpuid, void *opaque) |
206 | 9fecbed0 | Wen Congyang | { |
207 | c72bf468 | Jens Freimann | X86CPU *cpu = X86_CPU(cs); |
208 | 9fecbed0 | Wen Congyang | x86_elf_prstatus prstatus; |
209 | 9fecbed0 | Wen Congyang | Elf32_Nhdr *note; |
210 | 9fecbed0 | Wen Congyang | char *buf;
|
211 | 9fecbed0 | Wen Congyang | int descsz, note_size, name_size = 5; |
212 | 9fecbed0 | Wen Congyang | const char *name = "CORE"; |
213 | 9fecbed0 | Wen Congyang | int ret;
|
214 | 9fecbed0 | Wen Congyang | |
215 | c72bf468 | Jens Freimann | x86_fill_elf_prstatus(&prstatus, &cpu->env, cpuid); |
216 | 9fecbed0 | Wen Congyang | descsz = sizeof(x86_elf_prstatus);
|
217 | 9fecbed0 | Wen Congyang | note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 + |
218 | 9fecbed0 | Wen Congyang | (descsz + 3) / 4) * 4; |
219 | 9fecbed0 | Wen Congyang | note = g_malloc(note_size); |
220 | 9fecbed0 | Wen Congyang | |
221 | 9fecbed0 | Wen Congyang | memset(note, 0, note_size);
|
222 | 9fecbed0 | Wen Congyang | note->n_namesz = cpu_to_le32(name_size); |
223 | 9fecbed0 | Wen Congyang | note->n_descsz = cpu_to_le32(descsz); |
224 | 9fecbed0 | Wen Congyang | note->n_type = cpu_to_le32(NT_PRSTATUS); |
225 | 9fecbed0 | Wen Congyang | buf = (char *)note;
|
226 | 9fecbed0 | Wen Congyang | buf += ((sizeof(Elf32_Nhdr) + 3) / 4) * 4; |
227 | 9fecbed0 | Wen Congyang | memcpy(buf, name, name_size); |
228 | 9fecbed0 | Wen Congyang | buf += ((name_size + 3) / 4) * 4; |
229 | 9fecbed0 | Wen Congyang | memcpy(buf, &prstatus, sizeof(prstatus));
|
230 | 9fecbed0 | Wen Congyang | |
231 | 9fecbed0 | Wen Congyang | ret = f(note, note_size, opaque); |
232 | 9fecbed0 | Wen Congyang | g_free(note); |
233 | 9fecbed0 | Wen Congyang | if (ret < 0) { |
234 | 9fecbed0 | Wen Congyang | return -1; |
235 | 9fecbed0 | Wen Congyang | } |
236 | 9fecbed0 | Wen Congyang | |
237 | 9fecbed0 | Wen Congyang | return 0; |
238 | 9fecbed0 | Wen Congyang | } |
239 | 90166b71 | Wen Congyang | |
240 | 90166b71 | Wen Congyang | /*
|
241 | 90166b71 | Wen Congyang | * please count up QEMUCPUSTATE_VERSION if you have changed definition of
|
242 | 90166b71 | Wen Congyang | * QEMUCPUState, and modify the tools using this information accordingly.
|
243 | 90166b71 | Wen Congyang | */
|
244 | 90166b71 | Wen Congyang | #define QEMUCPUSTATE_VERSION (1) |
245 | 90166b71 | Wen Congyang | |
246 | 90166b71 | Wen Congyang | struct QEMUCPUSegment {
|
247 | 90166b71 | Wen Congyang | uint32_t selector; |
248 | 90166b71 | Wen Congyang | uint32_t limit; |
249 | 90166b71 | Wen Congyang | uint32_t flags; |
250 | 90166b71 | Wen Congyang | uint32_t pad; |
251 | 90166b71 | Wen Congyang | uint64_t base; |
252 | 90166b71 | Wen Congyang | }; |
253 | 90166b71 | Wen Congyang | |
254 | 90166b71 | Wen Congyang | typedef struct QEMUCPUSegment QEMUCPUSegment; |
255 | 90166b71 | Wen Congyang | |
256 | 90166b71 | Wen Congyang | struct QEMUCPUState {
|
257 | 90166b71 | Wen Congyang | uint32_t version; |
258 | 90166b71 | Wen Congyang | uint32_t size; |
259 | 90166b71 | Wen Congyang | uint64_t rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp; |
260 | 90166b71 | Wen Congyang | uint64_t r8, r9, r10, r11, r12, r13, r14, r15; |
261 | 90166b71 | Wen Congyang | uint64_t rip, rflags; |
262 | 90166b71 | Wen Congyang | QEMUCPUSegment cs, ds, es, fs, gs, ss; |
263 | 90166b71 | Wen Congyang | QEMUCPUSegment ldt, tr, gdt, idt; |
264 | 90166b71 | Wen Congyang | uint64_t cr[5];
|
265 | 90166b71 | Wen Congyang | }; |
266 | 90166b71 | Wen Congyang | |
267 | 90166b71 | Wen Congyang | typedef struct QEMUCPUState QEMUCPUState; |
268 | 90166b71 | Wen Congyang | |
269 | 90166b71 | Wen Congyang | static void copy_segment(QEMUCPUSegment *d, SegmentCache *s) |
270 | 90166b71 | Wen Congyang | { |
271 | 90166b71 | Wen Congyang | d->pad = 0;
|
272 | 90166b71 | Wen Congyang | d->selector = s->selector; |
273 | 90166b71 | Wen Congyang | d->limit = s->limit; |
274 | 90166b71 | Wen Congyang | d->flags = s->flags; |
275 | 90166b71 | Wen Congyang | d->base = s->base; |
276 | 90166b71 | Wen Congyang | } |
277 | 90166b71 | Wen Congyang | |
278 | 369ff018 | Andreas Färber | static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env) |
279 | 90166b71 | Wen Congyang | { |
280 | 90166b71 | Wen Congyang | memset(s, 0, sizeof(QEMUCPUState)); |
281 | 90166b71 | Wen Congyang | |
282 | 90166b71 | Wen Congyang | s->version = QEMUCPUSTATE_VERSION; |
283 | 90166b71 | Wen Congyang | s->size = sizeof(QEMUCPUState);
|
284 | 90166b71 | Wen Congyang | |
285 | 90166b71 | Wen Congyang | s->rax = env->regs[R_EAX]; |
286 | 90166b71 | Wen Congyang | s->rbx = env->regs[R_EBX]; |
287 | 90166b71 | Wen Congyang | s->rcx = env->regs[R_ECX]; |
288 | 90166b71 | Wen Congyang | s->rdx = env->regs[R_EDX]; |
289 | 90166b71 | Wen Congyang | s->rsi = env->regs[R_ESI]; |
290 | 90166b71 | Wen Congyang | s->rdi = env->regs[R_EDI]; |
291 | 90166b71 | Wen Congyang | s->rsp = env->regs[R_ESP]; |
292 | 90166b71 | Wen Congyang | s->rbp = env->regs[R_EBP]; |
293 | 90166b71 | Wen Congyang | #ifdef TARGET_X86_64
|
294 | 90166b71 | Wen Congyang | s->r8 = env->regs[8];
|
295 | 90166b71 | Wen Congyang | s->r9 = env->regs[9];
|
296 | 90166b71 | Wen Congyang | s->r10 = env->regs[10];
|
297 | 90166b71 | Wen Congyang | s->r11 = env->regs[11];
|
298 | 90166b71 | Wen Congyang | s->r12 = env->regs[12];
|
299 | 90166b71 | Wen Congyang | s->r13 = env->regs[13];
|
300 | 90166b71 | Wen Congyang | s->r14 = env->regs[14];
|
301 | 90166b71 | Wen Congyang | s->r15 = env->regs[15];
|
302 | 90166b71 | Wen Congyang | #endif
|
303 | 90166b71 | Wen Congyang | s->rip = env->eip; |
304 | 90166b71 | Wen Congyang | s->rflags = env->eflags; |
305 | 90166b71 | Wen Congyang | |
306 | 90166b71 | Wen Congyang | copy_segment(&s->cs, &env->segs[R_CS]); |
307 | 90166b71 | Wen Congyang | copy_segment(&s->ds, &env->segs[R_DS]); |
308 | 90166b71 | Wen Congyang | copy_segment(&s->es, &env->segs[R_ES]); |
309 | 90166b71 | Wen Congyang | copy_segment(&s->fs, &env->segs[R_FS]); |
310 | 90166b71 | Wen Congyang | copy_segment(&s->gs, &env->segs[R_GS]); |
311 | 90166b71 | Wen Congyang | copy_segment(&s->ss, &env->segs[R_SS]); |
312 | 90166b71 | Wen Congyang | copy_segment(&s->ldt, &env->ldt); |
313 | 90166b71 | Wen Congyang | copy_segment(&s->tr, &env->tr); |
314 | 90166b71 | Wen Congyang | copy_segment(&s->gdt, &env->gdt); |
315 | 90166b71 | Wen Congyang | copy_segment(&s->idt, &env->idt); |
316 | 90166b71 | Wen Congyang | |
317 | 90166b71 | Wen Congyang | s->cr[0] = env->cr[0]; |
318 | 90166b71 | Wen Congyang | s->cr[1] = env->cr[1]; |
319 | 90166b71 | Wen Congyang | s->cr[2] = env->cr[2]; |
320 | 90166b71 | Wen Congyang | s->cr[3] = env->cr[3]; |
321 | 90166b71 | Wen Congyang | s->cr[4] = env->cr[4]; |
322 | 90166b71 | Wen Congyang | } |
323 | 90166b71 | Wen Congyang | |
324 | c72bf468 | Jens Freimann | static inline int cpu_write_qemu_note(WriteCoreDumpFunction f, |
325 | 369ff018 | Andreas Färber | CPUX86State *env, |
326 | 90166b71 | Wen Congyang | void *opaque,
|
327 | 90166b71 | Wen Congyang | int type)
|
328 | 90166b71 | Wen Congyang | { |
329 | 90166b71 | Wen Congyang | QEMUCPUState state; |
330 | 90166b71 | Wen Congyang | Elf64_Nhdr *note64; |
331 | 90166b71 | Wen Congyang | Elf32_Nhdr *note32; |
332 | 90166b71 | Wen Congyang | void *note;
|
333 | 90166b71 | Wen Congyang | char *buf;
|
334 | 90166b71 | Wen Congyang | int descsz, note_size, name_size = 5, note_head_size; |
335 | 90166b71 | Wen Congyang | const char *name = "QEMU"; |
336 | 90166b71 | Wen Congyang | int ret;
|
337 | 90166b71 | Wen Congyang | |
338 | 90166b71 | Wen Congyang | qemu_get_cpustate(&state, env); |
339 | 90166b71 | Wen Congyang | |
340 | 90166b71 | Wen Congyang | descsz = sizeof(state);
|
341 | 90166b71 | Wen Congyang | if (type == 0) { |
342 | 90166b71 | Wen Congyang | note_head_size = sizeof(Elf32_Nhdr);
|
343 | 90166b71 | Wen Congyang | } else {
|
344 | 90166b71 | Wen Congyang | note_head_size = sizeof(Elf64_Nhdr);
|
345 | 90166b71 | Wen Congyang | } |
346 | 90166b71 | Wen Congyang | note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + |
347 | 90166b71 | Wen Congyang | (descsz + 3) / 4) * 4; |
348 | 90166b71 | Wen Congyang | note = g_malloc(note_size); |
349 | 90166b71 | Wen Congyang | |
350 | 90166b71 | Wen Congyang | memset(note, 0, note_size);
|
351 | 90166b71 | Wen Congyang | if (type == 0) { |
352 | 90166b71 | Wen Congyang | note32 = note; |
353 | 90166b71 | Wen Congyang | note32->n_namesz = cpu_to_le32(name_size); |
354 | 90166b71 | Wen Congyang | note32->n_descsz = cpu_to_le32(descsz); |
355 | 90166b71 | Wen Congyang | note32->n_type = 0;
|
356 | 90166b71 | Wen Congyang | } else {
|
357 | 90166b71 | Wen Congyang | note64 = note; |
358 | 90166b71 | Wen Congyang | note64->n_namesz = cpu_to_le32(name_size); |
359 | 90166b71 | Wen Congyang | note64->n_descsz = cpu_to_le32(descsz); |
360 | 90166b71 | Wen Congyang | note64->n_type = 0;
|
361 | 90166b71 | Wen Congyang | } |
362 | 90166b71 | Wen Congyang | buf = note; |
363 | 90166b71 | Wen Congyang | buf += ((note_head_size + 3) / 4) * 4; |
364 | 90166b71 | Wen Congyang | memcpy(buf, name, name_size); |
365 | 90166b71 | Wen Congyang | buf += ((name_size + 3) / 4) * 4; |
366 | 90166b71 | Wen Congyang | memcpy(buf, &state, sizeof(state));
|
367 | 90166b71 | Wen Congyang | |
368 | 90166b71 | Wen Congyang | ret = f(note, note_size, opaque); |
369 | 90166b71 | Wen Congyang | g_free(note); |
370 | 90166b71 | Wen Congyang | if (ret < 0) { |
371 | 90166b71 | Wen Congyang | return -1; |
372 | 90166b71 | Wen Congyang | } |
373 | 90166b71 | Wen Congyang | |
374 | 90166b71 | Wen Congyang | return 0; |
375 | 90166b71 | Wen Congyang | } |
376 | 90166b71 | Wen Congyang | |
377 | c72bf468 | Jens Freimann | int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cs,
|
378 | c72bf468 | Jens Freimann | void *opaque)
|
379 | 90166b71 | Wen Congyang | { |
380 | c72bf468 | Jens Freimann | X86CPU *cpu = X86_CPU(cs); |
381 | c72bf468 | Jens Freimann | |
382 | c72bf468 | Jens Freimann | return cpu_write_qemu_note(f, &cpu->env, opaque, 1); |
383 | 90166b71 | Wen Congyang | } |
384 | 90166b71 | Wen Congyang | |
385 | c72bf468 | Jens Freimann | int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs,
|
386 | c72bf468 | Jens Freimann | void *opaque)
|
387 | 90166b71 | Wen Congyang | { |
388 | c72bf468 | Jens Freimann | X86CPU *cpu = X86_CPU(cs); |
389 | c72bf468 | Jens Freimann | |
390 | c72bf468 | Jens Freimann | return cpu_write_qemu_note(f, &cpu->env, opaque, 0); |
391 | 90166b71 | Wen Congyang | } |
392 | 25ae9c1d | Wen Congyang | |
393 | 56c4bfb3 | Laszlo Ersek | int cpu_get_dump_info(ArchDumpInfo *info,
|
394 | 56c4bfb3 | Laszlo Ersek | const GuestPhysBlockList *guest_phys_blocks)
|
395 | 25ae9c1d | Wen Congyang | { |
396 | 25ae9c1d | Wen Congyang | bool lma = false; |
397 | 56c4bfb3 | Laszlo Ersek | GuestPhysBlock *block; |
398 | 25ae9c1d | Wen Congyang | |
399 | 25ae9c1d | Wen Congyang | #ifdef TARGET_X86_64
|
400 | 182735ef | Andreas Färber | X86CPU *first_x86_cpu = X86_CPU(first_cpu); |
401 | 182735ef | Andreas Färber | |
402 | 182735ef | Andreas Färber | lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK); |
403 | 25ae9c1d | Wen Congyang | #endif
|
404 | 25ae9c1d | Wen Congyang | |
405 | 25ae9c1d | Wen Congyang | if (lma) {
|
406 | 25ae9c1d | Wen Congyang | info->d_machine = EM_X86_64; |
407 | 25ae9c1d | Wen Congyang | } else {
|
408 | 25ae9c1d | Wen Congyang | info->d_machine = EM_386; |
409 | 25ae9c1d | Wen Congyang | } |
410 | 25ae9c1d | Wen Congyang | info->d_endian = ELFDATA2LSB; |
411 | 25ae9c1d | Wen Congyang | |
412 | 25ae9c1d | Wen Congyang | if (lma) {
|
413 | 25ae9c1d | Wen Congyang | info->d_class = ELFCLASS64; |
414 | 25ae9c1d | Wen Congyang | } else {
|
415 | 25ae9c1d | Wen Congyang | info->d_class = ELFCLASS32; |
416 | 25ae9c1d | Wen Congyang | |
417 | 56c4bfb3 | Laszlo Ersek | QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) { |
418 | 56c4bfb3 | Laszlo Ersek | if (block->target_end > UINT_MAX) {
|
419 | 25ae9c1d | Wen Congyang | /* The memory size is greater than 4G */
|
420 | 25ae9c1d | Wen Congyang | info->d_class = ELFCLASS64; |
421 | 25ae9c1d | Wen Congyang | break;
|
422 | 25ae9c1d | Wen Congyang | } |
423 | 25ae9c1d | Wen Congyang | } |
424 | 25ae9c1d | Wen Congyang | } |
425 | 25ae9c1d | Wen Congyang | |
426 | 25ae9c1d | Wen Congyang | return 0; |
427 | 25ae9c1d | Wen Congyang | } |
428 | 0038ffb0 | Wen Congyang | |
429 | 4720bd05 | Paolo Bonzini | ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) |
430 | 0038ffb0 | Wen Congyang | { |
431 | 0038ffb0 | Wen Congyang | int name_size = 5; /* "CORE" or "QEMU" */ |
432 | 0038ffb0 | Wen Congyang | size_t elf_note_size = 0;
|
433 | 0038ffb0 | Wen Congyang | size_t qemu_note_size = 0;
|
434 | 0038ffb0 | Wen Congyang | int elf_desc_size = 0; |
435 | 0038ffb0 | Wen Congyang | int qemu_desc_size = 0; |
436 | 0038ffb0 | Wen Congyang | int note_head_size;
|
437 | 0038ffb0 | Wen Congyang | |
438 | 0038ffb0 | Wen Congyang | if (class == ELFCLASS32) {
|
439 | 0038ffb0 | Wen Congyang | note_head_size = sizeof(Elf32_Nhdr);
|
440 | 0038ffb0 | Wen Congyang | } else {
|
441 | 0038ffb0 | Wen Congyang | note_head_size = sizeof(Elf64_Nhdr);
|
442 | 0038ffb0 | Wen Congyang | } |
443 | 0038ffb0 | Wen Congyang | |
444 | 0038ffb0 | Wen Congyang | if (machine == EM_386) {
|
445 | 0038ffb0 | Wen Congyang | elf_desc_size = sizeof(x86_elf_prstatus);
|
446 | 0038ffb0 | Wen Congyang | } |
447 | 0038ffb0 | Wen Congyang | #ifdef TARGET_X86_64
|
448 | 0038ffb0 | Wen Congyang | else {
|
449 | 0038ffb0 | Wen Congyang | elf_desc_size = sizeof(x86_64_elf_prstatus);
|
450 | 0038ffb0 | Wen Congyang | } |
451 | 0038ffb0 | Wen Congyang | #endif
|
452 | 0038ffb0 | Wen Congyang | qemu_desc_size = sizeof(QEMUCPUState);
|
453 | 0038ffb0 | Wen Congyang | |
454 | 0038ffb0 | Wen Congyang | elf_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + |
455 | 0038ffb0 | Wen Congyang | (elf_desc_size + 3) / 4) * 4; |
456 | 0038ffb0 | Wen Congyang | qemu_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + |
457 | 0038ffb0 | Wen Congyang | (qemu_desc_size + 3) / 4) * 4; |
458 | 0038ffb0 | Wen Congyang | |
459 | 0038ffb0 | Wen Congyang | return (elf_note_size + qemu_note_size) * nr_cpus;
|
460 | 0038ffb0 | Wen Congyang | } |