Крошечный x86_x64 JIT без использования mmap на Linux - PullRequest
4 голосов
/ 08 апреля 2020

Я реализую JIT (для исследований), и я хотел бы знать, возможно ли запускать коды операций без использования mmap, поскольку я «играю» в операционной системе, для которой MMAP не имеет определения MAP_ANONYMOUS.

Код JIT:

#include <stdio.h> 
#include <string.h> 
#include <sys/mman.h> 

int main () {
  // Hexadecimal x86_64 machine code for: int mul (int a, int b) { return a * b; }
  unsigned char code [] = {
    0x55,                   // push rbp
    0x48, 0x89, 0xe5,       // mov  rbp, rsp
    0x89, 0x7d, 0xfc,       // mov  DWORD PTR [rbp-0x4],edi
    0x89, 0x75, 0xf8,       // mov  DWORD PTR [rbp-0x8],esi
    0x8b, 0x75, 0xfc,       // mov  esi,DWORD PTR [rbp-04x]
    0x0f, 0xaf, 0x75, 0xf8, // imul esi,DWORD PTR [rbp-0x8]
    0x89, 0xf0,             // mov  eax,esi
    0x5d,                   // pop  rbp
    0xc3                    // ret
  };

  // allocate executable memory via sys call
  void* mem = mmap(NULL, sizeof(code), PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

  // copy runtime code into allocated memory
  memcpy(mem, code, sizeof(code));

  // typecast allocated memory to a function pointer
  int (*func) () = mem;

  // call function pointer
  printf("%d * %d = %d\n", 5, 11, func(5, 11));

  // Free up allocated memory
  munmap(mem, sizeof(code));
}

1 Ответ

4 голосов
/ 08 апреля 2020

Если я правильно помню, до изобретения MAP_ANONYMOUS стандартным способом сопоставления не-файловой памяти было открыть /dev/zero и отобразить его как файл. Если ваша система вообще имеет mmap, я ожидаю, что это сработает.

В противном случае вы можете выделить память любым удобным вам способом и использовать mprotect, чтобы сделать ее исполняемой. Обратите внимание, что вы захотите убедиться, что ваш код выровнен и дополнен границами страницы, чтобы вы случайно не изменили защиту других частей программы. posix_memalign это хороший способ сделать это, или более старый valloc.

...