C memcpy() a function

2019-03-30 02:44发布

Is there any method to calculate size of a function? I have a pointer to a function and I have to copy entire function using memcpy. I have to malloc some space and know 3rd parameter of memcpy - size. I know that sizeof(function) doesn't work. Do you have any suggestions?

15条回答
smile是对你的礼貌
2楼-- · 2019-03-30 02:54

Even if there was a way to get the sizeof() a function, it may still fail when you try to call a version that has been copied to another area in memory. What if the compiler has local or long jumps to specific memory locations. You can't just move a function in memory and expect it to run. The OS can do that but it has all the information it takes to do it.


I was going to ask how operating systems do this but, now that I think of it, when the OS moves stuff around it usually moves a whole page and handles memory such that addresses translate to a page/offset. I'm not sure even the OS ever moves a single function around in memory.


Even in the case of the OS moving a function around in memory, the function itself must be declared or otherwise compiled/assembled to permit such action, usually through a pragma that indicates the code is relocatable. All the memory references need to be relative to its own stack frame (aka local variables) or include some sort of segment+offset structure such that the CPU, either directly or at the behest of the OS, can pick the appropriate segment value. If there was a linker involved in creating the app, the app may have to be re-linked to account for the new function address.

There are operating systems which can give each application its own 32-bit address space but it applies to the entire process and any child threads, not to an individual function.

As mentioned elsewhere, you really need a language where functions are first class objects, otherwise you're out of luck.

查看更多
▲ chillily
3楼-- · 2019-03-30 02:57

You want to copy a function? I do not think that this is possible in C generally. Assume, you have a Harvard-Architecture microcontroller, where code (in other words "functions") is located in ROM. In this case you cannot do that at all. Also I know several compilers and linkers, which do optimization on file (not only function level). This results in opcode, where parts of C functions are mixed into each other.

The only way which I consider as possible may be:

  • Generate opcode of your function (e.g. by compiling/assembling it on its own).

  • Copy that opcode into an C array.

  • Use a proper function pointer, pointing to that array, to call this function.

  • Now you can perform all operations, common to typical "data", on that array.

But apart from this: Did you consider a redesign of your software, so that you do not need to copy a functions content?

查看更多
来,给爷笑一个
4楼-- · 2019-03-30 02:57

I think one solution can be as below.

For ex: if you want to know func() size in program a.c, and have indicators before and after the function.

Try writing a perl script which will compile this file into object format(cc -o) make sure that pre-processor statements are not removed. You need them later on to calculate the size from object file.

Now search for your two indicators and find out the code size in between.

查看更多
三岁会撩人
5楼-- · 2019-03-30 02:58

A similar discussion was done here:

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

They propose creating a dummy function after your function-to-be-copied, and then getting the memory pointers to both. But you need to switch off compiler optimizations for it to work.

If you have GCC >= 4.4, you could try switching off the optimizations for your function in particular using #pragma:

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

Another proposed solution was not to copy the function at all, but define the function in the place where you would want to copy it to.

Good luck!

查看更多
Fickle 薄情
6楼-- · 2019-03-30 02:58

As near as I can tell, the original poster wants to do something that is implementation-specific, and so not portable; this is going off what the C++ standard says on the subject of casting pointers-to-functions, rather than the C standard, but that should be good enough here.

In some environments, with some compilers, it might be possible to do what the poster seems to want to do (that is, copy a block of memory that is pointed to by the pointer-to-function to some other location, perhaps allocated with malloc, cast that block to a pointer-to-function, and call it directly). But it won't be portable, which may not be an issue. Finding the size required for that block of memory is itself dependent on the environment, and compiler, and may very well require some pretty arcane stuff (e.g., scanning the memory for a return opcode, or running the memory through a disassembler). Again, implementation-specific, and highly non-portable. And again, may not matter for the original poster.

The links to potential solutions all appear to make use of implementation-specific behaviour, and I'm not even sure that they do what the purport to do, but they may be suitable for the OP.

Having beaten this horse to death, I am curious to know why the OP wants to do this. It would be pretty fragile even if it works in the target environment (e.g., could break with changes to compiler options, compiler version, code refactoring, etc). I'm glad that I don't do work where this sort of magic is necessary (assuming that it is)...

查看更多
老娘就宠你
7楼-- · 2019-03-30 02:59

Functions are not first class objects in C. Which means they can't be passed to another function, they can't be returned from a function, and they can't be copied into another part of memory.

A function pointer though can satisfy all of this, and is a first class object. A function pointer is just a memory address and it usually has the same size as any other pointer on your machine.

查看更多
登录 后发表回答