我正在寻找一种方法来确定编译函数的大小(以字节为单位)。
我做了一些研究,在大多数编译器上,你不能使用sizeof(functionName)。我查看了PE32标题,我只能找到其中列出的入口点的地址。
使用GCC时,我认为您可以使用链接描述文件和it seems the info is also contained in the ELF file headers。
但是,这些解决方案仅适用于Unix。有没有办法在Windows中这样做?我正在使用Visual Studio,并想知道链接器是否能够做到这一点。
另一种方法是机器码分析(追踪jmps和ret操作码;我不知道这有多可靠),但这似乎很难实现。
编辑:有几个人问我为什么要这样做。我不考虑这部分问题,但我想在另一台计算机上运行某些计算密集型函数来运行一些测试。真的,只不过是在尝试。我认为这是一个比发送代码和每次重新编译更有效的解决方案。 (因此,也许分类为" XY问题"可能是真的)。我知道优化可以防止功能变得很好并阻止功能。代码,但我认为可以避免这种情况(通过使用函数指针或编译器指令:这是我在尝试从中提取函数大小时将函数包含在导出表中的方式PE数据)。
答案 0 :(得分:1)
使用 Grouped Sections ,因此函数按您想要的顺序排列,然后减去函数地址:
#include <stdio.h>
#include <windows.h>
#ifdef _MSC_VER
#define CODE_SEG(seg) __declspec(code_seg(seg))
#else
#define CODE_SEG(seg) __attribute__((section(seg)))
#endif
static CODE_SEG(".text$1") int sum_arr (int *arr, int qty)
{
int sum = 0;
int i;
for (i = 0; i < qty; i++)
sum += arr[i];
return sum;
}
static CODE_SEG(".text$2") int multiply (int m1, int m2)
{
return m1 * m2;
}
CODE_SEG(".text$3") int main( void )
{
printf ("size of sum_arr(): %u\n",
(unsigned)((UINT_PTR)&multiply - (UINT_PTR)&sum_arr));
printf ("size of multiply(): %u\n",
(unsigned)((UINT_PTR)&main - (UINT_PTR)&multiply));
return 0;
}
来自Microsoft Portable Executable and Common Object File Format Specification:
分组部分(仅限对象)
“$”字符(美元符号)有一个 对象文件中节名的特殊解释。
当 确定将包含一个内容的图像部分 对象部分,链接器丢弃“$”和所有字符 跟着它。因此,名为.text $ X的对象部分实际上有贡献 到图像中的.text部分。
然而,下面的字符 “$”确定对图像的贡献的顺序 部分。具有相同对象部分名称的所有贡献都是 在图像中连续分配,以及贡献块 按对象部分名称按词汇顺序排序。因此, 部分名称.text $ X的目标文件中的所有内容最终结合在一起, 在.text $ W贡献之后和.text $ Y贡献之前。
图像文件中的部分名称从不包含“$”字符。