4 #include <libelfu/libelfu.h>
9 void* elfu_mScnForall(ElfuElf *me, SectionHandlerFunc f, void *aux1, void *aux2)
14 // TODO: Sort PHDRs by offset before interating
16 CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
17 if (mp->phdr.p_type != PT_LOAD) {
21 CIRCLEQ_FOREACH(ms, &mp->childScnList, elemChildScn) {
22 void *rv = f(me, ms, aux1, aux2);
30 CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
31 void *rv = f(me, ms, aux1, aux2);
46 static void* subCounter(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
48 size_t *i = (size_t*)aux1;
49 ElfuScn *otherScn = (ElfuScn*)aux2;
62 size_t elfu_mScnCount(ElfuElf *me)
64 /* NULL section *is not* counted */
69 elfu_mScnForall(me, subCounter, &i, NULL);
75 /* Returns the index a section would have in the flattened ELF */
76 size_t elfu_mScnIndex(ElfuElf *me, ElfuScn *ms)
78 /* NULL section *is* counted */
84 elfu_mScnForall(me, subCounter, &i, ms);
86 /* If this assertion is broken then ms is not a section in me. */
87 assert(i <= elfu_mScnCount(me));
92 static void* subOldscn(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
94 ElfuScn *otherScn = (ElfuScn*)aux1;
97 if (ms->oldptr == otherScn) {
105 /* Returns the section with oldscn == oldscn */
106 ElfuScn* elfu_mScnByOldscn(ElfuElf *me, ElfuScn *oldscn)
111 return elfu_mScnForall(me, subOldscn, oldscn, NULL);
119 char* elfu_mScnName(ElfuElf *me, ElfuScn *ms)
128 if (!me->shstrtab->databuf) {
132 return &me->shstrtab->databuf[ms->shdr.sh_name];
136 static void* subScnsToArray(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
138 ElfuScn **arr = (ElfuScn**)aux1;
139 size_t *i = (size_t*)aux2;
148 static int cmpScnOffs(const void *ms1, const void *ms2)
156 s1 = *(ElfuScn**)ms1;
157 s2 = *(ElfuScn**)ms2;
163 if (s1->shdr.sh_offset < s2->shdr.sh_offset) {
165 } else if (s1->shdr.sh_offset == s2->shdr.sh_offset) {
167 } else /* if (s1->shdr.sh_offset > s2->shdr.sh_offset) */ {
172 ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count)
175 ElfuScn **sortedSecs;
180 /* Sort sections by offset in file */
181 numSecs = elfu_mScnCount(me);
182 sortedSecs = malloc(numSecs * sizeof(*sortedSecs));
184 ELFU_WARN("elfu_mScnSortedByOffset: Failed to allocate memory.\n");
189 elfu_mScnForall(me, subScnsToArray, sortedSecs, &i);
190 assert(i == numSecs);
192 qsort(sortedSecs, numSecs, sizeof(*sortedSecs), cmpScnOffs);
201 int elfu_mScnAppendData(ElfuScn *ms, void *buf, size_t len)
206 assert(ms->shdr.sh_type != SHT_NOBITS);
209 newbuf = realloc(ms->databuf, ms->shdr.sh_size + len);
211 ELFU_WARN("elfu_mScnAppendData: malloc() failed for newbuf.\n");
215 ms->databuf = newbuf;
216 memcpy(newbuf + ms->shdr.sh_size, buf, len);
217 ms->shdr.sh_size += len;
218 assert(ms->shdr.sh_size == ms->shdr.sh_size);
226 * Allocation, destruction
229 ElfuScn* elfu_mScnAlloc()
233 ms = malloc(sizeof(ElfuScn));
235 ELFU_WARN("mScnCreate: malloc() failed for ElfuScn.\n");
239 memset(ms, 0, sizeof(*ms));
241 CIRCLEQ_INIT(&ms->symtab.syms);
242 CIRCLEQ_INIT(&ms->reltab.rels);
247 void elfu_mScnDestroy(ElfuScn* ms)
251 // TODO: Free symtab/reltab