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