Move headers for ELF-based operations together
[centaur.git] / src / elfops / last-section-in-segment.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include <libelf.h>
5 #include <gelf.h>
6
7 #include <libelfu/libelfu.h>
8
9
10 /*
11  * Returns the first section that  is contained in the segment and
12  * ends as close to its memory image of as possible (the "last"
13  * section in the segment).
14  *
15  * If no section fits, NULL is returned.
16  */
17 Elf_Scn* elfu_lastSectionInSegment(Elf *e, GElf_Phdr *phdr)
18 {
19   Elf_Scn *last = NULL;
20   Elf_Scn *scn;
21
22
23   scn = elf_getscn(e, 1);
24   while (scn) {
25     GElf_Shdr shdr;
26
27     if (gelf_getshdr(scn, &shdr) != &shdr) {
28       fprintf(stderr, "gelf_getshdr() failed: %s\n", elf_errmsg(-1));
29       continue;
30     }
31
32     if (elfu_segmentContainsSection(phdr, &shdr)) {
33       if (!last) {
34         last = scn;
35       } else {
36         GElf_Shdr shdrOld;
37
38         if (gelf_getshdr(last, &shdrOld) != &shdrOld) {
39           continue;
40         }
41
42         if (shdr.sh_offset + shdr.sh_size
43             > shdrOld.sh_offset + shdrOld.sh_size) {
44           // TODO: Check (leftover space in memory image) < (p_align)
45           last = scn;
46         }
47       }
48     }
49
50     scn = elf_nextscn(e, scn);
51   }
52
53   return last;
54 }