~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to target-i386/arch_dump.c

  • Committer: Phil Dennis-Jordan
  • Author(s): Michael Tokarev
  • Date: 2017-05-23 06:58:03 UTC
  • Revision ID: phil@philjordan.eu-20170523065803-3subwvf3y8kzkjry
Tags: upstream-2.8+dfsg
ImportĀ upstreamĀ versionĀ 2.8+dfsg

Show diffs side-by-side

added added

removed removed

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