mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 12:23:15 +00:00
Merge ExecSpace into ELFLoader.
This commit is contained in:
parent
d90b891406
commit
422b5403e5
|
@ -3,8 +3,7 @@
|
|||
|
||||
//#define ELFLOADER_DEBUG
|
||||
|
||||
ELFLoader::ELFLoader(ExecSpace& execSpace, ByteBuffer&& buffer)
|
||||
: m_execSpace(execSpace)
|
||||
ELFLoader::ELFLoader(ByteBuffer&& buffer)
|
||||
{
|
||||
m_image = make<ELFImage>(move(buffer));
|
||||
}
|
||||
|
@ -43,7 +42,7 @@ bool ELFLoader::layout()
|
|||
#ifdef ELFLOADER_DEBUG
|
||||
kprintf("PH: L%x %u r:%u w:%u\n", program_header.laddr().get(), program_header.size_in_memory(), program_header.is_readable(), program_header.is_writable());
|
||||
#endif
|
||||
m_execSpace.allocate_section(program_header.laddr(), program_header.size_in_memory(), program_header.alignment(), program_header.is_readable(), program_header.is_writable());
|
||||
allocate_section(program_header.laddr(), program_header.size_in_memory(), program_header.alignment(), program_header.is_readable(), program_header.is_writable());
|
||||
});
|
||||
|
||||
m_image->forEachSectionOfType(SHT_PROGBITS, [this, &failed] (const ELFImage::Section& section) {
|
||||
|
@ -85,7 +84,7 @@ bool ELFLoader::layout()
|
|||
void* ELFLoader::lookup(const ELFImage::Symbol& symbol)
|
||||
{
|
||||
if (symbol.section().isUndefined())
|
||||
return m_execSpace.symbolPtr(symbol.name());
|
||||
return symbol_ptr(symbol.name());
|
||||
return areaForSection(symbol.section()) + symbol.value();
|
||||
}
|
||||
|
||||
|
@ -178,10 +177,35 @@ void ELFLoader::exportSymbols()
|
|||
ptr = areaForSection(symbol.section()) + symbol.value();
|
||||
else
|
||||
ASSERT_NOT_REACHED();
|
||||
m_execSpace.addSymbol(symbol.name(), ptr, symbol.size());
|
||||
add_symbol(symbol.name(), ptr, symbol.size());
|
||||
}
|
||||
// FIXME: What about other symbol types?
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
char* ELFLoader::symbol_ptr(const char* name)
|
||||
{
|
||||
if (auto it = m_symbols.find(name); it != m_symbols.end()) {
|
||||
auto& symbol = (*it).value;
|
||||
#ifdef EXECSPACE_DEBUG
|
||||
kprintf("[ELFLoader] symbol_ptr(%s) dump:\n", name);
|
||||
disassemble(symbol.ptr, symbol.size);
|
||||
#endif
|
||||
return symbol.ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ELFLoader::allocate_section(LinearAddress laddr, size_t size, size_t alignment, bool is_readable, bool is_writable)
|
||||
{
|
||||
ASSERT(alloc_section_hook);
|
||||
char namebuf[16];
|
||||
ksprintf(namebuf, "elf-%s%s", is_readable ? "r" : "", is_writable ? "w" : "");
|
||||
return alloc_section_hook(laddr, size, alignment, is_readable, is_writable, namebuf);
|
||||
}
|
||||
|
||||
void ELFLoader::add_symbol(String&& name, char* ptr, unsigned size)
|
||||
{
|
||||
m_symbols.set(move(name), { ptr, size });
|
||||
}
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Vector.h>
|
||||
#include "ExecSpace.h"
|
||||
#include "ELFImage.h"
|
||||
|
||||
class ELFLoader {
|
||||
public:
|
||||
ELFLoader(ExecSpace&, ByteBuffer&&);
|
||||
ELFLoader(ByteBuffer&&);
|
||||
~ELFLoader();
|
||||
|
||||
bool load();
|
||||
Function<void*(LinearAddress, size_t, size_t, bool, bool, const String&)> alloc_section_hook;
|
||||
char* symbol_ptr(const char* name);
|
||||
void add_symbol(String&& name, char* ptr, unsigned size);
|
||||
bool allocate_section(LinearAddress, size_t, size_t alignment, bool is_readable, bool is_writable);
|
||||
|
||||
private:
|
||||
bool layout();
|
||||
|
@ -21,7 +25,18 @@ private:
|
|||
char* areaForSection(const ELFImage::Section&);
|
||||
char* areaForSectionName(const char*);
|
||||
|
||||
ExecSpace& m_execSpace;
|
||||
struct PtrAndSize {
|
||||
PtrAndSize() { }
|
||||
PtrAndSize(char* p, unsigned s)
|
||||
: ptr(p)
|
||||
, size(s)
|
||||
{
|
||||
}
|
||||
|
||||
char* ptr { nullptr };
|
||||
unsigned size { 0 };
|
||||
};
|
||||
HashMap<String, PtrAndSize> m_symbols;
|
||||
HashMap<String, char*> m_sections;
|
||||
OwnPtr<ELFImage> m_image;
|
||||
};
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
#include "ExecSpace.h"
|
||||
#include "ELFLoader.h"
|
||||
#include <AK/Types.h>
|
||||
|
||||
//#define EXECSPACE_DEBUG
|
||||
|
||||
ExecSpace::ExecSpace()
|
||||
{
|
||||
}
|
||||
|
||||
ExecSpace::~ExecSpace()
|
||||
{
|
||||
}
|
||||
|
||||
bool ExecSpace::loadELF(ByteBuffer&& file)
|
||||
{
|
||||
ELFLoader loader(*this, move(file));
|
||||
if (!loader.load())
|
||||
return false;
|
||||
#ifdef EXECSPACE_DEBUG
|
||||
kprintf("ExecSpace: ELF loaded, symbol map now:\n");
|
||||
for (auto& s : m_symbols) {
|
||||
kprintf("> %p: %s (%u)\n",
|
||||
s.value.ptr,
|
||||
s.key.characters(),
|
||||
s.value.size);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
char* ExecSpace::symbolPtr(const char* name)
|
||||
{
|
||||
if (auto it = m_symbols.find(name); it != m_symbols.end()) {
|
||||
auto& symbol = (*it).value;
|
||||
#ifdef EXECSPACE_DEBUG
|
||||
kprintf("[ELFLoader] symbolPtr(%s) dump:\n", name);
|
||||
disassemble(symbol.ptr, symbol.size);
|
||||
#endif
|
||||
return symbol.ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ExecSpace::allocate_section(LinearAddress laddr, size_t size, size_t alignment, bool is_readable, bool is_writable)
|
||||
{
|
||||
ASSERT(alloc_section_hook);
|
||||
char namebuf[16];
|
||||
ksprintf(namebuf, "elf-%s%s", is_readable ? "r" : "", is_writable ? "w" : "");
|
||||
auto* ptr = static_cast<char*>(alloc_section_hook(laddr, size, alignment, is_readable, is_writable, namebuf));
|
||||
m_allocated_regions.append(ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExecSpace::addSymbol(String&& name, char* ptr, unsigned size)
|
||||
{
|
||||
m_symbols.set(move(name), { ptr, size });
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <AK/String.h>
|
||||
#include "types.h"
|
||||
|
||||
class ELFLoader;
|
||||
|
||||
class ExecSpace {
|
||||
public:
|
||||
struct PtrAndSize {
|
||||
PtrAndSize() { }
|
||||
PtrAndSize(char* p, unsigned s)
|
||||
: ptr(p)
|
||||
, size(s)
|
||||
{
|
||||
}
|
||||
|
||||
char* ptr { nullptr };
|
||||
unsigned size { 0 };
|
||||
};
|
||||
|
||||
ExecSpace();
|
||||
~ExecSpace();
|
||||
|
||||
Function<void*(LinearAddress, size_t, size_t, bool, bool, const String&)> alloc_section_hook;
|
||||
|
||||
bool loadELF(ByteBuffer&&);
|
||||
|
||||
char* symbolPtr(const char* name);
|
||||
|
||||
void addSymbol(String&& name, char* ptr, unsigned size);
|
||||
|
||||
bool allocate_section(LinearAddress, size_t, size_t alignment, bool is_readable, bool is_writable);
|
||||
|
||||
private:
|
||||
Vector<char*> m_allocated_regions;
|
||||
HashMap<String, PtrAndSize> m_symbols;
|
||||
};
|
||||
|
|
@ -39,8 +39,7 @@ VFS_OBJS = \
|
|||
|
||||
ELFLOADER_OBJS = \
|
||||
../ELFLoader/ELFImage.o \
|
||||
../ELFLoader/ELFLoader.o \
|
||||
../ELFLoader/ExecSpace.o
|
||||
../ELFLoader/ELFLoader.o
|
||||
|
||||
AK_OBJS = \
|
||||
../AK/String.o \
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "system.h"
|
||||
#include <VirtualFileSystem/FileHandle.h>
|
||||
#include <VirtualFileSystem/VirtualFileSystem.h>
|
||||
#include <ELFLoader/ExecSpace.h>
|
||||
#include <ELFLoader/ELFLoader.h>
|
||||
#include "MemoryManager.h"
|
||||
#include "errno.h"
|
||||
#include "i8253.h"
|
||||
|
@ -302,9 +302,6 @@ int Process::exec(const String& path, Vector<String>&& arguments, Vector<String>
|
|||
PageDirectory* old_page_directory;
|
||||
PageDirectory* new_page_directory;
|
||||
{
|
||||
ExecSpace space;
|
||||
Region* region = nullptr;
|
||||
|
||||
InterruptDisabler disabler;
|
||||
// Okay, here comes the sleight of hand, pay close attention..
|
||||
auto old_regions = move(m_regions);
|
||||
|
@ -313,13 +310,14 @@ int Process::exec(const String& path, Vector<String>&& arguments, Vector<String>
|
|||
MM.populate_page_directory(*new_page_directory);
|
||||
m_page_directory = new_page_directory;
|
||||
MM.enter_process_paging_scope(*this);
|
||||
space.alloc_section_hook = [&] (LinearAddress laddr, size_t size, size_t alignment, bool is_readable, bool is_writable, const String& name) {
|
||||
ELFLoader loader(move(elfData));
|
||||
loader.alloc_section_hook = [&] (LinearAddress laddr, size_t size, size_t alignment, bool is_readable, bool is_writable, const String& name) {
|
||||
ASSERT(size);
|
||||
size = ((size / 4096) + 1) * 4096; // FIXME: Use ceil_div?
|
||||
region = allocate_region(laddr, size, String(name), is_readable, is_writable);
|
||||
(void) allocate_region(laddr, size, String(name), is_readable, is_writable);
|
||||
return laddr.asPtr();
|
||||
};
|
||||
bool success = space.loadELF(move(elfData));
|
||||
bool success = loader.load();
|
||||
if (!success) {
|
||||
m_page_directory = old_page_directory;
|
||||
MM.enter_process_paging_scope(*this);
|
||||
|
@ -329,7 +327,7 @@ int Process::exec(const String& path, Vector<String>&& arguments, Vector<String>
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
entry_eip = (dword)space.symbolPtr("_start");
|
||||
entry_eip = (dword)loader.symbol_ptr("_start");
|
||||
if (!entry_eip) {
|
||||
m_page_directory = old_page_directory;
|
||||
MM.enter_process_paging_scope(*this);
|
||||
|
|
|
@ -219,7 +219,7 @@ static void init_stage2()
|
|||
|
||||
ExecSpace space;
|
||||
space.loadELF(move(testExecutableData));
|
||||
auto* elf_entry = space.symbolPtr("_start");
|
||||
auto* elf_entry = space.symbol_ptr("_start");
|
||||
ASSERT(elf_entry);
|
||||
|
||||
typedef int (*MainFunctionPtr)(void);
|
||||
|
|
Loading…
Reference in a new issue