Max OS 0.3
Loading...
Searching...
No Matches
elf.cpp
Go to the documentation of this file.
1
9#include <processes/elf.h>
10#include <common/logger.h>
11
12using namespace MaxOS;
13using namespace MaxOS::processes;
14using namespace MaxOS::memory;
15
16
17
23ELF64::ELF64(uintptr_t elf_header_address)
24: m_elf_header_address(elf_header_address)
25{
26}
27
31ELF64::~ELF64() = default;
32
39
40 if (!is_valid())
41 return;
42
43 load_program_headers();
44
45}
46
53
54 return (elf_64_header_t*) m_elf_header_address;
55}
56
64
65 // Check bounds
66 if (index >= header()->program_header_count)
67 return nullptr;
68
69 // Find the program headers and return the item
70 auto* program_headers = (elf_64_program_header_t*) (m_elf_header_address + header()->program_header_offset);
71 return &program_headers[index];
72
73}
74
82
83 // Check bound
84 if (index >= header()->section_header_count)
85 return nullptr;
86
87 // Find the section headers and return the item
88 auto* section_headers = (elf_64_section_header_t*) (m_elf_header_address + header()->section_header_offset);
89 return &section_headers[index];
90
91}
92
100bool ELF64::is_valid() const {
101
102 // Validate the magic number
103 for (size_t i = 0; i < 4; i++)
104 if (header()->identification[i] != ELF_MAGIC[i])
105 return false;
106
107 // Check if the elf is 64 bit
108 if (header()->identification[(int) ELFIdentification::Class] != (int) ELFClass::Bits64)
109 return false;
110
111 // Check if the elf is little endian
112 if (header()->identification[(int) ELFIdentification::Data] != (int) ELFData::LittleEndian)
113 return false;
114
115 // Check if the elf is version 1
116 if (header()->identification[(int) ELFIdentification::Version] != (int) ELFVersion::Current)
117 return false;
118
119 // Check if the elf is for the MaxOS platform
120 // if(header() -> identification[OSABI] != MaxOSABI)
121 // return false;
122
123 // Check if the elf is executable
124 if (header()->type != (int) ELFType::Executable)
125 return false;
126
127 // Check if the elf is for the x86_64 platform
128 if (header()->machine != (int) ELFMachine::x86_64)
129 return false;
130
131 // LGTM
132 return true;
133
134}
135
139void ELF64::load_program_headers() const {
140
141 for (size_t i = 0; i < header()->program_header_count; i++) {
142
143 // Get the header information
144 elf_64_program_header_t* program_header = get_program_header(i);
145
146 // Only load headers that actually need loading
147 if (program_header->type != (int) ELFProgramType::Load)
148 continue;
149
150 // Allocate space at the requested address
151 void* address = MemoryManager::s_current_memory_manager->vmm()->allocate(program_header->virtual_address, program_header->memory_size, PRESENT | WRITE);
152 ASSERT(address != nullptr, "Failed to allocate memory for program header\n");
153
154 // Copy the program into memory at that address
155 memcpy(address, (void*) (m_elf_header_address + program_header->offset), program_header->file_size);
156
157 // Zero the rest of the memory if needed
158 size_t zero_size = program_header->memory_size - program_header->file_size;
159 memset((void*) ((uintptr_t) address + program_header->file_size), 0, zero_size);
160
161 // Once the memory has been copied can now mark the pages as read only etc
162 uint64_t flags = to_vmm_flags(program_header->flags);
164 }
165}
166
173uint64_t ELF64::to_vmm_flags(uint32_t type) {
174
175 // Conversion
176 // ELF | VMM
177 // 0x0 | Executable
178 // 0x1 | Write
179 // 0x2 | Read
180
181 uint64_t flags = PRESENT | USER | NO_EXECUTE;
182
183 // Enable write
184 if (type & ELFWrite)
185 flags |= WRITE;
186
187 // Disable no execute
188 if (type & ELFExecute)
189 flags &= ~NO_EXECUTE;
190
191 return flags;
192}
static MemoryManager * s_current_memory_manager
The memory manager for the current process.
VirtualMemoryManager * vmm()
void change_page_flags(virtual_address_t *virtual_address, size_t flags, uint64_t *pml4_root)
Changes the flags of a page.
Definition physical.cpp:847
static PhysicalMemoryManager * s_current_manager
The current physical memory manager in use.
Definition physical.h:185
void * allocate(size_t size, size_t flags)
Allocate a new chunk of virtual memory.
Definition virtual.cpp:119
elf_64_header_t * header() const
Gets the header of the elf file.
Definition elf.cpp:52
static uint64_t to_vmm_flags(uint32_t type)
Converts elf flags to vmm flags.
Definition elf.cpp:173
ELF64(uintptr_t elf_header_address)
Constructor for the ELF64 class.
Definition elf.cpp:23
~ELF64()
Destructor for the ELF64 class.
elf_64_program_header_t * get_program_header(size_t index) const
Gets a program header from the elf file.
Definition elf.cpp:63
void load()
Loads the elf program into memory if a valid elf file.
Definition elf.cpp:38
elf_64_section_header_t * get_section_header(size_t index) const
Gets a section header from the elf file.
Definition elf.cpp:81
bool is_valid() const
Checks if the elf file is valid for MaxOS runtime.
Definition elf.cpp:100
Defines structures and enums for handling ELF (Executable and Linkable Format) files in MaxOS.
constexpr char ELF_MAGIC[4]
The expected ELF magic number at the start of the file.
Definition elf.h:22
Defines a Logger class for logging messages with different severity levels to multiple output streams...
#define ASSERT(condition, format,...)
If the specified condition is not met then the kernel will crash with the specified message.
Definition logger.h:100
void * memcpy(void *destination, const void *source, uint64_t num)
Copies a block of memory from one location to another.
Definition memoryIO.cpp:165
void * memset(void *ptr, uint32_t value, uint64_t num)
Fills a block of memory with a specified value.
Definition memoryIO.cpp:215
@ PRESENT
The page is present in memory.
Definition physical.h:43
@ WRITE
Memory in this page is writable.
Definition physical.h:44
@ USER
This page is accessible from user mode.
Definition physical.h:45
@ NO_EXECUTE
Dont let the CPU execute code on this page.
Definition physical.h:52
The header of a 64-bit ELF file.
Definition elf.h:110
uint64_t section_header_offset
The offset in the file where the section header table starts.
Definition elf.h:118
uint64_t program_header_offset
The offset in the file where the program header table starts.
Definition elf.h:117
uint16_t program_header_count
The number of entries in the program header table.
Definition elf.h:122
The header for the program segments in a 64-bit ELF file.
Definition elf.h:162
uint32_t type
The type of the program header (see ELFProgramType)
Definition elf.h:164
uint64_t memory_size
The size of the segment in memory (should be >= file_size)
Definition elf.h:170
uint64_t virtual_address
Where the segment is to be loaded in memory.
Definition elf.h:167
uint64_t file_size
The size of the segment in the file.
Definition elf.h:169
uint32_t flags
The flags of the program header (see ELFProgramFlags)
Definition elf.h:165
uint64_t offset
The offset in the file where the segment is located.
Definition elf.h:166
The header for the sections in a 64-bit ELF file.
Definition elf.h:198