mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
The ELF loader now uses program headers and not section headers.
This commit is contained in:
parent
b705bf27a1
commit
4898343e2f
2 changed files with 51 additions and 56 deletions
|
@ -26,8 +26,9 @@
|
||||||
#include <libmaxsi/memory.h>
|
#include <libmaxsi/memory.h>
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "memorymanagement.h"
|
#include "memorymanagement.h"
|
||||||
|
#include "panic.h"
|
||||||
|
|
||||||
#include "log.h" // DEBUG
|
using namespace Maxsi;
|
||||||
|
|
||||||
namespace Sortix
|
namespace Sortix
|
||||||
{
|
{
|
||||||
|
@ -44,69 +45,41 @@ namespace Sortix
|
||||||
|
|
||||||
addr_t entry = header->entry;
|
addr_t entry = header->entry;
|
||||||
|
|
||||||
// Find the location of the first section header.
|
// Find the location of the program headers.
|
||||||
addr_t shtbloffset = header->sectionheaderoffset;
|
addr_t phtbloffset = header->programheaderoffset;
|
||||||
addr_t shtblpos = ((addr_t) file) + shtbloffset;
|
if ( filelen < phtbloffset ) { return 0; }
|
||||||
size_t shsize = header->sectionheaderentrysize;
|
addr_t phtblpos = ((addr_t) file) + phtbloffset;
|
||||||
|
size_t phsize = header->programheaderentrysize;
|
||||||
|
const ProgramHeader32* phtbl = (const ProgramHeader32*) phtblpos;
|
||||||
|
|
||||||
// Validate that all sections are present.
|
// Validate that all program headers are present.
|
||||||
uint16_t numsections = header->numsectionheaderentries;
|
uint16_t numprogheaders = header->numprogramheaderentries;
|
||||||
size_t neededfilelen = shtbloffset + numsections * shsize;
|
size_t neededfilelen = phtbloffset + numprogheaders * phsize;
|
||||||
if ( filelen < neededfilelen ) { return 0; }
|
if ( filelen < neededfilelen ) { return 0; }
|
||||||
|
|
||||||
addr_t memlower = SIZE_MAX;
|
// Create all the segments in the final process.
|
||||||
addr_t memupper = 0;
|
// TODO: Handle errors on bad/malicious input or out-of-mem!
|
||||||
|
for ( uint16_t i = 0; i < numprogheaders; i++ )
|
||||||
// Valid all the data we need is in the file.
|
|
||||||
for ( uint16_t i = 0; i < numsections; i++ )
|
|
||||||
{
|
{
|
||||||
addr_t shoffset = i * shsize;
|
const ProgramHeader32* pht = &(phtbl[i]);
|
||||||
addr_t shpos = shtblpos + shoffset;
|
if ( pht->type != PT_LOAD ) { continue; }
|
||||||
const SectionHeader32* sh = (const SectionHeader32*) shpos;
|
addr_t virtualaddr = pht->virtualaddr;
|
||||||
if ( sh->addr == 0 ) { continue; }
|
addr_t mapto = Page::AlignDown(virtualaddr);
|
||||||
if ( sh->type == SHT_PROGBITS )
|
addr_t mapbytes = virtualaddr - mapto + pht->memorysize;
|
||||||
{
|
ASSERT(pht->offset % pht->align == virtualaddr % pht->align);
|
||||||
size_t sectionendsat = sh->offset + sh->size;
|
ASSERT(pht->offset + pht->filesize < filelen);
|
||||||
if ( filelen < sectionendsat ) { return 0; }
|
ASSERT(pht->filesize <= pht->memorysize);
|
||||||
}
|
|
||||||
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; }
|
if ( !VirtualMemory::MapRangeUser(mapto, mapbytes) )
|
||||||
|
|
||||||
// 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;
|
PanicF("Could not user-map at %p and %zu bytes onwards", mapto, mapbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( sh->addr == 0 ) { continue; }
|
// Copy as much data as possible and memset the rest to 0.
|
||||||
|
byte* memdest = (byte*) virtualaddr;
|
||||||
if ( sh->type == SHT_PROGBITS )
|
byte* memsource = (byte*) ( (addr_t)file + pht->offset);
|
||||||
{
|
Memory::Copy(memdest, memsource, pht->filesize);
|
||||||
void* memdest = (void*) sh->addr;
|
Memory::Set(memdest + pht->filesize, 0, pht->memorysize - pht->filesize);
|
||||||
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
|
// MEMORY LEAK: There is no system in place to delete the sections
|
||||||
|
|
22
sortix/elf.h
22
sortix/elf.h
|
@ -93,6 +93,28 @@ namespace Sortix
|
||||||
const uint32_t SHT_LOUSER = 0x80000000;
|
const uint32_t SHT_LOUSER = 0x80000000;
|
||||||
const uint32_t SHT_HIUSER = 0xffffffff;
|
const uint32_t SHT_HIUSER = 0xffffffff;
|
||||||
|
|
||||||
|
struct ProgramHeader32
|
||||||
|
{
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t virtualaddr;
|
||||||
|
uint32_t physicaladdr;
|
||||||
|
uint32_t filesize;
|
||||||
|
uint32_t memorysize;
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t align;
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32_t PT_NULL = 0;
|
||||||
|
const uint32_t PT_LOAD = 1;
|
||||||
|
const uint32_t PT_DYNAMIC = 2;
|
||||||
|
const uint32_t PT_INTERP = 3;
|
||||||
|
const uint32_t PT_NOTE = 4;
|
||||||
|
const uint32_t PT_SHLIB = 5;
|
||||||
|
const uint32_t PT_PHDR = 6;
|
||||||
|
const uint32_t PT_LOPROC = 0x70000000;
|
||||||
|
const uint32_t PT_HIPROC = 0x7FFFFFFF;
|
||||||
|
|
||||||
// Reads the elf file into the current address space and returns the
|
// Reads the elf file into the current address space and returns the
|
||||||
// entry address of the program, or 0 upon failure.
|
// entry address of the program, or 0 upon failure.
|
||||||
addr_t Construct(const void* file, size_t filelen);
|
addr_t Construct(const void* file, size_t filelen);
|
||||||
|
|
Loading…
Add table
Reference in a new issue