On Thu, Jul 21, 2022 at 5:23 PM Janosch Frank <fran...@linux.ibm.com> wrote: > > Allocating the header lets us write it at a later time and hence also > allows us to change section and segment table offsets until we > finally write it. > > Signed-off-by: Janosch Frank <fran...@linux.ibm.com>
you could have added from v2 Reviewed-by: Marc-André Lureau <marcandre.lur...@redhat.com> > --- > dump/dump.c | 127 +++++++++++++++++++++--------------------- > include/sysemu/dump.h | 1 + > 2 files changed, 64 insertions(+), 64 deletions(-) > > diff --git a/dump/dump.c b/dump/dump.c > index 5c9ed25c5a..2d04e06815 100644 > --- a/dump/dump.c > +++ b/dump/dump.c > @@ -98,6 +98,7 @@ static int dump_cleanup(DumpState *s) > memory_mapping_list_free(&s->list); > close(s->fd); > g_free(s->guest_note); > + g_free(s->elf_header); > s->guest_note = NULL; > if (s->resume) { > if (s->detached) { > @@ -126,73 +127,49 @@ static int fd_write_vmcore(const void *buf, size_t > size, void *opaque) > return 0; > } > > -static void write_elf64_header(DumpState *s, Error **errp) > +static void prepare_elf64_header(DumpState *s) > { > - /* > - * phnum in the elf header is 16 bit, if we have more segments we > - * set phnum to PN_XNUM and write the real number of segments to a > - * special section. > - */ > - uint16_t phnum = MIN(s->phdr_num, PN_XNUM); > - Elf64_Ehdr elf_header; > - int ret; > + uint16_t phnum = s->phdr_num >= PN_XNUM ? PN_XNUM : s->phdr_num; > + Elf64_Ehdr *elf_header = s->elf_header; > > - memset(&elf_header, 0, sizeof(Elf64_Ehdr)); > - memcpy(&elf_header, ELFMAG, SELFMAG); > - elf_header.e_ident[EI_CLASS] = ELFCLASS64; > - elf_header.e_ident[EI_DATA] = s->dump_info.d_endian; > - elf_header.e_ident[EI_VERSION] = EV_CURRENT; > - elf_header.e_type = cpu_to_dump16(s, ET_CORE); > - elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine); > - elf_header.e_version = cpu_to_dump32(s, EV_CURRENT); > - elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header)); > - elf_header.e_phoff = cpu_to_dump64(s, s->phdr_offset); > - elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr)); > - elf_header.e_phnum = cpu_to_dump16(s, phnum); > + memcpy(elf_header, ELFMAG, SELFMAG); > + elf_header->e_ident[EI_CLASS] = ELFCLASS64; > + elf_header->e_ident[EI_DATA] = s->dump_info.d_endian; > + elf_header->e_ident[EI_VERSION] = EV_CURRENT; > + elf_header->e_type = cpu_to_dump16(s, ET_CORE); > + elf_header->e_machine = cpu_to_dump16(s, s->dump_info.d_machine); > + elf_header->e_version = cpu_to_dump32(s, EV_CURRENT); > + elf_header->e_ehsize = cpu_to_dump16(s, sizeof(*elf_header)); > + elf_header->e_phoff = cpu_to_dump64(s, s->phdr_offset); > + elf_header->e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr)); > + elf_header->e_phnum = cpu_to_dump16(s, phnum); > if (s->shdr_num) { > - elf_header.e_shoff = cpu_to_dump64(s, s->shdr_offset); > - elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr)); > - elf_header.e_shnum = cpu_to_dump16(s, s->shdr_num); > - } > - > - ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s); > - if (ret < 0) { > - error_setg_errno(errp, -ret, "dump: failed to write elf header"); > + elf_header->e_shoff = cpu_to_dump64(s, s->shdr_offset); > + elf_header->e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr)); > + elf_header->e_shnum = cpu_to_dump16(s, s->shdr_num); > } > } > > -static void write_elf32_header(DumpState *s, Error **errp) > +static void prepare_elf32_header(DumpState *s) > { > - /* > - * phnum in the elf header is 16 bit, if we have more segments we > - * set phnum to PN_XNUM and write the real number of segments to a > - * special section. > - */ > - uint16_t phnum = MIN(s->phdr_num, PN_XNUM); > - Elf32_Ehdr elf_header; > - int ret; > + uint16_t phnum = s->phdr_num >= PN_XNUM ? PN_XNUM : s->phdr_num; > + Elf32_Ehdr *elf_header = s->elf_header; > > - memset(&elf_header, 0, sizeof(Elf32_Ehdr)); > - memcpy(&elf_header, ELFMAG, SELFMAG); > - elf_header.e_ident[EI_CLASS] = ELFCLASS32; > - elf_header.e_ident[EI_DATA] = s->dump_info.d_endian; > - elf_header.e_ident[EI_VERSION] = EV_CURRENT; > - elf_header.e_type = cpu_to_dump16(s, ET_CORE); > - elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine); > - elf_header.e_version = cpu_to_dump32(s, EV_CURRENT); > - elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header)); > - elf_header.e_phoff = cpu_to_dump32(s, s->phdr_offset); > - elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr)); > - elf_header.e_phnum = cpu_to_dump16(s, phnum); > + memcpy(elf_header, ELFMAG, SELFMAG); > + elf_header->e_ident[EI_CLASS] = ELFCLASS32; > + elf_header->e_ident[EI_DATA] = s->dump_info.d_endian; > + elf_header->e_ident[EI_VERSION] = EV_CURRENT; > + elf_header->e_type = cpu_to_dump16(s, ET_CORE); > + elf_header->e_machine = cpu_to_dump16(s, s->dump_info.d_machine); > + elf_header->e_version = cpu_to_dump32(s, EV_CURRENT); > + elf_header->e_ehsize = cpu_to_dump16(s, sizeof(*elf_header)); > + elf_header->e_phoff = cpu_to_dump32(s, s->phdr_offset); > + elf_header->e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr)); > + elf_header->e_phnum = cpu_to_dump16(s, phnum); > if (s->shdr_num) { > - elf_header.e_shoff = cpu_to_dump32(s, s->shdr_offset); > - elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr)); > - elf_header.e_shnum = cpu_to_dump16(s, s->shdr_num); > - } > - > - ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s); > - if (ret < 0) { > - error_setg_errno(errp, -ret, "dump: failed to write elf header"); > + elf_header->e_shoff = cpu_to_dump32(s, s->shdr_offset); > + elf_header->e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr)); > + elf_header->e_shnum = cpu_to_dump16(s, s->shdr_num); > } > } > > @@ -528,6 +505,26 @@ static void write_elf_notes(DumpState *s, Error **errp) > } > } > > +static void prepare_elf_header(DumpState *s) > +{ > + if (dump_is_64bit(s)) { > + prepare_elf64_header(s); > + } else { > + prepare_elf32_header(s); > + } > +} > + > +static void write_elf_header(DumpState *s, Error **errp) > +{ > + size_t size = dump_is_64bit(s) ? sizeof(Elf64_Ehdr) : sizeof(Elf32_Ehdr); > + int ret; > + > + ret = fd_write_vmcore(s->elf_header, size, s); > + if (ret < 0) { > + error_setg_errno(errp, -ret, "dump: failed to write elf header"); > + } > +} > + > /* write elf header, PT_NOTE and elf note to vmcore. */ > static void dump_begin(DumpState *s, Error **errp) > { > @@ -557,12 +554,11 @@ static void dump_begin(DumpState *s, Error **errp) > * vmcore. > */ > > - /* write elf header to vmcore */ > - if (dump_is_64bit(s)) { > - write_elf64_header(s, errp); > - } else { > - write_elf32_header(s, errp); > - } > + /* Write elf header to buffer */ > + prepare_elf_header(s); > + > + /* Start to write stuff into file descriptor */ > + write_elf_header(s, errp); > if (*errp) { > return; > } > @@ -1642,6 +1638,9 @@ static void dump_init(DumpState *s, int fd, bool > has_format, > goto cleanup; > } > > + s->elf_header = g_malloc0(dump_is_64bit(s) ? > + sizeof(Elf64_Ehdr) : sizeof(Elf32_Ehdr)); > + > /* > * The goal of this block is to (a) update the previously guessed > * phys_base, (b) copy the guest note out of the guest. > diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h > index 7025e50682..58f41bbf45 100644 > --- a/include/sysemu/dump.h > +++ b/include/sysemu/dump.h > @@ -171,6 +171,7 @@ typedef struct DumpState { > int64_t begin; /* Start address of the chunk we want to dump > */ > int64_t length; /* Length of the dump we want to dump */ > > + void *elf_header; > uint8_t *note_buf; /* buffer for notes */ > size_t note_buf_offset; /* the writing place in note_buf */ > uint32_t nr_cpus; /* number of guest's cpu */ > -- > 2.34.1 >