Skip to content

Commit abab8f7

Browse files
authored
kernel: core: move ELF loader to shared code (#627)
1 parent 1729f6e commit abab8f7

File tree

3 files changed

+81
-51
lines changed

3 files changed

+81
-51
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ libc_asm_objects = $(patsubst %.asm, $(lib_objs_dir)/%.o, $(libc_asm_files))
107107
# libk
108108
libk_c_files += $(wildcard $(kernel_src_dir)/*.c)
109109
libk_c_files += $(wildcard $(kernel_src_dir)/config/*.c)
110+
libk_c_files += $(wildcard $(kernel_src_dir)/core/elf.c)
110111
libk_c_files += $(wildcard $(kernel_src_dir)/core/isr.c)
111112
libk_c_files += $(wildcard $(kernel_src_dir)/fs/*.c)
112113
libk_c_files += $(wildcard $(kernel_src_dir)/fs/dev/*.c)

src/kernel/arch/x86_64/core/elf.h renamed to include/kernel/core/elf.h

+42-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
/**
22
* @file
33
* @see https://www.uclibc.org/docs/elf-64-gen.pdf
4+
* @see https://man7.org/linux/man-pages/man5/elf.5.html
5+
*
6+
* This header file contains the definitions of the Executable and Linking
7+
* Format (ELF) for both 32 (arm) and 64 bits (the default).
48
*/
59
#ifndef CORE_ELF_H
610
#define CORE_ELF_H
@@ -34,15 +38,29 @@
3438
/// Identifies a section that occupies memory during process execution.
3539
#define ELF_SECTION_FLAG_ALLOC 0x2
3640

41+
#ifdef __arm__
42+
43+
#define ElfN_Addr uint32_t
44+
#define ElfN_Off uint32_t
45+
#define ElfN_Size uint32_t
46+
47+
#else // __arm__
48+
49+
#define ElfN_Addr uint64_t
50+
#define ElfN_Off uint64_t
51+
#define ElfN_Size uint64_t
52+
53+
#endif
54+
3755
typedef struct elf_header
3856
{
3957
unsigned char identity[16];
4058
uint16_t type;
4159
uint16_t machine;
4260
uint32_t version;
43-
uint64_t entry;
44-
uint64_t ph_offset;
45-
uint64_t sh_offset;
61+
ElfN_Addr entry;
62+
ElfN_Off ph_offset;
63+
ElfN_Off sh_offset;
4664
uint32_t flags;
4765
uint16_t header_size;
4866
uint16_t ph_size;
@@ -55,27 +73,32 @@ typedef struct elf_header
5573
typedef struct elf_program_header
5674
{
5775
uint32_t type;
76+
#ifndef __arm__
5877
uint32_t flags;
59-
uint64_t offset;
60-
uint64_t virtual_address;
61-
uint64_t physical_address;
62-
uint64_t file_size;
63-
uint64_t mem_size;
64-
uint64_t align;
78+
#endif
79+
ElfN_Off offset;
80+
ElfN_Addr virtual_address;
81+
ElfN_Addr physical_address;
82+
ElfN_Size file_size;
83+
ElfN_Size mem_size;
84+
#ifdef __arm__
85+
ElfN_Size flags;
86+
#endif
87+
ElfN_Size align;
6588
} __attribute__((packed)) elf_program_header_t;
6689

6790
typedef struct elf_section_header
6891
{
69-
uint32_t name; ///< Section name
70-
uint32_t type; ///< Section type
71-
uint64_t flags; ///< Section attributes
72-
uint64_t virtual_address; ///< Virtual address in memory
73-
uint64_t offset; ///< Offset in file
74-
uint64_t size; ///< Size of section
75-
uint32_t link; ///< Link to other section
76-
uint32_t info; ///< Miscellaneous information
77-
uint64_t addralign; ///< Address alignment boundary
78-
uint64_t entsize; ///< Size of entries, if section has table
92+
uint32_t name; ///< Section name
93+
uint32_t type; ///< Section type
94+
ElfN_Size flags; ///< Section attributes
95+
ElfN_Addr virtual_address; ///< Virtual address in memory
96+
ElfN_Off offset; ///< Offset in file
97+
ElfN_Size size; ///< Size of section
98+
uint32_t link; ///< Link to other section
99+
uint32_t info; ///< Miscellaneous information
100+
ElfN_Size addralign; ///< Address alignment boundary
101+
ElfN_Size entsize; ///< Size of entries, if section has table
79102
} __attribute__((packed)) elf_section_header_t;
80103

81104
elf_header_t* elf_load(uint8_t* data);

src/kernel/arch/x86_64/core/elf.c renamed to src/kernel/core/elf.c

+38-32
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
1-
#include "elf.h"
1+
#include <core/elf.h>
22
#include <core/logging.h>
33
#include <inttypes.h>
4-
#include <mmu/paging.h>
54
#include <string.h>
65

7-
int get_elf_type(elf_header_t* elf);
8-
void load_segment(uint8_t* data, elf_program_header_t* program_header);
6+
#ifdef __x86_64__
7+
#include <mmu/paging.h>
8+
#endif
9+
10+
int elf_get_type(elf_header_t* elf);
11+
void elf_load_segment(uint8_t* data, elf_program_header_t* program_header);
912

1013
elf_header_t* elf_load(uint8_t* data)
1114
{
1215
elf_header_t* elf = (elf_header_t*)data;
1316

14-
if (get_elf_type(elf) != ELF_TYPE_EXECUTABLE) {
17+
if (elf_get_type(elf) != ELF_TYPE_EXECUTABLE) {
1518
CORE_DEBUG("%s", "not an executable");
16-
return 0;
19+
return NULL;
1720
}
1821

1922
CORE_DEBUG(
2023
"file header: machine=%#x version=%#x type=%d entry=%p header_size=%u"
21-
" ph_size=%u ph_num=%d ph_offset=%" PRIu64 " sh_size=%u sh_num=%d"
22-
" sh_offset=%" PRIu64 " strtab_index=%d",
24+
" ph_size=%u ph_num=%d sh_size=%u sh_num=%d strtab_index=%d",
2325
elf->machine,
2426
elf->version,
2527
elf->type,
2628
elf->entry,
2729
elf->header_size,
2830
elf->ph_size,
2931
elf->ph_num,
30-
elf->ph_offset,
3132
elf->sh_size,
3233
elf->sh_num,
33-
elf->sh_offset,
3434
elf->strtab_index);
3535

3636
elf_program_header_t* program_header =
37-
(elf_program_header_t*)((uint64_t)data + elf->ph_offset);
37+
(elf_program_header_t*)((uintptr_t)data + elf->ph_offset);
3838

39-
for (uint64_t i = 0; i < elf->ph_num; i++) {
40-
CORE_DEBUG("program header: type=%d addr=%p",
39+
for (uint16_t i = 0; i < elf->ph_num; i++) {
40+
CORE_DEBUG("program header: type=%" PRIu32 " addr=%p",
4141
program_header[i].type,
4242
program_header[i].virtual_address);
4343

4444
if (program_header[i].type == ELF_PROGRAM_TYPE_LOAD) {
45-
load_segment(data, &program_header[i]);
45+
elf_load_segment(data, &program_header[i]);
4646
}
4747
}
4848

@@ -51,7 +51,7 @@ elf_header_t* elf_load(uint8_t* data)
5151
return elf;
5252
}
5353

54-
int get_elf_type(elf_header_t* elf)
54+
int elf_get_type(elf_header_t* elf)
5555
{
5656
int iself = -1;
5757

@@ -64,7 +64,9 @@ int get_elf_type(elf_header_t* elf)
6464
CORE_DEBUG("%s", "validating elf structs");
6565

6666
if (elf->header_size != sizeof(elf_header_t)) {
67-
CORE_DEBUG("%s", "invalid elf header size");
67+
CORE_DEBUG("invalid elf header size: %d, expected: %d",
68+
elf->header_size,
69+
sizeof(elf_header_t));
6870

6971
iself = -1;
7072
} else if (elf->ph_size != sizeof(elf_program_header_t)) {
@@ -81,13 +83,18 @@ int get_elf_type(elf_header_t* elf)
8183
return iself;
8284
}
8385

84-
void load_segment(uint8_t* data, elf_program_header_t* program_header)
86+
void elf_load_segment(uint8_t* data, elf_program_header_t* program_header)
8587
{
86-
uint64_t mem_size = program_header->mem_size; // Size in memory
87-
uint64_t file_size = program_header->file_size; // Size in file
88-
uint64_t addr = program_header->virtual_address; // Offset in memory
89-
uint64_t offset = program_header->offset; // Offset in file
88+
ElfN_Size mem_size = program_header->mem_size; // Size in memory
89+
ElfN_Size file_size = program_header->file_size; // Size in file
90+
ElfN_Addr addr = program_header->virtual_address; // Address in memory
91+
ElfN_Off offset = program_header->offset; // Offset in file
92+
93+
if (mem_size == 0) {
94+
return;
95+
}
9096

97+
#ifdef __x86_64__
9198
// We need WRITABLE because we copy data right after.
9299
uint32_t flags =
93100
PAGING_FLAG_PRESENT | PAGING_FLAG_USER_ACCESSIBLE | PAGING_FLAG_WRITABLE;
@@ -102,11 +109,8 @@ void load_segment(uint8_t* data, elf_program_header_t* program_header)
102109
uint64_t start_page = page_containing_address(addr);
103110
uint32_t number_of_pages = paging_amount_for_byte_size(addr, mem_size);
104111

105-
if (mem_size == 0) {
106-
return;
107-
}
108-
109112
map_multiple(start_page, number_of_pages, flags);
113+
#endif
110114

111115
memcpy((void*)addr, data + offset, file_size);
112116
memset((void*)(addr + file_size), 0, mem_size - file_size);
@@ -118,21 +122,23 @@ void load_segment(uint8_t* data, elf_program_header_t* program_header)
118122
void elf_unload(elf_header_t* elf)
119123
{
120124
elf_program_header_t* program_header =
121-
(elf_program_header_t*)((uint64_t)elf + elf->ph_offset);
125+
(elf_program_header_t*)((uintptr_t)elf + elf->ph_offset);
122126

123-
for (uint64_t i = 0; i < elf->ph_num; i++) {
127+
for (uint16_t i = 0; i < elf->ph_num; i++) {
124128
if (program_header[i].type == ELF_PROGRAM_TYPE_LOAD) {
125-
uint64_t mem_size = program_header[i].mem_size;
126-
uint64_t addr = program_header[i].virtual_address;
127-
128-
uint64_t start_page = page_containing_address(addr);
129-
uint32_t number_of_pages = paging_amount_for_byte_size(addr, mem_size);
129+
ElfN_Size mem_size = program_header[i].mem_size;
130130

131131
if (mem_size == 0) {
132132
continue;
133133
}
134134

135+
#ifdef __x86_64__
136+
uint64_t addr = program_header[i].virtual_address;
137+
uint64_t start_page = page_containing_address(addr);
138+
uint32_t number_of_pages = paging_amount_for_byte_size(addr, mem_size);
139+
135140
unmap_multiple(start_page, number_of_pages);
141+
#endif
136142
}
137143
}
138144

0 commit comments

Comments
 (0)