ce9eafead50c278ce08823f0a67c10f8e979e517
[elfdbg/.git] / elf.c
1 #include <err.h>
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;
17     Elf_Obj *e = NULL;
18
19     if ((fd = open(filename, O_RDONLY)) == -1)
20         errx(1, "open");
21
22     e = (Elf_Obj *)malloc(sizeof(Elf_Obj));
23     if (e == NULL)
24         errx(1, "malloc");
25
26     e->fd = fd;
27
28     if (fstat(fd, &sb) == -1)
29         errx(1, "fstat");
30
31     e->sb = sb;
32
33     e->mm = mmap(NULL, sb.st_size, PROT_READ,  MAP_SHARED, fd, 0);
34     if (e->mm == MAP_FAILED)
35         errx(1, "mmap");
36
37     e->ehdr = (Elf_Ehdr *) e->mm;
38     e->ehdr_size = e->ehdr->e_ehsize;
39
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
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
52     return (e);
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);
62     if (e->strtab == NULL)
63         errx(1, "malloc %s:%d", __func__, __LINE__);
64
65     e->strtab_size = ptr->sh_size;
66
67     memcpy(e->strtab, (e->mm + ptr->sh_offset), ptr->sh_size);
68
69     return (ptr);
70 }
71
72 int
73 elf_destroy(Elf_Obj *e)
74 {
75     if (e == NULL)
76         return (1);
77
78     if (e->mm != NULL)
79         if (munmap(e->mm, e->sb.st_size) == -1)
80             return (1);
81
82     close(e->fd);
83
84     if (e->strtab != NULL)
85         free(e->strtab);
86
87     free(e);
88
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]);
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++) {
108         section_name = elf_str_get(e, i);
109         if (strnstr(section_name, debug_prefix, strlen(debug_prefix))) {
110             has_debug++;
111         }
112     }
113
114     return (has_debug);
115 }
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++) {
127         if (e->shdr[i].sh_type != SHT_PROGBITS)
128             continue;
129
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     }
135 }