4 #include <libelfu/libelfu.h>
9 void* elfu_mScnForall(ElfuElf *me, SectionHandlerFunc f, void *aux1, void *aux2)
14 CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
15 if (mp->phdr.p_type != PT_LOAD) {
19 CIRCLEQ_FOREACH(ms, &mp->childScnList, elemChildScn) {
20 void *rv = f(me, ms, aux1, aux2);
28 CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
29 void *rv = f(me, ms, aux1, aux2);
44 static void* subCounter(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
46 size_t *i = (size_t*)aux1;
47 ElfuScn *otherScn = (ElfuScn*)aux2;
60 size_t elfu_mScnCount(ElfuElf *me)
62 /* NULL section *is not* counted */
67 elfu_mScnForall(me, subCounter, &i, NULL);
73 /* Returns the index a section would have in the flattened ELF */
74 size_t elfu_mScnIndex(ElfuElf *me, ElfuScn *ms)
76 /* NULL section *is* counted */
82 elfu_mScnForall(me, subCounter, &i, ms);
84 /* If this assertion is broken then ms is not a section in me. */
85 assert(i <= elfu_mScnCount(me));
90 static void* subOldscn(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
92 ElfuScn *otherScn = (ElfuScn*)aux1;
95 if (ms->oldptr == otherScn) {
103 /* Returns the section with oldscn == oldscn */
104 ElfuScn* elfu_mScnByOldscn(ElfuElf *me, ElfuScn *oldscn)
109 return elfu_mScnForall(me, subOldscn, oldscn, NULL);
117 char* elfu_mScnName(ElfuElf *me, ElfuScn *ms)
126 if (!me->shstrtab->databuf) {
130 return &me->shstrtab->databuf[ms->shdr.sh_name];
134 static void* subScnsToArray(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
136 ElfuScn **arr = (ElfuScn**)aux1;
137 size_t *i = (size_t*)aux2;
146 static int cmpScnOffs(const void *ms1, const void *ms2)
154 s1 = *(ElfuScn**)ms1;
155 s2 = *(ElfuScn**)ms2;
161 if (s1->shdr.sh_offset < s2->shdr.sh_offset) {
163 } else if (s1->shdr.sh_offset == s2->shdr.sh_offset) {
165 } else /* if (s1->shdr.sh_offset > s2->shdr.sh_offset) */ {
170 ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count)
173 ElfuScn **sortedSecs;
178 /* Sort sections by offset in file */
179 numSecs = elfu_mScnCount(me);
180 sortedSecs = malloc(numSecs * sizeof(*sortedSecs));
182 ELFU_WARN("elfu_mScnSortedByOffset: Failed to allocate memory.\n");
187 elfu_mScnForall(me, subScnsToArray, sortedSecs, &i);
188 assert(i == numSecs);
190 qsort(sortedSecs, numSecs, sizeof(*sortedSecs), cmpScnOffs);
199 int elfu_mScnAppendData(ElfuScn *ms, void *buf, size_t len)
204 assert(ms->shdr.sh_type != SHT_NOBITS);
207 newbuf = realloc(ms->databuf, ms->shdr.sh_size + len);
209 ELFU_WARN("elfu_mScnAppendData: malloc() failed for newbuf.\n");
213 ms->databuf = newbuf;
214 memcpy(newbuf + ms->shdr.sh_size, buf, len);
215 ms->shdr.sh_size += len;
216 assert(ms->shdr.sh_size == ms->shdr.sh_size);
224 * Allocation, destruction
227 ElfuScn* elfu_mScnAlloc()
231 ms = malloc(sizeof(ElfuScn));
233 ELFU_WARN("mScnCreate: malloc() failed for ElfuScn.\n");
237 memset(ms, 0, sizeof(*ms));
239 CIRCLEQ_INIT(&ms->symtab.syms);
240 CIRCLEQ_INIT(&ms->reltab.rels);
245 void elfu_mScnDestroy(ElfuScn* ms)
249 if (!CIRCLEQ_EMPTY(&ms->symtab.syms)) {
252 nextsym = CIRCLEQ_FIRST(&ms->symtab.syms);
253 while ((void*)nextsym != (void*)&ms->symtab.syms) {
254 ElfuSym *cursym = nextsym;
255 nextsym = CIRCLEQ_NEXT(cursym, elem);
256 CIRCLEQ_REMOVE(&ms->symtab.syms, cursym, elem);
261 if (!CIRCLEQ_EMPTY(&ms->reltab.rels)) {
264 nextrel = CIRCLEQ_FIRST(&ms->reltab.rels);
265 while ((void*)nextrel != (void*)&ms->reltab.rels) {
266 ElfuRel *currel = nextrel;
267 nextrel = CIRCLEQ_NEXT(currel, elem);
268 CIRCLEQ_REMOVE(&ms->reltab.rels, currel, elem);