Files
s390-tools/zdump/dfo_elf.c
Mikhail Zaslonko f821a3c174 zdump: Drop support of 32-bit dump architecture
- Initialize dump and dump-tool architecture to DFI_ARCH_64 at the start
  of dfi_init() and dt_init() respectively.
- Bail out if any dump architecture other than ARCH_64 has been detected
  in s390_ext or s390mv_ext DASD dump header.
- Remove redundant dfi_arch_set() and dt_arch_set() functions.
- Get rid of l.arch local variables in dfi* and dt* source files and
  drop dfi_arch() function.
- Drop the usage of DFI_ARCH_32 and compeletely remove DFI_ARCH_UNKNOWN.
- Drop special register and lowcore processing functions used
  for DFI_ARCH_32.
- Drop df_s390_from_dfi_arch() and df_s390_to_dfi_arch() funcitons.
- Update the man file for zgetdump.

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-04-07 17:42:18 +02:00

153 lines
3.6 KiB
C

/*
* zgetdump - Tool for copying and converting System z dumps
*
* ELF core dump output format
*
* Copyright IBM Corp. 2001, 2018
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <assert.h>
#include <elf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "df_elf.h"
#include "dfi.h"
#include "dfi_mem_chunk.h"
#include "dfo_mem_chunk.h"
#include "dfi_vmcoreinfo.h"
#include "dfo.h"
#define HDR_PER_MEMC_SIZE 0x100
#define HDR_BASE_SIZE 0x2000
/*
* Initialize ELF loads program headers
*/
static u64 load_phdrs_init(Elf64_Phdr *phdr, u64 elf_offset)
{
struct dfi_mem_chunk *mem_chunk;
u64 mem_size = 0;
dfi_mem_chunk_iterate(mem_chunk) {
phdr->p_type = PT_LOAD;
phdr->p_offset = elf_offset;
phdr->p_vaddr = mem_chunk->start;
phdr->p_paddr = phdr->p_vaddr;
phdr->p_memsz = mem_chunk->size;
if (mem_chunk->read_fn == dfi_mem_chunk_read_zero)
/* Zero memory chunk */
phdr->p_filesz = 0;
else
phdr->p_filesz = phdr->p_memsz;
phdr->p_flags = PF_R | PF_W | PF_X;
phdr->p_align = PAGE_SIZE;
elf_offset += phdr->p_filesz;
mem_size += phdr->p_memsz;
phdr++;
}
return mem_size;
}
/*
* Initialize the program header entries for the notes and the related segment
* data.
*/
static void *notes_init(Elf64_Phdr *phdr, void *segment_start, u64 elf_offset)
{
void *ptr = segment_start;
struct dfi_cpu *cpu;
ptr = nt_prpsinfo(ptr);
if (dfi_cpu_content() != DFI_CPU_CONTENT_ALL)
goto out;
dfi_cpu_iterate(cpu) {
ptr = nt_prstatus(ptr, cpu);
ptr = nt_fpregset(ptr, cpu);
ptr = nt_s390_timer(ptr, cpu);
ptr = nt_s390_tod_cmp(ptr, cpu);
ptr = nt_s390_tod_preg(ptr, cpu);
ptr = nt_s390_ctrs(ptr, cpu);
ptr = nt_s390_prefix(ptr, cpu);
if (dfi_cpu_content_fac_check(DFI_CPU_CONTENT_FAC_VX)) {
ptr = nt_s390_vxrs_low(ptr, cpu);
ptr = nt_s390_vxrs_high(ptr, cpu);
}
if (dfi_cpu_content_fac_check(DFI_CPU_CONTENT_FAC_GS))
ptr = nt_s390_gs_cb(ptr, cpu);
}
out:
ptr = nt_vmcoreinfo(ptr, dfi_vmcoreinfo_get());
memset(phdr, 0, sizeof(*phdr));
phdr->p_type = PT_NOTE;
phdr->p_offset = elf_offset;
phdr->p_filesz = PTR_DIFF(ptr, segment_start);
return ptr;
}
/*
* Setup dump chunks
*/
static void dump_chunks_init(void *hdr, u64 hdr_size)
{
struct dfi_mem_chunk *mem_chunk;
u64 off = 0;
dfo_chunk_add(off, hdr_size, hdr, dfo_chunk_buf_fn);
off += hdr_size;
dfi_mem_chunk_iterate(mem_chunk) {
if (mem_chunk->read_fn == dfi_mem_chunk_read_zero)
/* Zero memory chunk */
continue;
dfo_chunk_add(off, mem_chunk->size, mem_chunk,
dfo_chunk_mem_fn);
off += mem_chunk->size;
}
}
/*
* Initialize ELF output dump format
*/
static void dfo_elf_init(void)
{
Elf64_Phdr *phdr_notes, *phdr_loads;
u32 alloc_size;
void *buf, *ptr;
u64 hdr_off;
df_elf_ensure_s390x();
alloc_size = HDR_BASE_SIZE + dfi_cpu_cnt() * get_max_note_size_per_cpu() +
dfi_mem_chunk_cnt() * HDR_PER_MEMC_SIZE;
buf = zg_alloc(alloc_size);
/* Init elf header */
ptr = ehdr_init(buf, dfi_mem_chunk_cnt() + 1);
/* Init program headers */
phdr_notes = ptr;
ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr));
phdr_loads = ptr;
ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr) * dfi_mem_chunk_cnt());
/* Init notes */
hdr_off = PTR_DIFF(ptr, buf);
ptr = notes_init(phdr_notes, ptr, hdr_off);
hdr_off = PTR_DIFF(ptr, buf);
load_phdrs_init(phdr_loads, hdr_off);
if (hdr_off > alloc_size)
ABORT("hdr_size=%llu alloc_size=%u", hdr_off, alloc_size);
dump_chunks_init(buf, hdr_off);
}
/*
* ELF DFO operations
*/
struct dfo dfo_elf = {
.name = "elf",
.init = dfo_elf_init,
};