]>
Commit | Line | Data |
---|---|---|
d0dd0df1 | 1 | #include <err.h> |
1960d10e SB |
2 | #include <fcntl.h> |
3 | #include <stdio.h> | |
4 | #include <stdlib.h> | |
5 | #include <string.h> | |
6 | #include <sys/mman.h> | |
7 | #include <unistd.h> | |
8 | ||
9 | #include "elf.h" | |
10 | ||
11 | ||
12 | Elf_Obj * | |
13 | elf_init(const char *filename) | |
14 | { | |
15 | int fd; | |
16 | struct stat sb; | |
d0dd0df1 SB |
17 | Elf_Obj *e = NULL; |
18 | ||
19 | if ((fd = open(filename, O_RDONLY)) == -1) | |
20 | errx(1, "open"); | |
1960d10e | 21 | |
1960d10e | 22 | e = (Elf_Obj *)malloc(sizeof(Elf_Obj)); |
d0dd0df1 SB |
23 | if (e == NULL) |
24 | errx(1, "malloc"); | |
25 | ||
1960d10e | 26 | e->fd = fd; |
d0dd0df1 SB |
27 | |
28 | if (fstat(fd, &sb) == -1) | |
29 | errx(1, "fstat"); | |
30 | ||
1960d10e SB |
31 | e->sb = sb; |
32 | ||
33 | e->mm = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); | |
d0dd0df1 SB |
34 | if (e->mm == MAP_FAILED) |
35 | errx(1, "mmap"); | |
36 | ||
1960d10e SB |
37 | e->ehdr = (Elf_Ehdr *) e->mm; |
38 | e->ehdr_size = e->ehdr->e_ehsize; | |
39 | ||
d0dd0df1 SB |
40 | if (e->sb.st_size < sizeof(Elf_Ehdr)) |
41 | errx(1, "not a ELF object"); | |
42 | ||
43 | if (memcmp(e->ehdr->e_ident, ELFMAG, sizeof(ELFMAG) -1) != 0) | |
44 | errx(1, "not a ELF object"); | |
45 | ||
1960d10e SB |
46 | e->shdr = (Elf_Shdr *) (e->mm + e->ehdr->e_shoff); |
47 | e->shdr_size = e->ehdr->e_shnum; | |
48 | ||
49 | e->strtab = NULL; | |
50 | e->strtab_size = 0; | |
51 | ||
d0dd0df1 | 52 | return (e); |
1960d10e SB |
53 | } |
54 | ||
55 | Elf_Shdr * | |
56 | elf_strtab(Elf_Obj *e) | |
57 | { | |
58 | Elf_Shdr *ptr; | |
59 | ||
60 | ptr = &e->shdr[e->ehdr->e_shstrndx]; | |
61 | e->strtab = malloc(ptr->sh_size); | |
d0dd0df1 SB |
62 | if (e->strtab == NULL) |
63 | errx(1, "malloc %s:%d", __func__, __LINE__); | |
64 | ||
1960d10e SB |
65 | e->strtab_size = ptr->sh_size; |
66 | ||
67 | memcpy(e->strtab, (e->mm + ptr->sh_offset), ptr->sh_size); | |
68 | ||
d0dd0df1 | 69 | return (ptr); |
1960d10e SB |
70 | } |
71 | ||
72 | int | |
73 | elf_destroy(Elf_Obj *e) | |
74 | { | |
75 | if (e == NULL) | |
d0dd0df1 SB |
76 | return (1); |
77 | ||
78 | if (e->mm != NULL) | |
79 | if (munmap(e->mm, e->sb.st_size) == -1) | |
80 | return (1); | |
1960d10e | 81 | |
1960d10e | 82 | close(e->fd); |
d0dd0df1 | 83 | |
1960d10e SB |
84 | if (e->strtab != NULL) |
85 | free(e->strtab); | |
d0dd0df1 | 86 | |
1960d10e SB |
87 | free(e); |
88 | ||
d0dd0df1 SB |
89 | return (0); |
90 | } | |
91 | ||
92 | char * | |
93 | elf_str_get(Elf_Obj *e, int index) { | |
94 | if (e == NULL || index > e->strtab_size) | |
95 | return (NULL); | |
96 | ||
97 | return (&e->strtab[e->shdr[index].sh_name]); | |
1960d10e SB |
98 | } |
99 | ||
100 | int | |
101 | elf_debug(Elf_Obj *e) | |
102 | { | |
103 | int i, has_debug = 0; | |
104 | char *debug_prefix = ".debug_"; | |
105 | char *section_name = NULL; | |
106 | ||
107 | for (i=0; i < e->shdr_size; i++) { | |
d0dd0df1 | 108 | section_name = elf_str_get(e, i); |
1960d10e | 109 | if (strnstr(section_name, debug_prefix, strlen(debug_prefix))) { |
1960d10e SB |
110 | has_debug++; |
111 | } | |
1960d10e SB |
112 | } |
113 | ||
d0dd0df1 SB |
114 | return (has_debug); |
115 | } | |
363fc57e SB |
116 | |
117 | void | |
118 | elf_debug_print(Elf_Obj *e) | |
119 | { | |
120 | int i; | |
121 | char *debug_prefix = ".debug_"; | |
122 | char *section_name = NULL; | |
123 | ||
124 | printf("%d ELF debug sections:\n", elf_debug(e)); | |
125 | ||
126 | for (i=0; i < e->shdr_size; i++) { | |
015997ab SB |
127 | if (e->shdr[i].sh_type != SHT_PROGBITS) |
128 | continue; | |
129 | ||
363fc57e SB |
130 | section_name = elf_str_get(e, i); |
131 | if (strnstr(section_name, debug_prefix, strlen(debug_prefix))) { | |
132 | printf("%s\n", section_name); | |
133 | } | |
134 | } | |
1960d10e | 135 | } |