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