mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
Build ELFLoader into Kernel.
This commit is contained in:
parent
3649638259
commit
c149d2a8f0
Notes:
sideshowbarker
2024-07-19 18:46:21 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c149d2a8f0d
7 changed files with 81 additions and 52 deletions
|
@ -13,6 +13,8 @@ typedef signed long long int signed_qword;
|
|||
|
||||
typedef dword size_t;
|
||||
typedef signed_dword ssize_t;
|
||||
|
||||
typedef signed_dword ptrdiff_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
#include "ELFImage.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <AK/kstdio.h>
|
||||
|
||||
ELFImage::ELFImage(MappedFile&& file)
|
||||
: m_file(std::move(file))
|
||||
#ifdef SERENITY_KERNEL
|
||||
ELFImage::ELFImage(const byte* data)
|
||||
: m_data(data)
|
||||
{
|
||||
m_isValid = parse();
|
||||
}
|
||||
#else
|
||||
ELFImage::ELFImage(MappedFile&& file)
|
||||
: m_file(move(file))
|
||||
{
|
||||
m_isValid = parse();
|
||||
}
|
||||
#endif
|
||||
|
||||
ELFImage::~ELFImage()
|
||||
{
|
||||
|
@ -41,43 +47,43 @@ unsigned ELFImage::symbolCount() const
|
|||
|
||||
void ELFImage::dump()
|
||||
{
|
||||
printf("AK::ELFImage{%p} {\n", this);
|
||||
printf(" isValid: %u\n", isValid());
|
||||
kprintf("AK::ELFImage{%p} {\n", this);
|
||||
kprintf(" isValid: %u\n", isValid());
|
||||
|
||||
if (!isValid()) {
|
||||
printf("}\n");
|
||||
kprintf("}\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" type: %s\n", objectFileTypeToString(header().e_type));
|
||||
printf(" machine: %u\n", header().e_machine);
|
||||
printf(" entry: %08x\n", header().e_entry);
|
||||
printf(" shoff: %u\n", header().e_shoff);
|
||||
printf(" shnum: %u\n", header().e_shnum);
|
||||
printf(" shstrndx: %u\n", header().e_shstrndx);
|
||||
kprintf(" type: %s\n", objectFileTypeToString(header().e_type));
|
||||
kprintf(" machine: %u\n", header().e_machine);
|
||||
kprintf(" entry: %08x\n", header().e_entry);
|
||||
kprintf(" shoff: %u\n", header().e_shoff);
|
||||
kprintf(" shnum: %u\n", header().e_shnum);
|
||||
kprintf(" shstrndx: %u\n", header().e_shstrndx);
|
||||
|
||||
for (unsigned i = 0; i < header().e_shnum; ++i) {
|
||||
auto& section = this->section(i);
|
||||
printf(" Section %u: {\n", i);
|
||||
printf(" name: %s\n", section.name());
|
||||
printf(" type: %x\n", section.type());
|
||||
printf(" offset: %x\n", section.offset());
|
||||
printf(" size: %u\n", section.size());
|
||||
printf(" \n");
|
||||
printf(" }\n");
|
||||
kprintf(" Section %u: {\n", i);
|
||||
kprintf(" name: %s\n", section.name());
|
||||
kprintf(" type: %x\n", section.type());
|
||||
kprintf(" offset: %x\n", section.offset());
|
||||
kprintf(" size: %u\n", section.size());
|
||||
kprintf(" \n");
|
||||
kprintf(" }\n");
|
||||
}
|
||||
|
||||
printf("Symbol count: %u (table is %u)\n", symbolCount(), m_symbolTableSectionIndex);
|
||||
kprintf("Symbol count: %u (table is %u)\n", symbolCount(), m_symbolTableSectionIndex);
|
||||
for (unsigned i = 1; i < symbolCount(); ++i) {
|
||||
auto& sym = symbol(i);
|
||||
printf("Symbol @%u:\n", i);
|
||||
printf(" Name: %s\n", sym.name());
|
||||
printf(" In section: %s\n", sectionIndexToString(sym.sectionIndex()));
|
||||
printf(" Value: %08x\n", sym.value());
|
||||
printf(" Size: %u\n", sym.size());
|
||||
kprintf("Symbol @%u:\n", i);
|
||||
kprintf(" Name: %s\n", sym.name());
|
||||
kprintf(" In section: %s\n", sectionIndexToString(sym.sectionIndex()));
|
||||
kprintf(" Value: %08x\n", sym.value());
|
||||
kprintf(" Size: %u\n", sym.size());
|
||||
}
|
||||
|
||||
printf("}\n");
|
||||
kprintf("}\n");
|
||||
}
|
||||
|
||||
unsigned ELFImage::sectionCount() const
|
||||
|
@ -107,7 +113,7 @@ bool ELFImage::parse()
|
|||
// Then create a name-to-index map.
|
||||
for (unsigned i = 0; i < sectionCount(); ++i) {
|
||||
auto& section = this->section(i);
|
||||
m_sections.set(section.name(), std::move(i));
|
||||
m_sections.set(section.name(), move(i));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -130,7 +136,11 @@ const char* ELFImage::tableString(unsigned offset) const
|
|||
|
||||
const char* ELFImage::rawData(unsigned offset) const
|
||||
{
|
||||
#ifdef SERENITY_KERNEL
|
||||
return reinterpret_cast<const char*>(m_data) + offset;
|
||||
#else
|
||||
return reinterpret_cast<const char*>(m_file.pointer()) + offset;
|
||||
#endif
|
||||
}
|
||||
|
||||
const Elf32_Ehdr& ELFImage::header() const
|
||||
|
@ -168,14 +178,14 @@ const ELFImage::RelocationSection ELFImage::Section::relocations() const
|
|||
{
|
||||
// FIXME: This is ugly.
|
||||
char relocationSectionName[128];
|
||||
sprintf(relocationSectionName, ".rel%s", name());
|
||||
ksprintf(relocationSectionName, ".rel%s", name());
|
||||
|
||||
printf("looking for '%s'\n", relocationSectionName);
|
||||
kprintf("looking for '%s'\n", relocationSectionName);
|
||||
auto relocationSection = m_image.lookupSection(relocationSectionName);
|
||||
if (relocationSection.type() != SHT_REL)
|
||||
return static_cast<const RelocationSection>(m_image.section(0));
|
||||
|
||||
printf("Found relocations for %s in %s\n", name(), relocationSection.name());
|
||||
kprintf("Found relocations for %s in %s\n", name(), relocationSection.name());
|
||||
return static_cast<const RelocationSection>(relocationSection);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#ifndef SERENITY_KERNEL
|
||||
#include <AK/MappedFile.h>
|
||||
#endif
|
||||
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/String.h>
|
||||
#include "elf.h"
|
||||
|
||||
class ELFImage {
|
||||
public:
|
||||
#ifdef SERENITY_KERNEL
|
||||
explicit ELFImage(const byte* data);
|
||||
#else
|
||||
explicit ELFImage(MappedFile&&);
|
||||
#endif
|
||||
~ELFImage();
|
||||
void dump();
|
||||
bool isValid() const { return m_isValid; }
|
||||
|
@ -123,7 +131,11 @@ private:
|
|||
const char* sectionHeaderTableString(unsigned offset) const;
|
||||
const char* sectionIndexToString(unsigned index);
|
||||
|
||||
#ifdef SERENITY_KERNEL
|
||||
const byte* m_data;
|
||||
#else
|
||||
MappedFile m_file;
|
||||
#endif
|
||||
HashMap<String, unsigned> m_sections;
|
||||
bool m_isValid { false };
|
||||
unsigned m_symbolTableSectionIndex { 0 };
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
#include "ELFLoader.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <AK/kstdio.h>
|
||||
|
||||
ELFLoader::ELFLoader(ExecSpace& execSpace, MappedFile&& file)
|
||||
: m_execSpace(execSpace)
|
||||
{
|
||||
m_image = make<ELFImage>(std::move(file));
|
||||
m_image = make<ELFImage>(move(file));
|
||||
}
|
||||
|
||||
ELFLoader::~ELFLoader()
|
||||
|
@ -28,12 +26,12 @@ bool ELFLoader::load()
|
|||
|
||||
void ELFLoader::layout()
|
||||
{
|
||||
printf("[ELFLoader] Layout\n");
|
||||
kprintf("[ELFLoader] Layout\n");
|
||||
m_image->forEachSectionOfType(SHT_PROGBITS, [this] (const ELFImage::Section& section) {
|
||||
printf("[ELFLoader] Allocating progbits section: %s\n", section.name());
|
||||
kprintf("[ELFLoader] Allocating progbits section: %s\n", section.name());
|
||||
char* ptr = m_execSpace.allocateArea(section.name(), section.size());
|
||||
memcpy(ptr, section.rawData(), section.size());
|
||||
m_sections.set(section.name(), std::move(ptr));
|
||||
m_sections.set(section.name(), move(ptr));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -59,7 +57,7 @@ char* ELFLoader::areaForSectionName(const char* name)
|
|||
|
||||
void ELFLoader::performRelocations()
|
||||
{
|
||||
printf("[ELFLoader] Performing relocations\n");
|
||||
kprintf("[ELFLoader] Performing relocations\n");
|
||||
|
||||
m_image->forEachSectionOfType(SHT_PROGBITS, [this] (const ELFImage::Section& section) {
|
||||
auto& relocations = section.relocations();
|
||||
|
@ -73,7 +71,7 @@ void ELFLoader::performRelocations()
|
|||
case R_386_PC32: {
|
||||
char* targetPtr = (char*)lookup(symbol);
|
||||
ptrdiff_t relativeOffset = (char*)targetPtr - ((char*)&patchPtr + 4);
|
||||
printf("[ELFLoader] Relocate PC32: offset=%08x, symbol=%u(%s) value=%08x target=%p, offset=%d\n",
|
||||
kprintf("[ELFLoader] Relocate PC32: offset=%08x, symbol=%u(%s) value=%08x target=%p, offset=%d\n",
|
||||
relocation.offset(),
|
||||
symbol.index(),
|
||||
symbol.name(),
|
||||
|
@ -85,7 +83,7 @@ void ELFLoader::performRelocations()
|
|||
break;
|
||||
}
|
||||
case R_386_32: {
|
||||
printf("[ELFLoader] Relocate Abs32: symbol=%u(%s), value=%08x, section=%s\n",
|
||||
kprintf("[ELFLoader] Relocate Abs32: symbol=%u(%s), value=%08x, section=%s\n",
|
||||
symbol.index(),
|
||||
symbol.name(),
|
||||
symbol.value(),
|
||||
|
@ -106,7 +104,7 @@ void ELFLoader::performRelocations()
|
|||
void ELFLoader::exportSymbols()
|
||||
{
|
||||
m_image->forEachSymbol([&] (const ELFImage::Symbol symbol) {
|
||||
printf("symbol: %u, type=%u, name=%s\n", symbol.index(), symbol.type(), symbol.name());
|
||||
kprintf("symbol: %u, type=%u, name=%s\n", symbol.index(), symbol.type(), symbol.name());
|
||||
if (symbol.type() == STT_FUNC)
|
||||
m_execSpace.addSymbol(symbol.name(), areaForSectionName(".text") + symbol.value(), symbol.size());
|
||||
// FIXME: What about other symbol types?
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "ExecSpace.h"
|
||||
#include "ELFLoader.h"
|
||||
#include <AK/TemporaryFile.h>
|
||||
#include <unistd.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
ExecSpace::ExecSpace()
|
||||
{
|
||||
|
@ -19,7 +19,7 @@ void ExecSpace::initializeBuiltins()
|
|||
|
||||
bool ExecSpace::loadELF(MappedFile&& file)
|
||||
{
|
||||
ELFLoader loader(*this, std::move(file));
|
||||
ELFLoader loader(*this, move(file));
|
||||
if (!loader.load())
|
||||
return false;
|
||||
printf("[ExecSpace] ELF loaded, symbol map now:\n");
|
||||
|
@ -34,6 +34,8 @@ bool ExecSpace::loadELF(MappedFile&& file)
|
|||
|
||||
static void disassemble(const char* data, size_t length)
|
||||
{
|
||||
#ifdef SERENITY_KERNEL
|
||||
#else
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
|
@ -52,6 +54,7 @@ static void disassemble(const char* data, size_t length)
|
|||
char cmdbuf[128];
|
||||
sprintf(cmdbuf, "nasm -f bin -o /dev/stdout %s | ndisasm -b32 -", temp.fileName().characters());
|
||||
system(cmdbuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
char* ExecSpace::symbolPtr(const char* name)
|
||||
|
@ -65,16 +68,15 @@ char* ExecSpace::symbolPtr(const char* name)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
char* ExecSpace::allocateArea(String&& name, unsigned size)
|
||||
{
|
||||
char* ptr = static_cast<char*>(malloc(size));
|
||||
char* ptr = static_cast<char*>(kmalloc(size));
|
||||
ASSERT(ptr);
|
||||
m_areas.append(make<Area>(std::move(name), ptr, size));
|
||||
m_areas.append(make<Area>(move(name), ptr, size));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void ExecSpace::addSymbol(String&& name, char* ptr, unsigned size)
|
||||
{
|
||||
m_symbols.set(std::move(name), { ptr, size });
|
||||
m_symbols.set(move(name), { ptr, size });
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ class ExecSpace {
|
|||
public:
|
||||
struct Area {
|
||||
Area(String&& n, char* m, unsigned s)
|
||||
: name(std::move(n))
|
||||
: name(move(n))
|
||||
, memory(m)
|
||||
, size(s)
|
||||
{
|
||||
|
|
|
@ -34,11 +34,16 @@ VFS_OBJS = \
|
|||
../VirtualFileSystem/VirtualFileSystem.o \
|
||||
../VirtualFileSystem/FileHandle.o
|
||||
|
||||
ELFLOADER_OBJS = \
|
||||
../ELFLoader/ELFImage.o \
|
||||
../ELFLoader/ELFLoader.o \
|
||||
../ELFLoader/ExecSpace.o
|
||||
|
||||
AK_OBJS = \
|
||||
../AK/String.o \
|
||||
../AK/StringImpl.o
|
||||
|
||||
OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS)
|
||||
OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS) $(ELFLOADER_OBJS)
|
||||
|
||||
NASM = nasm
|
||||
KERNEL = kernel
|
||||
|
|
Loading…
Reference in a new issue