mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zdump: df_elf: add multiple ELF section helper
Preparation for upcoming patches. Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-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
6176509076
commit
2734724432
@@ -8,6 +8,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/util_log.h"
|
||||
|
||||
#include "df_elf.h"
|
||||
|
||||
@@ -97,6 +98,102 @@ Elf64_Phdr *read_elf_phdrs(const struct zg_fh *fh, const Elf64_Ehdr *ehdr, unsig
|
||||
return phdrs;
|
||||
}
|
||||
|
||||
Elf64_Shdr *read_elf_shdrs(const struct zg_fh *fh, const Elf64_Ehdr *ehdr, unsigned int *shdr_count)
|
||||
{
|
||||
const Elf64_Half shnum = ehdr->e_shnum;
|
||||
size_t shdrs_size;
|
||||
Elf64_Shdr *shdrs;
|
||||
|
||||
if (!shnum) {
|
||||
*shdr_count = shnum;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ehdr->e_shoff > OFF_T_MAX)
|
||||
ERR_EXIT("Unsupported offset");
|
||||
|
||||
/* Cannot wraparound since `Elf64_Half`` is `uint16_t` */
|
||||
shdrs_size = sizeof(*shdrs) * shnum;
|
||||
shdrs = util_malloc(shdrs_size);
|
||||
zg_seek(fh, (off_t)ehdr->e_shoff, ZG_CHECK);
|
||||
zg_read(fh, shdrs, shdrs_size, ZG_CHECK);
|
||||
*shdr_count = shnum;
|
||||
return shdrs;
|
||||
}
|
||||
|
||||
unsigned char *read_elf_section_data(const struct zg_fh *fh, const Elf64_Shdr *shdr, size_t *size)
|
||||
{
|
||||
const size_t sh_size = shdr->sh_size;
|
||||
unsigned char *ret;
|
||||
|
||||
if (!sh_size) {
|
||||
*size = sh_size;
|
||||
return NULL;
|
||||
}
|
||||
if (shdr->sh_offset > OFF_T_MAX)
|
||||
ERR_EXIT("Unsupported offset");
|
||||
|
||||
ret = util_malloc(sh_size);
|
||||
zg_seek(fh, (off_t)shdr->sh_offset, ZG_CHECK);
|
||||
zg_read(fh, ret, sh_size, ZG_CHECK);
|
||||
*size = sh_size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *read_elf_shstrtab(const struct zg_fh *fh, const Elf64_Ehdr *ehdr, const Elf64_Shdr *shdrs,
|
||||
const unsigned int shnum, size_t *shstrtab_size)
|
||||
{
|
||||
const size_t shstrndx = ehdr->e_shstrndx;
|
||||
Elf64_Xword tmp_shstrtab_size;
|
||||
Elf64_Off shstrndx_off;
|
||||
char *shstrtab;
|
||||
|
||||
/* file has no section name string table */
|
||||
if (shstrndx == SHN_UNDEF) {
|
||||
*shstrtab_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Invalid ELF file */
|
||||
if (shstrndx >= shnum) {
|
||||
util_log_print(UTIL_LOG_ERROR, "Invalid ELF file: invalid string table index\n");
|
||||
*shstrtab_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shstrndx_off = shdrs[shstrndx].sh_offset;
|
||||
if (shstrndx_off > OFF_T_MAX)
|
||||
ERR_EXIT("Unsupported offset");
|
||||
|
||||
tmp_shstrtab_size = shdrs[shstrndx].sh_size;
|
||||
shstrtab = util_malloc(tmp_shstrtab_size);
|
||||
zg_seek(fh, (off_t)shstrndx_off, ZG_CHECK);
|
||||
zg_read(fh, shstrtab, tmp_shstrtab_size, ZG_CHECK);
|
||||
*shstrtab_size = tmp_shstrtab_size;
|
||||
return shstrtab;
|
||||
}
|
||||
|
||||
const Elf64_Shdr *find_elf_shdr_by_name(const Elf64_Shdr *shdrs, const unsigned int shnum,
|
||||
const char *const shstrtab, const size_t shstrtab_size,
|
||||
const char *name)
|
||||
{
|
||||
const Elf64_Shdr *shdr = shdrs;
|
||||
unsigned int idx;
|
||||
|
||||
for (idx = 0; idx < shnum; idx++, shdr++) {
|
||||
/* Invalid ELF file */
|
||||
if (shdr->sh_name >= shstrtab_size) {
|
||||
util_log_print(UTIL_LOG_ERROR,
|
||||
"Invalid ELF file: section name is too large\n");
|
||||
return NULL;
|
||||
}
|
||||
if (strcmp(name, &shstrtab[shdr->sh_name]) == 0)
|
||||
return shdr;
|
||||
}
|
||||
/* Not found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int nt_read(const struct zg_fh *fh, const Elf64_Nhdr *note, void *buf, size_t buf_len)
|
||||
{
|
||||
ssize_t nread;
|
||||
|
||||
@@ -165,6 +165,36 @@ Elf64_Ehdr *read_elf_hdr(const struct zg_fh *fh);
|
||||
Elf64_Phdr *read_elf_phdrs(const struct zg_fh *fh, const Elf64_Ehdr *ehdr,
|
||||
unsigned int *phdr_count);
|
||||
|
||||
/*
|
||||
* Read ELF section headers
|
||||
*
|
||||
* To read the section headers the offset of @fh is changed.
|
||||
*/
|
||||
Elf64_Shdr *read_elf_shdrs(const struct zg_fh *fh, const Elf64_Ehdr *ehdr,
|
||||
unsigned int *shdr_count);
|
||||
|
||||
/*
|
||||
* Read ELF section content
|
||||
*
|
||||
* To read the section content the offset of @fh is changed.
|
||||
*/
|
||||
unsigned char *read_elf_section_data(const struct zg_fh *fh, const Elf64_Shdr *shdr, size_t *size);
|
||||
|
||||
/*
|
||||
* Read ELF section header string table
|
||||
*
|
||||
* To read the section header string table the offset of @fh is changed.
|
||||
*/
|
||||
char *read_elf_shstrtab(const struct zg_fh *fh, const Elf64_Ehdr *ehdr, const Elf64_Shdr *shdrs,
|
||||
const unsigned int shnum, size_t *shstrtab_size);
|
||||
|
||||
/*
|
||||
* Find ELF section header by section name
|
||||
*/
|
||||
const Elf64_Shdr *find_elf_shdr_by_name(const Elf64_Shdr *shdrs, const unsigned int shnum,
|
||||
const char *shstrtab, const size_t shstrtab_size,
|
||||
const char *name);
|
||||
|
||||
/*
|
||||
* Read note and store the note description in @buf
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user