Abstract model more - break 'make check'
[centaur.git] / src / model / check.c
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <libelfu/libelfu.h>
5
6
7
8 static int isOverlapping(size_t off1, size_t sz1, size_t off2, size_t sz2)
9 {
10   size_t end1 = off1 + sz1;
11   size_t end2 = off2 + sz2;
12
13   if (off2 >= off1 && off2 < end1) {
14     return 1;
15   } else if (off1 >= off2 && off1 < end2) {
16     return 1;
17   } else {
18     return 0;
19   }
20 }
21
22
23 static int cmpScnOffs(const void *ms1, const void *ms2)
24 {
25   assert(ms1);
26   assert(ms2);
27
28   ElfuScn *s1 = *(ElfuScn**)ms1;
29   ElfuScn *s2 = *(ElfuScn**)ms2;
30
31   assert(s1);
32   assert(s2);
33
34
35   if (s1->shdr.sh_offset < s2->shdr.sh_offset) {
36     return -1;
37   } else if (s1->shdr.sh_offset == s2->shdr.sh_offset) {
38     return 0;
39   } else /* if (s1->shdr.sh_offset > s2->shdr.sh_offset) */ {
40     return 1;
41   }
42 }
43
44
45 int elfu_mCheck(ElfuElf *me)
46 {
47   ElfuScn *ms;
48   size_t numSecs;
49   ElfuScn **sortedSecs;
50   size_t i;
51
52   /* Sort sections by offset in file */
53   numSecs = elfu_mCountScns(me);
54   sortedSecs = malloc(numSecs * sizeof(*sortedSecs));
55   if (!sortedSecs) {
56     ELFU_WARN("elfu_check: Failed to allocate memory.\n");
57   }
58
59   i = 0;
60   CIRCLEQ_FOREACH(ms, &me->scnList, elem) {
61     sortedSecs[i] = ms;
62     i++;
63   }
64   assert(i == numSecs);
65
66   qsort(sortedSecs, numSecs, sizeof(*sortedSecs), cmpScnOffs);
67
68
69   /* Check for overlapping sections */
70   for (i = 0; i < numSecs - 1; i++) {
71     if (sortedSecs[i]->shdr.sh_offset + SCNFILESIZE(&sortedSecs[i]->shdr)
72         > sortedSecs[i+1]->shdr.sh_offset) {
73       ELFU_WARN("elfu_check: Found overlapping sections: %s and %s.\n",
74                 elfu_mScnName(me, sortedSecs[i]),
75                 elfu_mScnName(me, sortedSecs[i+1]));
76     }
77   }
78
79
80   /* Check for sections overlapping with EHDR */
81   for (i = 0; i < numSecs; i++) {
82     if (sortedSecs[i]->shdr.sh_offset < me->ehdr.e_ehsize) {
83       ELFU_WARN("elfu_check: Found section overlapping with EHDR: %s.\n",
84                 elfu_mScnName(me, sortedSecs[i]));
85     }
86   }
87
88
89   /* Check for sections overlapping with PHDRs */
90   for (i = 0; i < numSecs; i++) {
91     if (isOverlapping(sortedSecs[i]->shdr.sh_offset,
92                       SCNFILESIZE(&sortedSecs[i]->shdr),
93                       me->ehdr.e_phoff,
94                       me->ehdr.e_phentsize * me->ehdr.e_phnum)) {
95       ELFU_WARN("elfu_check: Found section overlapping with PHDRs: %s.\n",
96                 elfu_mScnName(me, sortedSecs[i]));
97     }
98   }
99
100   free(sortedSecs);
101
102   return 0;
103 }