Patchwork [2/4] dump: extract out note helper

login
register
mail settings
Submitter Rabin Vincent
Date June 20, 2012, 5:28 p.m.
Message ID <1340213303-596-2-git-send-email-rabin@rab.in>
Download mbox | patch
Permalink /patch/166132/
State New
Headers show

Comments

Rabin Vincent - June 20, 2012, 5:28 p.m.
Make a common helper function to add ELF notes.

Signed-off-by: Rabin Vincent <rabin@rab.in>
---
 dump.c                  |   49 +++++++++++
 dump.h                  |    4 +
 target-i386/arch_dump.c |  206 +++++++++++------------------------------------
 3 files changed, 100 insertions(+), 159 deletions(-)
Wen Congyang - July 4, 2012, 2:21 a.m.
Hi, Rabin

Sorry for later reviewing...

At 06/21/2012 01:28 AM, Rabin Vincent Wrote:
> Make a common helper function to add ELF notes.
> 
> Signed-off-by: Rabin Vincent <rabin@rab.in>
> ---
>  dump.c                  |   49 +++++++++++
>  dump.h                  |    4 +
>  target-i386/arch_dump.c |  206 +++++++++++------------------------------------
>  3 files changed, 100 insertions(+), 159 deletions(-)
> 
> diff --git a/dump.c b/dump.c
> index 5c5cb4d..be96c6c 100644
> --- a/dump.c
> +++ b/dump.c
> @@ -468,6 +468,55 @@ static target_phys_addr_t get_offset(target_phys_addr_t phys_addr,
>      return -1;
>  }
>  
> +int dump_write_elf_note(int class, const char *name, uint32_t type,
> +                        void *desc, size_t descsz,
> +                        write_core_dump_function f, void *opaque)
> +{
> +    Elf64_Nhdr *note64;
> +    Elf32_Nhdr *note32;
> +    void *note;
> +    char *buf;
> +    size_t note_size, name_size, note_head_size;
> +    int ret;
> +
> +    name_size = strlen(name) + 1;
> +
> +    if (class == ELFCLASS32) {
> +        note_head_size = sizeof(Elf32_Nhdr);
> +    } else {
> +        note_head_size = sizeof(Elf64_Nhdr);
> +    }
> +    note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
> +                (descsz + 3) / 4) * 4;
> +    note = g_malloc(note_size);
> +
> +    memset(note, 0, note_size);
> +    if (class == ELFCLASS32) {
> +        note32 = note;
> +        note32->n_namesz = cpu_to_le32(name_size);
> +        note32->n_descsz = cpu_to_le32(descsz);
> +        note32->n_type = cpu_to_le32(type);

This function may be called by all targets, so you can not say the target
is little endian.

The other code looks fine to me.

Thanks
Wen Congyang
> +    } else {
> +        note64 = note;
> +        note64->n_namesz = cpu_to_le32(name_size);
> +        note64->n_descsz = cpu_to_le32(descsz);
> +        note64->n_type = cpu_to_le32(type);
> +    }
> +    buf = note;
> +    buf += ((note_head_size + 3) / 4) * 4;
> +    memcpy(buf, name, name_size);
> +    buf += ((name_size + 3) / 4) * 4;
> +    memcpy(buf, desc, descsz);
> +
> +    ret = f(note, note_size, opaque);
> +    g_free(note);
> +    if (ret < 0) {
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
>  static int write_elf_loads(DumpState *s)
>  {
>      target_phys_addr_t offset;
> diff --git a/dump.h b/dump.h
> index e25b7cf..b07816a 100644
> --- a/dump.h
> +++ b/dump.h
> @@ -32,4 +32,8 @@ int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
>  int cpu_get_dump_info(ArchDumpInfo *info);
>  ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
>  
> +int dump_write_elf_note(int class, const char *name, uint32_t type, void *desc,
> +                        size_t descsz, write_core_dump_function f,
> +                        void *opaque);
> +
>  #endif
> diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
> index 4240278..dbc94bc 100644
> --- a/target-i386/arch_dump.c
> +++ b/target-i386/arch_dump.c
> @@ -38,66 +38,41 @@ static int x86_64_write_elf64_note(write_core_dump_function f,
>                                     CPUArchState *env, int id,
>                                     void *opaque)
>  {
> -    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 = sizeof(x86_64_elf_prstatus);
> -    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));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
> -
> -    return 0;
> +    x86_64_elf_prstatus prstatus;
> +
> +    prstatus.pid = id;
> +    prstatus.regs.r15 = env->regs[15];
> +    prstatus.regs.r14 = env->regs[14];
> +    prstatus.regs.r13 = env->regs[13];
> +    prstatus.regs.r12 = env->regs[12];
> +    prstatus.regs.r11 = env->regs[11];
> +    prstatus.regs.r10 = env->regs[10];
> +    prstatus.regs.r9  = env->regs[9];
> +    prstatus.regs.r8  = env->regs[8];
> +    prstatus.regs.rbp = env->regs[R_EBP];
> +    prstatus.regs.rsp = env->regs[R_ESP];
> +    prstatus.regs.rdi = env->regs[R_EDI];
> +    prstatus.regs.rsi = env->regs[R_ESI];
> +    prstatus.regs.rdx = env->regs[R_EDX];
> +    prstatus.regs.rcx = env->regs[R_ECX];
> +    prstatus.regs.rbx = env->regs[R_EBX];
> +    prstatus.regs.rax = env->regs[R_EAX];
> +    prstatus.regs.rip = env->eip;
> +    prstatus.regs.eflags = env->eflags;
> +
> +    prstatus.regs.orig_rax = 0; /* FIXME */
> +    prstatus.regs.cs = env->segs[R_CS].selector;
> +    prstatus.regs.ss = env->segs[R_SS].selector;
> +    prstatus.regs.fs_base = env->segs[R_FS].base;
> +    prstatus.regs.gs_base = env->segs[R_GS].base;
> +    prstatus.regs.ds = env->segs[R_DS].selector;
> +    prstatus.regs.es = env->segs[R_ES].selector;
> +    prstatus.regs.fs = env->segs[R_FS].selector;
> +    prstatus.regs.gs = env->segs[R_GS].selector;
> +
> +    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  #endif
>  
> @@ -148,35 +123,12 @@ static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env,
>                                  int id, void *opaque)
>  {
>      x86_elf_prstatus prstatus;
> -    Elf64_Nhdr *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5;
> -    const char *name = "CORE";
> -    int ret;
>  
>      x86_fill_elf_prstatus(&prstatus, env, id);
> -    descsz = sizeof(x86_elf_prstatus);
> -    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, &prstatus, sizeof(prstatus));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
>  
> -    return 0;
> +    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  
>  int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
> @@ -202,35 +154,12 @@ int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
>                           int cpuid, void *opaque)
>  {
>      x86_elf_prstatus prstatus;
> -    Elf32_Nhdr *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5;
> -    const char *name = "CORE";
> -    int ret;
>  
>      x86_fill_elf_prstatus(&prstatus, env, cpuid);
> -    descsz = sizeof(x86_elf_prstatus);
> -    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, &prstatus, sizeof(prstatus));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
>  
> -    return 0;
> +    return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  
>  /*
> @@ -317,69 +246,28 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
>      s->cr[4] = env->cr[4];
>  }
>  
> -static inline int cpu_write_qemu_note(write_core_dump_function f,
> +static inline int cpu_write_qemu_note(int class, write_core_dump_function f,
>                                        CPUArchState *env,
> -                                      void *opaque,
> -                                      int type)
> +                                      void *opaque)
>  {
>      QEMUCPUState state;
> -    Elf64_Nhdr *note64;
> -    Elf32_Nhdr *note32;
> -    void *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5, note_head_size;
> -    const char *name = "QEMU";
> -    int ret;
>  
>      qemu_get_cpustate(&state, env);
>  
> -    descsz = sizeof(state);
> -    if (type == 0) {
> -        note_head_size = sizeof(Elf32_Nhdr);
> -    } else {
> -        note_head_size = sizeof(Elf64_Nhdr);
> -    }
> -    note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
> -                (descsz + 3) / 4) * 4;
> -    note = g_malloc(note_size);
> -
> -    memset(note, 0, note_size);
> -    if (type == 0) {
> -        note32 = note;
> -        note32->n_namesz = cpu_to_le32(name_size);
> -        note32->n_descsz = cpu_to_le32(descsz);
> -        note32->n_type = 0;
> -    } else {
> -        note64 = note;
> -        note64->n_namesz = cpu_to_le32(name_size);
> -        note64->n_descsz = cpu_to_le32(descsz);
> -        note64->n_type = 0;
> -    }
> -    buf = note;
> -    buf += ((note_head_size + 3) / 4) * 4;
> -    memcpy(buf, name, name_size);
> -    buf += ((name_size + 3) / 4) * 4;
> -    memcpy(buf, &state, sizeof(state));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
> -
> -    return 0;
> +    return dump_write_elf_note(class, "QEMU", 0, &state, sizeof(state),
> +                               f, opaque);
>  }
>  
>  int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
>                               void *opaque)
>  {
> -    return cpu_write_qemu_note(f, env, opaque, 1);
> +    return cpu_write_qemu_note(ELFCLASS64, f, env, opaque);
>  }
>  
>  int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
>                               void *opaque)
>  {
> -    return cpu_write_qemu_note(f, env, opaque, 0);
> +    return cpu_write_qemu_note(ELFCLASS32, f, env, opaque);
>  }
>  
>  int cpu_get_dump_info(ArchDumpInfo *info)
Wen Congyang - July 4, 2012, 2:31 a.m.
At 06/21/2012 01:28 AM, Rabin Vincent Wrote:
> Make a common helper function to add ELF notes.
> 
> Signed-off-by: Rabin Vincent <rabin@rab.in>
> ---
>  dump.c                  |   49 +++++++++++
>  dump.h                  |    4 +
>  target-i386/arch_dump.c |  206 +++++++++++------------------------------------
>  3 files changed, 100 insertions(+), 159 deletions(-)
> 
> diff --git a/dump.c b/dump.c
> index 5c5cb4d..be96c6c 100644
> --- a/dump.c
> +++ b/dump.c
> @@ -468,6 +468,55 @@ static target_phys_addr_t get_offset(target_phys_addr_t phys_addr,
>      return -1;
>  }
>  
> +int dump_write_elf_note(int class, const char *name, uint32_t type,
> +                        void *desc, size_t descsz,
> +                        write_core_dump_function f, void *opaque)
> +{
> +    Elf64_Nhdr *note64;
> +    Elf32_Nhdr *note32;
> +    void *note;
> +    char *buf;
> +    size_t note_size, name_size, note_head_size;
> +    int ret;
> +
> +    name_size = strlen(name) + 1;
> +
> +    if (class == ELFCLASS32) {
> +        note_head_size = sizeof(Elf32_Nhdr);
> +    } else {
> +        note_head_size = sizeof(Elf64_Nhdr);
> +    }
> +    note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
> +                (descsz + 3) / 4) * 4;
> +    note = g_malloc(note_size);
> +
> +    memset(note, 0, note_size);
> +    if (class == ELFCLASS32) {
> +        note32 = note;
> +        note32->n_namesz = cpu_to_le32(name_size);
> +        note32->n_descsz = cpu_to_le32(descsz);
> +        note32->n_type = cpu_to_le32(type);
> +    } else {
> +        note64 = note;
> +        note64->n_namesz = cpu_to_le32(name_size);
> +        note64->n_descsz = cpu_to_le32(descsz);
> +        note64->n_type = cpu_to_le32(type);
> +    }
> +    buf = note;
> +    buf += ((note_head_size + 3) / 4) * 4;
> +    memcpy(buf, name, name_size);
> +    buf += ((name_size + 3) / 4) * 4;
> +    memcpy(buf, desc, descsz);
> +
> +    ret = f(note, note_size, opaque);
> +    g_free(note);
> +    if (ret < 0) {
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
>  static int write_elf_loads(DumpState *s)
>  {
>      target_phys_addr_t offset;
> diff --git a/dump.h b/dump.h
> index e25b7cf..b07816a 100644
> --- a/dump.h
> +++ b/dump.h
> @@ -32,4 +32,8 @@ int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
>  int cpu_get_dump_info(ArchDumpInfo *info);
>  ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
>  
> +int dump_write_elf_note(int class, const char *name, uint32_t type, void *desc,
> +                        size_t descsz, write_core_dump_function f,
> +                        void *opaque);
> +
>  #endif
> diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
> index 4240278..dbc94bc 100644
> --- a/target-i386/arch_dump.c
> +++ b/target-i386/arch_dump.c
> @@ -38,66 +38,41 @@ static int x86_64_write_elf64_note(write_core_dump_function f,
>                                     CPUArchState *env, int id,
>                                     void *opaque)
>  {
> -    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 = sizeof(x86_64_elf_prstatus);
> -    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));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
> -
> -    return 0;
> +    x86_64_elf_prstatus prstatus;

You should set all fileds of prstatus to 0. If not,
I guess you may meet some surprising problem when
you deal with the core.

Thanks
Wen Congyang

> +
> +    prstatus.pid = id;
> +    prstatus.regs.r15 = env->regs[15];
> +    prstatus.regs.r14 = env->regs[14];
> +    prstatus.regs.r13 = env->regs[13];
> +    prstatus.regs.r12 = env->regs[12];
> +    prstatus.regs.r11 = env->regs[11];
> +    prstatus.regs.r10 = env->regs[10];
> +    prstatus.regs.r9  = env->regs[9];
> +    prstatus.regs.r8  = env->regs[8];
> +    prstatus.regs.rbp = env->regs[R_EBP];
> +    prstatus.regs.rsp = env->regs[R_ESP];
> +    prstatus.regs.rdi = env->regs[R_EDI];
> +    prstatus.regs.rsi = env->regs[R_ESI];
> +    prstatus.regs.rdx = env->regs[R_EDX];
> +    prstatus.regs.rcx = env->regs[R_ECX];
> +    prstatus.regs.rbx = env->regs[R_EBX];
> +    prstatus.regs.rax = env->regs[R_EAX];
> +    prstatus.regs.rip = env->eip;
> +    prstatus.regs.eflags = env->eflags;
> +
> +    prstatus.regs.orig_rax = 0; /* FIXME */
> +    prstatus.regs.cs = env->segs[R_CS].selector;
> +    prstatus.regs.ss = env->segs[R_SS].selector;
> +    prstatus.regs.fs_base = env->segs[R_FS].base;
> +    prstatus.regs.gs_base = env->segs[R_GS].base;
> +    prstatus.regs.ds = env->segs[R_DS].selector;
> +    prstatus.regs.es = env->segs[R_ES].selector;
> +    prstatus.regs.fs = env->segs[R_FS].selector;
> +    prstatus.regs.gs = env->segs[R_GS].selector;
> +
> +    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  #endif
>  
> @@ -148,35 +123,12 @@ static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env,
>                                  int id, void *opaque)
>  {
>      x86_elf_prstatus prstatus;
> -    Elf64_Nhdr *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5;
> -    const char *name = "CORE";
> -    int ret;
>  
>      x86_fill_elf_prstatus(&prstatus, env, id);
> -    descsz = sizeof(x86_elf_prstatus);
> -    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, &prstatus, sizeof(prstatus));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
>  
> -    return 0;
> +    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  
>  int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
> @@ -202,35 +154,12 @@ int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
>                           int cpuid, void *opaque)
>  {
>      x86_elf_prstatus prstatus;
> -    Elf32_Nhdr *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5;
> -    const char *name = "CORE";
> -    int ret;
>  
>      x86_fill_elf_prstatus(&prstatus, env, cpuid);
> -    descsz = sizeof(x86_elf_prstatus);
> -    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, &prstatus, sizeof(prstatus));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
>  
> -    return 0;
> +    return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS,
> +                               &prstatus, sizeof(prstatus),
> +                               f, opaque);
>  }
>  
>  /*
> @@ -317,69 +246,28 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
>      s->cr[4] = env->cr[4];
>  }
>  
> -static inline int cpu_write_qemu_note(write_core_dump_function f,
> +static inline int cpu_write_qemu_note(int class, write_core_dump_function f,
>                                        CPUArchState *env,
> -                                      void *opaque,
> -                                      int type)
> +                                      void *opaque)
>  {
>      QEMUCPUState state;
> -    Elf64_Nhdr *note64;
> -    Elf32_Nhdr *note32;
> -    void *note;
> -    char *buf;
> -    int descsz, note_size, name_size = 5, note_head_size;
> -    const char *name = "QEMU";
> -    int ret;
>  
>      qemu_get_cpustate(&state, env);
>  
> -    descsz = sizeof(state);
> -    if (type == 0) {
> -        note_head_size = sizeof(Elf32_Nhdr);
> -    } else {
> -        note_head_size = sizeof(Elf64_Nhdr);
> -    }
> -    note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
> -                (descsz + 3) / 4) * 4;
> -    note = g_malloc(note_size);
> -
> -    memset(note, 0, note_size);
> -    if (type == 0) {
> -        note32 = note;
> -        note32->n_namesz = cpu_to_le32(name_size);
> -        note32->n_descsz = cpu_to_le32(descsz);
> -        note32->n_type = 0;
> -    } else {
> -        note64 = note;
> -        note64->n_namesz = cpu_to_le32(name_size);
> -        note64->n_descsz = cpu_to_le32(descsz);
> -        note64->n_type = 0;
> -    }
> -    buf = note;
> -    buf += ((note_head_size + 3) / 4) * 4;
> -    memcpy(buf, name, name_size);
> -    buf += ((name_size + 3) / 4) * 4;
> -    memcpy(buf, &state, sizeof(state));
> -
> -    ret = f(note, note_size, opaque);
> -    g_free(note);
> -    if (ret < 0) {
> -        return -1;
> -    }
> -
> -    return 0;
> +    return dump_write_elf_note(class, "QEMU", 0, &state, sizeof(state),
> +                               f, opaque);
>  }
>  
>  int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
>                               void *opaque)
>  {
> -    return cpu_write_qemu_note(f, env, opaque, 1);
> +    return cpu_write_qemu_note(ELFCLASS64, f, env, opaque);
>  }
>  
>  int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
>                               void *opaque)
>  {
> -    return cpu_write_qemu_note(f, env, opaque, 0);
> +    return cpu_write_qemu_note(ELFCLASS32, f, env, opaque);
>  }
>  
>  int cpu_get_dump_info(ArchDumpInfo *info)

Patch

diff --git a/dump.c b/dump.c
index 5c5cb4d..be96c6c 100644
--- a/dump.c
+++ b/dump.c
@@ -468,6 +468,55 @@  static target_phys_addr_t get_offset(target_phys_addr_t phys_addr,
     return -1;
 }
 
+int dump_write_elf_note(int class, const char *name, uint32_t type,
+                        void *desc, size_t descsz,
+                        write_core_dump_function f, void *opaque)
+{
+    Elf64_Nhdr *note64;
+    Elf32_Nhdr *note32;
+    void *note;
+    char *buf;
+    size_t note_size, name_size, note_head_size;
+    int ret;
+
+    name_size = strlen(name) + 1;
+
+    if (class == ELFCLASS32) {
+        note_head_size = sizeof(Elf32_Nhdr);
+    } else {
+        note_head_size = sizeof(Elf64_Nhdr);
+    }
+    note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
+                (descsz + 3) / 4) * 4;
+    note = g_malloc(note_size);
+
+    memset(note, 0, note_size);
+    if (class == ELFCLASS32) {
+        note32 = note;
+        note32->n_namesz = cpu_to_le32(name_size);
+        note32->n_descsz = cpu_to_le32(descsz);
+        note32->n_type = cpu_to_le32(type);
+    } else {
+        note64 = note;
+        note64->n_namesz = cpu_to_le32(name_size);
+        note64->n_descsz = cpu_to_le32(descsz);
+        note64->n_type = cpu_to_le32(type);
+    }
+    buf = note;
+    buf += ((note_head_size + 3) / 4) * 4;
+    memcpy(buf, name, name_size);
+    buf += ((name_size + 3) / 4) * 4;
+    memcpy(buf, desc, descsz);
+
+    ret = f(note, note_size, opaque);
+    g_free(note);
+    if (ret < 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
 static int write_elf_loads(DumpState *s)
 {
     target_phys_addr_t offset;
diff --git a/dump.h b/dump.h
index e25b7cf..b07816a 100644
--- a/dump.h
+++ b/dump.h
@@ -32,4 +32,8 @@  int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
 int cpu_get_dump_info(ArchDumpInfo *info);
 ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
 
+int dump_write_elf_note(int class, const char *name, uint32_t type, void *desc,
+                        size_t descsz, write_core_dump_function f,
+                        void *opaque);
+
 #endif
diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
index 4240278..dbc94bc 100644
--- a/target-i386/arch_dump.c
+++ b/target-i386/arch_dump.c
@@ -38,66 +38,41 @@  static int x86_64_write_elf64_note(write_core_dump_function f,
                                    CPUArchState *env, int id,
                                    void *opaque)
 {
-    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 = sizeof(x86_64_elf_prstatus);
-    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));
-
-    ret = f(note, note_size, opaque);
-    g_free(note);
-    if (ret < 0) {
-        return -1;
-    }
-
-    return 0;
+    x86_64_elf_prstatus prstatus;
+
+    prstatus.pid = id;
+    prstatus.regs.r15 = env->regs[15];
+    prstatus.regs.r14 = env->regs[14];
+    prstatus.regs.r13 = env->regs[13];
+    prstatus.regs.r12 = env->regs[12];
+    prstatus.regs.r11 = env->regs[11];
+    prstatus.regs.r10 = env->regs[10];
+    prstatus.regs.r9  = env->regs[9];
+    prstatus.regs.r8  = env->regs[8];
+    prstatus.regs.rbp = env->regs[R_EBP];
+    prstatus.regs.rsp = env->regs[R_ESP];
+    prstatus.regs.rdi = env->regs[R_EDI];
+    prstatus.regs.rsi = env->regs[R_ESI];
+    prstatus.regs.rdx = env->regs[R_EDX];
+    prstatus.regs.rcx = env->regs[R_ECX];
+    prstatus.regs.rbx = env->regs[R_EBX];
+    prstatus.regs.rax = env->regs[R_EAX];
+    prstatus.regs.rip = env->eip;
+    prstatus.regs.eflags = env->eflags;
+
+    prstatus.regs.orig_rax = 0; /* FIXME */
+    prstatus.regs.cs = env->segs[R_CS].selector;
+    prstatus.regs.ss = env->segs[R_SS].selector;
+    prstatus.regs.fs_base = env->segs[R_FS].base;
+    prstatus.regs.gs_base = env->segs[R_GS].base;
+    prstatus.regs.ds = env->segs[R_DS].selector;
+    prstatus.regs.es = env->segs[R_ES].selector;
+    prstatus.regs.fs = env->segs[R_FS].selector;
+    prstatus.regs.gs = env->segs[R_GS].selector;
+
+    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
+                               &prstatus, sizeof(prstatus),
+                               f, opaque);
 }
 #endif
 
@@ -148,35 +123,12 @@  static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env,
                                 int id, void *opaque)
 {
     x86_elf_prstatus prstatus;
-    Elf64_Nhdr *note;
-    char *buf;
-    int descsz, note_size, name_size = 5;
-    const char *name = "CORE";
-    int ret;
 
     x86_fill_elf_prstatus(&prstatus, env, id);
-    descsz = sizeof(x86_elf_prstatus);
-    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, &prstatus, sizeof(prstatus));
-
-    ret = f(note, note_size, opaque);
-    g_free(note);
-    if (ret < 0) {
-        return -1;
-    }
 
-    return 0;
+    return dump_write_elf_note(ELFCLASS64, "CORE", NT_PRSTATUS,
+                               &prstatus, sizeof(prstatus),
+                               f, opaque);
 }
 
 int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
@@ -202,35 +154,12 @@  int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
                          int cpuid, void *opaque)
 {
     x86_elf_prstatus prstatus;
-    Elf32_Nhdr *note;
-    char *buf;
-    int descsz, note_size, name_size = 5;
-    const char *name = "CORE";
-    int ret;
 
     x86_fill_elf_prstatus(&prstatus, env, cpuid);
-    descsz = sizeof(x86_elf_prstatus);
-    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, &prstatus, sizeof(prstatus));
-
-    ret = f(note, note_size, opaque);
-    g_free(note);
-    if (ret < 0) {
-        return -1;
-    }
 
-    return 0;
+    return dump_write_elf_note(ELFCLASS32, "CORE", NT_PRSTATUS,
+                               &prstatus, sizeof(prstatus),
+                               f, opaque);
 }
 
 /*
@@ -317,69 +246,28 @@  static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
     s->cr[4] = env->cr[4];
 }
 
-static inline int cpu_write_qemu_note(write_core_dump_function f,
+static inline int cpu_write_qemu_note(int class, write_core_dump_function f,
                                       CPUArchState *env,
-                                      void *opaque,
-                                      int type)
+                                      void *opaque)
 {
     QEMUCPUState state;
-    Elf64_Nhdr *note64;
-    Elf32_Nhdr *note32;
-    void *note;
-    char *buf;
-    int descsz, note_size, name_size = 5, note_head_size;
-    const char *name = "QEMU";
-    int ret;
 
     qemu_get_cpustate(&state, env);
 
-    descsz = sizeof(state);
-    if (type == 0) {
-        note_head_size = sizeof(Elf32_Nhdr);
-    } else {
-        note_head_size = sizeof(Elf64_Nhdr);
-    }
-    note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
-                (descsz + 3) / 4) * 4;
-    note = g_malloc(note_size);
-
-    memset(note, 0, note_size);
-    if (type == 0) {
-        note32 = note;
-        note32->n_namesz = cpu_to_le32(name_size);
-        note32->n_descsz = cpu_to_le32(descsz);
-        note32->n_type = 0;
-    } else {
-        note64 = note;
-        note64->n_namesz = cpu_to_le32(name_size);
-        note64->n_descsz = cpu_to_le32(descsz);
-        note64->n_type = 0;
-    }
-    buf = note;
-    buf += ((note_head_size + 3) / 4) * 4;
-    memcpy(buf, name, name_size);
-    buf += ((name_size + 3) / 4) * 4;
-    memcpy(buf, &state, sizeof(state));
-
-    ret = f(note, note_size, opaque);
-    g_free(note);
-    if (ret < 0) {
-        return -1;
-    }
-
-    return 0;
+    return dump_write_elf_note(class, "QEMU", 0, &state, sizeof(state),
+                               f, opaque);
 }
 
 int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
                              void *opaque)
 {
-    return cpu_write_qemu_note(f, env, opaque, 1);
+    return cpu_write_qemu_note(ELFCLASS64, f, env, opaque);
 }
 
 int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
                              void *opaque)
 {
-    return cpu_write_qemu_note(f, env, opaque, 0);
+    return cpu_write_qemu_note(ELFCLASS32, f, env, opaque);
 }
 
 int cpu_get_dump_info(ArchDumpInfo *info)