Remove bootstrapping code from ELFLoader.

This runs inside the kernel now, and I no longer need the emulated version.
This commit is contained in:
Andreas Kling 2018-11-04 13:42:44 +01:00
parent 9bd09454e3
commit d90b891406
9 changed files with 7 additions and 196 deletions

View file

@ -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()
{ {

View file

@ -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; }

View file

@ -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));

View file

@ -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();

View file

@ -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);

View file

@ -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 };
}; };

View file

@ -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)

View file

@ -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();
}

View file

@ -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;
}