4 #include <libelfu/libelfu.h>
7 static void flattenSymtab(ElfuElf *me)
14 /* Update section indexes and count symbols */
15 CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
17 sym->shndx = elfu_mScnIndex(me, sym->scnptr);
23 /* Copy symbols to elfclass-specific format */
24 if (me->elfclass == ELFCLASS32) {
25 size_t newsize = (numsyms + 1) * sizeof(Elf32_Sym);
28 if (me->symtab->data.d_buf) {
29 free(me->symtab->data.d_buf);
31 me->symtab->data.d_buf = malloc(newsize);
32 assert(me->symtab->data.d_buf);
34 me->symtab->data.d_size = newsize;
35 me->symtab->shdr.sh_size = newsize;
36 memset(me->symtab->data.d_buf, 0, newsize);
39 CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
40 Elf32_Sym *es = ((Elf32_Sym*)me->symtab->data.d_buf) + i;
42 es->st_name = sym->name;
43 es->st_value = sym->value;
44 es->st_size = sym->size;
45 es->st_info = ELF32_ST_INFO(sym->bind, sym->type);
46 es->st_other = sym->other;
47 es->st_shndx = sym->shndx;
51 } else if (me->elfclass == ELFCLASS64) {
52 size_t newsize = (numsyms + 1) * sizeof(Elf64_Sym);
55 if (me->symtab->data.d_buf) {
56 free(me->symtab->data.d_buf);
58 me->symtab->data.d_buf = malloc(newsize);
59 assert(me->symtab->data.d_buf);
61 me->symtab->data.d_size = newsize;
62 me->symtab->shdr.sh_size = newsize;
63 memset(me->symtab->data.d_buf, 0, newsize);
66 CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
67 Elf64_Sym *es = ((Elf64_Sym*)me->symtab->data.d_buf) + i;
69 es->st_name = sym->name;
70 es->st_value = sym->value;
71 es->st_size = sym->size;
72 es->st_info = ELF64_ST_INFO(sym->bind, sym->type);
73 es->st_other = sym->other;
74 es->st_shndx = sym->shndx;
87 static void modelToPhdrs(ElfuElf *me, Elf *e)
94 CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
98 if (!gelf_newphdr(e, i)) {
99 ELFU_WARNELF("gelf_newphdr");
104 CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
105 if (!gelf_update_phdr (e, i, &mp->phdr)) {
106 ELFU_WARNELF("gelf_update_phdr");
115 static void* modelToSection(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
122 scnOut = elf_newscn(e);
124 ELFU_WARNELF("elf_newscn");
131 ms->shdr.sh_link = elfu_mScnIndex(me, ms->linkptr);
134 ms->shdr.sh_info = elfu_mScnIndex(me, ms->infoptr);
136 if (!gelf_update_shdr(scnOut, &ms->shdr)) {
137 ELFU_WARNELF("gelf_update_shdr");
142 if (ms->data.d_buf) {
143 Elf_Data *dataOut = elf_newdata(scnOut);
145 ELFU_WARNELF("elf_newdata");
148 dataOut->d_align = ms->data.d_align;
149 dataOut->d_buf = ms->data.d_buf;
150 dataOut->d_off = ms->data.d_off;
151 dataOut->d_type = ms->data.d_type;
152 dataOut->d_size = ms->data.d_size;
153 dataOut->d_version = ms->data.d_version;
163 void elfu_mToElf(ElfuElf *me, Elf *e)
170 /* We control the ELF file's layout now. */
171 /* tired's libelf also offers ELF_F_LAYOUT_OVERLAP for overlapping sections,
172 * but we don't want that since we filtered it out in the reading stage
173 * already. It would be too mind-blowing to handle the dependencies between
174 * the PHDRs and sections then... */
175 elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
179 if (!gelf_newehdr(e, me->elfclass)) {
180 ELFU_WARNELF("gelf_newehdr");
184 me->ehdr.e_shstrndx = elfu_mScnIndex(me, me->shstrtab);
187 if (!gelf_update_ehdr(e, &me->ehdr)) {
188 ELFU_WARNELF("gelf_update_ehdr");
193 elfu_mScnForall(me, modelToSection, e, NULL);
200 elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY);