-#include <stdio.h>
#include <stdlib.h>
-
-#include <libelf.h>
-#include <gelf.h>
-
+#include <libelf/libelf.h>
+#include <libelf/gelf.h>
#include <libelfu/libelfu.h>
-static void elfu_modelToPhdrs(ElfuElf *me, Elf *e)
+static void 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) {
+ CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
i++;
}
if (!gelf_newphdr(e, i)) {
- fprintf(stderr, "gelf_newphdr() failed: %s\n", elf_errmsg(-1));
+ ELFU_WARNELF("gelf_newphdr");
}
/* Copy PHDRs */
i = 0;
- for (mp = me->phdrList.cqh_first;
- mp != (void *)&me->phdrList;
- mp = mp->elem.cqe_next) {
+ CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
if (!gelf_update_phdr (e, i, &mp->phdr)) {
- fprintf(stderr, "gelf_update_phdr() failed: %s\n", elf_errmsg(-1));
+ ELFU_WARNELF("gelf_update_phdr");
}
i++;
-static void elfu_modelToSection(ElfuScn *ms, Elf *e)
+static int 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) {
- fprintf(stderr, "elf_newscn() failed: %s\n", elf_errmsg(-1));
- return;
+ ELFU_WARNELF("elf_newscn");
+ return 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)) {
- fprintf(stderr, "gelf_update_shdr() failed: %s\n", elf_errmsg(-1));
+ ELFU_WARNELF("gelf_update_shdr");
}
/* Data */
- ElfuData *md;
- for (md = ms->dataList.cqh_first;
- md != (void *)&ms->dataList;
- md = md->elem.cqe_next) {
+ if (ms->data.d_buf) {
Elf_Data *dataOut = elf_newdata(scnOut);
if (!dataOut) {
- fprintf(stderr, "elf_newdata() failed: %s\n", elf_errmsg(-1));
+ ELFU_WARNELF("elf_newdata");
}
- 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;
+ 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 0;
}
-void elfu_modelToElf(ElfuElf *me, Elf *e)
+void elfu_mToElf(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. */
+ /* 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)) {
- fprintf(stderr, "gelf_newehdr() failed: %s\n", elf_errmsg(-1));
+ ELFU_WARNELF("gelf_newehdr");
+ }
+
+ if (me->shstrtab) {
+ me->ehdr.e_shstrndx = elfu_mScnIndex(me, me->shstrtab);
}
if (!gelf_update_ehdr(e, &me->ehdr)) {
- fprintf(stderr, "gelf_update_ehdr() failed: %s\n", elf_errmsg(-1));
+ ELFU_WARNELF("gelf_update_ehdr");
}
/* Sections */
- for (ms = me->scnList.cqh_first;
- ms != (void *)&me->scnList;
- ms = ms->elem.cqe_next) {
- elfu_modelToSection(ms, e);
- }
+ elfu_mScnForall(me, modelToSection, e, NULL);
/* PHDRs */
- elfu_modelToPhdrs(me, e);
+ modelToPhdrs(me, e);
elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY);