qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Janosch Frank <frankja@linux.ibm.com>
To: qemu-devel@nongnu.org
Cc: marcandre.lureau@redhat.com, pbonzini@redhat.com,
	mhartmay@linux.ibm.com,  borntraeger@linux.ibm.com,
	imbrenda@linux.ibm.com, pasic@linux.ibm.com, cohuck@redhat.com,
	thuth@redhat.com, qemu-s390x@nongnu.org, seiden@linux.ibm.com
Subject: [PATCH v3 05/14] dump: Split write of section headers and data and add a prepare step
Date: Thu, 21 Jul 2022 13:22:47 +0000	[thread overview]
Message-ID: <20220721132256.2171-6-frankja@linux.ibm.com> (raw)
In-Reply-To: <20220721132256.2171-1-frankja@linux.ibm.com>

By splitting the writing of the section headers and (future) section
data we prepare for the addition of a string table section and
architecture sections.

At the same time we move the writing of the section to the end of the
dump process. This allows the upcoming architecture section code to
add data after all of the common dump data has been written.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
 dump/dump.c           | 114 ++++++++++++++++++++++++++++++++----------
 include/sysemu/dump.h |   4 ++
 2 files changed, 92 insertions(+), 26 deletions(-)

diff --git a/dump/dump.c b/dump/dump.c
index 2d04e06815..980702d476 100644
--- a/dump/dump.c
+++ b/dump/dump.c
@@ -342,30 +342,71 @@ static void write_elf_phdr_note(DumpState *s, Error **errp)
     }
 }
 
-static void write_elf_section(DumpState *s, int type, Error **errp)
+static size_t prepare_elf_section_hdr_zero(DumpState *s, void *buff)
 {
-    Elf32_Shdr shdr32;
-    Elf64_Shdr shdr64;
-    int shdr_size;
-    void *shdr;
-    int ret;
+    if (dump_is_64bit(s)) {
+        Elf64_Shdr *shdr64 = buff;
 
-    if (type == 0) {
-        shdr_size = sizeof(Elf32_Shdr);
-        memset(&shdr32, 0, shdr_size);
-        shdr32.sh_info = cpu_to_dump32(s, s->phdr_num);
-        shdr = &shdr32;
+        shdr64->sh_info = cpu_to_dump32(s, s->phdr_num);
     } else {
-        shdr_size = sizeof(Elf64_Shdr);
-        memset(&shdr64, 0, shdr_size);
-        shdr64.sh_info = cpu_to_dump32(s, s->phdr_num);
-        shdr = &shdr64;
+        Elf32_Shdr *shdr32 = buff;
+
+        shdr32->sh_info = cpu_to_dump32(s, s->phdr_num);
     }
 
-    ret = fd_write_vmcore(shdr, shdr_size, s);
+    return dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr);
+}
+
+static void prepare_elf_section_hdrs(DumpState *s)
+{
+    uint8_t *buff_hdr;
+    size_t len, sizeof_shdr;
+
+    /*
+     * Section ordering:
+     * - HDR zero (if needed)
+     */
+    sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr);
+    len = sizeof_shdr * s->shdr_num;
+    s->elf_section_hdrs = g_malloc0(len);
+    buff_hdr = s->elf_section_hdrs;
+
+    /* Write special section first */
+    if (s->phdr_num == PN_XNUM) {
+            prepare_elf_section_hdr_zero(s, buff_hdr);
+    }
+}
+
+static void prepare_elf_sections(DumpState *s, Error **errp)
+{
+    if (!s->shdr_num) {
+        return;
+    }
+
+    prepare_elf_section_hdrs(s);
+}
+
+static void write_elf_section_headers(DumpState *s, Error **errp)
+{
+    size_t sizeof_shdr;
+    int ret;
+
+    sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr);
+
+    ret = fd_write_vmcore(s->elf_section_hdrs, s->shdr_num * sizeof_shdr, s);
     if (ret < 0) {
-        error_setg_errno(errp, -ret,
-                         "dump: failed to write section header table");
+        error_setg_errno(errp, -ret, "dump: failed to write section headers");
+    }
+}
+
+static void write_elf_sections(DumpState *s, Error **errp)
+{
+    int ret;
+
+    /* Write section zero */
+    ret = fd_write_vmcore(s->elf_section_data, s->elf_section_data_size, s);
+    if (ret < 0) {
+        error_setg_errno(errp, -ret, "dump: failed to write section data");
     }
 }
 
@@ -557,12 +598,22 @@ static void dump_begin(DumpState *s, Error **errp)
     /* Write elf header to buffer */
     prepare_elf_header(s);
 
+    prepare_elf_sections(s, errp);
+    if (*errp) {
+        return;
+    }
+
     /* Start to write stuff into file descriptor */
     write_elf_header(s, errp);
     if (*errp) {
         return;
     }
 
+    write_elf_section_headers(s, errp);
+    if (*errp) {
+        return;
+    }
+
     /* write PT_NOTE to vmcore */
     write_elf_phdr_note(s, errp);
     if (*errp) {
@@ -575,14 +626,6 @@ static void dump_begin(DumpState *s, Error **errp)
         return;
     }
 
-    /* write section to vmcore */
-    if (s->shdr_num) {
-        write_elf_section(s, 1, errp);
-        if (*errp) {
-            return;
-        }
-    }
-
     /* write notes to vmcore */
     write_elf_notes(s, errp);
 }
@@ -610,6 +653,19 @@ static void dump_iterate(DumpState *s, Error **errp)
     }
 }
 
+static void dump_end(DumpState *s, Error **errp)
+{
+    ERRP_GUARD();
+
+    if (!s->elf_section_data_size) {
+        return;
+    }
+    s->elf_section_data = g_malloc0(s->elf_section_data_size);
+
+    /* write sections to vmcore */
+    write_elf_sections(s, errp);
+}
+
 static void create_vmcore(DumpState *s, Error **errp)
 {
     ERRP_GUARD();
@@ -620,6 +676,12 @@ static void create_vmcore(DumpState *s, Error **errp)
     }
 
     dump_iterate(s, errp);
+    if (*errp) {
+        return;
+    }
+
+    /* Write section data after memory has been dumped */
+    dump_end(s, errp);
 }
 
 static int write_start_flat_header(int fd)
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index 58f41bbf45..dad10dee0b 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -172,6 +172,10 @@ typedef struct DumpState {
     int64_t length;            /* Length of the dump we want to dump */
 
     void *elf_header;
+    void *elf_section_hdrs;
+    uint64_t elf_section_data_size;
+    void *elf_section_data;
+
     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



  parent reply	other threads:[~2022-07-21 13:25 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-21 13:22 [PATCH v3 00/14] dump: Add arch section and s390x PV dump Janosch Frank
2022-07-21 13:22 ` [PATCH v3 01/14] dump: Introduce GuestPhysBlock offset and length filter functions Janosch Frank
2022-07-21 14:24   ` Marc-André Lureau
2022-07-21 13:22 ` [PATCH v3 02/14] dump: Rename write_elf_loads to write_elf_phdr_loads Janosch Frank
2022-07-21 14:26   ` Marc-André Lureau
2022-07-21 13:22 ` [PATCH v3 03/14] dump: Convert GuestPhysBlock iterators and use the filter functions Janosch Frank
2022-07-21 14:36   ` Marc-André Lureau
2022-07-21 16:26     ` Janosch Frank
2022-07-21 13:22 ` [PATCH v3 04/14] dump: Allocate header Janosch Frank
2022-07-21 14:38   ` Marc-André Lureau
2022-07-21 13:22 ` Janosch Frank [this message]
2022-07-21 14:41   ` [PATCH v3 05/14] dump: Split write of section headers and data and add a prepare step Marc-André Lureau
2022-07-21 14:59     ` Janosch Frank
2022-07-21 13:22 ` [PATCH v3 06/14] dump: Reorder struct DumpState Janosch Frank
2022-07-21 14:43   ` Marc-André Lureau
2022-07-21 13:22 ` [PATCH v3 07/14] dump: Swap segment and section header locations Janosch Frank
2022-07-21 15:07   ` Marc-André Lureau
2022-07-21 15:13     ` Janosch Frank
2022-07-21 13:22 ` [PATCH v3 08/14] dump/dump: Add section string table support Janosch Frank
2022-07-21 15:31   ` Janosch Frank
2022-07-21 13:22 ` [PATCH v3 09/14] dump/dump: Add arch section support Janosch Frank
2022-07-21 13:22 ` [PATCH v3 10/14] linux header sync Janosch Frank
2022-07-21 15:05   ` Marc-André Lureau
2022-07-21 15:10     ` Janosch Frank
2022-07-21 13:22 ` [PATCH v3 11/14] s390x: Add protected dump cap Janosch Frank
2022-07-22 11:45   ` Steffen Eiden
2022-07-21 13:22 ` [PATCH v3 12/14] s390x: Introduce PV query interface Janosch Frank
2022-07-22 11:46   ` Steffen Eiden
2022-07-21 13:22 ` [PATCH v3 13/14] s390x: Add KVM PV dump interface Janosch Frank
2022-07-22 11:46   ` Steffen Eiden
2022-07-21 13:22 ` [PATCH v3 14/14] s390x: pv: Add dump support Janosch Frank
2022-07-22 11:46   ` Steffen Eiden

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=20220721132256.2171-6-frankja@linux.ibm.com \
    --to=frankja@linux.ibm.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mhartmay@linux.ibm.com \
    --cc=pasic@linux.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=seiden@linux.ibm.com \
    --cc=thuth@redhat.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).