Started work on the full ELF loader and C++ support
This commit is contained in:
parent
0440b775d8
commit
e5330b1df0
@ -127,9 +127,14 @@ static int close(int fd) {
|
||||
|
||||
static int sys_sbrk(int size) {
|
||||
uintptr_t ret = current_process->image.heap;
|
||||
current_process->image.heap += size;
|
||||
uintptr_t i_ret = ret;
|
||||
while (ret % 0x1000) {
|
||||
ret++;
|
||||
}
|
||||
current_process->image.heap += (ret - i_ret) + size;
|
||||
while (current_process->image.heap > current_process->image.heap_actual) {
|
||||
current_process->image.heap_actual += 0x1000;
|
||||
assert(current_process->image.heap_actual % 0x1000 == 0);
|
||||
alloc_frame(get_page(current_process->image.heap_actual, 1, current_directory), 0, 1);
|
||||
}
|
||||
return ret;
|
||||
|
@ -1,6 +1,8 @@
|
||||
CC = i686-pc-toaru-gcc
|
||||
CPP = i686-pc-toaru-g++
|
||||
CFLAGS = -march=core2 -std=c99 -O3 -m32 -Wa,--32
|
||||
EXECUTABLES = $(patsubst %.c,../hdd/bin/%,$(wildcard *.c))
|
||||
CPPFLAGS = -march=core2 -O3 -m32 -Wa,--32
|
||||
EXECUTABLES = $(patsubst %.c,../hdd/bin/%,$(wildcard *.c)) $(patsubst %.cpp,../hdd/bin/%,$(wildcard *.cpp))
|
||||
ERRORS = 2>>/tmp/.build-errors || util/mk-error
|
||||
|
||||
|
||||
@ -14,5 +16,11 @@ clean:
|
||||
../hdd/bin/freetype_test: freetype_test.c
|
||||
${CC} ${CFLAGS} -s -I ../util/toaru-toolchain/i686-pc-toaru/include/freetype2/ -o $@ $< ../util/toaru-toolchain/i686-pc-toaru/lib/libfreetype.a
|
||||
|
||||
../hdd/bin/%: %.cpp
|
||||
${CPP} ${CPPFLAGS} -s -o $@ $<
|
||||
|
||||
../hdd/bin/ld: ld.c
|
||||
${CC} ${CFLAGS} -s -fPIC -o $@ $<
|
||||
|
||||
../hdd/bin/%: %.c
|
||||
${CC} ${CFLAGS} -s -o $@ $<
|
||||
|
52
userspace/cpp_test.cpp
Normal file
52
userspace/cpp_test.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
class test {
|
||||
private:
|
||||
int i;
|
||||
public:
|
||||
test() {
|
||||
i = 0;
|
||||
}
|
||||
void inc() {
|
||||
i++;
|
||||
}
|
||||
int value() {
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
std::cout << "Hello world\n";
|
||||
|
||||
int * x = (int *)malloc(sizeof(int));
|
||||
printf("%p\n", x);
|
||||
test * t = new test();
|
||||
printf("%d\n", t->value());
|
||||
t->inc();
|
||||
printf("%d\n", t->value());
|
||||
|
||||
std::queue<int> q;
|
||||
q.push(4);
|
||||
q.push(20);
|
||||
q.push(5);
|
||||
q.push(19);
|
||||
|
||||
while (!q.empty()) {
|
||||
printf("%d\n", q.front());
|
||||
q.pop();
|
||||
}
|
||||
|
||||
std::string s;
|
||||
|
||||
std::cin >> s;
|
||||
|
||||
printf("%d: %s\n", s.length(), s.c_str());
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
@ -30,6 +30,7 @@ uintptr_t DESTINATION = 0x03000000;
|
||||
int _main();
|
||||
int argc;
|
||||
char ** argv;
|
||||
uintptr_t epoint = 0;
|
||||
|
||||
/**
|
||||
* Application entry point.
|
||||
@ -63,19 +64,21 @@ here:
|
||||
size_t binary_size; /**< Size of the file */
|
||||
char * binary_buf; /**< Buffer to store the binary in memory */
|
||||
Elf32_Header * header; /**< ELF header */
|
||||
char * string_table[5]; /**< Room for some string tables */
|
||||
char * string_table; /**< Room for some string tables */
|
||||
uintptr_t __init = 0;
|
||||
|
||||
/* Open the requested binary */
|
||||
binary = fopen(argv[1], "r");
|
||||
|
||||
/* Hack because we don't have seek/tell */
|
||||
char garbage[3];
|
||||
binary_size = 0;
|
||||
while (fread((void *)&garbage, 1, 1, binary) != 0) {
|
||||
++binary_size;
|
||||
if (!binary) {
|
||||
printf("Oh no! This is terrible!\n");
|
||||
return 1;
|
||||
}
|
||||
fclose(binary);
|
||||
binary = fopen(argv[1], "r");
|
||||
|
||||
/* Hack because we don't have seek/tell */
|
||||
fseek(binary, 0, SEEK_END);
|
||||
binary_size = ftell(binary);
|
||||
fseek(binary, 0, SEEK_SET);
|
||||
|
||||
/* Read the binary into a buffer */
|
||||
binary_buf = malloc(binary_size);
|
||||
@ -89,6 +92,21 @@ here:
|
||||
header->e_ident[1] != ELFMAG1 ||
|
||||
header->e_ident[2] != ELFMAG2 ||
|
||||
header->e_ident[3] != ELFMAG3) {
|
||||
printf("Failed to load binary: bad magic\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t i = 0;
|
||||
for (uint32_t x = 0; x < header->e_shentsize * header->e_shnum; x += header->e_shentsize) {
|
||||
Elf32_Shdr * shdr = (Elf32_Shdr *)((uintptr_t)header + (header->e_shoff + x));
|
||||
if (i == header->e_shstrndx) {
|
||||
string_table = (char *)((uintptr_t)header + shdr->sh_offset);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (!string_table) {
|
||||
printf("No string table?\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -100,18 +118,37 @@ here:
|
||||
Elf32_Shdr * shdr = (Elf32_Shdr *)((uintptr_t)binary_buf + (header->e_shoff + x));
|
||||
|
||||
if (shdr->sh_addr) {
|
||||
memcpy((void *)shdr->sh_addr,(void *)((uintptr_t)header + shdr->sh_offset), shdr->sh_size);
|
||||
if (shdr->sh_type == SHT_NOBITS) {
|
||||
/* This is the .bss, zero it */
|
||||
memset((void *)(shdr->sh_addr), 0x0, shdr->sh_size);
|
||||
} else {
|
||||
memcpy((void *)(shdr->sh_addr), (void *)((uintptr_t)header + shdr->sh_offset), shdr->sh_size);
|
||||
}
|
||||
char * sh_name = (char *)((uintptr_t)string_table + shdr->sh_name);
|
||||
printf("%s %p\n", sh_name, shdr->sh_addr);
|
||||
if (!strcmp(sh_name,".init")) {
|
||||
__init = shdr->sh_addr;
|
||||
printf("Found .init\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t location = header->e_entry;
|
||||
uintptr_t argc_ = (uintptr_t)&argc;
|
||||
if (__init) {
|
||||
printf("Calling _init()\n");
|
||||
__asm__ __volatile__ (
|
||||
"push %2\n"
|
||||
"push %1\n"
|
||||
"push $0\n"
|
||||
"call *%0\n"
|
||||
: : "m"(location), "m"(argc_), "m"(argv));
|
||||
: : "m"(__init));
|
||||
}
|
||||
|
||||
|
||||
epoint = header->e_entry;
|
||||
__asm__ __volatile__ (
|
||||
"pushl $0\n"
|
||||
"pushl %2\n"
|
||||
"pushl %1\n"
|
||||
"pushl $0xDECADE21\n"
|
||||
"jmp *%0\n"
|
||||
: : "m"(epoint), "r"(argc-1), "r"(argv+1));
|
||||
|
||||
return 0;
|
||||
}
|
@ -35,7 +35,7 @@ int main(int argc, char ** argv) {
|
||||
size_t binary_size; /**< Size of the file */
|
||||
char * binary_buf; /**< Buffer to store the binary in memory */
|
||||
Elf32_Header * header; /**< ELF header */
|
||||
char * string_table[5]; /**< Room for some string tables */
|
||||
char * string_table; /**< Room for some string tables */
|
||||
|
||||
/* Open the requested binary */
|
||||
binary = fopen(argv[1], "r");
|
||||
@ -159,11 +159,11 @@ int main(int argc, char ** argv) {
|
||||
return 1;
|
||||
}
|
||||
Elf32_Shdr * shdr = (Elf32_Shdr *)((uintptr_t)binary_buf + (header->e_shoff + x));
|
||||
if (shdr->sh_type != SHT_STRTAB) continue;
|
||||
string_table[i] = (char *)((uintptr_t)binary_buf + shdr->sh_offset);
|
||||
if (i == header->e_shstrndx) {
|
||||
string_table = (char *)((uintptr_t)binary_buf + shdr->sh_offset);
|
||||
printf("Found a string table at 0x%x\n", shdr->sh_offset);
|
||||
}
|
||||
++i;
|
||||
if (i == 5) break;
|
||||
}
|
||||
|
||||
/* Read the section headers */
|
||||
@ -175,7 +175,7 @@ int main(int argc, char ** argv) {
|
||||
}
|
||||
Elf32_Shdr * shdr = (Elf32_Shdr *)((uintptr_t)binary_buf + (header->e_shoff + x));
|
||||
|
||||
printf("[%d] %s\n", shdr->sh_type, (char *)((uintptr_t)string_table[0] + shdr->sh_name));
|
||||
printf("[%d] %s\n", shdr->sh_type, (char *)((uintptr_t)string_table + shdr->sh_name));
|
||||
printf("Section starts at 0x%x and is 0x%x bytes long.\n", shdr->sh_offset, shdr->sh_size);
|
||||
if (shdr->sh_addr) {
|
||||
printf("It should be loaded at 0x%x.\n", shdr->sh_addr);
|
||||
|
Loading…
Reference in New Issue
Block a user