Re-indent using clang-format
[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 Elf_Obj *
12 elf_init(const char *filename)
13 {
14         int fd;
15         struct stat sb;
16         Elf_Obj *e = NULL;
17
18         if ((fd = open(filename, O_RDONLY)) == -1)
19                 errx(1, "open");
20
21         e = (Elf_Obj *)malloc(sizeof(Elf_Obj));
22         if (e == NULL)
23                 errx(1, "malloc");
24
25         e->fd = fd;
26
27         if (fstat(fd, &sb) == -1)
28                 errx(1, "fstat");
29
30         e->sb = sb;
31
32         e->mm = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
33         if (e->mm == MAP_FAILED)
34                 errx(1, "mmap");
35
36         e->ehdr = (Elf_Ehdr *)e->mm;
37         e->ehdr_size = e->ehdr->e_ehsize;
38
39         if (e->sb.st_size < sizeof(Elf_Ehdr))
40                 errx(1, "not a ELF object");
41
42         if (memcmp(e->ehdr->e_ident, ELFMAG, sizeof(ELFMAG) - 1) != 0)
43                 errx(1, "not a ELF object");
44
45         e->shdr = (Elf_Shdr *)(e->mm + e->ehdr->e_shoff);
46         e->shdr_size = e->ehdr->e_shnum;
47
48         e->strtab = NULL;
49         e->strtab_size = 0;
50
51         return (e);
52 }
53
54 Elf_Shdr *
55 elf_strtab(Elf_Obj *e)
56 {
57         Elf_Shdr *ptr;
58
59         ptr = &e->shdr[e->ehdr->e_shstrndx];
60         e->strtab = malloc(ptr->sh_size);
61         if (e->strtab == NULL)
62                 errx(1, "malloc %s:%d", __func__, __LINE__);
63
64         e->strtab_size = ptr->sh_size;
65
66         memcpy(e->strtab, (e->mm + ptr->sh_offset), ptr->sh_size);
67
68         return (ptr);
69 }
70
71 int
72 elf_destroy(Elf_Obj *e)
73 {
74         if (e == NULL)
75                 return (1);
76
77         if (e->mm != NULL)
78                 if (munmap(e->mm, e->sb.st_size) == -1)
79                         return (1);
80
81         close(e->fd);
82
83         if (e->strtab != NULL)
84                 free(e->strtab);
85
86         free(e);
87
88         return (0);
89 }
90
91 char *
92 elf_str_get(Elf_Obj *e, int index)
93 {
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 }