summaryrefslogtreecommitdiff
path: root/src/modelops/toFile.c
diff options
context:
space:
mode:
authornorly <ny-git@enpas.org>2013-06-12 18:41:42 +0100
committernorly <ny-git@enpas.org>2013-06-12 18:41:42 +0100
commit164b3a3a62a0577f9a28078771dd6fdc102598dc (patch)
tree2fedb22c74164b536f0bd8e09c8faf2d3f809254 /src/modelops/toFile.c
parentf661dd3e9708687574ad193b24a5d3d37b825bd7 (diff)
Rename elfedit to centaur, model to modelops
Diffstat (limited to 'src/modelops/toFile.c')
-rw-r--r--src/modelops/toFile.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/modelops/toFile.c b/src/modelops/toFile.c
new file mode 100644
index 0000000..da06f4a
--- /dev/null
+++ b/src/modelops/toFile.c
@@ -0,0 +1,115 @@
+#include <stdlib.h>
+#include <libelfu/libelfu.h>
+
+
+
+static void modelToPhdrs(ElfuElf *me, Elf *e)
+{
+ ElfuPhdr *mp;
+ size_t i;
+
+ /* Count PHDRs */
+ i = 0;
+ CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
+ i++;
+ }
+
+ if (!gelf_newphdr(e, i)) {
+ ELFU_WARNELF("gelf_newphdr");
+ }
+
+ /* Copy PHDRs */
+ i = 0;
+ CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
+ if (!gelf_update_phdr (e, i, &mp->phdr)) {
+ ELFU_WARNELF("gelf_update_phdr");
+ }
+
+ i++;
+ }
+}
+
+
+
+static void* modelToSection(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
+{
+ (void) me;
+ (void) aux2;
+ Elf *e = (Elf*)aux1;
+ Elf_Scn *scnOut;
+
+ scnOut = elf_newscn(e);
+ if (!scnOut) {
+ ELFU_WARNELF("elf_newscn");
+ return (void*)-1;
+ }
+
+
+ /* SHDR */
+ if (ms->linkptr) {
+ ms->shdr.sh_link = elfu_mScnIndex(me, ms->linkptr);
+ }
+ if (ms->infoptr) {
+ ms->shdr.sh_info = elfu_mScnIndex(me, ms->infoptr);
+ }
+ if (!gelf_update_shdr(scnOut, &ms->shdr)) {
+ ELFU_WARNELF("gelf_update_shdr");
+ }
+
+
+ /* Data */
+ if (ms->data.d_buf) {
+ Elf_Data *dataOut = elf_newdata(scnOut);
+ if (!dataOut) {
+ ELFU_WARNELF("elf_newdata");
+ }
+
+ dataOut->d_align = ms->data.d_align;
+ dataOut->d_buf = ms->data.d_buf;
+ dataOut->d_off = ms->data.d_off;
+ dataOut->d_type = ms->data.d_type;
+ dataOut->d_size = ms->data.d_size;
+ dataOut->d_version = ms->data.d_version;
+ }
+
+ return NULL;
+}
+
+
+
+
+
+void elfu_mToElf(ElfuElf *me, Elf *e)
+{
+ /* We control the ELF file's layout now. */
+ /* tired's libelf also offers ELF_F_LAYOUT_OVERLAP for overlapping sections,
+ * but we don't want that since we filtered it out in the reading stage
+ * already. It would be too mind-blowing to handle the dependencies between
+ * the PHDRs and sections then... */
+ elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
+
+
+ /* EHDR */
+ if (!gelf_newehdr(e, me->elfclass)) {
+ ELFU_WARNELF("gelf_newehdr");
+ }
+
+ if (me->shstrtab) {
+ me->ehdr.e_shstrndx = elfu_mScnIndex(me, me->shstrtab);
+ }
+
+ if (!gelf_update_ehdr(e, &me->ehdr)) {
+ ELFU_WARNELF("gelf_update_ehdr");
+ }
+
+
+ /* Sections */
+ elfu_mScnForall(me, modelToSection, e, NULL);
+
+
+ /* PHDRs */
+ modelToPhdrs(me, e);
+
+
+ elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY);
+}