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