dump: Split elf header functions into prepare and write

Let's split the write from the modification of the elf header so we
can consolidate the write of the data in one function.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Janis Schoetterl-Glausch <scgl@linux.ibm.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20220811121111.9878-8-frankja@linux.ibm.com>
This commit is contained in:
Janosch Frank 2022-08-11 12:11:00 +00:00 committed by Marc-André Lureau
parent c370d5300f
commit 670e76998a
1 changed files with 53 additions and 47 deletions

View File

@ -131,7 +131,7 @@ 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, Elf64_Ehdr *elf_header)
{
/*
* phnum in the elf header is 16 bit, if we have more segments we
@ -139,34 +139,27 @@ static void write_elf64_header(DumpState *s, Error **errp)
* special section.
*/
uint16_t phnum = MIN(s->phdr_num, PN_XNUM);
Elf64_Ehdr elf_header;
int ret;
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);
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);
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, Elf32_Ehdr *elf_header)
{
/*
* phnum in the elf header is 16 bit, if we have more segments we
@ -174,28 +167,45 @@ static void write_elf32_header(DumpState *s, Error **errp)
* special section.
*/
uint16_t phnum = MIN(s->phdr_num, PN_XNUM);
Elf32_Ehdr 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);
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);
}
}
static void write_elf_header(DumpState *s, Error **errp)
{
Elf32_Ehdr elf32_header;
Elf64_Ehdr elf64_header;
size_t header_size;
void *header_ptr;
int ret;
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);
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);
if (dump_is_64bit(s)) {
prepare_elf64_header(s, &elf64_header);
header_size = sizeof(elf64_header);
header_ptr = &elf64_header;
} else {
prepare_elf32_header(s, &elf32_header);
header_size = sizeof(elf32_header);
header_ptr = &elf32_header;
}
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
ret = fd_write_vmcore(header_ptr, header_size, s);
if (ret < 0) {
error_setg_errno(errp, -ret, "dump: failed to write elf header");
}
@ -564,11 +574,7 @@ static void dump_begin(DumpState *s, Error **errp)
*/
/* write elf header to vmcore */
if (dump_is_64bit(s)) {
write_elf64_header(s, errp);
} else {
write_elf32_header(s, errp);
}
write_elf_header(s, errp);
if (*errp) {
return;
}