4

Just-In-Time コンパイラを作成しようとしていますが、動作させたくないコードがあります。私のプラットフォームは x86-64 ubuntu です。

yasm で次のコードを記述しました。

bits 64

mov rdx, 1
mov rcx, 'A'
mov rbx, 1
mov rax, 4
int 0x80
ret

したがって、正しく理解できれば、これはAstdout に書き込まれるはずです。今、私はこのコードをコンパイルします

yasm -f bin test.yasm

これにより、次のマシンコードが生成されました。

0x48 0xc7 0xc2 0x01 0x00 0x00 0x00 0x48 0xc7 0xc1 0x41 0x00
0x00 0x00 0x48 0xc7 0xc3 0x01 0x00 0x00 0x00 0x48 0xc7 0xc0
0x04 0x00 0x00 0x00 0xcd 0x80 0xc3

次に、結果のコードを C++ で読み取り、次のように呼び出します。

void *memory = allocate_executable_memory(sizeof(code));
emit_code_into_memory(sizeof(code), code, memory);
JittedFunc func = reinterpret_cast<JittedFunc>(memory);
func();

C++ の部分は、単純な算術演算で既に試しており、うまく機能したので問題ないと思います。

とにかく、セグメンテーション違反はありません。コードは実行されているようですが、何も起こりません。stdout には何もありません。

何かアドバイス?

//編集:完全な C++ コード:

#include <stdio.h>
#include <string.h>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <sys/mman.h>

void* allocate_executable_memory(size_t size) {
    void *ptr = mmap(
        0,
        size,
        PROT_READ | PROT_WRITE | PROT_EXEC,
        MAP_PRIVATE | MAP_ANONYMOUS,
        -1,
        0
    );
    if (ptr == (void*)(-1)) {
        perror("mmap");
        return nullptr;
    }
    return ptr;
};

void emit_code_into_memory(size_t code_length, uint8_t *code, void *memory) {
    memcpy(reinterpret_cast<uint8_t*>(memory), code, code_length);
};

typedef void (*JittedFunc)();

int main(int argc, char* argv[]) {
    /* Use like this:
    bin/jit 0xb8 0x11 0x00 0x00 0x00 0xc3
    */
    if (argc <= 1) {
        return 1;
    }

    uint8_t code[argc-1];
    for (int i = 1; i < argc; i++) {
        code[i-1] = std::stoul(argv[i], nullptr, 16);
    }

    void *memory = allocate_executable_memory(sizeof(code));
    emit_code_into_memory(sizeof(code), code, memory);
    JittedFunc func = reinterpret_cast<JittedFunc>(memory);
    func();
    return 0;
};
4

1 に答える 1