@@ -398,6 +398,7 @@ static void prepare_elf_section_hdrs(DumpState *s)
/*
* Section ordering:
* - HDR zero (if needed)
+ * - Arch section hdrs
* - String table hdr
*/
sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr);
@@ -415,6 +416,9 @@ static void prepare_elf_section_hdrs(DumpState *s)
return;
}
+ size = dump_arch_sections_write_hdr(&s->dump_info, s, buff_hdr);
+ buff_hdr += size;
+
/*
* String table needs to be last section since strings are added
* via arch_sections_write_hdr().
@@ -565,14 +569,23 @@ static void get_offset_range(hwaddr phys_addr,
}
}
-static void write_elf_loads(DumpState *s, Error **errp)
+static void write_elf_phdr_loads(DumpState *s, Error **errp)
{
ERRP_GUARD();
hwaddr offset, filesz;
MemoryMapping *memory_mapping;
uint32_t phdr_index = 1;
+ hwaddr min = 0, max = 0;
QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {
+ if (memory_mapping->phys_addr < min) {
+ min = memory_mapping->phys_addr;
+ }
+ if (memory_mapping->phys_addr + memory_mapping->length > max) {
+ max = memory_mapping->phys_addr + memory_mapping->length;
+ }
+
+
get_offset_range(memory_mapping->phys_addr,
memory_mapping->length,
s, &offset, &filesz);
@@ -685,8 +698,8 @@ static void dump_begin(DumpState *s, Error **errp)
return;
}
- /* write all PT_LOAD to vmcore */
- write_elf_loads(s, errp);
+ /* write all PT_LOADs to vmcore */
+ write_elf_phdr_loads(s, errp);
if (*errp) {
return;
}
@@ -755,6 +768,7 @@ static void dump_end(DumpState *s, Error **errp)
return;
}
s->elf_section_data = g_malloc0(s->elf_section_data_size);
+ dump_arch_sections_write(&s->dump_info, s, s->elf_section_data);
/* write sections to vmcore */
write_elf_sections(s, errp);
@@ -1939,6 +1953,7 @@ static void dump_init(DumpState *s, int fd, bool has_format,
* If phdr_num overflowed we have at least one section header
* More sections/hdrs can be added by the architectures
*/
+ dump_arch_sections_add(&s->dump_info, (void *)s);
if (s->shdr_num > 1) {
/* Reserve the string table */
s->shdr_num += 1;
@@ -21,6 +21,9 @@ typedef struct ArchDumpInfo {
uint32_t page_size; /* The target's page size. If it's variable and
* unknown, then this should be the maximum. */
uint64_t phys_base; /* The target's physmem base. */
+ void (*arch_sections_add_fn)(void *opaque);
+ uint64_t (*arch_sections_write_hdr_fn)(void *opaque, uint8_t *buff);
+ void (*arch_sections_write_fn)(void *opaque, uint8_t *buff);
} ArchDumpInfo;
struct GuestPhysBlockList; /* memory_mapping.h */
@@ -28,4 +31,28 @@ int cpu_get_dump_info(ArchDumpInfo *info,
const struct GuestPhysBlockList *guest_phys_blocks);
ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
+static inline void dump_arch_sections_add(ArchDumpInfo *info, void *opaque)
+{
+ if (info->arch_sections_add_fn) {
+ info->arch_sections_add_fn(opaque);
+ }
+}
+
+static inline uint64_t dump_arch_sections_write_hdr(ArchDumpInfo *info,
+ void *opaque, uint8_t *buff)
+{
+ if (info->arch_sections_write_hdr_fn) {
+ return info->arch_sections_write_hdr_fn(opaque, buff);
+ }
+ return 0;
+}
+
+static inline void dump_arch_sections_write(ArchDumpInfo *info, void *opaque,
+ uint8_t *buff)
+{
+ if (info->arch_sections_write_fn) {
+ info->arch_sections_write_fn(opaque, buff);
+ }
+}
+
#endif
Add hooks which architectures can use to add arbitrary data to custom sections. Signed-off-by: Janosch Frank <frankja@linux.ibm.com> --- dump/dump.c | 21 ++++++++++++++++++--- include/sysemu/dump-arch.h | 27 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-)