1/*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include <arch/kernel/elf.h>
8#include <linker.h>
9
10/* minimal ELF functionality for loading GRUB boot module */
11
12BOOT_CODE bool_t elf_checkFile(Elf32_Header_t *elfFile)
13{
14    return (
15               elfFile->e_ident[0] == '\177' &&
16               elfFile->e_ident[1] == 'E'    &&
17               elfFile->e_ident[2] == 'L'    &&
18               elfFile->e_ident[3] == 'F'    &&
19               elfFile->e_ident[4] == 1
20           );
21}
22
23BOOT_CODE v_region_t elf_getMemoryBounds(Elf32_Header_t *elfFile)
24{
25    Elf32_Phdr_t *phdr = (Elf32_Phdr_t *)((paddr_t)elfFile + elfFile->e_phoff);
26    v_region_t elf_reg;
27    vptr_t     sect_start;
28    vptr_t     sect_end;
29    uint32_t   i;
30
31    elf_reg.start = 0xffffffff;
32    elf_reg.end = 0;
33
34    /* loop through all program headers (segments) and record start/end address */
35    for (i = 0; i < elfFile->e_phnum; i++) {
36        if (phdr[i].p_memsz > 0) {
37            sect_start = phdr[i].p_vaddr;
38            sect_end = sect_start + phdr[i].p_memsz;
39            if (sect_start < elf_reg.start) {
40                elf_reg.start = sect_start;
41            }
42            if (sect_end > elf_reg.end) {
43                elf_reg.end = sect_end;
44            }
45        }
46    }
47
48    return elf_reg;
49}
50
51BOOT_CODE void elf_load(Elf32_Header_t *elfFile, seL4_Word offset)
52{
53    Elf32_Phdr_t *phdr = (Elf32_Phdr_t *)((paddr_t)elfFile + elfFile->e_phoff);
54    paddr_t       src;
55    paddr_t       dst;
56    uint32_t      len;
57    uint32_t      i;
58
59    /* loop through all program headers (segments) and load them */
60    for (i = 0; i < elfFile->e_phnum; i++) {
61        src = (paddr_t)elfFile + phdr[i].p_offset;
62        dst = phdr[i].p_vaddr + offset;
63        len = phdr[i].p_filesz;
64        memcpy((void *)dst, (char *)src, len);
65        dst += len;
66        memset((void *)dst, 0, phdr[i].p_memsz - len);
67    }
68}
69