1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | |
3 | #pragma once |
4 | |
5 | #include "mos/tasks/process.h" |
6 | #include "mos/tasks/task_types.h" |
7 | |
8 | #include <elf.h> |
9 | #include <mos/types.h> |
10 | |
11 | typedef enum |
12 | { |
13 | ELF_ENDIANNESS_INVALID = 0, |
14 | ELF_ENDIANNESS_LSB = 1, |
15 | ELF_ENDIANNESS_MSB = 2, |
16 | } elf_endianness; |
17 | |
18 | #if MOS_LITTLE_ENDIAN |
19 | #define ELF_ENDIANNESS_MOS_DEFAULT ELF_ENDIANNESS_LSB |
20 | #else |
21 | #define ELF_ENDIANNESS_MOS_DEFAULT ELF_ENDIANNESS_MSB |
22 | #endif |
23 | |
24 | typedef struct |
25 | { |
26 | char magic[4]; |
27 | u32 bits : 8; |
28 | u32 endianness : 8; |
29 | u32 version : 8; |
30 | u32 osabi : 8; |
31 | u8 abiversion : 8; |
32 | u8 __padding[7]; |
33 | } elf_identity_t; |
34 | |
35 | MOS_STATIC_ASSERT(sizeof(elf_identity_t) == 16, "elf_identity_t has wrong size" ); |
36 | |
37 | typedef struct |
38 | { |
39 | elf_identity_t ; |
40 | int : 16; |
41 | int : 16; |
42 | |
43 | u32 ; |
44 | |
45 | ptr_t ; |
46 | size_t ; |
47 | size_t ; |
48 | |
49 | u32 ; |
50 | u16 ; |
51 | |
52 | struct |
53 | { |
54 | u16 entry_size, count; |
55 | } __packed , ; |
56 | |
57 | u16 ; |
58 | } __packed ; |
59 | |
60 | typedef enum |
61 | { |
62 | ELF_PT_NULL = 0, // Unused entry |
63 | ELF_PT_LOAD = 1, // Loadable segment |
64 | ELF_PT_DYNAMIC = 2, // Dynamic linking information |
65 | ELF_PT_INTERP = 3, // Interpreter information |
66 | ELF_PT_NOTE = 4, // Auxiliary information |
67 | ELF_PT_SHLIB = 5, // reserved |
68 | ELF_PT_PHDR = 6, // Segment containing program header table |
69 | ELF_PT_TLS = 7, // Thread-local storage segment |
70 | |
71 | _ELF_PT_COUNT, |
72 | |
73 | ELF_PT_OS_LOW = 0x60000000, // reserved |
74 | ELF_PT_OS_HIGH = 0x6fffffff, // reserved |
75 | ELF_PT_PROCESSOR_LO = 0x70000000, // reserved |
76 | ELF_PT_PROCESSOR_HI = 0x7fffffff, // reserved |
77 | } ; |
78 | |
79 | typedef enum |
80 | { |
81 | ELF_PF_X = 1 << 0, // Executable |
82 | ELF_PF_W = 1 << 1, // Writable |
83 | ELF_PF_R = 1 << 2, // Readable |
84 | } elf_ph_flags; |
85 | |
86 | typedef struct |
87 | { |
88 | elf_program_header_type ; |
89 | elf_ph_flags p_flags; // Segment independent flags (64-bit only) |
90 | ptr_t data_offset; // Offset of the segment in the file |
91 | ptr_t vaddr; // Virtual address of the segment |
92 | ptr_t _reserved; // reserved |
93 | ptr_t size_in_file; // Size of the segment in the file (may be 0) |
94 | ptr_t size_in_mem; // Size of the segment in memory (may be 0) |
95 | ptr_t required_alignment; |
96 | } __packed elf_program_hdr_t; |
97 | |
98 | #define AUXV_VEC_SIZE 16 |
99 | |
100 | typedef struct |
101 | { |
102 | int count; |
103 | Elf64_auxv_t vector[AUXV_VEC_SIZE]; |
104 | } auxv_vec_t; |
105 | |
106 | typedef struct |
107 | { |
108 | const char *invocation; |
109 | auxv_vec_t auxv; |
110 | int argc; |
111 | const char **argv; |
112 | |
113 | int envc; |
114 | const char **envp; |
115 | } elf_startup_info_t; |
116 | |
117 | __nodiscard bool elf_read_and_verify_executable(file_t *file, elf_header_t *); |
118 | __nodiscard bool elf_fill_process(process_t *proc, file_t *file, const char *path, const char *const argv[], const char *const envp[]); |
119 | __nodiscard bool elf_do_fill_process(process_t *proc, file_t *file, elf_header_t elf, elf_startup_info_t *info); |
120 | process_t *elf_create_process(const char *path, process_t *parent, const char *const argv[], const char *const envp[], const stdio_t *ios); |
121 | |