3 #include <libelf/libelf.h>
4 #include <libelf/gelf.h>
5 #include <libelfu/libelfu.h>
7 int elfu_eCheck(Elf *e)
11 GElf_Phdr *phdrs = NULL;
12 GElf_Shdr *shdrs = NULL;
13 size_t i, j, numPhdr, numShdr;
18 elfclass = gelf_getclass(e);
19 if (elfclass == ELFCLASSNONE) {
20 ELFU_WARNELF("getclass");
24 if (!gelf_getehdr(e, &ehdr)) {
25 ELFU_WARNELF("gelf_getehdr");
29 if (elf_getphdrnum(e, &numPhdr)) {
30 ELFU_WARNELF("elf_getphdrnum");
34 if (elf_getshdrnum(e, &numShdr)) {
35 ELFU_WARNELF("elf_getshdrnum");
41 phdrs = malloc(numPhdr * sizeof(GElf_Phdr));
43 ELFU_WARN("elfu_eCheck: malloc() failed for phdrs.\n");
47 /* Attempt to load all PHDRs at once to catch any errors early */
48 for (i = 0; i < numPhdr; i++) {
50 if (gelf_getphdr(e, i, &phdr) != &phdr) {
51 ELFU_WARN("gelf_getphdr() failed for #%d: %s\n", i, elf_errmsg(-1));
58 /* Check that LOAD PHDR memory ranges do not overlap, and that others
59 * are either fully contained in a LOAD range, or not at all. */
60 for (i = 0; i < numPhdr; i++) {
61 if (phdrs[i].p_type != PT_LOAD) {
65 for (j = 0; j < numPhdr; j++) {
66 if (j == i || phdrs[j].p_type != PT_LOAD) {
70 if (OVERLAPPING(phdrs[i].p_vaddr, phdrs[i].p_memsz,
71 phdrs[j].p_vaddr, phdrs[j].p_memsz)) {
72 if (phdrs[j].p_type == PT_LOAD) {
73 ELFU_WARN("elfu_eCheck: Found LOAD PHDRs that overlap in memory.\n");
75 } else if (!FULLY_OVERLAPPING(phdrs[i].p_vaddr, phdrs[i].p_memsz,
76 phdrs[j].p_vaddr, phdrs[j].p_memsz)) {
77 ELFU_WARN("elfu_eCheck: PHDRs %d and %d partially overlap in memory.\n", i, j);
87 /* SHDRs should not overlap with PHDRs. */
88 if (OVERLAPPING(ehdr.e_shoff, numShdr * ehdr.e_shentsize,
89 ehdr.e_phoff, numPhdr * ehdr.e_phentsize)) {
90 ELFU_WARN("elfu_eCheck: SHDRs overlap with PHDRs.\n");
94 shdrs = malloc(numShdr * sizeof(GElf_Shdr));
96 ELFU_WARN("elfu_eCheck: malloc() failed for shdrs.\n");
100 /* Attempt to load all SHDRs at once to catch any errors early */
101 for (i = 1; i < numShdr; i++) {
105 scn = elf_getscn(e, i);
107 ELFU_WARN("elf_getscn() failed for #%d: %s\n", i, elf_errmsg(-1));
110 if (gelf_getshdr(scn, &shdr) != &shdr) {
111 ELFU_WARNELF("gelf_getshdr");
119 /* Check that Section memory ranges do not overlap.
120 * NB: Section 0 is reserved and thus ignored. */
121 for (i = 1; i < numShdr; i++) {
122 /* Section should not overlap with EHDR. */
123 if (shdrs[i].sh_offset == 0) {
124 ELFU_WARN("elfu_eCheck: Section %d overlaps with EHDR.\n", i);
128 /* Section should not overlap with PHDRs. */
129 if (OVERLAPPING(shdrs[i].sh_offset, elfu_gScnSizeFile(&shdrs[i]),
130 ehdr.e_phoff, numPhdr * ehdr.e_phentsize)) {
131 ELFU_WARN("elfu_eCheck: Section %d overlaps with PHDR.\n", i);
135 /* Section should not overlap with SHDRs. */
136 if (OVERLAPPING(shdrs[i].sh_offset, elfu_gScnSizeFile(&shdrs[i]),
137 ehdr.e_shoff, numShdr * ehdr.e_shentsize)) {
138 ELFU_WARN("elfu_eCheck: Section %d overlaps with SHDRs.\n", i);
142 for (j = 1; j < numShdr; j++) {
147 /* Sections must not overlap in memory. */
148 if (shdrs[i].sh_addr != 0
149 && shdrs[j].sh_addr != 0
150 && OVERLAPPING(shdrs[i].sh_addr, shdrs[i].sh_size,
151 shdrs[j].sh_addr, shdrs[j].sh_size)) {
152 ELFU_WARN("elfu_eCheck: Sections %d and %d overlap in memory.\n", i, j);
156 /* Sections must not overlap in file. */
157 if (OVERLAPPING(shdrs[i].sh_offset, elfu_gScnSizeFile(&shdrs[i]),
158 shdrs[j].sh_offset, elfu_gScnSizeFile(&shdrs[j]))) {
159 ELFU_WARN("elfu_eCheck: Sections %d and %d overlap in file.\n", i, j);
177 ELFU_WARN("elfu_eCheck: Errors found.\n");