mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zdump: dfi_elf: refactor nt_* functions
The functions are refactored so the `struct zg_fh` value is now passed as argument to the `nt_*` functions instead of accessing the global variable `g.fh` from within of the functions. This makes the functions reusable and easier to test. While at it, improve the documentation of `nt_read`. Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com> Reviewed-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
922d29ee49
commit
4e6d43e2ac
@@ -86,6 +86,31 @@ Elf64_Phdr *read_elf_phdrs(const struct zg_fh *fh, const Elf64_Ehdr *ehdr, unsig
|
||||
return phdrs;
|
||||
}
|
||||
|
||||
int nt_read(const struct zg_fh *fh, const Elf64_Nhdr *note, void *buf, size_t buf_len)
|
||||
{
|
||||
ssize_t nread;
|
||||
|
||||
/* We cannot read more than the current note provides */
|
||||
if (note->n_descsz < buf_len)
|
||||
return -EINVAL;
|
||||
/* Skip note's name and position file at note's descriptor */
|
||||
zg_seek_cur(fh, ELF_NOTE_ROUNDUP(note->n_namesz), ZG_CHECK);
|
||||
/* Read note's descriptor */
|
||||
nread = zg_read(fh, buf, buf_len, ZG_CHECK_ERR);
|
||||
if (nread < 0 || (size_t)nread != buf_len)
|
||||
return -EINVAL;
|
||||
/* Skip the rest of note's descriptor until the next note */
|
||||
zg_seek_cur(fh, ELF_NOTE_ROUNDUP(note->n_descsz) - buf_len, ZG_CHECK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nt_skip(const struct zg_fh *fh, const Elf64_Nhdr *note)
|
||||
{
|
||||
/* Skip note's name + descriptor and position file at the next note */
|
||||
zg_seek_cur(fh, ELF_NOTE_ROUNDUP(note->n_namesz) + ELF_NOTE_ROUNDUP(note->n_descsz),
|
||||
ZG_CHECK);
|
||||
}
|
||||
|
||||
void *nt_init(void *buf, Elf64_Word type, const void *desc, int d_len,
|
||||
const char *name)
|
||||
{
|
||||
|
||||
@@ -156,6 +156,16 @@ int read_elf_hdr(const struct zg_fh *fh, Elf64_Ehdr *ehdr);
|
||||
Elf64_Phdr *read_elf_phdrs(const struct zg_fh *fh, const Elf64_Ehdr *ehdr,
|
||||
unsigned int *phdr_count);
|
||||
|
||||
/*
|
||||
* Read note and store the note description in @buf
|
||||
*/
|
||||
int nt_read(const struct zg_fh *fh, const Elf64_Nhdr *note, void *buf, size_t buf_len);
|
||||
|
||||
/*
|
||||
* Skip note
|
||||
*/
|
||||
void nt_skip(const struct zg_fh *fh, const Elf64_Nhdr *note);
|
||||
|
||||
/*
|
||||
* Initialize ELF note
|
||||
*/
|
||||
|
||||
101
zdump/dfi_elf.c
101
zdump/dfi_elf.c
@@ -75,37 +75,6 @@ static int pt_load_add(const Elf64_Phdr *phdr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read note
|
||||
*/
|
||||
static int nt_read(const Elf64_Nhdr *note, void *buf, size_t buf_len)
|
||||
{
|
||||
ssize_t nread;
|
||||
|
||||
/* We cannot read more than the current note provides */
|
||||
if (note->n_descsz < buf_len)
|
||||
return -EINVAL;
|
||||
/* Skip note's name and position file at note's descriptor */
|
||||
zg_seek_cur(g.fh, ELF_NOTE_ROUNDUP(note->n_namesz), ZG_CHECK);
|
||||
/* Read note's descriptor */
|
||||
nread = zg_read(g.fh, buf, buf_len, ZG_CHECK_ERR);
|
||||
if (nread < 0 || (size_t)nread != buf_len)
|
||||
return -EINVAL;
|
||||
/* Skip the rest of note's descriptor until the next note */
|
||||
zg_seek_cur(g.fh, ELF_NOTE_ROUNDUP(note->n_descsz) - buf_len, ZG_CHECK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip note
|
||||
*/
|
||||
static void nt_skip(const Elf64_Nhdr *note)
|
||||
{
|
||||
/* Skip note's name + descriptor and position file at the next note */
|
||||
zg_seek_cur(g.fh, ELF_NOTE_ROUNDUP(note->n_namesz) + ELF_NOTE_ROUNDUP(note->n_descsz),
|
||||
ZG_CHECK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that CPU is already defined by prstatus note
|
||||
*/
|
||||
@@ -119,12 +88,12 @@ static void check_cpu(struct dfi_cpu *cpu, const char *note_str)
|
||||
/*
|
||||
* Read prstatus note and return new DFI CPU
|
||||
*/
|
||||
static struct dfi_cpu *nt_prstatus_read(Elf64_Nhdr *note)
|
||||
static struct dfi_cpu *nt_prstatus_read(const struct zg_fh *fh, const Elf64_Nhdr *note)
|
||||
{
|
||||
struct dfi_cpu *cpu = dfi_cpu_alloc();
|
||||
struct nt_prstatus_64 nt_prstatus;
|
||||
|
||||
if (nt_read(note, &nt_prstatus, sizeof(nt_prstatus)))
|
||||
if (nt_read(fh, note, &nt_prstatus, sizeof(nt_prstatus)))
|
||||
return NULL;
|
||||
|
||||
memcpy(cpu->gprs, &nt_prstatus.gprs, sizeof(cpu->gprs));
|
||||
@@ -138,12 +107,12 @@ static struct dfi_cpu *nt_prstatus_read(Elf64_Nhdr *note)
|
||||
/*
|
||||
* Read fpregset note
|
||||
*/
|
||||
static int nt_fpregset_read(struct dfi_cpu *cpu, Elf64_Nhdr *note)
|
||||
static int nt_fpregset_read(const struct zg_fh *fh, struct dfi_cpu *cpu, const Elf64_Nhdr *note)
|
||||
{
|
||||
struct nt_fpregset_64 nt_fpregset;
|
||||
|
||||
check_cpu(cpu, "FPREGSET");
|
||||
if (nt_read(note, &nt_fpregset, sizeof(nt_fpregset)))
|
||||
if (nt_read(fh, note, &nt_fpregset, sizeof(nt_fpregset)))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(&cpu->fpc, &nt_fpregset.fpc, sizeof(cpu->fpc));
|
||||
@@ -154,64 +123,66 @@ static int nt_fpregset_read(struct dfi_cpu *cpu, Elf64_Nhdr *note)
|
||||
/*
|
||||
* Read s390 timer note
|
||||
*/
|
||||
static int nt_s390_timer_read(struct dfi_cpu *cpu, Elf64_Nhdr *note)
|
||||
static int nt_s390_timer_read(const struct zg_fh *fh, struct dfi_cpu *cpu, const Elf64_Nhdr *note)
|
||||
{
|
||||
check_cpu(cpu, "S390_TIMER");
|
||||
return nt_read(note, &cpu->timer, sizeof(cpu->timer));
|
||||
return nt_read(fh, note, &cpu->timer, sizeof(cpu->timer));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read s390 todcmp note
|
||||
*/
|
||||
static int nt_s390_todcmp_read(struct dfi_cpu *cpu, Elf64_Nhdr *note)
|
||||
static int nt_s390_todcmp_read(const struct zg_fh *fh, struct dfi_cpu *cpu, const Elf64_Nhdr *note)
|
||||
{
|
||||
check_cpu(cpu, "S390_TODCMP");
|
||||
return nt_read(note, &cpu->todcmp, sizeof(cpu->todcmp));
|
||||
return nt_read(fh, note, &cpu->todcmp, sizeof(cpu->todcmp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read s390 todpreg note
|
||||
*/
|
||||
static int nt_s390_todpreg_read(struct dfi_cpu *cpu, Elf64_Nhdr *note)
|
||||
static int nt_s390_todpreg_read(const struct zg_fh *fh, struct dfi_cpu *cpu, const Elf64_Nhdr *note)
|
||||
{
|
||||
check_cpu(cpu, "S390_TODPREG");
|
||||
return nt_read(note, &cpu->todpreg, sizeof(cpu->todpreg));
|
||||
return nt_read(fh, note, &cpu->todpreg, sizeof(cpu->todpreg));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read s390 ctrs note
|
||||
*/
|
||||
static int nt_s390_ctrs_read(struct dfi_cpu *cpu, Elf64_Nhdr *note)
|
||||
static int nt_s390_ctrs_read(const struct zg_fh *fh, struct dfi_cpu *cpu, const Elf64_Nhdr *note)
|
||||
{
|
||||
check_cpu(cpu, "S390_CTRS");
|
||||
return nt_read(note, &cpu->ctrs, sizeof(cpu->ctrs));
|
||||
return nt_read(fh, note, &cpu->ctrs, sizeof(cpu->ctrs));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read s390 prefix note
|
||||
*/
|
||||
static int nt_s390_prefix_read(struct dfi_cpu *cpu, Elf64_Nhdr *note)
|
||||
static int nt_s390_prefix_read(const struct zg_fh *fh, struct dfi_cpu *cpu, const Elf64_Nhdr *note)
|
||||
{
|
||||
check_cpu(cpu, "S390_PREFIX");
|
||||
return nt_read(note, &cpu->prefix, sizeof(cpu->prefix));
|
||||
return nt_read(fh, note, &cpu->prefix, sizeof(cpu->prefix));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read s390 vxrs_low note
|
||||
*/
|
||||
static int nt_s390_vxrs_low_read(struct dfi_cpu *cpu, Elf64_Nhdr *note)
|
||||
static int nt_s390_vxrs_low_read(const struct zg_fh *fh, struct dfi_cpu *cpu,
|
||||
const Elf64_Nhdr *note)
|
||||
{
|
||||
check_cpu(cpu, "S390_VXRS_LOW");
|
||||
return nt_read(note, &cpu->vxrs_low, sizeof(cpu->vxrs_low));
|
||||
return nt_read(fh, note, &cpu->vxrs_low, sizeof(cpu->vxrs_low));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read s390 vxrs_high note
|
||||
*/
|
||||
static int nt_s390_vxrs_high_read(struct dfi_cpu *cpu, Elf64_Nhdr *note)
|
||||
static int nt_s390_vxrs_high_read(const struct zg_fh *fh, struct dfi_cpu *cpu,
|
||||
const Elf64_Nhdr *note)
|
||||
{
|
||||
check_cpu(cpu, "S390_VXRS_HIGH");
|
||||
return nt_read(note, &cpu->vxrs_high, sizeof(cpu->vxrs_high));
|
||||
return nt_read(fh, note, &cpu->vxrs_high, sizeof(cpu->vxrs_high));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -220,60 +191,60 @@ static int nt_s390_vxrs_high_read(struct dfi_cpu *cpu, Elf64_Nhdr *note)
|
||||
static int pt_notes_add(const Elf64_Phdr *phdr)
|
||||
{
|
||||
struct dfi_cpu *cpu_current = NULL;
|
||||
u64 notes_start_off;
|
||||
Elf64_Nhdr note;
|
||||
const struct zg_fh *fh = g.fh;
|
||||
int rc;
|
||||
|
||||
zg_seek(g.fh, phdr->p_offset, ZG_CHECK);
|
||||
notes_start_off = zg_tell(g.fh, ZG_CHECK);
|
||||
while (zg_tell(g.fh, ZG_CHECK) - notes_start_off < phdr->p_filesz) {
|
||||
rc = zg_read(g.fh, ¬e, sizeof(note), ZG_CHECK_ERR);
|
||||
zg_seek(fh, phdr->p_offset, ZG_CHECK);
|
||||
while (zg_tell(fh, ZG_CHECK) - phdr->p_offset < phdr->p_filesz) {
|
||||
Elf64_Nhdr note;
|
||||
|
||||
rc = zg_read(fh, ¬e, sizeof(note), ZG_CHECK_ERR);
|
||||
if (rc != sizeof(note))
|
||||
return -EINVAL;
|
||||
util_log_print(UTIL_LOG_DEBUG, "DFI ELF n_type 0x%x\n",
|
||||
note.n_type);
|
||||
switch (note.n_type) {
|
||||
case NT_PRSTATUS:
|
||||
cpu_current = nt_prstatus_read(¬e);
|
||||
cpu_current = nt_prstatus_read(fh, ¬e);
|
||||
if (!cpu_current)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NT_FPREGSET:
|
||||
if (nt_fpregset_read(cpu_current, ¬e))
|
||||
if (nt_fpregset_read(fh, cpu_current, ¬e))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NT_S390_TIMER:
|
||||
if (nt_s390_timer_read(cpu_current, ¬e))
|
||||
if (nt_s390_timer_read(fh, cpu_current, ¬e))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NT_S390_TODCMP:
|
||||
if (nt_s390_todcmp_read(cpu_current, ¬e))
|
||||
if (nt_s390_todcmp_read(fh, cpu_current, ¬e))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NT_S390_TODPREG:
|
||||
if (nt_s390_todpreg_read(cpu_current, ¬e))
|
||||
if (nt_s390_todpreg_read(fh, cpu_current, ¬e))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NT_S390_CTRS:
|
||||
if (nt_s390_ctrs_read(cpu_current, ¬e))
|
||||
if (nt_s390_ctrs_read(fh, cpu_current, ¬e))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NT_S390_PREFIX:
|
||||
if (nt_s390_prefix_read(cpu_current, ¬e))
|
||||
if (nt_s390_prefix_read(fh, cpu_current, ¬e))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case NT_S390_VXRS_LOW:
|
||||
if (nt_s390_vxrs_low_read(cpu_current, ¬e))
|
||||
if (nt_s390_vxrs_low_read(fh, cpu_current, ¬e))
|
||||
return -EINVAL;
|
||||
dfi_cpu_content_fac_add(DFI_CPU_CONTENT_FAC_VX);
|
||||
break;
|
||||
case NT_S390_VXRS_HIGH:
|
||||
if (nt_s390_vxrs_high_read(cpu_current, ¬e))
|
||||
if (nt_s390_vxrs_high_read(fh, cpu_current, ¬e))
|
||||
return -EINVAL;
|
||||
dfi_cpu_content_fac_add(DFI_CPU_CONTENT_FAC_VX);
|
||||
break;
|
||||
default:
|
||||
nt_skip(¬e);
|
||||
nt_skip(fh, ¬e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user