All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wen Congyang <wency@cn.fujitsu.com>
To: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Eric Blake <eblake@redhat.com>,
	HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>,
	Dave Anderson <anderson@redhat.com>,
	qemu-devel <qemu-devel@nongnu.org>,
	Luiz Capitulino <lcapitulino@redhat.com>
Subject: Re: [Qemu-devel] [RFC][PATCH 06/16 v6] target-i386: Add API to write elf notes to core file
Date: Wed, 15 Feb 2012 11:16:33 +0800	[thread overview]
Message-ID: <4F3B2391.1010100@cn.fujitsu.com> (raw)
In-Reply-To: <4F3A9A6C.10408@siemens.com>

At 02/15/2012 01:31 AM, Jan Kiszka Wrote:
> On 2012-02-09 04:24, Wen Congyang wrote:
>> The core file contains register's value. These APIs write registers to
>> core file, and them will be called in the following patch.
>>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> ---
>>  cpu-all.h               |    6 +
>>  target-i386/arch-dump.c |  243 +++++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 249 insertions(+), 0 deletions(-)
>>
>> diff --git a/cpu-all.h b/cpu-all.h
>> index 4cd7fbb..efb5ba3 100644
>> --- a/cpu-all.h
>> +++ b/cpu-all.h
>> @@ -526,8 +526,14 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
>>  
>>  #if defined(TARGET_I386)
>>  void cpu_get_memory_mapping(MemoryMappingList *list, CPUState *env);
>> +int cpu_write_elf64_note(int fd, CPUState *env, int cpuid,
>> +                         target_phys_addr_t *offset);
>> +int cpu_write_elf32_note(int fd, CPUState *env, int cpuid,
>> +                         target_phys_addr_t *offset);
> 
> Again, some HAVE_XXX would be nicer. Maybe you put the whole block under
> HAVE_GUEST_CORE_DUMP or so.

OK

> 
> Is writing to file descriptor generic enough? What if we want to dump
> via QMP, letting the receiver side decide about where to write it?

Currently, writing to file descriptor is supported. If we want to
support some other target, I will modify the API and make the other
target is ealily supported.

> 
>>  #else
>>  #define cpu_get_memory_mapping(list, env)
>> +#define cpu_write_elf64_note(fd, env, cpuid, offset) ({ -1; })
>> +#define cpu_write_elf32_note(fd, env, cpuid, offset) ({ -1; })
>>  #endif
>>  
>>  #endif /* CPU_ALL_H */
>> diff --git a/target-i386/arch-dump.c b/target-i386/arch-dump.c
>> index 2e921c7..4c0ff77 100644
>> --- a/target-i386/arch-dump.c
>> +++ b/target-i386/arch-dump.c
>> @@ -11,8 +11,11 @@
>>   *
>>   */
>>  
>> +#include <elf.h>
> 
> Does this create a new dependency and break non-Linux hosts? Can you
> pull the required bits into qemu's elf.h then?

OK.

> 
>> +
>>  #include "cpu.h"
>>  #include "cpu-all.h"
>> +#include "monitor.h"
>>  
>>  /* PAE Paging or IA-32e Paging */
>>  static void walk_pte(MemoryMappingList *list, target_phys_addr_t pte_start_addr,
>> @@ -252,3 +255,243 @@ void cpu_get_memory_mapping(MemoryMappingList *list, CPUState *env)
>>          walk_pde2(list, pde_addr, env->a20_mask, pse);
>>      }
>>  }
>> +
>> +#ifdef TARGET_X86_64
>> +typedef struct {
>> +    target_ulong r15, r14, r13, r12, rbp, rbx, r11, r10;
>> +    target_ulong r9, r8, rax, rcx, rdx, rsi, rdi, orig_rax;
>> +    target_ulong rip, cs, eflags;
>> +    target_ulong rsp, ss;
>> +    target_ulong fs_base, gs_base;
>> +    target_ulong ds, es, fs, gs;
>> +} x86_64_user_regs_struct;
>> +
>> +static int x86_64_write_elf64_note(int fd, CPUState *env, int id,
>> +                                   target_phys_addr_t *offset)
>> +{
>> +    x86_64_user_regs_struct regs;
>> +    Elf64_Nhdr *note;
>> +    char *buf;
>> +    int descsz, note_size, name_size = 5;
>> +    const char *name = "CORE";
>> +    int ret;
>> +
>> +    regs.r15 = env->regs[15];
>> +    regs.r14 = env->regs[14];
>> +    regs.r13 = env->regs[13];
>> +    regs.r12 = env->regs[12];
>> +    regs.r11 = env->regs[11];
>> +    regs.r10 = env->regs[10];
>> +    regs.r9  = env->regs[9];
>> +    regs.r8  = env->regs[8];
>> +    regs.rbp = env->regs[R_EBP];
>> +    regs.rsp = env->regs[R_ESP];
>> +    regs.rdi = env->regs[R_EDI];
>> +    regs.rsi = env->regs[R_ESI];
>> +    regs.rdx = env->regs[R_EDX];
>> +    regs.rcx = env->regs[R_ECX];
>> +    regs.rbx = env->regs[R_EBX];
>> +    regs.rax = env->regs[R_EAX];
>> +    regs.rip = env->eip;
>> +    regs.eflags = env->eflags;
>> +
>> +    regs.orig_rax = 0; /* FIXME */
>> +    regs.cs = env->segs[R_CS].selector;
>> +    regs.ss = env->segs[R_SS].selector;
>> +    regs.fs_base = env->segs[R_FS].base;
>> +    regs.gs_base = env->segs[R_GS].base;
>> +    regs.ds = env->segs[R_DS].selector;
>> +    regs.es = env->segs[R_ES].selector;
>> +    regs.fs = env->segs[R_FS].selector;
>> +    regs.gs = env->segs[R_GS].selector;
>> +
>> +    descsz = 336; /* sizeof(prstatus_t) is 336 on x86_64 box */
>> +    note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
>> +                (descsz + 3) / 4) * 4;
>> +    note = g_malloc(note_size);
>> +
>> +    memset(note, 0, note_size);
>> +    note->n_namesz = cpu_to_le32(name_size);
>> +    note->n_descsz = cpu_to_le32(descsz);
>> +    note->n_type = cpu_to_le32(NT_PRSTATUS);
>> +    buf = (char *)note;
>> +    buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
>> +    memcpy(buf, name, name_size);
>> +    buf += ((name_size + 3) / 4) * 4;
>> +    memcpy(buf + 32, &id, 4); /* pr_pid */
>> +    buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong);
>> +    memcpy(buf, &regs, sizeof(x86_64_user_regs_struct));
>> +
>> +    lseek(fd, *offset, SEEK_SET);
>> +    ret = write(fd, note, note_size);
>> +    g_free(note);
>> +    if (ret < 0) {
>> +        return -1;
>> +    }
>> +
>> +    *offset += note_size;
>> +
>> +    return 0;
>> +}
>> +#endif
>> +
>> +typedef struct {
>> +    uint32_t ebx, ecx, edx, esi, edi, ebp, eax;
>> +    unsigned short ds, __ds, es, __es;
>> +    unsigned short fs, __fs, gs, __gs;
>> +    uint32_t orig_eax, eip;
>> +    unsigned short cs, __cs;
>> +    uint32_t eflags, esp;
>> +    unsigned short ss, __ss;
>> +} x86_user_regs_struct;
>> +
>> +static int x86_write_elf64_note(int fd, CPUState *env, int id,
>> +                                target_phys_addr_t *offset)
>> +{
>> +    x86_user_regs_struct regs;
>> +    Elf64_Nhdr *note;
>> +    char *buf;
>> +    int descsz, note_size, name_size = 5;
>> +    const char *name = "CORE";
>> +    int ret;
>> +
>> +    regs.ebp = env->regs[R_EBP] & 0xffffffff;
>> +    regs.esp = env->regs[R_ESP] & 0xffffffff;
>> +    regs.edi = env->regs[R_EDI] & 0xffffffff;
>> +    regs.esi = env->regs[R_ESI] & 0xffffffff;
>> +    regs.edx = env->regs[R_EDX] & 0xffffffff;
>> +    regs.ecx = env->regs[R_ECX] & 0xffffffff;
>> +    regs.ebx = env->regs[R_EBX] & 0xffffffff;
>> +    regs.eax = env->regs[R_EAX] & 0xffffffff;
>> +    regs.eip = env->eip & 0xffffffff;
>> +    regs.eflags = env->eflags & 0xffffffff;
>> +
>> +    regs.cs = env->segs[R_CS].selector;
>> +    regs.__cs = 0;
>> +    regs.ss = env->segs[R_SS].selector;
>> +    regs.__ss = 0;
>> +    regs.ds = env->segs[R_DS].selector;
>> +    regs.__ds = 0;
>> +    regs.es = env->segs[R_ES].selector;
>> +    regs.__es = 0;
>> +    regs.fs = env->segs[R_FS].selector;
>> +    regs.__fs = 0;
>> +    regs.gs = env->segs[R_GS].selector;
>> +    regs.__gs = 0;
>> +
>> +    descsz = 144; /* sizeof(prstatus_t) is 144 on x86 box */
>> +    note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
>> +                (descsz + 3) / 4) * 4;
>> +    note = g_malloc(note_size);
>> +
>> +    memset(note, 0, note_size);
>> +    note->n_namesz = cpu_to_le32(name_size);
>> +    note->n_descsz = cpu_to_le32(descsz);
>> +    note->n_type = cpu_to_le32(NT_PRSTATUS);
>> +    buf = (char *)note;
>> +    buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
>> +    memcpy(buf, name, name_size);
>> +    buf += ((name_size + 3) / 4) * 4;
>> +    memcpy(buf + 24, &id, 4); /* pr_pid */
>> +    buf += descsz - sizeof(x86_user_regs_struct)-4;
>> +    memcpy(buf, &regs, sizeof(x86_user_regs_struct));
>> +
>> +    lseek(fd, *offset, SEEK_SET);
>> +    ret = write(fd, note, note_size);
>> +    g_free(note);
>> +    if (ret < 0) {
>> +        return -1;
>> +    }
>> +
>> +    *offset += note_size;
>> +
>> +    return 0;
>> +}
>> +
>> +static int x86_write_elf32_note(int fd, CPUState *env, int id,
>> +                                target_phys_addr_t *offset)
>> +{
>> +    x86_user_regs_struct regs;
>> +    Elf32_Nhdr *note;
>> +    char *buf;
>> +    int descsz, note_size, name_size = 5;
>> +    const char *name = "CORE";
>> +    int ret;
>> +
>> +    regs.ebp = env->regs[R_EBP] & 0xffffffff;
>> +    regs.esp = env->regs[R_ESP] & 0xffffffff;
>> +    regs.edi = env->regs[R_EDI] & 0xffffffff;
>> +    regs.esi = env->regs[R_ESI] & 0xffffffff;
>> +    regs.edx = env->regs[R_EDX] & 0xffffffff;
>> +    regs.ecx = env->regs[R_ECX] & 0xffffffff;
>> +    regs.ebx = env->regs[R_EBX] & 0xffffffff;
>> +    regs.eax = env->regs[R_EAX] & 0xffffffff;
>> +    regs.eip = env->eip & 0xffffffff;
>> +    regs.eflags = env->eflags & 0xffffffff;
>> +
>> +    regs.cs = env->segs[R_CS].selector;
>> +    regs.__cs = 0;
>> +    regs.ss = env->segs[R_SS].selector;
>> +    regs.__ss = 0;
>> +    regs.ds = env->segs[R_DS].selector;
>> +    regs.__ds = 0;
>> +    regs.es = env->segs[R_ES].selector;
>> +    regs.__es = 0;
>> +    regs.fs = env->segs[R_FS].selector;
>> +    regs.__fs = 0;
>> +    regs.gs = env->segs[R_GS].selector;
>> +    regs.__gs = 0;
>> +
>> +    descsz = 144; /* sizeof(prstatus_t) is 144 on x86 box */
>> +    note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
>> +                (descsz + 3) / 4) * 4;
>> +    note = g_malloc(note_size);
>> +
>> +    memset(note, 0, note_size);
>> +    note->n_namesz = cpu_to_le32(name_size);
>> +    note->n_descsz = cpu_to_le32(descsz);
>> +    note->n_type = cpu_to_le32(NT_PRSTATUS);
>> +    buf = (char *)note;
>> +    buf += ((sizeof(Elf32_Nhdr) + 3) / 4) * 4;
>> +    memcpy(buf, name, name_size);
>> +    buf += ((name_size + 3) / 4) * 4;
>> +    memcpy(buf + 24, &id, 4); /* pr_pid */
>> +    buf += descsz - sizeof(x86_user_regs_struct)-4;
>> +    memcpy(buf, &regs, sizeof(x86_user_regs_struct));
>> +
>> +    lseek(fd, *offset, SEEK_SET);
>> +    ret = write(fd, note, note_size);
>> +    g_free(note);
>> +    if (ret < 0) {
>> +        return -1;
>> +    }
>> +
>> +    *offset += note_size;
>> +
>> +    return 0;
>> +}
>> +
>> +int cpu_write_elf64_note(int fd, CPUState *env, int cpuid,
>> +                         target_phys_addr_t *offset)
>> +{
>> +    int ret;
>> +#ifdef TARGET_X86_64
>> +    bool lma = !!(first_cpu->hflags & HF_LMA_MASK);
>> +
>> +    if (lma) {
>> +        ret = x86_64_write_elf64_note(fd, env, cpuid, offset);
>> +    } else {
>> +#endif
>> +        ret = x86_write_elf64_note(fd, env, cpuid, offset);
>> +#ifdef TARGET_X86_64
>> +    }
>> +#endif
>> +
>> +    return ret;
>> +}
>> +
>> +int cpu_write_elf32_note(int fd, CPUState *env, int cpuid,
>> +                         target_phys_addr_t *offset)
>> +{
>> +    return x86_write_elf32_note(fd, env, cpuid, offset);
>> +}
> 
> Minor nit: I think this wrapping is not needed, just fold
> x86_write_elf32_note into this function.

OK

Thanks
Wen Congyang

> 
> Jan
> 

  reply	other threads:[~2012-02-15  3:16 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-09  3:16 [Qemu-devel] [RFC][PATCH 00/16 v6] introducing a new, dedicated memory dump mechanism Wen Congyang
2012-02-09  3:19 ` [Qemu-devel] [RFC][PATCH 01/16 v6] monitor: introduce qemu_suspend_monitor()/qemu_resume_monitor() Wen Congyang
2012-02-14 16:19   ` Jan Kiszka
2012-02-15  2:54     ` Wen Congyang
2012-02-15  8:51       ` Jan Kiszka
2012-02-15 13:01         ` Luiz Capitulino
2012-02-16  1:35           ` Wen Congyang
2012-02-09  3:20 ` [Qemu-devel] [RFC][PATCH 02/16 v6] Add API to create memory mapping list Wen Congyang
2012-02-14 16:39   ` Jan Kiszka
2012-02-15  3:00     ` Wen Congyang
2012-02-09  3:21 ` [Qemu-devel] [RFC][PATCH 03/16 v6] Add API to check whether a physical address is I/O address Wen Congyang
2012-02-14 16:52   ` Jan Kiszka
2012-02-15  3:03     ` Wen Congyang
2012-02-09  3:21 ` [Qemu-devel] [RFC][PATCH 04/16 v6] target-i386: implement cpu_get_memory_mapping() Wen Congyang
2012-02-14 17:07   ` Jan Kiszka
2012-02-15  3:05     ` Wen Congyang
2012-02-09  3:22 ` [Qemu-devel] [RFC][PATCH 05/16 v6] Add API to get memory mapping Wen Congyang
2012-02-14 17:21   ` Jan Kiszka
2012-02-15  4:07     ` Wen Congyang
2012-02-15  9:17       ` Jan Kiszka
2012-02-15  9:41         ` Wen Congyang
2012-02-15  9:47           ` HATAYAMA Daisuke
2012-02-15 10:19             ` Jan Kiszka
2012-02-09  3:24 ` [Qemu-devel] [RFC][PATCH 06/16 v6] target-i386: Add API to write elf notes to core file Wen Congyang
2012-02-14 17:31   ` Jan Kiszka
2012-02-15  3:16     ` Wen Congyang [this message]
2012-02-09  3:24 ` [Qemu-devel] [RFC][PATCH 07/16 v6] target-i386: Add API to add extra memory mapping Wen Congyang
2012-02-14 17:35   ` Jan Kiszka
2012-02-15  5:19     ` Wen Congyang
2012-02-15  9:21       ` Jan Kiszka
2012-02-15  9:44         ` Wen Congyang
2012-02-15 10:21           ` Jan Kiszka
2012-02-17  9:32             ` Wen Congyang
2012-02-17 11:34               ` HATAYAMA Daisuke
2012-02-09  3:26 ` [Qemu-devel] [RFC][PATCH 08/16 v6] target-i386: add API to get dump info Wen Congyang
2012-02-14 17:39   ` Jan Kiszka
2012-02-15  3:30     ` Wen Congyang
2012-02-15  9:05       ` Jan Kiszka
2012-02-15  9:10         ` Wen Congyang
2012-02-15  9:12   ` Peter Maydell
2012-02-15  9:19     ` Wen Congyang
2012-02-09  3:28 ` [Qemu-devel] [RFC][PATCH 09/16 v6] introduce a new monitor command 'dump' to dump guest's memory Wen Congyang
2012-02-14 17:59   ` Jan Kiszka
2012-02-15  3:44     ` Wen Congyang
2012-02-17  8:52     ` Wen Congyang
2012-02-17  9:26       ` Jan Kiszka
2012-02-17  9:35         ` Wen Congyang
2012-02-17  9:35           ` Jan Kiszka
2012-02-17 16:32       ` Eric Blake
2012-02-17 16:51         ` Jan Kiszka
2012-02-17 17:05           ` Eric Blake
2012-02-09  3:28 ` [Qemu-devel] [RFC][PATCH 10/16 v6] run dump at the background Wen Congyang
2012-02-14 18:05   ` Jan Kiszka
2012-02-14 18:27     ` Jan Kiszka
2012-02-15  3:47       ` Wen Congyang
2012-02-15  9:07         ` Jan Kiszka
2012-02-15  9:22           ` Wen Congyang
2012-02-15  9:21             ` Jan Kiszka
2012-02-15  9:35               ` Wen Congyang
2012-02-15 10:16                 ` Jan Kiszka
2012-02-09  3:29 ` [Qemu-devel] [RFC][PATCH 11/16 v6] support detached dump Wen Congyang
2012-02-09  3:30 ` [Qemu-devel] [RFC][PATCH 12/16 v6] support to cancel the current dumping Wen Congyang
2012-02-09  3:32 ` [Qemu-devel] [RFC][PATCH 13/16 v6] support to set dumping speed Wen Congyang
2012-02-09  3:32 ` [Qemu-devel] [RFC][PATCH 14/16 v6] support to query dumping status Wen Congyang
2012-02-09  3:33 ` [Qemu-devel] [RFC][PATCH 15/16 v6] auto cancel dumping after vm state is changed to run Wen Congyang
2012-02-09  3:34 ` [Qemu-devel] [RFC][PATCH 16/16 v6] allow user to dump a fraction of the memory Wen Congyang
2012-02-14 18:27   ` Jan Kiszka
2012-02-13  1:45 ` [Qemu-devel] [RFC][PATCH 00/16 v6] introducing a new, dedicated memory dump mechanism Wen Congyang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F3B2391.1010100@cn.fujitsu.com \
    --to=wency@cn.fujitsu.com \
    --cc=anderson@redhat.com \
    --cc=d.hatayama@jp.fujitsu.com \
    --cc=eblake@redhat.com \
    --cc=jan.kiszka@siemens.com \
    --cc=lcapitulino@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.