Reputation: 195
How can I get the size of a function in C++?
Let's say I have a function:
void f()
{
/*do something*/
}
...By "size of f
", I mean the size of the code /*do something*/
, starting from the address indicated by a pointer to f
.
Upvotes: 6
Views: 10629
Reputation: 41
You can do that pretty easily if you are OK with changing the original function. You can change your function to look like that:
void f()
{
/* do something */
{ volatile unsigned int _ = 0xBAD0BEEF; }
}
size_t getFunctionSize() {
auto p = (char*)&f;
// get close to the functions end
while(*(unsigned int*)p != 0xBAD0BEEF) p++;
// dont forget to skip our constant
p += sizeof(unsigned int);
// loop until you find ret/retn (0xC3 and 0xC2 on x86)
while(*p != 0xC3 && *p != 0xC2) p++;
// note that you should add additional 2 bytes for retn
if(*p == 0xC2) p += 2;
return ((size_t)p - (size_t)&f);
}
Note that any destructors could, in theory, trigger the loop finding the ret/retn instructions.
Above code was not tested and it has been written from my memory, so it might be wrong, but that is a working design.
Upvotes: 1
Reputation: 385174
Functions do not have "a size". As far as C++ is concerned, they are not objects and they do not take any storage space. In practice of course they exist as execution instructions in your resultant executable binary.
Upvotes: 0
Reputation: 1
I want to get the size of the generated code in bytes so I can Copy the code to a new locatio and execute it from there . I know this is posible because i done it usig the 2 function and substraction method
void f() { ... }
void g() { ... }
char *fp = (char *)&f;
char *gp = (char *)&g;
int size = gp - fp;
and it worked in visual studio in release mode .
The reason why I put this question is because I still have some problem with compiler optimizations , and I need a more secure mothod.
Upvotes: 0
Reputation: 279255
You can't. It may not even be a well-defined concept. For example, consider the following code:
int f(int a) {
return (3*a)+1;
}
int g(int a) {
return (2*a)+1;
}
I doubt it happens in practice for this particular example, because it wouldn't be an optimization, but the compiler is permitted to introduce a block of code that computes a+1
then returns, and jump to that block from each of the entry points of f
and g
(after doing a multiplication in each case). What then would be the size of f
? Should it include the size of the shared block? Half that size? It just doesn't make sense in C++ terms to claim that the function f
has a size.
Also, a "pointer to f" may not simply be the address of the function f. It certainly provides a way to get to the entry point of f
, but for example on an ARM processor in interworking mode, a pointer to a function consisting of Thumb code is actually the address of the first instruction, plus 1. In effect, the lsb of the pointer is masked off by the CPU when performing the jump to the function, but that bit tells the CPU to switch into Thumb mode rather than ARM mode. So the value of the pointer is not the address of the function (although it's close). Anyway, the entry point of a function need not necessarily be the at the start of it - if your compiler creates constant pools or similar, they could precede the executable code.
There may be platform-specific ways of examining your executables (either the files, or after loading into memory, or both), and saying what code is associated with what C++ functions. After all, it's what debug info is for. But there's no way of doing that in standard C++, and the standard doesn't require that any such mechanism exists.
Upvotes: 15
Reputation: 103703
Most compilers have an option to output assembly. Do that, look up the instructions in your processor's documentation and do the math.
Upvotes: 3
Reputation: 3197
I suggest you do something like strlen except you use return opcode instead of zero as terminator.
Upvotes: 1
Reputation: 21055
With a text editor and wc
? :) It's still not clear you mean by the size of a function, but I'd assume you mean the size of the machine code of the function. There's no way to do it, especially one portable across compilers. Many compilers would simply convert the program to assembly, so they don't know the size of the machine code.
At best, you could put a function after it and subtract the addresses, hoping that they would occupy consecutive and continuous parts of the memory, but there's really no guarantee that the compiler would do that.
Upvotes: 1
Reputation: 118651
Well, technically I don't believe you can, not portably.
But practically you may well be able to do this:
void f() { ... }
void g() { ... }
char *fp = (char *)&f;
char *gp = (char *)&g;
int size = gp - fp;
You're kind of relying on the compiler to put 'g' after 'f' in the object file, and that the linker followed suit, placing g after f.
Then you're just subtracting the pointers to get the difference.
There will likely be padding and other possible issues involved as well, so it may not be "exactly" the size of the function.
Upvotes: 4