【问题标题】:Using mmap to get start and end address of function?使用 mmap 获取函数的开始和结束地址?
【发布时间】:2014-02-24 12:04:59
【问题描述】:

如何使用 mmap 获取函数的开始和结束地址?我想执行该函数,然后调用 __clear_cache。从刚刚执行的缓存中清除所有内容。 clear_cache 需要开始和结束地址。

我的代码中的一个函数代表一个测试用例,我需要清除缓存才能正确进行基准测试。我正在使用 Linux 3.7 和 C。

我需要使用 mmap 而不是这里所说的 malloc:

How clear and invalidate ARM v7 processor cache from User Mode on Linux 2.6.35

目前我刚刚制作了一个大小为 32kb 的 mmap,也就是我的缓存大小。但是如何获取开始和结束地址并将其映射到特定函数呢?

我已经这样做了

//在标题中

extern void __clear_cache (char*, char*);

//获取地址的函数指针。 typedef void (*_func_pointer) (void);

在.c

_func_pointer = test_func;

uint32_t *  map_to_function = mmap(
        NULL,
        32768,  // 32kb -- Whole Cache.
        PROT_READ | PROT_WRITE | PROT_EXEC,
        MAP_PRIVATE | MAP_ANONYMOUS,
        -1,
        0);
if (map_to_function == MAP_FAILED) {
    printf("Could not mmap a memory buffer with the proper permissions.\n");
    return -1;
}


test_func = (_func_pointer ) map_to_function ;


//Run Test case 1:

 Some how run function 1 and get start and end address.

__clear_cache((char*)start_address, (char*)end_address);

感谢您的帮助

【问题讨论】:

  • function_1 是一个实际的 C 函数吗?或者它是一组发出的操作码?公元前。我想您可能会混淆您提供的链接中的问题实际上是在讨论什么。他们正在谈论生成代码,就像在 JIT 中一样,它存储在 mmap 提供的内存中。如果您的函数是用 C 编写并编译到您的程序中,则标准 C 无法获取函数的结束地址或大小(以字节为单位)。
  • 那么,我只能通过在链接中这样处理来使用 __clear_cache 吗?有没有更简单的方法来调用__clear_cache,我知道我的功能,只想清除缓存。是的,我只是使用普通的 C 代码和一个实际的 C 函数。
  • 嗯,没有标准的方法。可能有一些黑客攻击。也许你可以描述为什么你甚至需要这样做。也许有更好的方法来实现这一目标。甚至是医生。功能提示中,它适用于自修改代码或代码生成器:gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
  • 我的最终目标只是调用 __clear_cache()。为此,我需要告诉它我的开始和结束地址。那么,在每个功能之后我怎么知道要清除什么?我可以清除整个缓存,这是否更容易。我需要清除缓存以进行基准测试。
  • 这是唯一允许从用户端代码清除缓存的函数。

标签: mmap


【解决方案1】:

如您的问题的 cmets 中所述,mmap 仅对自我修改代码或代码生成是必需的。

你的函数的开始显然只是函数指针。但是没有标准的 C 方法来获取函数的长度或指向其末尾的指针。

您可以尝试的一件事是使用 GCC 扩展,它为您提供标签的地址,即一元“&&”运算符。 所以你可以修改你的函数在最后有一个标签:

...
    do_stuff();
MYFUNC_END:
    return;
}

不确定是否可以在最后一条语句之后,就在右花括号之前添加标签。我不这么认为。

不管怎样,你可以这样做:

__clear_cache((char *)myfunc, (char *) &&MYFUNC_END);

【讨论】:

  • 好的,非常感谢您的帮助。我想删除重要数据可能更容易。所以,如果我有一个双数组 A。我可以像这样清除它: __clear_cache((char*)A, (char*)&A[N][N]);
  • 你还在使用 ARM CPU 吗?我做了一些研究,我认为 x86 没有实现。所以它不会在这样的 CPU 上做任何事情。
  • 是的,抱歉忘了说。我正在使用 ARM Cortex A9。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-24
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 2011-11-14
相关资源
最近更新 更多