2 * Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <sys/param.h>
18 #include <sys/exec_elf.h>
24 iself(const char *p, size_t filesize)
26 Elf_Ehdr *eh = (Elf_Ehdr *)p;
28 if (eh->e_ehsize < sizeof(Elf_Ehdr) || !IS_ELF(*eh))
31 if (eh->e_ident[EI_CLASS] != ELFCLASS) {
32 warnx("unexpected word size %u", eh->e_ident[EI_CLASS]);
35 if (eh->e_ident[EI_VERSION] != ELF_TARG_VER) {
36 warnx("unexpected version %u", eh->e_ident[EI_VERSION]);
39 if (eh->e_ident[EI_DATA] >= ELFDATANUM) {
40 warnx("unexpected data format %u", eh->e_ident[EI_DATA]);
43 if (eh->e_shoff > filesize) {
44 warnx("bogus section table offset 0x%llx", (off_t)eh->e_shoff);
47 if (eh->e_shentsize < sizeof(Elf_Shdr)) {
48 warnx("bogus section header size %u", eh->e_shentsize);
51 if (eh->e_shnum > (filesize - eh->e_shoff) / eh->e_shentsize) {
52 warnx("bogus section header count %u", eh->e_shnum);
55 if (eh->e_shstrndx >= eh->e_shnum) {
56 warnx("bogus string table index %u", eh->e_shstrndx);
64 elf_getshstrtab(const char *p, size_t filesize, const char **shstrtab,
67 Elf_Ehdr *eh = (Elf_Ehdr *)p;
70 sh = (Elf_Shdr *)(p + eh->e_shoff + eh->e_shstrndx * eh->e_shentsize);
71 if (sh->sh_type != SHT_STRTAB) {
72 warnx("unexpected string table type");
75 if (sh->sh_offset > filesize) {
76 warnx("bogus string table offset");
79 if (sh->sh_size > filesize - sh->sh_offset) {
80 warnx("bogus string table size");
84 *shstrtab = p + sh->sh_offset;
85 if (shstrtabsize != NULL)
86 *shstrtabsize = sh->sh_size;
92 elf_getsymtab(const char *p, const char *shstrtab, size_t shstrtabsize,
93 const Elf_Sym **symtab, size_t *nsymb)
95 Elf_Ehdr *eh = (Elf_Ehdr *)p;
99 for (i = 0; i < eh->e_shnum; i++) {
100 sh = (Elf_Shdr *)(p + eh->e_shoff + i * eh->e_shentsize);
102 if (sh->sh_type != SHT_SYMTAB)
105 if ((sh->sh_link >= eh->e_shnum) ||
106 (sh->sh_name >= shstrtabsize))
109 if (strncmp(shstrtab + sh->sh_name, ELF_SYMTAB,
110 strlen(ELF_SYMTAB)) == 0) {
112 *symtab = (Elf_Sym *)(p + sh->sh_offset);
114 *nsymb = (sh->sh_size / sh->sh_entsize);
124 elf_getsection(const char *p, const char *sname, const char *shstrtab,
125 size_t shstrtabsize, const char **sdata, size_t *ssize)
127 Elf_Ehdr *eh = (Elf_Ehdr *)p;
131 for (i = 0; i < eh->e_shnum; i++) {
132 sh = (Elf_Shdr *)(p + eh->e_shoff + i * eh->e_shentsize);
134 if ((sh->sh_link >= eh->e_shnum) ||
135 (sh->sh_name >= shstrtabsize))
138 if (strncmp(shstrtab + sh->sh_name, sname,
139 strlen(sname)) == 0) {
141 *sdata = p + sh->sh_offset;
143 *ssize = sh->sh_size;