7e6206b812cda5b79cdf4d79d23d31852b523bcb
[centaur.git] / src / elfops / section-in-segment.c
1 #include <stdlib.h>
2 #include <libelfu/libelfu.h>
3
4
5 /*
6  * Returns the section that starts at the same point in the file as
7  * the segment AND is wholly contained in the memory image.
8  *
9  * If no section fits, NULL is returned.
10  */
11 Elf_Scn* elfu_eScnFirstInSegment(Elf *e, GElf_Phdr *phdr)
12 {
13   Elf_Scn *scn;
14
15   scn = elf_getscn(e, 1);
16   while (scn) {
17     GElf_Shdr shdr;
18
19     if (gelf_getshdr(scn, &shdr) != &shdr) {
20       return NULL;
21     }
22
23     if (shdr.sh_offset == phdr->p_offset
24         && PHDR_CONTAINS_SCN_IN_MEMORY(phdr, &shdr)) {
25       return scn;
26     }
27
28     scn = elf_nextscn(e, scn);
29   }
30
31   return NULL;
32 }
33
34
35
36 /*
37  * Returns the first section that  is contained in the segment and
38  * ends as close to its memory image of as possible (the "last"
39  * section in the segment).
40  *
41  * If no section fits, NULL is returned.
42  */
43 Elf_Scn* elfu_eScnLastInSegment(Elf *e, GElf_Phdr *phdr)
44 {
45   Elf_Scn *last = NULL;
46   Elf_Scn *scn;
47
48
49   scn = elf_getscn(e, 1);
50   while (scn) {
51     GElf_Shdr shdr;
52
53     if (gelf_getshdr(scn, &shdr) != &shdr) {
54       ELFU_WARNELF("gelf_getshdr");
55       continue;
56     }
57
58     if (PHDR_CONTAINS_SCN_IN_MEMORY(phdr, &shdr)) {
59       if (!last) {
60         last = scn;
61       } else {
62         GElf_Shdr shdrOld;
63
64         if (gelf_getshdr(last, &shdrOld) != &shdrOld) {
65           continue;
66         }
67
68         if (shdr.sh_offset + shdr.sh_size
69             > shdrOld.sh_offset + shdrOld.sh_size) {
70           // TODO: Check (leftover space in memory image) < (p_align)
71           last = scn;
72         }
73       }
74     }
75
76     scn = elf_nextscn(e, scn);
77   }
78
79   return last;
80 }