mirror of
https://github.com/openbsd/src.git
synced 2024-12-22 16:42:56 -08:00
Use elf(3) api instead of an ad-hoc elf parser.
Ok mpi@
This commit is contained in:
parent
24b86205f8
commit
9b214edac7
@ -1,11 +1,11 @@
|
||||
|
||||
PROG= ctfdump
|
||||
SRCS= ctfdump.c elf.c
|
||||
SRCS= ctfdump.c
|
||||
|
||||
CFLAGS+= -W -Wall -Wstrict-prototypes -Wno-unused -Wunused-variable
|
||||
|
||||
CFLAGS+= -DZLIB
|
||||
LDADD+= -lz
|
||||
DPADD+= ${LIBZ}
|
||||
LDADD+= -lelf -lz
|
||||
DPADD+= ${LIBELF} ${LIBZ}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ctfdump.c,v 1.22 2019/03/16 16:35:03 sunil Exp $ */
|
||||
/* $OpenBSD: ctfdump.c,v 1.23 2019/05/14 03:16:55 sunil Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
|
||||
@ -21,9 +21,10 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ctf.h>
|
||||
|
||||
#include <elf.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <gelf.h>
|
||||
#include <libelf.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@ -60,19 +61,9 @@ const char *ctf_fpenc2name(uint16_t);
|
||||
const char *ctf_off2name(struct ctf_header *, const char *, off_t,
|
||||
uint32_t);
|
||||
|
||||
int elf_dump(char *, size_t, uint8_t);
|
||||
const char *elf_idx2sym(size_t *, uint8_t);
|
||||
|
||||
/* elf.c */
|
||||
int iself(const char *, size_t);
|
||||
int elf_getshstab(const char *, size_t, const char **, size_t *);
|
||||
ssize_t elf_getsymtab(const char *, size_t filesize, const char *,
|
||||
size_t, const Elf_Sym **, size_t *, const char **,
|
||||
size_t *);
|
||||
ssize_t elf_getsection(char *, size_t, const char *, const char *,
|
||||
size_t, const char **, size_t *);
|
||||
|
||||
char *decompress(const char *, size_t, off_t);
|
||||
int elf_dump(uint8_t);
|
||||
const char *elf_idx2sym(size_t *, uint8_t);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
@ -121,119 +112,162 @@ main(int argc, char *argv[])
|
||||
if (flags == 0)
|
||||
flags = 0xff;
|
||||
|
||||
if (elf_version(EV_CURRENT) == EV_NONE)
|
||||
errx(1, "elf_version: %s", elf_errmsg(-1));
|
||||
|
||||
while ((filename = *argv++) != NULL)
|
||||
error |= dump(filename, flags);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
Elf *e;
|
||||
Elf_Scn *scnsymtab;
|
||||
size_t strtabndx, strtabsz, nsymb;
|
||||
|
||||
int
|
||||
dump(const char *path, uint8_t flags)
|
||||
{
|
||||
struct stat st;
|
||||
int fd, error = 1;
|
||||
char *p;
|
||||
int fd, error = 1;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
warn("open");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
|
||||
warnx("elf_begin: %s", elf_errmsg(-1));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (elf_kind(e) == ELF_K_ELF) {
|
||||
error = elf_dump(flags);
|
||||
elf_end(e);
|
||||
goto done;
|
||||
}
|
||||
elf_end(e);
|
||||
|
||||
if (fstat(fd, &st) == -1) {
|
||||
warn("fstat");
|
||||
close(fd);
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
if ((uintmax_t)st.st_size > SIZE_MAX) {
|
||||
warnx("file too big to fit memory");
|
||||
close(fd);
|
||||
return 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (p == MAP_FAILED)
|
||||
err(1, "mmap");
|
||||
|
||||
if (iself(p, st.st_size)) {
|
||||
error = elf_dump(p, st.st_size, flags);
|
||||
} else if (isctf(p, st.st_size)) {
|
||||
if (isctf(p, st.st_size))
|
||||
error = ctf_dump(p, st.st_size, flags);
|
||||
}
|
||||
|
||||
munmap(p, st.st_size);
|
||||
close(fd);
|
||||
|
||||
done:
|
||||
close(fd);
|
||||
return error;
|
||||
}
|
||||
|
||||
const char *strtab;
|
||||
const Elf_Sym *symtab;
|
||||
size_t strtabsz, nsymb;
|
||||
|
||||
const char *
|
||||
elf_idx2sym(size_t *idx, uint8_t type)
|
||||
{
|
||||
const Elf_Sym *st;
|
||||
GElf_Sym sym;
|
||||
Elf_Data *data;
|
||||
char *name;
|
||||
size_t i;
|
||||
|
||||
if (strtab == NULL)
|
||||
if (scnsymtab == NULL || strtabndx == 0)
|
||||
return NULL;
|
||||
|
||||
data = NULL;
|
||||
while ((data = elf_rawdata(scnsymtab, data)) != NULL) {
|
||||
for (i = *idx + 1; i < nsymb; i++) {
|
||||
st = &symtab[i];
|
||||
|
||||
if (ELF_ST_TYPE(st->st_info) != type)
|
||||
if (gelf_getsym(data, i, &sym) != &sym)
|
||||
continue;
|
||||
if (GELF_ST_TYPE(sym.st_info) != type)
|
||||
continue;
|
||||
if (sym.st_name >= strtabsz)
|
||||
break;
|
||||
if ((name = elf_strptr(e, strtabndx,
|
||||
sym.st_name)) == NULL)
|
||||
continue;
|
||||
|
||||
if (st->st_name >= strtabsz)
|
||||
break;
|
||||
|
||||
*idx = i;
|
||||
return strtab + st->st_name;
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
elf_dump(char *p, size_t filesize, uint8_t flags)
|
||||
elf_dump(uint8_t flags)
|
||||
{
|
||||
Elf_Ehdr *eh = (Elf_Ehdr *)p;
|
||||
Elf_Shdr *sh;
|
||||
const char *shstab;
|
||||
size_t i, shstabsz;
|
||||
GElf_Shdr shdr;
|
||||
Elf_Scn *scn, *scnctf;
|
||||
Elf_Data *data;
|
||||
char *name;
|
||||
size_t shstrndx;
|
||||
int error = 1;
|
||||
|
||||
/* Find section header string table location and size. */
|
||||
if (elf_getshstab(p, filesize, &shstab, &shstabsz))
|
||||
return 1;
|
||||
|
||||
/* Find symbol table and associated string table. */
|
||||
if (elf_getsymtab(p, filesize, shstab, shstabsz, &symtab, &nsymb,
|
||||
&strtab, &strtabsz) == -1)
|
||||
warnx("symbol table not found");
|
||||
|
||||
/* Find CTF section and dump it. */
|
||||
for (i = 0; i < eh->e_shnum; i++) {
|
||||
sh = (Elf_Shdr *)(p + eh->e_shoff + i * eh->e_shentsize);
|
||||
|
||||
if ((sh->sh_link >= eh->e_shnum) ||
|
||||
(sh->sh_name >= shstabsz))
|
||||
continue;
|
||||
|
||||
if (strncmp(shstab + sh->sh_name, ELF_CTF, strlen(ELF_CTF)))
|
||||
continue;
|
||||
|
||||
if ((sh->sh_offset + sh->sh_size) > filesize)
|
||||
continue;
|
||||
|
||||
if (!isctf(p + sh->sh_offset, sh->sh_size))
|
||||
break;
|
||||
|
||||
return ctf_dump(p + sh->sh_offset, sh->sh_size, flags);
|
||||
if (elf_getshdrstrndx(e, &shstrndx) != 0) {
|
||||
warnx("elf_getshdrstrndx: %s", elf_errmsg(-1));
|
||||
return error;
|
||||
}
|
||||
|
||||
scn = scnctf = NULL;
|
||||
while ((scn = elf_nextscn(e, scn)) != NULL) {
|
||||
if (gelf_getshdr(scn, &shdr) != &shdr) {
|
||||
warnx("elf_getshdr: %s", elf_errmsg(-1));
|
||||
return error;
|
||||
}
|
||||
|
||||
if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) {
|
||||
warnx("elf_strptr: %s", elf_errmsg(-1));
|
||||
return error;
|
||||
}
|
||||
|
||||
if (strcmp(name, ELF_CTF) == 0)
|
||||
scnctf = scn;
|
||||
|
||||
if (strcmp(name, ELF_SYMTAB) == 0 &&
|
||||
shdr.sh_type == SHT_SYMTAB && shdr.sh_entsize != 0) {
|
||||
scnsymtab = scn;
|
||||
nsymb = shdr.sh_size / shdr.sh_entsize;
|
||||
}
|
||||
|
||||
if (strcmp(name, ELF_STRTAB) == 0 &&
|
||||
shdr.sh_type == SHT_STRTAB) {
|
||||
strtabndx = elf_ndxscn(scn);
|
||||
strtabsz = shdr.sh_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (scnctf == NULL) {
|
||||
warnx("%s section not found", ELF_CTF);
|
||||
return 1;
|
||||
return error;
|
||||
}
|
||||
|
||||
if (scnsymtab == NULL)
|
||||
warnx("symbol table not found");
|
||||
|
||||
data = NULL;
|
||||
while ((data = elf_rawdata(scnctf, data)) != NULL) {
|
||||
if (data->d_buf == NULL) {
|
||||
warnx("%s section size is zero", ELF_CTF);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (isctf(data->d_buf, data->d_size))
|
||||
error |= ctf_dump(data->d_buf, data->d_size, flags);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1,348 +0,0 @@
|
||||
/* $OpenBSD: elf.c,v 1.8 2017/11/14 09:14:50 mpi Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <machine/reloc.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <elf.h>
|
||||
#include <err.h>
|
||||
#include <string.h>
|
||||
|
||||
static int elf_reloc_size(unsigned long);
|
||||
static void elf_reloc_apply(const char *, size_t, const char *, size_t,
|
||||
ssize_t, char *, size_t);
|
||||
|
||||
int
|
||||
iself(const char *p, size_t filesize)
|
||||
{
|
||||
Elf_Ehdr *eh = (Elf_Ehdr *)p;
|
||||
|
||||
if (filesize < (off_t)sizeof(Elf_Ehdr)) {
|
||||
warnx("file too small to be ELF");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (eh->e_ehsize < sizeof(Elf_Ehdr) || !IS_ELF(*eh))
|
||||
return 0;
|
||||
|
||||
if (eh->e_ident[EI_CLASS] != ELFCLASS) {
|
||||
warnx("unexpected word size %u", eh->e_ident[EI_CLASS]);
|
||||
return 0;
|
||||
}
|
||||
if (eh->e_ident[EI_VERSION] != ELF_TARG_VER) {
|
||||
warnx("unexpected version %u", eh->e_ident[EI_VERSION]);
|
||||
return 0;
|
||||
}
|
||||
if (eh->e_ident[EI_DATA] >= ELFDATANUM) {
|
||||
warnx("unexpected data format %u", eh->e_ident[EI_DATA]);
|
||||
return 0;
|
||||
}
|
||||
if (eh->e_shoff > filesize) {
|
||||
warnx("bogus section table offset 0x%llx", (off_t)eh->e_shoff);
|
||||
return 0;
|
||||
}
|
||||
if (eh->e_shentsize < sizeof(Elf_Shdr)) {
|
||||
warnx("bogus section header size %u", eh->e_shentsize);
|
||||
return 0;
|
||||
}
|
||||
if (eh->e_shnum > (filesize - eh->e_shoff) / eh->e_shentsize) {
|
||||
warnx("bogus section header count %u", eh->e_shnum);
|
||||
return 0;
|
||||
}
|
||||
if (eh->e_shstrndx >= eh->e_shnum) {
|
||||
warnx("bogus string table index %u", eh->e_shstrndx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
elf_getshstab(const char *p, size_t filesize, const char **shstab,
|
||||
size_t *shstabsize)
|
||||
{
|
||||
Elf_Ehdr *eh = (Elf_Ehdr *)p;
|
||||
Elf_Shdr *sh;
|
||||
size_t shoff;
|
||||
|
||||
shoff = eh->e_shoff + eh->e_shstrndx * eh->e_shentsize;
|
||||
if (shoff > (filesize - sizeof(*sh))) {
|
||||
warnx("unexpected string table size");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sh = (Elf_Shdr *)(p + shoff);
|
||||
if (sh->sh_type != SHT_STRTAB) {
|
||||
warnx("unexpected string table type");
|
||||
return -1;
|
||||
}
|
||||
if (sh->sh_offset > filesize) {
|
||||
warnx("bogus string table offset");
|
||||
return -1;
|
||||
}
|
||||
if (sh->sh_size > filesize - sh->sh_offset) {
|
||||
warnx("bogus string table size");
|
||||
return -1;
|
||||
}
|
||||
if (shstab != NULL)
|
||||
*shstab = p + sh->sh_offset;
|
||||
if (shstabsize != NULL)
|
||||
*shstabsize = sh->sh_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
elf_getsymtab(const char *p, size_t filesize, const char *shstab,
|
||||
size_t shstabsz, const Elf_Sym **symtab, size_t *nsymb, const char **strtab,
|
||||
size_t *strtabsz)
|
||||
{
|
||||
Elf_Ehdr *eh = (Elf_Ehdr *)p;
|
||||
Elf_Shdr *sh, *symsh;
|
||||
size_t snlen, shoff;
|
||||
ssize_t i;
|
||||
|
||||
snlen = strlen(ELF_SYMTAB);
|
||||
symsh = NULL;
|
||||
|
||||
for (i = 0; i < eh->e_shnum; i++) {
|
||||
shoff = eh->e_shoff + i * eh->e_shentsize;
|
||||
if (shoff > (filesize - sizeof(*sh)))
|
||||
continue;
|
||||
|
||||
sh = (Elf_Shdr *)(p + shoff);
|
||||
if (sh->sh_type != SHT_SYMTAB)
|
||||
continue;
|
||||
|
||||
if ((sh->sh_link >= eh->e_shnum) || (sh->sh_name >= shstabsz))
|
||||
continue;
|
||||
|
||||
if (sh->sh_offset > filesize)
|
||||
continue;
|
||||
|
||||
if (sh->sh_size > (filesize - sh->sh_offset))
|
||||
continue;
|
||||
|
||||
if (sh->sh_entsize == 0)
|
||||
continue;
|
||||
|
||||
if (strncmp(shstab + sh->sh_name, ELF_SYMTAB, snlen) == 0) {
|
||||
if (symtab != NULL)
|
||||
*symtab = (Elf_Sym *)(p + sh->sh_offset);
|
||||
if (nsymb != NULL)
|
||||
*nsymb = (sh->sh_size / sh->sh_entsize);
|
||||
symsh = sh;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (symsh == NULL || (symsh->sh_link >= eh->e_shnum))
|
||||
return -1;
|
||||
|
||||
shoff = eh->e_shoff + symsh->sh_link * eh->e_shentsize;
|
||||
if (shoff > (filesize - sizeof(*sh)))
|
||||
return -1;
|
||||
|
||||
sh = (Elf_Shdr *)(p + shoff);
|
||||
if ((sh->sh_offset + sh->sh_size) > filesize)
|
||||
return -1;
|
||||
|
||||
if (strtab != NULL)
|
||||
*strtab = p + sh->sh_offset;
|
||||
if (strtabsz != NULL)
|
||||
*strtabsz = sh->sh_size;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
elf_getsection(char *p, size_t filesize, const char *sname, const char *shstab,
|
||||
size_t shstabsz, const char **psdata, size_t *pssz)
|
||||
{
|
||||
Elf_Ehdr *eh = (Elf_Ehdr *)p;
|
||||
Elf_Shdr *sh;
|
||||
char *sdata = NULL;
|
||||
size_t snlen, shoff, ssz = 0;
|
||||
ssize_t sidx, i;
|
||||
|
||||
snlen = strlen(sname);
|
||||
if (snlen == 0)
|
||||
return -1;
|
||||
|
||||
/* Find the given section. */
|
||||
for (i = 0; i < eh->e_shnum; i++) {
|
||||
shoff = eh->e_shoff + i * eh->e_shentsize;
|
||||
if (shoff > (filesize - sizeof(*sh)))
|
||||
continue;
|
||||
|
||||
sh = (Elf_Shdr *)(p + shoff);
|
||||
if ((sh->sh_link >= eh->e_shnum) || (sh->sh_name >= shstabsz))
|
||||
continue;
|
||||
|
||||
if (sh->sh_offset > filesize)
|
||||
continue;
|
||||
|
||||
if (sh->sh_size > (filesize - sh->sh_offset))
|
||||
continue;
|
||||
|
||||
if (strncmp(shstab + sh->sh_name, sname, snlen) == 0) {
|
||||
sidx = i;
|
||||
sdata = p + sh->sh_offset;
|
||||
ssz = sh->sh_size;
|
||||
elf_reloc_apply(p, filesize, shstab, shstabsz, sidx,
|
||||
sdata, ssz);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sdata == NULL)
|
||||
return -1;
|
||||
|
||||
if (psdata != NULL)
|
||||
*psdata = sdata;
|
||||
if (pssz != NULL)
|
||||
*pssz = ssz;
|
||||
|
||||
return sidx;
|
||||
}
|
||||
|
||||
static int
|
||||
elf_reloc_size(unsigned long type)
|
||||
{
|
||||
switch (type) {
|
||||
#ifdef R_X86_64_64
|
||||
case R_X86_64_64:
|
||||
return sizeof(uint64_t);
|
||||
#endif
|
||||
#ifdef R_X86_64_32
|
||||
case R_X86_64_32:
|
||||
return sizeof(uint32_t);
|
||||
#endif
|
||||
#ifdef RELOC_32
|
||||
case RELOC_32:
|
||||
return sizeof(uint32_t);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define ELF_WRITE_RELOC(buf, val, rsize) \
|
||||
do { \
|
||||
if (rsize == 4) { \
|
||||
uint32_t v32 = val; \
|
||||
memcpy(buf, &v32, sizeof(v32)); \
|
||||
} else { \
|
||||
uint64_t v64 = val; \
|
||||
memcpy(buf, &v64, sizeof(v64)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
elf_reloc_apply(const char *p, size_t filesize, const char *shstab,
|
||||
size_t shstabsz, ssize_t sidx, char *sdata, size_t ssz)
|
||||
{
|
||||
Elf_Ehdr *eh = (Elf_Ehdr *)p;
|
||||
Elf_Shdr *sh;
|
||||
Elf_Rel *rel = NULL;
|
||||
Elf_RelA *rela = NULL;
|
||||
const Elf_Sym *symtab, *sym;
|
||||
ssize_t symtabidx;
|
||||
size_t nsymb, rsym, rtyp, roff;
|
||||
size_t shoff, i, j;
|
||||
uint64_t value;
|
||||
int rsize;
|
||||
|
||||
/* Find symbol table location and number of symbols. */
|
||||
symtabidx = elf_getsymtab(p, filesize, shstab, shstabsz, &symtab,
|
||||
&nsymb, NULL, NULL);
|
||||
if (symtabidx == -1) {
|
||||
warnx("symbol table not found");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Apply possible relocation. */
|
||||
for (i = 0; i < eh->e_shnum; i++) {
|
||||
shoff = eh->e_shoff + i * eh->e_shentsize;
|
||||
if (shoff > (filesize - sizeof(*sh)))
|
||||
continue;
|
||||
|
||||
sh = (Elf_Shdr *)(p + shoff);
|
||||
if (sh->sh_size == 0)
|
||||
continue;
|
||||
|
||||
if ((sh->sh_info != sidx) || (sh->sh_link != symtabidx))
|
||||
continue;
|
||||
|
||||
if (sh->sh_offset > filesize)
|
||||
continue;
|
||||
|
||||
if (sh->sh_size > (filesize - sh->sh_offset))
|
||||
continue;
|
||||
|
||||
switch (sh->sh_type) {
|
||||
case SHT_RELA:
|
||||
rela = (Elf_RelA *)(p + sh->sh_offset);
|
||||
for (j = 0; j < (sh->sh_size / sizeof(Elf_RelA)); j++) {
|
||||
rsym = ELF_R_SYM(rela[j].r_info);
|
||||
rtyp = ELF_R_TYPE(rela[j].r_info);
|
||||
roff = rela[j].r_offset;
|
||||
if (rsym >= nsymb)
|
||||
continue;
|
||||
if (roff >= filesize)
|
||||
continue;
|
||||
sym = &symtab[rsym];
|
||||
value = sym->st_value + rela[j].r_addend;
|
||||
|
||||
rsize = elf_reloc_size(rtyp);
|
||||
if (rsize == -1 || roff + rsize >= ssz)
|
||||
continue;
|
||||
|
||||
ELF_WRITE_RELOC(sdata + roff, value, rsize);
|
||||
}
|
||||
break;
|
||||
case SHT_REL:
|
||||
rel = (Elf_Rel *)(p + sh->sh_offset);
|
||||
for (j = 0; j < (sh->sh_size / sizeof(Elf_Rel)); j++) {
|
||||
rsym = ELF_R_SYM(rel[j].r_info);
|
||||
rtyp = ELF_R_TYPE(rel[j].r_info);
|
||||
roff = rel[j].r_offset;
|
||||
if (rsym >= nsymb)
|
||||
continue;
|
||||
if (roff >= filesize)
|
||||
continue;
|
||||
sym = &symtab[rsym];
|
||||
value = sym->st_value;
|
||||
|
||||
rsize = elf_reloc_size(rtyp);
|
||||
if (rsize == -1 || roff + rsize >= ssz)
|
||||
continue;
|
||||
|
||||
ELF_WRITE_RELOC(sdata + roff, value, rsize);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user