mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 18:02:05 -05:00
Remove bootstrapping code from ELFLoader.
This runs inside the kernel now, and I no longer need the emulated version.
This commit is contained in:
parent
9bd09454e3
commit
d90b891406
9 changed files with 7 additions and 196 deletions
|
@ -1,19 +1,11 @@
|
||||||
#include "ELFImage.h"
|
#include "ELFImage.h"
|
||||||
#include <AK/kstdio.h>
|
#include <AK/kstdio.h>
|
||||||
|
|
||||||
#ifdef SERENITY
|
|
||||||
ELFImage::ELFImage(ByteBuffer&& buffer)
|
ELFImage::ELFImage(ByteBuffer&& buffer)
|
||||||
: m_buffer(buffer)
|
: m_buffer(buffer)
|
||||||
{
|
{
|
||||||
m_isValid = parse();
|
m_isValid = parse();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
ELFImage::ELFImage(MappedFile&& file)
|
|
||||||
: m_file(move(file))
|
|
||||||
{
|
|
||||||
m_isValid = parse();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ELFImage::~ELFImage()
|
ELFImage::~ELFImage()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef SERENITY
|
|
||||||
#include <AK/MappedFile.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
@ -12,11 +8,7 @@
|
||||||
|
|
||||||
class ELFImage {
|
class ELFImage {
|
||||||
public:
|
public:
|
||||||
#ifdef SERENITY
|
|
||||||
explicit ELFImage(ByteBuffer&&);
|
explicit ELFImage(ByteBuffer&&);
|
||||||
#else
|
|
||||||
explicit ELFImage(MappedFile&&);
|
|
||||||
#endif
|
|
||||||
~ELFImage();
|
~ELFImage();
|
||||||
void dump();
|
void dump();
|
||||||
bool isValid() const { return m_isValid; }
|
bool isValid() const { return m_isValid; }
|
||||||
|
|
|
@ -3,14 +3,10 @@
|
||||||
|
|
||||||
//#define ELFLOADER_DEBUG
|
//#define ELFLOADER_DEBUG
|
||||||
|
|
||||||
#ifdef SERENITY
|
ELFLoader::ELFLoader(ExecSpace& execSpace, ByteBuffer&& buffer)
|
||||||
ELFLoader::ELFLoader(ExecSpace& execSpace, ByteBuffer&& file)
|
|
||||||
#else
|
|
||||||
ELFLoader::ELFLoader(ExecSpace& execSpace, MappedFile&& file)
|
|
||||||
#endif
|
|
||||||
: m_execSpace(execSpace)
|
: m_execSpace(execSpace)
|
||||||
{
|
{
|
||||||
m_image = make<ELFImage>(move(file));
|
m_image = make<ELFImage>(move(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
ELFLoader::~ELFLoader()
|
ELFLoader::~ELFLoader()
|
||||||
|
@ -58,9 +54,10 @@ bool ELFLoader::layout()
|
||||||
return true;
|
return true;
|
||||||
char* ptr = (char*)section.address();
|
char* ptr = (char*)section.address();
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
kprintf("ELFLoader: failed to allocate section '%s'\n", section.name());
|
#ifdef ELFLOADER_DEBUG
|
||||||
failed = true;
|
kprintf("ELFLoader: ignoring section '%s' with null address\n", section.name());
|
||||||
return false;
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
memcpy(ptr, section.rawData(), section.size());
|
memcpy(ptr, section.rawData(), section.size());
|
||||||
m_sections.set(section.name(), move(ptr));
|
m_sections.set(section.name(), move(ptr));
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/MappedFile.h>
|
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include "ExecSpace.h"
|
#include "ExecSpace.h"
|
||||||
|
@ -9,11 +8,7 @@
|
||||||
|
|
||||||
class ELFLoader {
|
class ELFLoader {
|
||||||
public:
|
public:
|
||||||
#ifdef SERENITY
|
|
||||||
ELFLoader(ExecSpace&, ByteBuffer&&);
|
ELFLoader(ExecSpace&, ByteBuffer&&);
|
||||||
#else
|
|
||||||
ELFLoader(ExecSpace&, MappedFile&&);
|
|
||||||
#endif
|
|
||||||
~ELFLoader();
|
~ELFLoader();
|
||||||
|
|
||||||
bool load();
|
bool load();
|
||||||
|
|
|
@ -2,41 +2,17 @@
|
||||||
#include "ELFLoader.h"
|
#include "ELFLoader.h"
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
|
||||||
#ifndef SERENITY
|
|
||||||
#include <AK/TemporaryFile.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//#define EXECSPACE_DEBUG
|
//#define EXECSPACE_DEBUG
|
||||||
|
|
||||||
ExecSpace::ExecSpace()
|
ExecSpace::ExecSpace()
|
||||||
{
|
{
|
||||||
initializeBuiltins();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecSpace::~ExecSpace()
|
ExecSpace::~ExecSpace()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SERENITY
|
|
||||||
int puts(const char* str)
|
|
||||||
{
|
|
||||||
kprintf("%s\n", str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ExecSpace::initializeBuiltins()
|
|
||||||
{
|
|
||||||
#ifndef SERENITY
|
|
||||||
m_symbols.set("puts", { (char*)puts, 0 });
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SERENITY
|
|
||||||
bool ExecSpace::loadELF(ByteBuffer&& file)
|
bool ExecSpace::loadELF(ByteBuffer&& file)
|
||||||
#else
|
|
||||||
bool ExecSpace::loadELF(MappedFile&& file)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
ELFLoader loader(*this, move(file));
|
ELFLoader loader(*this, move(file));
|
||||||
if (!loader.load())
|
if (!loader.load())
|
||||||
|
@ -53,37 +29,6 @@ bool ExecSpace::loadELF(MappedFile&& file)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EXECSPACE_DEBUG
|
|
||||||
static void disassemble(const char* data, size_t length)
|
|
||||||
{
|
|
||||||
if (!length)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef SERENITY
|
|
||||||
for (unsigned i = 0; i < length; ++i) {
|
|
||||||
kprintf("%b ", (unsigned char)data[i]);
|
|
||||||
}
|
|
||||||
kprintf("\n");
|
|
||||||
#else
|
|
||||||
TemporaryFile temp;
|
|
||||||
if (!temp.isValid()) {
|
|
||||||
fprintf(stderr, "Unable to create temp file for disassembly.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fprintf(temp.stream(), "db ");
|
|
||||||
for (unsigned i = 0; i < length; ++i) {
|
|
||||||
fprintf(temp.stream(), "0x%02x, ", (unsigned char)data[i]);
|
|
||||||
}
|
|
||||||
fprintf(temp.stream(), "\n");
|
|
||||||
temp.sync();
|
|
||||||
|
|
||||||
char cmdbuf[128];
|
|
||||||
ksprintf(cmdbuf, "nasm -f bin -o /dev/stdout %s | ndisasm -b32 -", temp.fileName().characters());
|
|
||||||
system(cmdbuf);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char* ExecSpace::symbolPtr(const char* name)
|
char* ExecSpace::symbolPtr(const char* name)
|
||||||
{
|
{
|
||||||
if (auto it = m_symbols.find(name); it != m_symbols.end()) {
|
if (auto it = m_symbols.find(name); it != m_symbols.end()) {
|
||||||
|
@ -97,15 +42,6 @@ char* ExecSpace::symbolPtr(const char* name)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecSpace::allocateUniverse(size_t size)
|
|
||||||
{
|
|
||||||
ASSERT(!m_universe);
|
|
||||||
if (hookableAlloc)
|
|
||||||
m_universe = static_cast<char*>(hookableAlloc("elf-sec", size));
|
|
||||||
else
|
|
||||||
m_universe = static_cast<char*>(kmalloc(size));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ExecSpace::allocate_section(LinearAddress laddr, size_t size, size_t alignment, bool is_readable, bool is_writable)
|
bool ExecSpace::allocate_section(LinearAddress laddr, size_t size, size_t alignment, bool is_readable, bool is_writable)
|
||||||
{
|
{
|
||||||
ASSERT(alloc_section_hook);
|
ASSERT(alloc_section_hook);
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/MappedFile.h>
|
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
class ELFLoader;
|
class ELFLoader;
|
||||||
|
@ -26,28 +26,18 @@ public:
|
||||||
ExecSpace();
|
ExecSpace();
|
||||||
~ExecSpace();
|
~ExecSpace();
|
||||||
|
|
||||||
Function<void*(const String&, size_t)> hookableAlloc;
|
|
||||||
Function<void*(LinearAddress, size_t, size_t, bool, bool, const String&)> alloc_section_hook;
|
Function<void*(LinearAddress, size_t, size_t, bool, bool, const String&)> alloc_section_hook;
|
||||||
|
|
||||||
#ifdef SERENITY
|
|
||||||
bool loadELF(ByteBuffer&&);
|
bool loadELF(ByteBuffer&&);
|
||||||
#else
|
|
||||||
bool loadELF(MappedFile&&);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char* symbolPtr(const char* name);
|
char* symbolPtr(const char* name);
|
||||||
|
|
||||||
void addSymbol(String&& name, char* ptr, unsigned size);
|
void addSymbol(String&& name, char* ptr, unsigned size);
|
||||||
|
|
||||||
void allocateUniverse(size_t);
|
|
||||||
|
|
||||||
bool allocate_section(LinearAddress, size_t, size_t alignment, bool is_readable, bool is_writable);
|
bool allocate_section(LinearAddress, size_t, size_t alignment, bool is_readable, bool is_writable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initializeBuiltins();
|
|
||||||
|
|
||||||
Vector<char*> m_allocated_regions;
|
Vector<char*> m_allocated_regions;
|
||||||
HashMap<String, PtrAndSize> m_symbols;
|
HashMap<String, PtrAndSize> m_symbols;
|
||||||
char* m_universe { nullptr };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
PROGRAM = run
|
|
||||||
|
|
||||||
AK_OBJS = \
|
|
||||||
../AK/String.o \
|
|
||||||
../AK/StringImpl.o \
|
|
||||||
../AK/MappedFile.o \
|
|
||||||
../AK/TemporaryFile.o \
|
|
||||||
../AK/kmalloc.o
|
|
||||||
|
|
||||||
CSILLA_OBJS = \
|
|
||||||
ExecSpace.o \
|
|
||||||
ELFImage.o \
|
|
||||||
ELFLoader.o \
|
|
||||||
test.o
|
|
||||||
|
|
||||||
TEST_OBJ = \
|
|
||||||
_test.o
|
|
||||||
|
|
||||||
TEST_OBJ_CXXFLAGS = -Os -fno-exceptions -fno-rtti -fno-asynchronous-unwind-tables
|
|
||||||
|
|
||||||
OBJS = $(AK_OBJS) $(CSILLA_OBJS)
|
|
||||||
|
|
||||||
CXXFLAGS = -std=c++17 -Os -W -Wall -I. -I.. -ggdb3
|
|
||||||
|
|
||||||
all: $(PROGRAM) $(TEST_OBJ)
|
|
||||||
|
|
||||||
_test.o: _test.cpp
|
|
||||||
$(CXX) $(TEST_OBJ_CXXFLAGS) -c $<
|
|
||||||
|
|
||||||
.cpp.o:
|
|
||||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJS) $(TEST_OBJ) $(PROGRAM)
|
|
||||||
|
|
||||||
$(PROGRAM): $(OBJS)
|
|
||||||
$(CXX) $(LDFLAGS) -o $@ $(OBJS)
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
extern "C" const char hello_string[] = "Hello World!";
|
|
||||||
|
|
||||||
extern "C" int foo()
|
|
||||||
{
|
|
||||||
volatile int i = 3;
|
|
||||||
i = 4;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int bar()
|
|
||||||
{
|
|
||||||
return foo();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int baz()
|
|
||||||
{
|
|
||||||
return bar();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int EntryPoint()
|
|
||||||
{
|
|
||||||
puts(hello_string);
|
|
||||||
printf("abc!\n");
|
|
||||||
printf("def!\n");
|
|
||||||
return 10 + baz();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
#include "ExecSpace.h"
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
typedef int (*MainFunctionPtr)(void);
|
|
||||||
|
|
||||||
int main(int, char**)
|
|
||||||
{
|
|
||||||
MappedFile f("_test.o");
|
|
||||||
if (!f.isValid()) {
|
|
||||||
fprintf(stderr, "Failed to map file :(\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExecSpace space;
|
|
||||||
space.loadELF(std::move(f));
|
|
||||||
|
|
||||||
auto func = reinterpret_cast<MainFunctionPtr>(space.symbolPtr("EntryPoint"));
|
|
||||||
printf("func: %p\n", func);
|
|
||||||
|
|
||||||
int z = func();
|
|
||||||
printf("func() returned %d\n", z);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue