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
11typedef 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
24typedef 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
35MOS_STATIC_ASSERT(sizeof(elf_identity_t) == 16, "elf_identity_t has wrong size");
36
37typedef struct
38{
39 elf_identity_t identity;
40 int object_type : 16;
41 int machine_type : 16;
42
43 u32 version;
44
45 ptr_t entry_point;
46 size_t ph_offset;
47 size_t sh_offset;
48
49 u32 flags;
50 u16 header_size;
51
52 struct
53 {
54 u16 entry_size, count;
55 } __packed ph, sh;
56
57 u16 sh_strtab_index;
58} __packed elf_header_t;
59
60typedef 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} elf_program_header_type;
78
79typedef 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
86typedef struct
87{
88 elf_program_header_type 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
100typedef struct
101{
102 int count;
103 Elf64_auxv_t vector[AUXV_VEC_SIZE];
104} auxv_vec_t;
105
106typedef 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 *header);
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);
120process_t *elf_create_process(const char *path, process_t *parent, const char *const argv[], const char *const envp[], const stdio_t *ios);
121