Основы JIT - PullRequest
       38

Основы JIT

0 голосов
/ 05 июля 2010

Я немного понимаю, как «int a = b + abs (c)» можно перевести в простые инструкции по сборке, а затем перевести это в некоторый двоичный двоичный объект.Но как это можно запустить и динамически взаимодействовать в памяти?

- edit -

Я знаю, что C не имеет функции eval.Но то, к чему это компилируется, делает.Я имею в виду, что именно это делает Java подобным JIT, и в этом отношении вредоносное ПО для внедрения кода возможно?Например, функция abs () - это просто указатель, который можно вызывать по протоколу cdecl.Новые функции должны быть доступны через прохождение указателей на функции cdecl.Что я не понимаю, так это то, как этот новый код может быть введен во время выполнения.

Я спрашиваю это скорее как давний академический интерес, чем наиболее эффективно решить актуальную проблему.

- пример -

Скажем, у меня есть фрагмент встроенного кода Python, который часто вызывается из нативной программы и который также вызывает нативную привязку notify ():

def add(a, b):
    notify()
    return a+b

Для того, чтобы это было делом, функция, вероятно, должна содержать немного больше кода (и гораздо более полезного), но потерпите меня.Профилировщик (или подсказки из c-bindings) также определил, что все вызовы с целыми числами как со всеми параметрами, так и с возвращаемым значением.Это соответствует:

int add(int a, int b) {
    notify();
    return a + b;
}

Что может быть скомпилировано в x86 cdecl примерно так:

:_add
push ebp ;setting up scope
mov ebp, esp
call _notify ;or more likely by a pointer reference
mov eax, [ebp + 8]
mov edx, [ebp + 12]
add eax, edx
pop ebp
ret

Затем, наконец, собрана в двоичную строку.Конечно, для каждой платформы нужно было бы реализовать базовый компилятор.Но в стороне от этой проблемы, скажем, теперь у меня есть указатель на этот действительный двоичный код x86.Можно ли каким-то образом извлечь из этого указатель на функцию cdecl, пригодную для родной программы?

Извините за неясное намерение по поводу моего вопроса

Ответы [ 3 ]

1 голос
/ 06 июля 2010

Если у вас уже есть код, скомпилированный в блоке памяти, и адрес блока, он может быть приведен к указателю на функцию:

typedef int (*func)(int, int);
...
char * compiledCode = ...;
func f = (func) compiledCode;

и тогда можно вызвать функцию:

int x = f(2, 3);
1 голос
/ 16 июля 2010

Программа должна находиться в области памяти, которая позволяет выполнять.

На Linux вы можете сделать это:

void *address;
functype proc;
int prot, flags;

prot = PROT_READ|PROT_WRITE|PROT_EXEC;
flags = MAP_PRIVATE|MAP_ANONYMOUS;
address = mmap(NULL, length, prot, flags, -1, 0);
if (address == NULL) error;

memcpy(address, program, length);
link(address, program_info);

proc = (functype)address;
1 голос
/ 05 июля 2010

C испытывает недостаток в какой-либо функции eval, которая является как ограничением, так и одной из вещей, которая позволяет ей быть эффективной.Если все, что вам нужно, - это вычислять математические выражения с помощью небольшого набора встроенных математических функций, таких как abs(), а не произвольного кода на языке C, написать такой оценщик выражений довольно просто.

Вотссылка на прошлую ветку SO на похожую тему: c выражением Evaluator

...