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