Automate tests
[centaur.git] / src / modelops / toFile.c
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <libelfu/libelfu.h>
5
6
7 static void modelToPhdrs(ElfuElf *me, Elf *e)
8 {
9   ElfuPhdr *mp;
10   size_t i;
11
12   /* Count PHDRs */
13   i = 0;
14   CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
15     i++;
16   }
17
18   if (!gelf_newphdr(e, i)) {
19     ELFU_WARNELF("gelf_newphdr");
20   }
21
22   /* Copy PHDRs */
23   i = 0;
24   CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
25     if (!gelf_update_phdr (e, i, &mp->phdr)) {
26       ELFU_WARNELF("gelf_update_phdr");
27     }
28
29     i++;
30   }
31 }
32
33
34
35 static void* modelToSection(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
36 {
37   Elf_Scn *scnOut;
38   Elf *e = (Elf*)aux1;
39   (void) me;
40   (void) aux2;
41
42   scnOut = elf_newscn(e);
43   if (!scnOut) {
44     ELFU_WARNELF("elf_newscn");
45     return (void*)-1;
46   }
47
48
49   /* SHDR */
50   if (ms->linkptr) {
51     ms->shdr.sh_link = elfu_mScnIndex(me, ms->linkptr);
52   }
53   if (ms->infoptr) {
54     ms->shdr.sh_info = elfu_mScnIndex(me, ms->infoptr);
55   }
56   if (!gelf_update_shdr(scnOut, &ms->shdr)) {
57     ELFU_WARNELF("gelf_update_shdr");
58   }
59
60
61   /* Data */
62   if (ms->data.d_buf) {
63     Elf_Data *dataOut = elf_newdata(scnOut);
64     if (!dataOut) {
65       ELFU_WARNELF("elf_newdata");
66     }
67
68     dataOut->d_align = ms->data.d_align;
69     dataOut->d_buf  = ms->data.d_buf;
70     dataOut->d_off  = ms->data.d_off;
71     dataOut->d_type = ms->data.d_type;
72     dataOut->d_size = ms->data.d_size;
73     dataOut->d_version = ms->data.d_version;
74   }
75
76   return NULL;
77 }
78
79
80
81
82
83 void elfu_mToElf(ElfuElf *me, Elf *e)
84 {
85   if (me->symtab) {
86     elfu_mSymtabFlatten(me);
87   }
88
89
90   /* We control the ELF file's layout now. */
91   /* tired's libelf also offers ELF_F_LAYOUT_OVERLAP for overlapping sections,
92    * but we don't want that since we filtered it out in the reading stage
93    * already. It would be too mind-blowing to handle the dependencies between
94    * the PHDRs and sections then... */
95   elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
96
97
98   /* EHDR */
99   if (!gelf_newehdr(e, me->elfclass)) {
100     ELFU_WARNELF("gelf_newehdr");
101   }
102
103   if (me->shstrtab) {
104     me->ehdr.e_shstrndx = elfu_mScnIndex(me, me->shstrtab);
105   }
106
107   if (!gelf_update_ehdr(e, &me->ehdr)) {
108     ELFU_WARNELF("gelf_update_ehdr");
109   }
110
111
112   /* Sections */
113   elfu_mScnForall(me, modelToSection, e, NULL);
114
115
116   /* PHDRs */
117   modelToPhdrs(me, e);
118
119
120   elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY);
121 }