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