Ç的memcpy()函数

有没有什么方法来计算一个函数的大小? 我有一个指针的函数,我用的memcpy来复制整个功能。 我要的malloc一定的空间和知道的memcpy的第三个参数 - 大小。 我知道sizeof(function)不起作用。 你有什么建议吗?

--------------解决方案-------------

功能都没有在C的第一类对象这意味着它们不能被传递到另一个功能,它们不能从函数返回的,并且它们不能被复制到存储器的另一部分。

一个函数指针,虽然能满足这一切,并且是第一类对象。 的函数指针仅仅是一个存储器地址,它通常具有大小相同的机器上的任何其他指针。

它不直接回答你的问题, 你不应该执行回调的内核代码到用户空间

注入代码到内核空间是不是一个伟大的 解决方法无论是。

这是更好地代表像一个进程间屏障用户/内核障碍。 通过一个字符设备传递数据,而不是代码,来回一个明确的协议之间。 如果你确实需要传递代码 ,只是把它包在一个内核模块。 然后,您可以动态加载/卸载它,就像一个.so基于插件系统。

在一个侧面说明 ,起初我误解你并想传递memcpy()内核。 你必须要提醒的是它是一个非常特殊的功能。 它是在C标准,相当简单的定义,以及一个相当宽的范围,因此它是一个完美的目标将被提供作为内置由编译器。

就像strlen() strcmp()和其他海湾合作委员会。

这就是说,即内置不妨碍你能力采取一个指向它的指针的事实。

即使有办法得到的sizeof()的函数,它可能仍然在尝试调用已被复制到内存中的另一个区域中的版本失败。 如果编译器本地或远程跳转到特定内存位置。 你不能只是移动存储功能,并希望它运行。 操作系统可以做到这一点,但它拥有所有需要做的信息。



我要问的操作系统是如何做到这一点,但是,现在,我想起来了,当OS移动的东西围绕它通常移动一整页和处理内存,使得地址转换为一个页面/偏移。 我不知道,即使操作系统以往任何时候都围绕移动一个单一的功能在内存中。



即使是在OS的存储器中四处移动的函数的情况下,函数本身必须声明或以其它方式编译/汇编以允许这种动作,通常是通过一个杂指示代码是可重定位的。 所有的内存引用需要是相对于它自己的堆栈帧(又名局部变量)或包括偏置结构,用于使CPU,直接或在OS的要求下,可以挑选适当的段值某种段+。 如果有涉及创建该应用连接子,该应用可能必须被重新连接到帐户为新的功能地址。

有操作系统,可以给每个应用其自己的32位地址空间,但它适用于整个过程和任何子线程,而不是一个独立的功能。

正如在其他地方所提到的,你真的需要一个语言,其中函数是第一类对象,否则你的运气了。

要复制功能? 我不认为这是可能在C中一般。 假设,你有一个Harvard架构微控制器,其中的代码(即“职能”)位于ROM。 在这种情况下,你不能这样做的。 此外,我知道有几家编译器和链接,里面做优化的文件(不只是功能菜单)。 这导致操作码,其中的C函数份被混合到彼此。

我认为是可能的也许是唯一的方法:

  • 生成的函数的操作码(通过编译/自行组装它EG)。
  • 该操作码复制到C数组的。
  • 使用正确的函数指针,指向一个数组,调用此函数。
  • 现在,您可以执行所有操作,共同为典型的“数据”,该阵列上。

但除了这一点:你认为你的软件的重新设计,使您不必复制功能的内容?

我不太明白你怎么做到的,但假设你编译-fPIC并没有你的函数做任何幻想,没有其他的函数调用,而不是从外部访问功能的数据,你甚至可以逃脱做它一次。 我想说的最安全的可能性是限制支持功能的最大尺寸,比方说,1千字节,只是转移了,并忽略尾随的垃圾。

如果你真的需要知道一个函数的确切大小,计算出你的编译器的尾声和序幕。 这应该是这个样子在x86:

:your_func_epilogue
mov esp, ebp
pop ebp
ret
:end_of_func

;expect a varying length run of NOPs here

:next_func_prologue
push ebp
mov ebp, esp

拆开你的编译器的输出进行检查,并采取相应的装配顺序来搜索。 单独尾声可能就足够了,但所有这一切都可以在弹,如果搜索序列弹出太早,比如嵌入式的函数的数据。 搜索下一个序幕也可能让你陷入困境,我想。

现在,请忽略一切,我写的,因为你显然正在试图解决这个问题,在错误的和固有的不安全性的方式。 涂料我们照片放大请,为什么你想做到这一点,看看我们能否找出一个完全不同的方法。

类似的讨论在这里完成:

http://www.motherboardpoint.com/getting-code-size-function-c-t95049.html

他们提出创建一个虚拟函数后的函数要被复制,然后获得存储器指针两者。 但是,你需要关闭编译器优化为它工作。

如果你有GCC> = 4.4,你可以尝试关掉优化您在使用#pragma特定的功能:

http://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html#Function-Specific-Option-Pragmas

另一种建议的解决方案并没有复制功能可言,但在那里你会想将它复制到地方定义函数。

祝你好运!

如果你的连接器不执行全局优化,那么就计算函数指针和下一函数的地址之差。

请注意,复制功能将产生,如果你的代码不编译重定位不能被援引的东西(即代码中的所有地址必须是相对的,例如分支机构;全局工作,但因为它们不动)。

这听起来像你想从你的核心驱动程序用户空间有一个回调,以便它可以在一些异步工作完成后通知用户空间。

这听起来合理的,因为它是这样一个普通的用户态库可能会做的事情 - 但内核/用户空间的接口,这是相当错误的。 即使你设法让你的函数代码复制到内核,即使你把它适当的位置无关,它仍然是错的,因为内核和用户空间代码执行的完全不同的环境。 为可能导致问题的差异只是一个例子,如果一个页错误内核上下文发生由于换出页,那将导致内核糟糕而不是交换在网页中。

正确的做法是为内核做出一些文件描述符可读当异步工作已完成(在你的情况下,该文件描述几乎可以肯定的是字符设备驱动程序提供)。 然后,用户进程可以等待该事件select / poll ,或read -它可以设置文件描述符非阻塞要想,基本上只使用所有标准的UNIX工具来处理这种情况。 这毕竟是如何的网络套接字(和几乎所有其他的情况下,台异步)异步特性的处理。

如果您需要提供有关所发生的事件,可以提供给用户进程在调用更多的信息read的可读文件描述符。

功能不只是对象,你可以复制。 那么交叉引用/符号等等? 当然你也可以采取类似的标准Linux“的binutils”包和折磨你的二进制代码,但是是你想要的吗?

顺便说一句,如果你仅仅是想取代的memcpy()的实施,环顾四周LD_PRELOAD机制。

我能想到的方式来完成你想要什么,但我不会告诉你,因为它是语言的一个可怕的虐待。

比禁用优化和依靠编译器来维持秩序的功能,更清洁的方法是安排该函数(或一组需要复印功能)是在其自己的部分。 这是编译器和连接器相关的,你还需要相对于使用地址,如果你被复制的功能之间打电话。 对于那些问你为什么会做到这一点,需要更新运行代码的嵌入式系统的一个共同要求。

我的建议是:没有。

注入代码到内核空间是这样的,最现代的操作系统完全禁止自修改代码的巨大的安全漏洞。

尽可能接近我可以告诉大家,原来的海报想要做的东西是实现特定的,因此不便于携带; 这是怎么回事关什么的C ++标准说在铸造指针到函数,而不是C标准的主题,但应该是够用了这里。

在某些环境中,用一些编译器,有可能做的海报似乎想要做(即,复制的存储器的块是所指向指针到功能到一些其他位置,或者分配malloc的,投了块的指针到函数,直接调用它)。 但它不会是便携式的,这可能不是一个问题。 发现所需的存储器块的大小是本身取决于环境,和编译器,以及很可能需要一些相当神秘的东西(例如,扫描存储器为一个操作码返回,或者通过运行一个拆装器的存储器)。 再次,实现特定的,且高度非便携式的。 再次,可能不重要了原来的海报。

该链接可能的解决方案似乎都利用执行特定的行为,我甚至不知道他们做主旨​​做的,但它们可能适用于OP。

已经击败这匹死,我很好奇,想知道为什么OP想这样做。 这将是即使它在目标环境(例如,可能的变化突破到编译器选项,编译器的版本,代码重构等)相当脆弱。 我很高兴,我不这样做的工作在哪里这样的神奇是必要的(假设它是)...

我有一个任天堂GBA,我已经复制了一些低级别的闪存(16位访问slowish内存),以高速工作区RAM渲染功能做到了这一点(32位访问,至少快一倍)。 这是通过采用函数的地址,我想复制功能,尺寸后immdiately做=(int)的(NextFuncPtr - SourceFuncPtr)。 这也很好地工作,但显然在所有平台上(不能在Windows工作的肯定)不能被garunteed。

我认为一个解决方案可以如下。

对于例如:如果你想知道在节目交流FUNC()的大小,以及前后功能之后有指标。

试着写一个perl脚本,将编译该文件为对象格式(CC -o)确保预处理器语句不会被删除。 你需要他们稍后来计算对象文件的大小。

现在搜索你的两个指标,并找出代码大小介于两者之间。

分类:C# 时间:2015-03-16 人气:6
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.878 (s). 10 q(s)