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
10BOOT_CODE bool_t elf_checkFile(Elf64_Header_t *elf)
11{
12    return (
13               elf->e_ident[0] == '\177' &&
14               elf->e_ident[1] == 'E'    &&
15               elf->e_ident[2] == 'L'    &&
16               elf->e_ident[3] == 'F'    &&
17               elf->e_ident[4] == 2
18           );
19}
20
21
22BOOT_CODE v_region_t elf_getMemoryBounds(Elf64_Header_t *elf)
23{
24    v_region_t  elf_reg;
25    vptr_t      sect_start;
26    vptr_t      sect_end;
27    uint32_t    i;
28    Elf64_Phdr_t *phdr = (Elf64_Phdr_t *)((paddr_t)elf + elf->e_phoff);
29
30    elf_reg.start = 0x7fffffffffffffffUL;
31    elf_reg.end = 0;
32
33    for (i = 0; i < elf->e_phnum; i++) {
34        if (phdr[i].p_memsz > 0) {
35            sect_start = phdr[i].p_vaddr;
36            sect_end = sect_start + phdr[i].p_memsz;
37            if (sect_start < elf_reg.start) {
38                elf_reg.start = sect_start;
39            }
40            if (sect_end > elf_reg.end) {
41                elf_reg.end = sect_end;
42            }
43        }
44    }
45
46    return elf_reg;
47}
48
49BOOT_CODE void elf_load(Elf64_Header_t *elf, seL4_Word offset)
50{
51    paddr_t     src;
52    paddr_t     dst;
53    uint64_t    len;
54    uint32_t    i;
55    Elf64_Phdr_t *phdr = (Elf64_Phdr_t *)((paddr_t)elf + elf->e_phoff);
56
57    for (i = 0; i < elf->e_phnum; i++) {
58        src = (paddr_t)elf + phdr[i].p_offset;
59        dst = phdr[i].p_vaddr + offset;
60        len = phdr[i].p_filesz;
61        memcpy((void *)dst, (char *)src, len);
62        dst += len;
63        memset((void *)dst, 0, phdr[i].p_memsz - len);
64    }
65}
66