1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <log/log.h>
#include "elf.h"
Elf *elf_open_image(const char *image)
{
int fd;
Elf *elf = NULL;
int err;
if (!image) {
pb_log_fn("kernel image path is null\n");
return NULL;
}
if ((elf_version(EV_CURRENT) == EV_NONE) ||
((fd = open(image, O_RDONLY, 0)) == -1) ||
(!(elf = elf_begin(fd, ELF_C_READ, NULL)))) {
err = elf_errno();
if (err)
pb_log_fn("failed to read %s elf: %s\n",
image, elf_errmsg(err));
}
return elf;
}
static bool elf_getnote_offset(Elf_Data * const edata,
const char *namespace,
const uint32_t type, GElf_Nhdr *nhdr,
size_t *n_off, size_t *d_off)
{
size_t off = 0;
size_t next;
/* Iterate through notes */
while ((next = gelf_getnote(edata, off, nhdr, n_off, d_off)) > 0) {
char *note_ns = (char *) edata->d_buf + (*n_off);
if ((strcmp(note_ns, namespace) == 0) && (nhdr->n_type == type))
return true;
off = next;
}
return false;
}
void *elf_getnote_desc(Elf *elf,
const char *namespace,
uint32_t type)
{
Elf_Scn *scn = NULL;
Elf_Data *edata = NULL;
GElf_Shdr shdr;
GElf_Nhdr nhdr;
size_t n_off;
size_t d_off;
void *desc = NULL;
if (!elf || !namespace)
return NULL;
/* Iterate through sections */
while ((scn = elf_nextscn(elf, scn))) {
gelf_getshdr(scn, &shdr);
/* ELF might have more than one SHT_NOTE section but
only one has the 'namespace' note */
if (shdr.sh_type == SHT_NOTE) {
edata = elf_getdata(scn, NULL);
if (elf_getnote_offset(edata, namespace, type,
&nhdr, &n_off, &d_off)) {
desc = calloc(nhdr.n_descsz, sizeof(char));
memcpy(desc, edata->d_buf + d_off,
nhdr.n_descsz);
break;
}
}
}
return desc;
}
|