summaryrefslogtreecommitdiff
path: root/ELFLoader/ExecSpace.cpp
blob: fb6d55a0dde3a23d35aaf703fe533d2dd0b94b07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "ExecSpace.h"
#include "ELFLoader.h"
#include <AK/TemporaryFile.h>
#include <AK/Types.h>

ExecSpace::ExecSpace()
{
    initializeBuiltins();
}

ExecSpace::~ExecSpace()
{
}

#ifdef SERENITY
int puts(const char* str)
{
    kprintf("%s\n", str);
    return 0;
}
#endif

void ExecSpace::initializeBuiltins()
{
    m_symbols.set("puts", { (char*)puts, 0 });
}

#ifdef SERENITY
bool ExecSpace::loadELF(ByteBuffer&& file)
#else
bool ExecSpace::loadELF(MappedFile&& file)
#endif
{
    ELFLoader loader(*this, move(file));
    if (!loader.load())
        return false;
    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);
    }
    return true;
}

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
}

char* ExecSpace::symbolPtr(const char* name)
{
    if (auto it = m_symbols.find(name); it != m_symbols.end()) {
        kprintf("[ELFLoader] symbolPtr(%s) dump:\n", name);
        auto& symbol = (*it).value;
        disassemble(symbol.ptr, symbol.size);
        return symbol.ptr;
    }
    return nullptr;
}

char* ExecSpace::allocateArea(String&& name, unsigned size)
{
    char* ptr = static_cast<char*>(kmalloc(size));
    ASSERT(ptr);
    m_areas.append(make<Area>(move(name), ptr, size));
    return ptr;
}

void ExecSpace::addSymbol(String&& name, char* ptr, unsigned size)
{
    m_symbols.set(move(name), { ptr, size });
}