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