JIT的基本面

时间:2010-07-05 10:24:14

标签: c assembly compilation jit

我有点理解“int a = b + abs(c)”如何转换为简单的汇编指令,然后将其转换为某个二进制blob。但是如何运行并在内存中动态交互?

- 编辑 -

我知道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代码的char指针。是否有可能以任何方式提取一个可用于本机程序的cdecl函数指针?

很抱歉我的问题意图不明确

3 个答案:

答案 0 :(得分:1)

C缺乏任何“评估”功能,这既是一种限制,也是一种允许其高效的事情。如果你需要做的就是使用一小组内置数学函数(如abs()而不是任意C代码)来评估数学表达式,那么编写这样的表达式求值器会非常容易。

以下是类似主题的过去SO主题的链接: c expression Evaluator

答案 1 :(得分:1)

假设您已经在内存块中编译了代码,并且您拥有该块的地址,则可以将其转换为函数指针:

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

然后可以调用该函数:

int x = f(2, 3);

答案 2 :(得分:1)

程序必须位于允许执行的内存区域中。

在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;