summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c24
-rw-r--r--src/model/toFile.c115
-rw-r--r--src/options.c6
3 files changed, 137 insertions, 8 deletions
diff --git a/src/main.c b/src/main.c
index 87b47ef..bd6d294 100644
--- a/src/main.c
+++ b/src/main.c
@@ -59,14 +59,26 @@ int main(int argc, char **argv)
}
- /* Generate a memory model of the file */
- if (opts.model) {
- ElfuElf *me;
+ /* Copy the input ELF to the output file */
+ if (!opts.fnOutput) {
+ if (opts.copy) {
+ fprintf(stderr, "Error: Missing output file name for requested operation.\n");
+ }
+ } else {
+ if (opts.copy) {
+ ElfuElf *me;
+
+ me = elfu_modelFromElf(hIn.e);
+
+ if (me) {
+ printf("Model successfully loaded.\n");
- me = elfu_modelFromElf(hIn.e);
+ elfu_modelToElf(me, hOut.e);
- if (me) {
- printf("Model successfully loaded.\n");
+ printf("Model converted to ELF, ready to be written.\n");
+ } else {
+ printf("Failed to load model.\n");
+ }
}
}
diff --git a/src/model/toFile.c b/src/model/toFile.c
new file mode 100644
index 0000000..294cfe4
--- /dev/null
+++ b/src/model/toFile.c
@@ -0,0 +1,115 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <libelf.h>
+#include <gelf.h>
+
+#include <libelfu/libelfu.h>
+
+
+
+static void elfu_modelToPhdrs(ElfuElf *me, Elf *e)
+{
+ ElfuPhdr *mp;
+ size_t i;
+
+ /* Count PHDRs */
+ i = 0;
+ for (mp = me->phdrList.cqh_first;
+ mp != (void *)&me->phdrList;
+ mp = mp->elem.cqe_next) {
+ i++;
+ }
+
+ if (!gelf_newphdr(e, i)) {
+ fprintf(stderr, "gelf_newphdr() failed: %s\n", elf_errmsg(-1));
+ }
+
+ /* Copy PHDRs */
+ i = 0;
+ for (mp = me->phdrList.cqh_first;
+ mp != (void *)&me->phdrList;
+ mp = mp->elem.cqe_next) {
+ if (!gelf_update_phdr (e, i, &mp->phdr)) {
+ fprintf(stderr, "gelf_update_phdr() failed: %s\n", elf_errmsg(-1));
+ }
+
+ i++;
+ }
+}
+
+
+
+static void elfu_modelToSection(ElfuScn *ms, Elf *e)
+{
+ Elf_Scn *scnOut;
+
+ scnOut = elf_newscn(e);
+ if (!scnOut) {
+ fprintf(stderr, "elf_newscn() failed: %s\n", elf_errmsg(-1));
+ return;
+ }
+
+
+ /* SHDR */
+ if (!gelf_update_shdr(scnOut, &ms->shdr)) {
+ fprintf(stderr, "gelf_update_shdr() failed: %s\n", elf_errmsg(-1));
+ }
+
+
+ /* Data */
+ ElfuData *md;
+ for (md = ms->dataList.cqh_first;
+ md != (void *)&ms->dataList;
+ md = md->elem.cqe_next) {
+ Elf_Data *dataOut = elf_newdata(scnOut);
+ if (!dataOut) {
+ fprintf(stderr, "elf_newdata() failed: %s\n", elf_errmsg(-1));
+ }
+
+ dataOut->d_align = md->data.d_align;
+ dataOut->d_buf = md->data.d_buf;
+ dataOut->d_off = md->data.d_off;
+ dataOut->d_type = md->data.d_type;
+ dataOut->d_size = md->data.d_size;
+ dataOut->d_version = md->data.d_version;
+ }
+}
+
+
+
+
+
+void elfu_modelToElf(ElfuElf *me, Elf *e)
+{
+ ElfuScn *ms;
+
+ /* We control the ELF file's layout now. */
+ /* tired's libelf also offers ELF_F_LAYOUT_OVERLAP for overlapping sections. */
+ elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
+
+
+ /* EHDR */
+ if (!gelf_newehdr(e, me->elfclass)) {
+ fprintf(stderr, "gelf_newehdr() failed: %s\n", elf_errmsg(-1));
+ }
+
+ if (!gelf_update_ehdr(e, &me->ehdr)) {
+ fprintf(stderr, "gelf_update_ehdr() failed: %s\n", elf_errmsg(-1));
+ }
+
+
+ /* Sections */
+ for (ms = me->scnList.cqh_first;
+ ms != (void *)&me->scnList;
+ ms = ms->elem.cqe_next) {
+ elfu_modelToSection(ms, e);
+ }
+
+
+ /* PHDRs */
+ elfu_modelToPhdrs(me, e);
+
+
+ elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY);
+}
diff --git a/src/options.c b/src/options.c
index 42637f0..3975bad 100644
--- a/src/options.c
+++ b/src/options.c
@@ -17,6 +17,8 @@ static void printUsage(char *progname)
" --print-header Print ELF header\n"
" --print-segments Print program headers\n"
" --print-sections Print sections\n"
+ "\n"
+ " --copy Copy input to output\n"
"\n");
}
@@ -34,7 +36,7 @@ void parseOptions(CLIOpts *opts, int argc, char **argv)
{"print-header", 0, 0, 10001},
{"print-segments", 0, 0, 10002},
{"print-sections", 0, 0, 10003},
- {"model", 0, 0, 10004},
+ {"copy", 0, 0, 10004},
{NULL, 0, NULL, 0}
};
@@ -57,7 +59,7 @@ void parseOptions(CLIOpts *opts, int argc, char **argv)
opts->printSections = 1;
break;
case 10004:
- opts->model = 1;
+ opts->copy = 1;
break;
case '?':
default: