GPLv2 release
[centaur.git] / src / elfhandle.c
1 /* This file is part of centaur.
2  *
3  * centaur is free software: you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License 2 as
5  * published by the Free Software Foundation.
6
7  * centaur is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11
12  * You should have received a copy of the GNU General Public License
13  * along with centaur.  If not, see <http://www.gnu.org/licenses/>.
14  */
15
16 #include <errno.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <libelf.h>
24
25 #include "elfhandle.h"
26
27
28 void openElf(ELFHandles *h, char *fn, Elf_Cmd elfmode)
29 {
30   int openflags = 0;
31   int openmode = 0;
32
33   h->e = NULL;
34
35   switch(elfmode) {
36     case ELF_C_READ:
37       openflags = O_RDONLY;
38       break;
39     case ELF_C_WRITE:
40       openflags = O_WRONLY | O_CREAT;
41       openmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
42       break;
43     case ELF_C_RDWR:
44       openflags = O_RDWR;
45       break;
46     default:
47       return;
48   }
49
50
51   h->fd = open(fn, openflags, openmode);
52   if (h->fd < 0) {
53     fprintf(stderr, "Cannot open %s: %s\n", fn, strerror(errno));
54     return;
55   }
56
57   h->e = elf_begin(h->fd, elfmode, NULL);
58   if (!h->e) {
59     fprintf(stderr, "elf_begin() failed on %s: %s\n", fn, elf_errmsg(-1));
60     goto ERR;
61   }
62
63   if (elfmode == ELF_C_READ || elfmode == ELF_C_RDWR) {
64     if (elf_kind(h->e) != ELF_K_ELF) {
65       fprintf(stderr, "Not an ELF object: %s", fn);
66       goto ERR;
67     }
68   }
69
70   return;
71
72 ERR:
73   if (h->e) {
74     elf_end(h->e);
75     h->e = NULL;
76   }
77   close(h->fd);
78 }
79
80
81 void closeElf(ELFHandles *h)
82 {
83   if (h->e) {
84     elf_end(h->e);
85     close(h->fd);
86     h->e = NULL;
87   }
88 }