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