First memory model of an ELF file
[centaur.git] / src / model / fromFile.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include <libelf.h>
5 #include <gelf.h>
6
7 #include <libelfu/libelfu.h>
8
9
10 ElfuPhdr* elfu_modelFromPhdr(GElf_Phdr *phdr)
11 {
12   ElfuPhdr *mp;
13
14   mp = malloc(sizeof(ElfuPhdr));
15   if (!mp) {
16     return NULL;
17   }
18
19   mp->phdr = *phdr;
20
21   return mp;
22 }
23
24
25 ElfuScn* elfu_modelFromSection(Elf_Scn *scn)
26 {
27   ElfuScn *ms;
28   Elf_Data *data;
29
30   ms = malloc(sizeof(ElfuScn));
31   if (!ms) {
32     return NULL;
33   }
34
35   CIRCLEQ_INIT(&ms->dataList);
36
37
38   if (gelf_getshdr(scn, &ms->shdr) != &ms->shdr) {
39     fprintf(stderr, "gelf_getshdr() failed: %s\n", elf_errmsg(-1));
40     goto out;
41   }
42
43
44
45   /* Copy each data part in source segment */
46   data = elf_rawdata(scn, NULL);
47   while (data) {
48     ElfuData *md;
49
50     md = malloc(sizeof(ElfuData));
51     if (!md) {
52       goto out;
53     }
54
55     md->data = *data;
56
57     CIRCLEQ_INSERT_TAIL(&ms->dataList, md, elem);
58
59     data = elf_rawdata(scn, data);
60   }
61
62   return ms;
63
64   out:
65   // FIXME
66   return NULL;
67 }
68
69
70
71
72 ElfuElf* elfu_modelFromElf(Elf *e)
73 {
74   ElfuElf *me;
75
76   me = malloc(sizeof(ElfuElf));
77   if (!me) {
78     return NULL;
79   }
80
81   CIRCLEQ_INIT(&me->scnList);
82   CIRCLEQ_INIT(&me->phdrList);
83
84   /*
85    * General stuff
86    */
87   me->elfclass = gelf_getclass(e);
88   if (me->elfclass == ELFCLASSNONE) {
89     fprintf(stderr, "getclass() failed: %s\n", elf_errmsg(-1));
90   }
91
92   if (!gelf_getehdr(e, &me->ehdr)) {
93     fprintf(stderr, "gelf_getehdr() failed: %s\n", elf_errmsg(-1));
94     goto out;
95   }
96
97
98   /*
99    * Sections
100    */
101   Elf_Scn *scn;
102
103   scn = elf_getscn(e, 1);
104   while (scn) {
105     ElfuScn *ms = elfu_modelFromSection(scn);
106
107     if (ms) {
108       CIRCLEQ_INSERT_TAIL(&me->scnList, ms, elem);
109     } else {
110       goto out;
111     }
112
113     scn = elf_nextscn(e, scn);
114   }
115
116
117
118   /*
119    * Segments
120    */
121   size_t i, n;
122
123   if (elf_getphdrnum(e, &n)) {
124     fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1));
125   }
126
127   for (i = 0; i < n; i++) {
128     GElf_Phdr phdr;
129     ElfuPhdr *mp;
130
131     if (gelf_getphdr(e, i, &phdr) != &phdr) {
132       fprintf(stderr, "gelf_getphdr() failed for #%d: %s\n", i, elf_errmsg(-1));
133       break;
134     }
135
136     mp = elfu_modelFromPhdr(&phdr);
137
138     if (mp) {
139       CIRCLEQ_INSERT_TAIL(&me->phdrList, mp, elem);
140     } else {
141       goto out;
142     }
143   }
144
145
146
147   return me;
148
149   out:
150   // FIXME
151   return NULL;
152 }