2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2015 Sofian Brabez <sbz@FreeBSD.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer
12 * in this position and unchanged.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 elf_init(const char *filename)
46 if ((fd = open(filename, O_RDONLY)) == -1)
49 e = malloc(sizeof(Elf_Obj));
55 if (fstat(fd, &sb) == -1)
60 e->mm = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
61 if (e->mm == MAP_FAILED)
64 e->ehdr = (Elf_Ehdr *)e->mm;
65 e->ehdr_size = e->ehdr->e_ehsize;
67 if (e->sb.st_size < sizeof(Elf_Ehdr))
68 errx(1, "not a ELF object %s:%d", __func__, __LINE__);
70 if (memcmp(e->ehdr->e_ident, ELFMAG, sizeof(ELFMAG) - 1) != 0)
71 errx(1, "not a ELF object %s:%d", __func__, __LINE__);
73 e->shdr = (Elf_Shdr *)(e->mm + e->ehdr->e_shoff);
74 e->shdr_size = e->ehdr->e_shnum;
83 elf_strtab(Elf_Obj *e)
87 ptr = &e->shdr[e->ehdr->e_shstrndx];
88 e->strtab = malloc(ptr->sh_size);
89 if (e->strtab == NULL)
90 errx(1, "malloc %s:%d", __func__, __LINE__);
92 e->strtab_size = ptr->sh_size;
94 memcpy(e->strtab, (e->mm + ptr->sh_offset), ptr->sh_size);
100 elf_destroy(Elf_Obj *e)
106 if (munmap(e->mm, e->sb.st_size) == -1)
111 if (e->strtab != NULL)
120 elf_str_get(Elf_Obj *e, size_t index)
122 if (e == NULL || index > e->strtab_size)
125 return (&e->strtab[e->shdr[index].sh_name]);
129 elf_debug_count(Elf_Obj *e)
131 unsigned int has_debug = 0;
132 const char debug_prefix[] = ".debug_";
133 char *section_name = NULL;
135 for (size_t i = 0; i < e->shdr_size; i++) {
136 section_name = elf_str_get(e, i);
137 if (strnstr(section_name, debug_prefix,
138 strlen(debug_prefix))) {
147 elf_debug_print(Elf_Obj *e)
149 const char debug_prefix[] = ".debug_";
150 char *section_name = NULL;
152 printf("%u ELF debug sections:\n", elf_debug_count(e));
154 for (size_t i = 0; i < e->shdr_size; i++) {
155 if (e->shdr[i].sh_type != SHT_PROGBITS)
158 section_name = elf_str_get(e, i);
159 if (strnstr(section_name, debug_prefix,
160 strlen(debug_prefix))) {
161 printf("%s\n", section_name);