Started work on the full ELF loader and C++ support

This commit is contained in:
Kevin Lange 2012-01-18 20:12:04 -06:00
parent 0440b775d8
commit e5330b1df0
5 changed files with 126 additions and 24 deletions

View File

@ -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;

View File

@ -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
View 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;
}

View File

@ -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;
}

View File

@ -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);