mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Sortix can now load ELF executables into addresses spaces.
This commit is contained in:
parent
e5eaf3eeb5
commit
9db2c88aca
3 changed files with 249 additions and 1 deletions
|
@ -44,7 +44,7 @@ DEFINES:=$(DEFINES) -DINITRD
|
||||||
CPPFLAGSRELEASE=-s -O3
|
CPPFLAGSRELEASE=-s -O3
|
||||||
CPPFLAGSDEBUG=
|
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)
|
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))
|
JSOBJS:=$(subst .o,-js.o,$(OBJS))
|
||||||
|
|
||||||
all: sortix.bin
|
all: sortix.bin
|
||||||
|
|
146
sortix/elf.cpp
Normal file
146
sortix/elf.cpp
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
elf.h
|
||||||
|
Constructs processes from ELF files.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include <libmaxsi/memory.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
102
sortix/elf.h
Normal file
102
sortix/elf.h
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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
|
Loading…
Reference in a new issue