Refactor mdoel-related code
[centaur.git] / src / model / toFile.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <libelf.h>
4 #include <gelf.h>
5 #include <libelfu/libelfu.h>
6
7
8
9 static void modelToPhdrs(ElfuElf *me, Elf *e)
10 {
11   ElfuPhdr *mp;
12   size_t i;
13
14   /* Count PHDRs */
15   i = 0;
16   CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
17     i++;
18   }
19
20   if (!gelf_newphdr(e, i)) {
21     fprintf(stderr, "gelf_newphdr() failed: %s\n", elf_errmsg(-1));
22   }
23
24   /* Copy PHDRs */
25   i = 0;
26   CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
27     if (!gelf_update_phdr (e, i, &mp->phdr)) {
28       fprintf(stderr, "gelf_update_phdr() failed: %s\n", elf_errmsg(-1));
29     }
30
31     i++;
32   }
33 }
34
35
36
37 static void modelToSection(ElfuScn *ms, Elf *e)
38 {
39   Elf_Scn *scnOut;
40
41   scnOut = elf_newscn(e);
42   if (!scnOut) {
43     fprintf(stderr, "elf_newscn() failed: %s\n", elf_errmsg(-1));
44     return;
45   }
46
47
48   /* SHDR */
49   if (!gelf_update_shdr(scnOut, &ms->shdr)) {
50     fprintf(stderr, "gelf_update_shdr() failed: %s\n", elf_errmsg(-1));
51   }
52
53
54   /* Data */
55   ElfuData *md;
56   CIRCLEQ_FOREACH(md, &ms->dataList, elem) {
57     Elf_Data *dataOut = elf_newdata(scnOut);
58     if (!dataOut) {
59       fprintf(stderr, "elf_newdata() failed: %s\n", elf_errmsg(-1));
60     }
61
62     dataOut->d_align = md->data.d_align;
63     dataOut->d_buf  = md->data.d_buf;
64     dataOut->d_off  = md->data.d_off;
65     dataOut->d_type = md->data.d_type;
66     dataOut->d_size = md->data.d_size;
67     dataOut->d_version = md->data.d_version;
68   }
69 }
70
71
72
73
74
75 void elfu_mToElf(ElfuElf *me, Elf *e)
76 {
77   ElfuScn *ms;
78
79   /* We control the ELF file's layout now. */
80   /* tired's libelf also offers ELF_F_LAYOUT_OVERLAP for overlapping sections. */
81   elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
82
83
84   /* EHDR */
85   if (!gelf_newehdr(e, me->elfclass)) {
86     fprintf(stderr, "gelf_newehdr() failed: %s\n", elf_errmsg(-1));
87   }
88
89   if (!gelf_update_ehdr(e, &me->ehdr)) {
90     fprintf(stderr, "gelf_update_ehdr() failed: %s\n", elf_errmsg(-1));
91   }
92
93
94   /* Sections */
95   CIRCLEQ_FOREACH(ms, &me->scnList, elem) {
96     modelToSection(ms, e);
97   }
98
99
100   /* PHDRs */
101   modelToPhdrs(me, e);
102
103
104   elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY);
105 }