thebeanogamer / rpms / qemu-kvm

Forked from rpms/qemu-kvm 6 months ago
Clone

Blame SOURCES/kvm-dump-Use-a-buffer-for-ELF-section-data-and-headers.patch

97168e
From a918c7305ec7c68e8bc37b449f71e75d84124cd0 Mon Sep 17 00:00:00 2001
97168e
From: Janosch Frank <frankja@linux.ibm.com>
97168e
Date: Mon, 17 Oct 2022 08:38:13 +0000
97168e
Subject: [PATCH 32/42] dump: Use a buffer for ELF section data and headers
97168e
MIME-Version: 1.0
97168e
Content-Type: text/plain; charset=UTF-8
97168e
Content-Transfer-Encoding: 8bit
97168e
97168e
RH-Author: Cédric Le Goater <clg@redhat.com>
97168e
RH-MergeRequest: 226: s390: Enhanced Interpretation for PCI Functions and Secure Execution guest dump
97168e
RH-Bugzilla: 1664378 2043909
97168e
RH-Acked-by: Thomas Huth <thuth@redhat.com>
97168e
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
97168e
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
97168e
RH-Commit: [32/41] e1a03e202e67764581e486f37e13e479200e5846
97168e
97168e
Currently we're writing the NULL section header if we overflow the
97168e
physical header number in the ELF header. But in the future we'll add
97168e
custom section headers AND section data.
97168e
97168e
To facilitate this we need to rearange section handling a bit. As with
97168e
the other ELF headers we split the code into a prepare and a write
97168e
step.
97168e
97168e
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
97168e
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
97168e
Message-Id: <20221017083822.43118-2-frankja@linux.ibm.com>
97168e
(cherry picked from commit e41ed29bcee5cb16715317bcf290f6b5c196eb0a)
97168e
Signed-off-by: Cédric Le Goater <clg@redhat.com>
97168e
---
97168e
 dump/dump.c           | 75 +++++++++++++++++++++++++++++--------------
97168e
 include/sysemu/dump.h |  2 ++
97168e
 2 files changed, 53 insertions(+), 24 deletions(-)
97168e
97168e
diff --git a/dump/dump.c b/dump/dump.c
97168e
index 88177fa886..4142b4cc0c 100644
97168e
--- a/dump/dump.c
97168e
+++ b/dump/dump.c
97168e
@@ -381,31 +381,60 @@ static void write_elf_phdr_note(DumpState *s, Error **errp)
97168e
     }
97168e
 }
97168e
 
97168e
-static void write_elf_section(DumpState *s, int type, Error **errp)
97168e
+static void prepare_elf_section_hdr_zero(DumpState *s)
97168e
 {
97168e
-    Elf32_Shdr shdr32;
97168e
-    Elf64_Shdr shdr64;
97168e
-    int shdr_size;
97168e
-    void *shdr;
97168e
-    int ret;
97168e
+    if (dump_is_64bit(s)) {
97168e
+        Elf64_Shdr *shdr64 = s->elf_section_hdrs;
97168e
 
97168e
-    if (type == 0) {
97168e
-        shdr_size = sizeof(Elf32_Shdr);
97168e
-        memset(&shdr32, 0, shdr_size);
97168e
-        shdr32.sh_info = cpu_to_dump32(s, s->phdr_num);
97168e
-        shdr = &shdr32;
97168e
+        shdr64->sh_info = cpu_to_dump32(s, s->phdr_num);
97168e
     } else {
97168e
-        shdr_size = sizeof(Elf64_Shdr);
97168e
-        memset(&shdr64, 0, shdr_size);
97168e
-        shdr64.sh_info = cpu_to_dump32(s, s->phdr_num);
97168e
-        shdr = &shdr64;
97168e
+        Elf32_Shdr *shdr32 = s->elf_section_hdrs;
97168e
+
97168e
+        shdr32->sh_info = cpu_to_dump32(s, s->phdr_num);
97168e
+    }
97168e
+}
97168e
+
97168e
+static void prepare_elf_section_hdrs(DumpState *s)
97168e
+{
97168e
+    size_t len, sizeof_shdr;
97168e
+
97168e
+    /*
97168e
+     * Section ordering:
97168e
+     * - HDR zero
97168e
+     */
97168e
+    sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr);
97168e
+    len = sizeof_shdr * s->shdr_num;
97168e
+    s->elf_section_hdrs = g_malloc0(len);
97168e
+
97168e
+    /*
97168e
+     * The first section header is ALWAYS a special initial section
97168e
+     * header.
97168e
+     *
97168e
+     * The header should be 0 with one exception being that if
97168e
+     * phdr_num is PN_XNUM then the sh_info field contains the real
97168e
+     * number of segment entries.
97168e
+     *
97168e
+     * As we zero allocate the buffer we will only need to modify
97168e
+     * sh_info for the PN_XNUM case.
97168e
+     */
97168e
+    if (s->phdr_num >= PN_XNUM) {
97168e
+        prepare_elf_section_hdr_zero(s);
97168e
     }
97168e
+}
97168e
 
97168e
-    ret = fd_write_vmcore(shdr, shdr_size, s);
97168e
+static void write_elf_section_headers(DumpState *s, Error **errp)
97168e
+{
97168e
+    size_t sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr);
97168e
+    int ret;
97168e
+
97168e
+    prepare_elf_section_hdrs(s);
97168e
+
97168e
+    ret = fd_write_vmcore(s->elf_section_hdrs, s->shdr_num * sizeof_shdr, s);
97168e
     if (ret < 0) {
97168e
-        error_setg_errno(errp, -ret,
97168e
-                         "dump: failed to write section header table");
97168e
+        error_setg_errno(errp, -ret, "dump: failed to write section headers");
97168e
     }
97168e
+
97168e
+    g_free(s->elf_section_hdrs);
97168e
 }
97168e
 
97168e
 static void write_data(DumpState *s, void *buf, int length, Error **errp)
97168e
@@ -592,12 +621,10 @@ static void dump_begin(DumpState *s, Error **errp)
97168e
         return;
97168e
     }
97168e
 
97168e
-    /* write section to vmcore */
97168e
-    if (s->shdr_num) {
97168e
-        write_elf_section(s, 1, errp);
97168e
-        if (*errp) {
97168e
-            return;
97168e
-        }
97168e
+    /* write section headers to vmcore */
97168e
+    write_elf_section_headers(s, errp);
97168e
+    if (*errp) {
97168e
+        return;
97168e
     }
97168e
 
97168e
     /* write notes to vmcore */
97168e
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
97168e
index b62513d87d..9995f65dc8 100644
97168e
--- a/include/sysemu/dump.h
97168e
+++ b/include/sysemu/dump.h
97168e
@@ -177,6 +177,8 @@ typedef struct DumpState {
97168e
     int64_t filter_area_begin;  /* Start address of partial guest memory area */
97168e
     int64_t filter_area_length; /* Length of partial guest memory area */
97168e
 
97168e
+    void *elf_section_hdrs;     /* Pointer to section header buffer */
97168e
+
97168e
     uint8_t *note_buf;          /* buffer for notes */
97168e
     size_t note_buf_offset;     /* the writing place in note_buf */
97168e
     uint32_t nr_cpus;           /* number of guest's cpu */
97168e
-- 
97168e
2.37.3
97168e