#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 256
unsigned long parse_elf_function(const char* elf_path, const char* func_name) {
char cmd[512];
FILE *fp;
char line[MAX_LINE];
// 构建readelf命令
snprintf(cmd, sizeof(cmd), "readelf -sW %s | grep %s", elf_path, func_name);
// 执行命令并获取输出
if ((fp = popen(cmd, "r")) == NULL) {
perror("popen failed");
exit(EXIT_FAILURE);
}
// 解析输出行
while (fgets(line, sizeof(line), fp)) {
unsigned long addr;
char name[128];
// 匹配格式: " Num: Value Size Type Bind Vis Ndx Name"
if (sscanf(line, "%*d: %lx %*d %*s %*s %*s %*d %127s", &addr, name) == 2) {
if (strcmp(name, func_name) == 0) {
pclose(fp);
return addr;
}
}
}
pclose(fp);
fprintf(stderr, "Function '%s' not found\n", func_name);
exit(EXIT_FAILURE);
}
void qemu_set_irq(qemu_irq irq, int level)
{
unsigned long run_addr, addr_offset;
if( !irq ){
return;
}
irq->handler(irq->opaque, irq->n, level);
//printf("\nlevel = %d\n", level);
//printf("irq->n = %d\n", irq->n);
//printf("irq->handler = %p\n", irq->handler);
//printf("qemu_set_irq = %p\n", qemu_set_irq);
//set_irq_level
//arm_cpu_set_irq
//abort();
//printf("Caller: %p\n", __builtin_return_address(0));
//printf("irq->handler xxx= %p\n", irq->handler);
//system( "readelf -sW ../qemu5p1/qemu-5.1.0/arm-softmmu/qemu-system-arm | grep qemu_set_irq" );
unsigned long addr = parse_elf_function("../qemu5p1/qemu-5.1.0/arm-softmmu/qemu-system-arm", "qemu_set_irq" );
run_addr = qemu_set_irq;
//printf("elf_addr = %p\n", addr );
//printf("run_addr = %p\n", run_addr );
//printf("sizeof(run_addr) = %d\n", sizeof(run_addr) );
addr_offset = run_addr-addr;
//printf("addr_offset = 0x%lx\n", addr_offset );
//printf("irq->handler xxx= %p\n", irq->handler);
printf("irq->handler in elf = %lx\n", irq->handler - addr_offset );
}
readelf -sW arm-softmmu/qemu-system-arm | grep 466ae0
2517: 0000000000466ae0 242 FUNC LOCAL DEFAULT 14 arm_cpu_set_irq