version 1.4, 2017/09/26 09:40:28 |
version 1.5, 2017/09/29 16:05:53 |
|
|
#include <string.h> |
#include <string.h> |
|
|
static int elf_reloc_size(unsigned long); |
static int elf_reloc_size(unsigned long); |
static void elf_reloc_apply(const char *, const char *, size_t, ssize_t, |
static void elf_reloc_apply(const char *, size_t, const char *, size_t, |
char *, size_t); |
ssize_t, char *, size_t); |
|
|
int |
int |
iself(const char *p, size_t filesize) |
iself(const char *p, size_t filesize) |
|
|
} |
} |
|
|
ssize_t |
ssize_t |
elf_getsymtab(const char *p, const char *shstab, size_t shstabsz, |
elf_getsymtab(const char *p, size_t filesize, const char *shstab, |
const Elf_Sym **symtab, size_t *nsymb) |
size_t shstabsz, const Elf_Sym **symtab, size_t *nsymb) |
{ |
{ |
Elf_Ehdr *eh = (Elf_Ehdr *)p; |
Elf_Ehdr *eh = (Elf_Ehdr *)p; |
Elf_Shdr *sh; |
Elf_Shdr *sh; |
|
|
if ((sh->sh_link >= eh->e_shnum) || (sh->sh_name >= shstabsz)) |
if ((sh->sh_link >= eh->e_shnum) || (sh->sh_name >= shstabsz)) |
continue; |
continue; |
|
|
|
if ((sh->sh_offset + sh->sh_size) > filesize) |
|
continue; |
|
|
if (strncmp(shstab + sh->sh_name, ELF_SYMTAB, snlen) == 0) { |
if (strncmp(shstab + sh->sh_name, ELF_SYMTAB, snlen) == 0) { |
if (symtab != NULL) |
if (symtab != NULL) |
*symtab = (Elf_Sym *)(p + sh->sh_offset); |
*symtab = (Elf_Sym *)(p + sh->sh_offset); |
|
|
if ((sh->sh_link >= eh->e_shnum) || (sh->sh_name >= shstabsz)) |
if ((sh->sh_link >= eh->e_shnum) || (sh->sh_name >= shstabsz)) |
continue; |
continue; |
|
|
if (sh->sh_offset >= filesize) |
if ((sh->sh_offset + sh->sh_size) > filesize) |
continue; |
continue; |
|
|
if (strncmp(shstab + sh->sh_name, sname, snlen) == 0) { |
if (strncmp(shstab + sh->sh_name, sname, snlen) == 0) { |
sidx = i; |
sidx = i; |
sdata = p + sh->sh_offset; |
sdata = p + sh->sh_offset; |
ssz = sh->sh_size; |
ssz = sh->sh_size; |
elf_reloc_apply(p, shstab, shstabsz, sidx, sdata, ssz); |
elf_reloc_apply(p, filesize, shstab, shstabsz, sidx, |
|
sdata, ssz); |
break; |
break; |
} |
} |
} |
} |
|
|
} while (0) |
} while (0) |
|
|
static void |
static void |
elf_reloc_apply(const char *p, const char *shstab, size_t shstabsz, |
elf_reloc_apply(const char *p, size_t filesize, const char *shstab, |
ssize_t sidx, char *sdata, size_t ssz) |
size_t shstabsz, ssize_t sidx, char *sdata, size_t ssz) |
{ |
{ |
Elf_Ehdr *eh = (Elf_Ehdr *)p; |
Elf_Ehdr *eh = (Elf_Ehdr *)p; |
Elf_Shdr *sh; |
Elf_Shdr *sh; |
|
|
int rsize; |
int rsize; |
|
|
/* Find symbol table location and number of symbols. */ |
/* Find symbol table location and number of symbols. */ |
symtabidx = elf_getsymtab(p, shstab, shstabsz, &symtab, &nsymb); |
symtabidx = elf_getsymtab(p, filesize, shstab, shstabsz, &symtab, |
|
&nsymb); |
if (symtabidx == -1) { |
if (symtabidx == -1) { |
warnx("symbol table not found"); |
warnx("symbol table not found"); |
return; |
return; |