Cleaner error handling with ELFU_WARN and ELFU_WARNELF
[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 void modelToSection(ElfuScn *ms, Elf *e)
37 {
38   Elf_Scn *scnOut;
39
40   scnOut = elf_newscn(e);
41   if (!scnOut) {
42     ELFU_WARNELF("elf_newscn");
43     return;
44   }
45
46
47   /* SHDR */
48   if (!gelf_update_shdr(scnOut, &ms->shdr)) {
49     ELFU_WARNELF("gelf_update_shdr");
50   }
51
52
53   /* Data */
54   if (ms->data.d_buf) {
55     Elf_Data *dataOut = elf_newdata(scnOut);
56     if (!dataOut) {
57       ELFU_WARNELF("elf_newdata");
58     }
59
60     dataOut->d_align = ms->data.d_align;
61     dataOut->d_buf  = ms->data.d_buf;
62     dataOut->d_off  = ms->data.d_off;
63     dataOut->d_type = ms->data.d_type;
64     dataOut->d_size = ms->data.d_size;
65     dataOut->d_version = ms->data.d_version;
66   }
67 }
68
69
70
71
72
73 void elfu_mToElf(ElfuElf *me, Elf *e)
74 {
75   ElfuScn *ms;
76
77   /* We control the ELF file's layout now. */
78   /* tired's libelf also offers ELF_F_LAYOUT_OVERLAP for overlapping sections. */
79   elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
80
81
82   /* EHDR */
83   if (!gelf_newehdr(e, me->elfclass)) {
84     ELFU_WARNELF("gelf_newehdr");
85   }
86
87   if (!gelf_update_ehdr(e, &me->ehdr)) {
88     ELFU_WARNELF("gelf_update_ehdr");
89   }
90
91
92   /* Sections */
93   CIRCLEQ_FOREACH(ms, &me->scnList, elem) {
94     modelToSection(ms, e);
95   }
96
97
98   /* PHDRs */
99   modelToPhdrs(me, e);
100
101
102   elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY);
103 }