Skip to content

Commit 4778344

Browse files
committed
ipl3: add fatal error in case a ELF segment does not fit RDRAM
1 parent c455e4e commit 4778344

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

boot/loader.c

+17-2
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,15 @@ static const char MSG_ELF_OFFSET_NOT_ALIGNED[] = {
159159
_('A'), _('L'), _('I'), _('G'), _('N'), _('E'), _('D'), 0
160160
};
161161

162+
// "ELF SEGMENT TOO LARGE"
163+
__attribute__((aligned(1)))
164+
static const char MSG_ELF_SEGMENT_TOO_LARGE[] = {
165+
_('E'), _('L'), _('F'), _(' '),
166+
_('S'), _('E'), _('G'), _('M'), _('E'), _('N'), _('T'), _(' '),
167+
_('T'), _('O'), _('O'), _(' '),
168+
_('L'), _('A'), _('R'), _('G'), _('E'), 0
169+
};
170+
162171
#undef _
163172

164173
__attribute__((noreturn))
@@ -251,6 +260,7 @@ void stage2(void)
251260

252261
// Store the ELF offset in the boot flags
253262
*(uint32_t*)0xA400000C = elf_header << 8;
263+
uint32_t ramsize = *(uint32_t*)0xA4000000;
254264

255265
// Check if the ELF is 32/64 bit, and if it's big/little endian
256266
uint32_t elf_type = io_read32(elf_header + 0x4);
@@ -282,6 +292,7 @@ void stage2(void)
282292
uint32_t vaddr = phdr[elf64 ? 5 : 2];
283293
uint32_t paddr = phdr[elf64 ? 7 : 3];
284294
uint32_t size = phdr[elf64 ? 9 : 4];
295+
uint32_t memsize = phdr[elf64 ? 11 : 5];
285296
uint32_t flags = phdr[elf64 ? 1 : 6];
286297

287298
if (phdr[0] == PT_N64_DECOMP) {
@@ -300,6 +311,8 @@ void stage2(void)
300311

301312
if (!size) continue;
302313

314+
debugf("Segment ", i, phdr[0], offset, vaddr, paddr, size, memsize, flags);
315+
303316
// Make sure we can do PI DMA
304317
if ((vaddr % 8) != 0) {
305318
debugf("ELF: vaddr is not 8-byte aligned in segment");
@@ -309,8 +322,10 @@ void stage2(void)
309322
debugf("ELF: file offset is not 2-byte aligned in segment");
310323
fatal(MSG_ELF_OFFSET_NOT_ALIGNED);
311324
}
312-
313-
debugf("Segment ", i, phdr[0], offset, vaddr, size, flags);
325+
if ((flags & PF_N64_COMPRESSED ? paddr : vaddr) + memsize > 0x80000000 + ramsize) {
326+
debugf("ELF: segment does not fit in RDRAM");
327+
fatal(MSG_ELF_SEGMENT_TOO_LARGE);
328+
}
314329

315330
// Load the segment into RDRAM. Notice that we don't need to clear
316331
// extra size at the end of the segment (as specified by phdr[5])

0 commit comments

Comments
 (0)