diff --git a/sortix/Makefile b/sortix/Makefile index 029b05f8..64c498bd 100644 --- a/sortix/Makefile +++ b/sortix/Makefile @@ -44,7 +44,7 @@ DEFINES:=$(DEFINES) -DINITRD CPPFLAGSRELEASE=-s -O3 CPPFLAGSDEBUG= CPPFLAGS=-I.. -I. $(CPUDEFINES) $(CPUFLAGS) -std=gnu++0x -Wall -Wextra -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector $(DEFINES) $(CPPFLAGSRELEASE) -OBJS=$(CPUOBJS) kernel.o descriptor_tables.o isr.o time.o log.o iprintable.o panic.o keyboard.o memorymanagement.o scheduler.o syscall.o application.o pong.o sound.o pci.o uart.o conway.o test.o http.o vgaterminal.o serialterminal.o descriptors.o device.o vga.o ../libmaxsi/libmaxsi-sortix.a +OBJS=$(CPUOBJS) kernel.o descriptor_tables.o isr.o time.o log.o iprintable.o panic.o keyboard.o memorymanagement.o scheduler.o syscall.o application.o pong.o sound.o pci.o uart.o conway.o test.o http.o vgaterminal.o serialterminal.o descriptors.o device.o vga.o elf.o ../libmaxsi/libmaxsi-sortix.a JSOBJS:=$(subst .o,-js.o,$(OBJS)) all: sortix.bin diff --git a/sortix/elf.cpp b/sortix/elf.cpp new file mode 100644 index 00000000..bf9aff23 --- /dev/null +++ b/sortix/elf.cpp @@ -0,0 +1,146 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along + with Sortix. If not, see . + + elf.h + Constructs processes from ELF files. + +******************************************************************************/ + +#include "platform.h" +#include +#include "elf.h" +#include "memorymanagement.h" + +#include "log.h" // DEBUG + +namespace Sortix +{ + namespace ELF + { + addr_t Construct32(const void* file, size_t filelen) + { + if ( filelen < sizeof(Header32) ) { return 0; } + const Header32* header = (const Header32*) file; + + // Check for little endian. + if ( header->dataencoding != DATA2LSB ) { return 0; } + if ( header->version != CURRENTVERSION ) { return 0; } + + addr_t entry = header->entry; + + // Find the location of the first section header. + addr_t shtbloffset = header->sectionheaderoffset; + addr_t shtblpos = ((addr_t) file) + shtbloffset; + size_t shsize = header->sectionheaderentrysize; + + // Validate that all sections are present. + uint16_t numsections = header->numsectionheaderentries; + size_t neededfilelen = shtbloffset + numsections * shsize; + if ( filelen < neededfilelen ) { return 0; } + + addr_t memlower = SIZE_MAX; + addr_t memupper = 0; + + // Valid all the data we need is in the file. + for ( uint16_t i = 0; i < numsections; i++ ) + { + addr_t shoffset = i * shsize; + addr_t shpos = shtblpos + shoffset; + const SectionHeader32* sh = (const SectionHeader32*) shpos; + if ( sh->addr == 0 ) { continue; } + if ( sh->type == SHT_PROGBITS ) + { + size_t sectionendsat = sh->offset + sh->size; + if ( filelen < sectionendsat ) { return 0; } + } + if ( sh->type == SHT_PROGBITS || sh->type == SHT_NOBITS ) + { + if ( sh->addr < memlower ) { memlower = sh->addr; } + if ( memupper < sh->addr + sh->size ) { memupper = sh->addr + sh->size; } + } + } + + if ( memupper < memlower ) { return entry; } + + // HACK: For now just put it in the same continious block. This is + // very wasteful and not very intelligent. + addr_t mapto = Page::AlignDown(memlower); + addr_t mapbytes = memupper - mapto; + // TODO: Validate that we actually may map here! + if ( !VirtualMemory::MapRangeUser(mapto, mapbytes) ) + { + return 0; + } + + // Create all the sections in the final process. + for ( uint16_t i = 0; i < numsections; i++ ) + { + addr_t shoffset = i * shsize; + addr_t shpos = shtblpos + shoffset; + const SectionHeader32* sh = (const SectionHeader32*) shpos; + if ( sh->type != SHT_PROGBITS && sh->type != SHT_NOBITS ) + { + continue; + } + + if ( sh->addr == 0 ) { continue; } + + if ( sh->type == SHT_PROGBITS ) + { + void* memdest = (void*) sh->addr; + void* memsource = (void*) ( ((addr_t) file) + sh->offset ); + Maxsi::Memory::Copy(memdest, memsource, sh->size); + } + } + + // MEMORY LEAK: There is no system in place to delete the sections + // once the process has terminated. + + return entry; + } + + addr_t Construct64(const void* /*file*/, size_t /*filelen*/) + { + return 0; + } + + addr_t Construct(const void* file, size_t filelen) + { + if ( filelen < sizeof(Header) ) { return 0; } + const Header* header = (const Header*) file; + + if ( !(header->magic[0] == 0x7F && header->magic[1] == 'E' && + header->magic[2] == 'L' && header->magic[3] == 'F' ) ) + { + return 0; + } + + switch ( header->fileclass ) + { + case CLASS32: + return Construct32(file, filelen); + case CLASS64: + return Construct64(file, filelen); + default: + return 0; + } + } + } +} + diff --git a/sortix/elf.h b/sortix/elf.h new file mode 100644 index 00000000..9579f733 --- /dev/null +++ b/sortix/elf.h @@ -0,0 +1,102 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along + with Sortix. If not, see . + + elf.h + Constructs processes from ELF files. + +******************************************************************************/ + +#ifndef SORTIX_ELF_H +#define SORTIX_ELF_H + +namespace Sortix +{ + namespace ELF + { + struct Header + { + unsigned char magic[4]; + unsigned char fileclass; + unsigned char dataencoding; + unsigned char version; + unsigned char padding[9]; + }; + + const unsigned char CLASSNONE = 0; + const unsigned char CLASS32 = 1; + const unsigned char CLASS64 = 2; + const unsigned char DATA2LSB = 1; + const unsigned char DATA2MSB = 2; + const unsigned char CURRENTVERSION = 1; + + struct Header32 : public Header + { + uint16_t type; + uint16_t machine; + uint32_t version; + uint32_t entry; + uint32_t programheaderoffset; + uint32_t sectionheaderoffset; + uint32_t flags; + uint16_t elfheadersize; + uint16_t programheaderentrysize; + uint16_t numprogramheaderentries; + uint16_t sectionheaderentrysize; + uint16_t numsectionheaderentries; + uint16_t sectionheaderstringindex; + }; + + struct SectionHeader32 + { + uint32_t name; + uint32_t type; + uint32_t flags; + uint32_t addr; + uint32_t offset; + uint32_t size; + uint32_t link; + uint32_t info; + uint32_t addralign; + uint32_t entsize; + }; + + const uint32_t SHT_NULL = 0; + const uint32_t SHT_PROGBITS = 1; + const uint32_t SHT_SYMTAB = 2; + const uint32_t SHT_STRTAB = 3; + const uint32_t SHT_RELA = 4; + const uint32_t SHT_HASH = 5; + const uint32_t SHT_DYNAMIC = 6; + const uint32_t SHT_NOTE = 7; + const uint32_t SHT_NOBITS = 8; + const uint32_t SHT_REL = 9; + const uint32_t SHT_SHLIB = 10; + const uint32_t SHT_DYNSYM = 11; + const uint32_t SHT_LOPROC = 0x70000000; + const uint32_t SHT_HIPROC = 0x7fffffff; + const uint32_t SHT_LOUSER = 0x80000000; + const uint32_t SHT_HIUSER = 0xffffffff; + + // Reads the elf file into the current address space and returns the + // entry address of the program, or 0 upon failure. + addr_t Construct(const void* file, size_t filelen); + } +} + +#endif