EmbeddedRelated.com
Forums

Getting the size of a C function

Started by john January 22, 2010
Hi,

I need to know the size of a function or module because I need to
temporarily relocate the function or module from flash into sram to
do firmware updates.

How can I determine that at runtime? The
sizeof( myfunction)
generates an error: "size of function unknown".

Thanks.
john wrote:
> Hi, > > I need to know the size of a function or module because I need to > temporarily relocate the function or module from flash into sram to > do firmware updates. > > How can I determine that at runtime? The > sizeof( myfunction) > generates an error: "size of function unknown". > > Thanks.
If you give us the details on your target and tools, someone here will surely be able to help you do the thing you *actually* want to do. Bob
john <john@nospam.com> wrote:

> I need to know the size of a function or module because I need to > temporarily relocate the function or module from flash into sram to > do firmware updates.
In general, C does not provide a mechanism to find the size of a function. Some compilers might implement sizeof(function) but it is not standard C. If your compiler always outputs functions to the object code in the same order as they appear in the source code, you could take the address of the next function and the address of the function in question, convert them to (char *) and get the difference between them. This assumes you never rearrange your source code - comment well! If your compiler outputs functions in a somewhat unpredictable order then this won't work. The technique I used for a similar problem was to examine the object code to determine the size of the function manually, added a safety margin to allow for potential code growth, and embedded that as a constant in the source code. It then needs to be re-checked after source changes (or a revised compiler) to confirm that the size hasn't grown too much. -- David Empson dempson@actrix.gen.nz
In article <hjda8u$t4k$1@speranza.aioe.org>, john@nospam.com says...
> Hi, > > I need to know the size of a function or module because I need to > temporarily relocate the function or module from flash into sram to > do firmware updates. > > How can I determine that at runtime? The > sizeof( myfunction) > generates an error: "size of function unknown". > > Thanks. >
Good question, and I would like to know if there is an easy way to do it during runtime, and a portable way would be nice too. I would probably look at the map file and use the size I calculated from there, but that's surely not runtime. You can get the starting address of the function pretty easy, but how about the end? Hmmm, gotta' think about that. Jim
john a &eacute;crit :
> Hi, > > I need to know the size of a function or module because I need to > temporarily relocate the function or module from flash into sram to > do firmware updates. > > How can I determine that at runtime? The > sizeof( myfunction) > generates an error: "size of function unknown". > > Thanks.
(1) There is the method already mentioned that subtracts two function addresses. If your compiler is "well behaved" that could work except for the last function in the module... (2) Another method is to generate an assembly listing and insert at the end of each function a "marker" by just using (the equivalent) of .byte 0,1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1 Then, at runtime you load the code and search for the terminator marker Obviously the terminator should contain at least one illegal instruction to be sure that it doesn't appear in the code itself (3) Yet another method is to generate a linker map table and read the size of each function from the table, what comes to method (1) but at compile time. (4) Another method is to locate all function prologues and function epilogues ofthe functions in the code you generate. Locating the prologue means searching for the sequence of instructions that the compiler generates for each function start, probably the saving of some registers and the allocating of stack space for the local variables. Caveat: It could be that for certain functions the compiler doesn't generate any prologue... specially if the function doesn't call any other functions and receives no arguments... Locating the epilogue means searching for the return instruction Caveat: It could be that the compiler generates several... You should find the last one, before you find a prologue. From all those possibilities, the option (3) looks the more promising one to me. Method (1) isn't very precise and there is the problem of the last function in a compilation unit. Method 2 is a PITA since you have to generate the assembly, insert the markers, re-assemble... Method (4) needs a disassembler, and a LOT of parsing work, and it is very sensitive to compilation options.

john wrote:

> Hi, > > I need to know the size of a function or module because I need to > temporarily relocate the function or module from flash into sram to > do firmware updates. > > How can I determine that at runtime? The > sizeof( myfunction) > generates an error: "size of function unknown". > > Thanks.
Several times I encountered the following construction: //-------------------------- your_function() { } next_function() { } *fu() = next_function; *bar() = your_function; size_of_your_function = ((int)fu) - ((int)bar); //------------------------- Of course, this is not guaranteed to work as it depends on many things, however I've seen that solution used in bootloaders. Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com
"john" <john@nospam.com> wrote in message 
news:hjda8u$t4k$1@speranza.aioe.org...
> Hi, > > I need to know the size of a function or module because I need to > temporarily relocate the function or module from flash into sram to > do firmware updates. > > How can I determine that at runtime? The > sizeof( myfunction) > generates an error: "size of function unknown". >
my recommendation: in this case, it might actually be better advised to generate the function as a chunk of arch-specific ASM or machine code (ASM is preferable IMO, but requires an assembler...), which could then be located wherever (such as the heap). the reason for suggesting this is that, for many archs, relocating compiled code (for example, via memcpy) may very well cause it to break. at least with custom ASM, one can be more certain that the code will survive the relocation. another possibility would be to compile some code itself as a relocatable module (such as an ELF or COFF object or image or whatever is common on the arch), which can then be stored as a glob of binary data (this can be done fairly easily by writing a tool to convert the module into a an array of bytes in C syntax which can be linked into the image). when needed, this module is itself relocated to the target address, and jumped to. this would allow more complex modules to be used (and is less-effort in the non-trivial case than would be writing it in ASM or raw machine code). keep in mind that there is no really "good" or "general purpose" ways to do these sorts of tasks.
> Thanks.
On 2010-01-23, BGB / cr88192 <cr88192@hotmail.com> wrote:

> in this case, it might actually be better advised to generate the function > as a chunk of arch-specific ASM or machine code (ASM is preferable IMO, but > requires an assembler...), which could then be located wherever (such as the > heap).
IMO, the "right" thing to do is to tell the compiler to put the function into a separate section and then have it linked so that it's "located" to run in RAM at the proper address but stored in ROM. That way you know the code will work correctly when it's run from RAM. Defining approprate symbols in the linker command file will allow the program to refer to the start and end of the section's address in ROM. The OP needs to spend some time studying the manuals for his compiler and linker.
WangoTango <Asgard24@mindspring.com> writes:
> In article <hjda8u$t4k$1@speranza.aioe.org>, john@nospam.com says... >> I need to know the size of a function or module because I need to >> temporarily relocate the function or module from flash into sram to >> do firmware updates. >> >> How can I determine that at runtime? The >> sizeof( myfunction) >> generates an error: "size of function unknown". >> > Good question, and I would like to know if there is an easy way to do it > during runtime, and a portable way would be nice too. I would probably > look at the map file and use the size I calculated from there, but > that's surely not runtime. > > You can get the starting address of the function pretty easy, but how > about the end? Hmmm, gotta' think about that.
You can't even portably assume that &func is the memory address of the beginning of the function. I think there are systems (AS/400) where function pointers are not just machine addresses. Given whatever it is you're doing, you're probably not too concerned with portability, so that likely not to be an issue. But there's no portable way in C to determine the size of a function, so you're more likely to get help somewhere other than comp.lang.c. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"
On Sat, 23 Jan 2010 12:03:18 +1300, David Empson wrote:

> john <john@nospam.com> wrote: > >> I need to know the size of a function or module because I need to >> temporarily relocate the function or module from flash into sram to do >> firmware updates. > > In general, C does not provide a mechanism to find the size of a > function. Some compilers might implement sizeof(function) but it is not > standard C. > > If your compiler always outputs functions to the object code in the same > order as they appear in the source code, you could take the address of > the next function and the address of the function in question, convert > them to (char *) and get the difference between them. This assumes you > never rearrange your source code - comment well!
I've seen it done like this: whatever my_eeprom_burning_code() { // insert deathless prose here } void end_my_eeprom_burning_code(void) { } As long as the second function doesn't get optimized away or moved, you're home free. -- www.wescottdesign.com