mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Load program symbol tables.
This commit is contained in:
parent
b84d9d26d0
commit
cd1cc19b01
4 changed files with 180 additions and 10 deletions
135
sortix/elf.cpp
135
sortix/elf.cpp
|
@ -35,6 +35,7 @@
|
||||||
#include <sortix/kernel/platform.h>
|
#include <sortix/kernel/platform.h>
|
||||||
#include <sortix/kernel/memorymanagement.h>
|
#include <sortix/kernel/memorymanagement.h>
|
||||||
#include <sortix/kernel/process.h>
|
#include <sortix/kernel/process.h>
|
||||||
|
#include <sortix/kernel/symbol.h>
|
||||||
|
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
|
||||||
|
@ -60,7 +61,11 @@ static int ToProgramSectionType(int flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t Construct32(Process* process, const void* file, size_t filelen)
|
// TODO: This code doesn't respect that the size of program headers and section
|
||||||
|
// headers may vary depending on the ELF header and that using a simple
|
||||||
|
// table indexation isn't enough.
|
||||||
|
|
||||||
|
addr_t Construct32(Process* process, const uint8_t* file, size_t filelen)
|
||||||
{
|
{
|
||||||
if ( filelen < sizeof(Header32) )
|
if ( filelen < sizeof(Header32) )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -145,10 +150,71 @@ addr_t Construct32(Process* process, const void* file, size_t filelen)
|
||||||
memset(memdest + pht->filesize, 0, pht->memorysize - pht->filesize);
|
memset(memdest + pht->filesize, 0, pht->memorysize - pht->filesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the location of the section headers.
|
||||||
|
addr_t shtblpos = (addr_t) file + header->sectionheaderoffset;
|
||||||
|
const SectionHeader32* shtbl = (const SectionHeader32*) shtblpos;
|
||||||
|
|
||||||
|
const SectionHeader32* section_names_section = shtbl + header->sectionheaderstringindex;
|
||||||
|
const char* section_names = (const char*) (file + section_names_section->offset);
|
||||||
|
|
||||||
|
// Find the string table.
|
||||||
|
const SectionHeader32* string_table_section = NULL;
|
||||||
|
for ( size_t i = 0; i < header->numsectionheaderentries; i++ )
|
||||||
|
if ( !strcmp(section_names + shtbl[i].name, ".strtab") )
|
||||||
|
{
|
||||||
|
string_table_section = shtbl + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the symbol table.
|
||||||
|
const SectionHeader32* symbol_table_section = NULL;
|
||||||
|
for ( size_t i = 0; i < header->numsectionheaderentries; i++ )
|
||||||
|
if ( !strcmp(section_names + shtbl[i].name, ".symtab") )
|
||||||
|
{
|
||||||
|
symbol_table_section = shtbl + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !string_table_section || !symbol_table_section )
|
||||||
|
return entry;
|
||||||
|
|
||||||
|
// Prepare copying debug information.
|
||||||
|
const char* elf_string_table = (const char*) (file + string_table_section->offset);
|
||||||
|
size_t elf_string_table_size = string_table_section->size;
|
||||||
|
const Symbol32* elf_symbols = (const Symbol32*) (file + symbol_table_section->offset);
|
||||||
|
size_t elf_symbol_count = symbol_table_section->size / sizeof(Symbol32);
|
||||||
|
|
||||||
|
// Duplicate the string table.
|
||||||
|
char* string_table = new char[elf_string_table_size];
|
||||||
|
if ( !string_table )
|
||||||
|
return entry;
|
||||||
|
memcpy(string_table, elf_string_table, elf_string_table_size);
|
||||||
|
|
||||||
|
// Duplicate the symbol table.
|
||||||
|
Symbol* symbol_table = new Symbol[elf_symbol_count-1];
|
||||||
|
if ( !symbol_table )
|
||||||
|
{
|
||||||
|
delete[] string_table;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy all entires except the leading null entry.
|
||||||
|
for ( size_t i = 1; i < elf_symbol_count; i++ )
|
||||||
|
{
|
||||||
|
symbol_table[i-1].address = elf_symbols[i].st_value;
|
||||||
|
symbol_table[i-1].size = elf_symbols[i].st_size;
|
||||||
|
symbol_table[i-1].name = string_table + elf_symbols[i].st_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
process->string_table = string_table;
|
||||||
|
process->string_table_length = elf_string_table_size;
|
||||||
|
process->symbol_table = symbol_table;
|
||||||
|
process->symbol_table_length = elf_symbol_count-1;
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t Construct64(Process* process, const void* file, size_t filelen)
|
addr_t Construct64(Process* process, const uint8_t* file, size_t filelen)
|
||||||
{
|
{
|
||||||
#ifndef PLATFORM_X64
|
#ifndef PLATFORM_X64
|
||||||
(void) process;
|
(void) process;
|
||||||
|
@ -241,6 +307,67 @@ addr_t Construct64(Process* process, const void* file, size_t filelen)
|
||||||
memset(memdest + pht->filesize, 0, pht->memorysize - pht->filesize);
|
memset(memdest + pht->filesize, 0, pht->memorysize - pht->filesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the location of the section headers.
|
||||||
|
addr_t shtblpos = (addr_t) file + header->sectionheaderoffset;
|
||||||
|
const SectionHeader64* shtbl = (const SectionHeader64*) shtblpos;
|
||||||
|
|
||||||
|
const SectionHeader64* section_names_section = shtbl + header->sectionheaderstringindex;
|
||||||
|
const char* section_names = (const char*) (file + section_names_section->offset);
|
||||||
|
|
||||||
|
// Find the string table.
|
||||||
|
const SectionHeader64* string_table_section = NULL;
|
||||||
|
for ( size_t i = 0; i < header->numsectionheaderentries; i++ )
|
||||||
|
if ( !strcmp(section_names + shtbl[i].name, ".strtab") )
|
||||||
|
{
|
||||||
|
string_table_section = shtbl + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the symbol table.
|
||||||
|
const SectionHeader64* symbol_table_section = NULL;
|
||||||
|
for ( size_t i = 0; i < header->numsectionheaderentries; i++ )
|
||||||
|
if ( !strcmp(section_names + shtbl[i].name, ".symtab") )
|
||||||
|
{
|
||||||
|
symbol_table_section = shtbl + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !string_table_section || !symbol_table_section )
|
||||||
|
return entry;
|
||||||
|
|
||||||
|
// Prepare copying debug information.
|
||||||
|
const char* elf_string_table = (const char*) (file + string_table_section->offset);
|
||||||
|
size_t elf_string_table_size = string_table_section->size;
|
||||||
|
const Symbol64* elf_symbols = (const Symbol64*) (file + symbol_table_section->offset);
|
||||||
|
size_t elf_symbol_count = symbol_table_section->size / sizeof(Symbol64);
|
||||||
|
|
||||||
|
// Duplicate the string table.
|
||||||
|
char* string_table = new char[elf_string_table_size];
|
||||||
|
if ( !string_table )
|
||||||
|
return entry;
|
||||||
|
memcpy(string_table, elf_string_table, elf_string_table_size);
|
||||||
|
|
||||||
|
// Duplicate the symbol table.
|
||||||
|
Symbol* symbol_table = new Symbol[elf_symbol_count-1];
|
||||||
|
if ( !symbol_table )
|
||||||
|
{
|
||||||
|
delete[] string_table;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy all entires except the leading null entry.
|
||||||
|
for ( size_t i = 1; i < elf_symbol_count; i++ )
|
||||||
|
{
|
||||||
|
symbol_table[i-1].address = elf_symbols[i].st_value;
|
||||||
|
symbol_table[i-1].size = elf_symbols[i].st_size;
|
||||||
|
symbol_table[i-1].name = string_table + elf_symbols[i].st_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
process->string_table = string_table;
|
||||||
|
process->string_table_length = elf_string_table_size;
|
||||||
|
process->symbol_table = symbol_table;
|
||||||
|
process->symbol_table_length = elf_symbol_count-1;
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -258,8 +385,8 @@ addr_t Construct(Process* process, const void* file, size_t filelen)
|
||||||
|
|
||||||
switch ( header->fileclass )
|
switch ( header->fileclass )
|
||||||
{
|
{
|
||||||
case CLASS32: return Construct32(process, file, filelen);
|
case CLASS32: return Construct32(process, (const uint8_t*) file, filelen);
|
||||||
case CLASS64: return Construct64(process, file, filelen);
|
case CLASS64: return Construct64(process, (const uint8_t*) file, filelen);
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
12
sortix/elf.h
12
sortix/elf.h
|
@ -178,12 +178,12 @@ struct Symbol32
|
||||||
|
|
||||||
struct Symbol64
|
struct Symbol64
|
||||||
{
|
{
|
||||||
uint32_t st_name;
|
uint32_t st_name;
|
||||||
uint8_t st_info;
|
uint8_t st_info;
|
||||||
uint8_t st_other;
|
uint8_t st_other;
|
||||||
uint16_t st_shndx;
|
uint16_t st_shndx;
|
||||||
uint64_t st_value;
|
uint64_t st_value;
|
||||||
uint64_t st_size;
|
uint64_t st_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reads the elf file into the current address space and returns the entry
|
// Reads the elf file into the current address space and returns the entry
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct ProcessSegment;
|
||||||
struct ProcessTimer;
|
struct ProcessTimer;
|
||||||
struct ioctx_struct;
|
struct ioctx_struct;
|
||||||
typedef struct ioctx_struct ioctx_t;
|
typedef struct ioctx_struct ioctx_t;
|
||||||
|
struct Symbol;
|
||||||
|
|
||||||
const int SEG_NONE = 0;
|
const int SEG_NONE = 0;
|
||||||
const int SEG_TEXT = 1;
|
const int SEG_TEXT = 1;
|
||||||
|
@ -88,6 +89,10 @@ private:
|
||||||
static pid_t AllocatePID();
|
static pid_t AllocatePID();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
char* string_table;
|
||||||
|
size_t string_table_length;
|
||||||
|
Symbol* symbol_table;
|
||||||
|
size_t symbol_table_length;
|
||||||
char* program_image_path;
|
char* program_image_path;
|
||||||
addr_t addrspace;
|
addr_t addrspace;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <sortix/kernel/syscall.h>
|
#include <sortix/kernel/syscall.h>
|
||||||
#include <sortix/kernel/sortedlist.h>
|
#include <sortix/kernel/sortedlist.h>
|
||||||
#include <sortix/kernel/scheduler.h>
|
#include <sortix/kernel/scheduler.h>
|
||||||
|
#include <sortix/kernel/symbol.h>
|
||||||
#include <sortix/kernel/process.h>
|
#include <sortix/kernel/process.h>
|
||||||
#include <sortix/kernel/thread.h>
|
#include <sortix/kernel/thread.h>
|
||||||
#include <sortix/kernel/time.h>
|
#include <sortix/kernel/time.h>
|
||||||
|
@ -107,6 +108,10 @@ namespace Sortix
|
||||||
|
|
||||||
Process::Process()
|
Process::Process()
|
||||||
{
|
{
|
||||||
|
string_table = NULL;
|
||||||
|
string_table_length = 0;
|
||||||
|
symbol_table = NULL;
|
||||||
|
symbol_table_length = 0;
|
||||||
addrspace = 0;
|
addrspace = 0;
|
||||||
segments = NULL;
|
segments = NULL;
|
||||||
parent = NULL;
|
parent = NULL;
|
||||||
|
@ -139,6 +144,8 @@ namespace Sortix
|
||||||
|
|
||||||
Process::~Process()
|
Process::~Process()
|
||||||
{
|
{
|
||||||
|
delete[] string_table;
|
||||||
|
delete[] symbol_table;
|
||||||
if ( alarm_timer.IsAttached() )
|
if ( alarm_timer.IsAttached() )
|
||||||
alarm_timer.Detach();
|
alarm_timer.Detach();
|
||||||
if ( program_image_path )
|
if ( program_image_path )
|
||||||
|
@ -280,6 +287,10 @@ namespace Sortix
|
||||||
curthread);
|
curthread);
|
||||||
addrspace = 0;
|
addrspace = 0;
|
||||||
|
|
||||||
|
// Unload the process symbol and string tables.
|
||||||
|
delete[] symbol_table; symbol_table = NULL;
|
||||||
|
delete[] string_table; string_table = NULL;
|
||||||
|
|
||||||
// Init is nice and will gladly raise our orphaned children and zombies.
|
// Init is nice and will gladly raise our orphaned children and zombies.
|
||||||
Process* init = Scheduler::GetInitProcess();
|
Process* init = Scheduler::GetInitProcess();
|
||||||
assert(init);
|
assert(init);
|
||||||
|
@ -618,6 +629,28 @@ namespace Sortix
|
||||||
if ( !(clone->program_image_path = String::Clone(program_image_path)) )
|
if ( !(clone->program_image_path = String::Clone(program_image_path)) )
|
||||||
failure = false;
|
failure = false;
|
||||||
|
|
||||||
|
if ( string_table && (clone->string_table = new char[string_table_length]) )
|
||||||
|
{
|
||||||
|
memcpy(clone->string_table, string_table, string_table_length);
|
||||||
|
clone->string_table_length = string_table_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( clone->string_table && symbol_table &&
|
||||||
|
(clone->symbol_table = new Symbol[symbol_table_length]) )
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < symbol_table_length; i++ )
|
||||||
|
{
|
||||||
|
clone->symbol_table[i].address = symbol_table[i].address;
|
||||||
|
clone->symbol_table[i].size = symbol_table[i].size;
|
||||||
|
clone->symbol_table[i].name =
|
||||||
|
(const char*)((uintptr_t) symbol_table[i].name -
|
||||||
|
(uintptr_t) string_table +
|
||||||
|
(uintptr_t) clone->string_table);
|
||||||
|
}
|
||||||
|
clone->symbol_table_length = symbol_table_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( pid == 1)
|
if ( pid == 1)
|
||||||
assert(dtable->Get(1));
|
assert(dtable->Get(1));
|
||||||
|
|
||||||
|
@ -640,6 +673,11 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
// TODO: Delete all threads and their stacks.
|
// TODO: Delete all threads and their stacks.
|
||||||
|
|
||||||
|
string_table_length = 0;
|
||||||
|
symbol_table_length = 0;
|
||||||
|
delete[] string_table; string_table = NULL;
|
||||||
|
delete[] symbol_table; symbol_table = NULL;
|
||||||
|
|
||||||
DeleteTimers();
|
DeleteTimers();
|
||||||
|
|
||||||
ResetAddressSpace();
|
ResetAddressSpace();
|
||||||
|
|
Loading…
Reference in a new issue