1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

Getting the code size of a function in C

Discussion in 'Embedded' started by Tosca Berisha, Nov 1, 2005.

  1. I need to determine the size of a function or module since I need to
    temporary relocate the function or module from flash into sram for
    firmware updates.

    How can I find that out during runtime. The
    sizeof( myfunction)
    generates an error saying "size of function unknown".

    Thanks.
    Tosca Berisha, Nov 1, 2005
    #1
    1. Advertising

  2. On 2005-11-01, Tosca Berisha <> wrote:

    > I need to determine the size of a function or module since I
    > need to temporary relocate the function or module from flash
    > into sram for firmware updates.
    >
    > How can I find that out during runtime.


    You'll need to do something in your linker script to create
    global symbols before and after the function. In your C code,
    you should then be able to take the address of those global
    symboals and do some math to determine the size.

    --
    Grant Edwards grante Yow! UH-OH!! We're out
    at of AUTOMOBILE PARTS and
    visi.com RUBBER GOODS!
    Grant Edwards, Nov 1, 2005
    #2
    1. Advertising

  3. "Grant Edwards" ...
    > On 2005-11-01, Tosca Berisha <> wrote:
    >
    > > I need to determine the size of a function or module since I
    > > need to temporary relocate the function or module from flash
    > > into sram for firmware updates.
    > >
    > > How can I find that out during runtime.

    >
    > You'll need to do something in your linker script to create
    > global symbols before and after the function. In your C code,
    > you should then be able to take the address of those global
    > symboals and do some math to determine the size.


    I've often seen compiler generated (optimized) code that jumps to common
    sections of code, shared between functions. Labels around a function won't
    help you when that happens.
    Also, don't expect multiple functions in a module to stay in the same
    sequence as they were in the source file, not even with all optimisation
    off.

    You could put the function as the only function in a **module** (a single
    source file), which is also the only way I know with a (GNU) linker script
    to put labels before and after it.

    Regards,
    Arie de Muynck
    Arie de Muynck, Nov 1, 2005
    #3
  4. On 2005-11-01, Arie de Muynck <> wrote:

    > I've often seen compiler generated (optimized) code that jumps
    > to common sections of code, shared between functions. Labels
    > around a function won't help you when that happens.


    Such labels will allow him to determine the size of a function
    (which is what he asked for). I didn't guarantee that answering
    his question would solve his problem. :)

    > Also, don't expect multiple functions in a module to stay in
    > the same sequence as they were in the source file, not even
    > with all optimisation off.


    Ordering is probably not guaranteed, but I've never seen it
    change.

    > You could put the function as the only function in a
    > **module** (a single source file), which is also the only way
    > I know with a (GNU) linker script to put labels before and
    > after it.


    If you're using GCC, the easiest thing to do is to put the
    function in question in its own section using
    __attribute__((section "whatever")). Then you can put labels
    at the start and end of section "whatever". Or you can define
    a global symbol having the value of the size of the section
    (which even more directly answers the original question).

    Of course you could also put all functions in individual
    sections using -ffunction-sections.

    --
    Grant Edwards grante Yow! You were s'posed
    at to laugh!
    visi.com
    Grant Edwards, Nov 1, 2005
    #4
  5. Arie de Muynck wrote:
    > "Grant Edwards" ...
    >
    >>On 2005-11-01, Tosca Berisha <> wrote:
    >>
    >>
    >>>I need to determine the size of a function or module since I
    >>>need to temporary relocate the function or module from flash
    >>>into sram for firmware updates.
    >>>
    >>>How can I find that out during runtime.

    >>
    >>You'll need to do something in your linker script to create
    >>global symbols before and after the function. In your C code,
    >>you should then be able to take the address of those global
    >>symboals and do some math to determine the size.

    >
    >
    > I've often seen compiler generated (optimized) code that jumps to common
    > sections of code, shared between functions. Labels around a function won't
    > help you when that happens.
    > Also, don't expect multiple functions in a module to stay in the same
    > sequence as they were in the source file, not even with all optimisation
    > off.
    >
    > You could put the function as the only function in a **module** (a single
    > source file), which is also the only way I know with a (GNU) linker script
    > to put labels before and after it.
    >
    > Regards,
    > Arie de Muynck
    >


    So then the only proper way would be to access the symbol table and see
    whats the next entry after my function and get the difference between
    the two.

    Is there a standard way of accessing the symbol table?

    For now (after reading Grants answer, thank you) I created a dummy
    function after the needed function, and I am getting the size by
    subtracting the pointers to those functions to get the size. This linker
    I am using seems to keep the functions in the same order as written in
    the .c file.


    But I don't like relying on this solution, so I still seek for an
    alternative.

    Thanks Arie,
    Tosca
    Tosca Berisha, Nov 1, 2005
    #5
  6. Tosca Berisha

    Tauno Voipio Guest

    Tosca Berisha wrote:
    > I need to determine the size of a function or module since I need to
    > temporary relocate the function or module from flash into sram for
    > firmware updates.
    >
    > How can I find that out during runtime. The
    > sizeof( myfunction)
    > generates an error saying "size of function unknown".


    If you're using GCC, probably you do not need to
    copy anything, just locate your function to the initialized
    data section:

    /* Write unlock sequence */

    static void unlock(void) __attribute__((section(".data")));
    static void unlock(void)
    {
    FLASHMEM[KEYLOC1] = KEY1;
    FLASHMEM[KEYLOC2] = KEY2;
    }

    This is the Flash unlock routine from an embedded
    system.

    --

    Tauno Voipio
    tauno voipio (at) iki fi
    Tauno Voipio, Nov 1, 2005
    #6
  7. On 2005-11-01, Tauno Voipio <> wrote:

    >> I need to determine the size of a function or module since I
    >> need to temporary relocate the function or module from flash
    >> into sram for firmware updates.
    >>
    >> How can I find that out during runtime. The sizeof(
    >> myfunction) generates an error saying "size of function
    >> unknown".

    >
    > If you're using GCC, probably you do not need to copy
    > anything, just locate your function to the initialized data
    > section:
    >
    > /* Write unlock sequence */
    >
    > static void unlock(void) __attribute__((section(".data")));
    > static void unlock(void)
    > {
    > FLASHMEM[KEYLOC1] = KEY1;
    > FLASHMEM[KEYLOC2] = KEY2;
    > }
    >
    > This is the Flash unlock routine from an embedded
    > system.


    That works, but it can be a bit of a waste since the function
    is sitting in both flash and RAM 100% of the time. If there
    are multiple routines that need to be run from RAM at different
    points in time, you can save a bit of RAM by overlaying them.

    --
    Grant Edwards grante Yow! I'll show you MY
    at telex number if you show
    visi.com me YOURS...
    Grant Edwards, Nov 1, 2005
    #7
  8. Tosca Berisha

    Guest

    Tosca Berisha wrote:
    > I need to determine the size of a function or module since I need to
    > temporary relocate the function or module from flash into sram for
    > firmware updates.
    >
    > How can I find that out during runtime. The
    > sizeof( myfunction)
    > generates an error saying "size of function unknown".


    What you want to do is highly non-portable but try this working code
    snippet I use for the MSP430:

    // Blinks the LED
    void codeFunction(void)
    {
    uartPrintf(": BLINK Press ESC to quit\r\n");

    for(;;)
    {
    if(uartGetByte() == ESC) break;

    LED_ON(P3OUT,BIT0);
    delay(100);
    LED_OFF(P3OUT,BIT0);
    delay(100);
    }
    }

    void codeFunction_END(void) { }

    // Executes the BLINK command
    void funcBLINK(int count,char *cmd,char *arg1,char *arg2)
    {
    byte codeRam[90];
    size_t loadSize;
    void (*pfnFunction)(void);

    USE(count);
    USE(cmd);
    USE(arg1);
    USE(arg2);

    loadSize = (size_t)(codeFunction_END) - (size_t)(codeFunction);
    uartPrintf(": BLINK Load size = %u\r\n",loadSize);

    if(loadSize >= sizeof(codeRam))
    {
    uartPrintf(": BLINK Can't load code\r\n");
    }
    else
    {
    // Copy the code to RAM
    memset(codeRam,0,sizeof(codeRam));
    memcpy(codeRam,codeFunction,loadSize);

    // Point to the function starting in RAM
    pfnFunction = (void (*)(void))(codeRam);

    // Execute from RAM
    pfnFunction();

    uartPrintf(": BLINK ok\r\n");
    }
    }

    Note that delay() and uartPrintf() and uartGetByte() do NOT get copied
    to RAM. That's part of the challenge.

    JJS
    , Nov 1, 2005
    #8
  9. Tosca Berisha

    Tauno Voipio Guest

    Grant Edwards wrote:
    > On 2005-11-01, Tauno Voipio <> wrote:
    >
    >
    >>>I need to determine the size of a function or module since I
    >>>need to temporary relocate the function or module from flash
    >>>into sram for firmware updates.
    >>>
    >>>How can I find that out during runtime. The sizeof(
    >>>myfunction) generates an error saying "size of function
    >>>unknown".

    >>
    >>If you're using GCC, probably you do not need to copy
    >>anything, just locate your function to the initialized data
    >>section:
    >>
    >>/* Write unlock sequence */
    >>
    >>static void unlock(void) __attribute__((section(".data")));
    >>static void unlock(void)
    >> {
    >> FLASHMEM[KEYLOC1] = KEY1;
    >> FLASHMEM[KEYLOC2] = KEY2;
    >> }
    >>
    >>This is the Flash unlock routine from an embedded
    >>system.

    >
    >
    > That works, but it can be a bit of a waste since the function
    > is sitting in both flash and RAM 100% of the time. If there
    > are multiple routines that need to be run from RAM at different
    > points in time, you can save a bit of RAM by overlaying them.
    >


    The amount of code needed in RAM for Flash writing is pretty
    small: about 250 bytes on an ARM for garden-variety AMD Flashes.

    --

    Tauno Voipio
    tauno voipio (at) iki fi
    Tauno Voipio, Nov 1, 2005
    #9
  10. On 2005-11-01, Tauno Voipio <> wrote:

    >>>>I need to determine the size of a function or module since I
    >>>>need to temporary relocate the function or module from flash
    >>>>into sram for firmware updates.


    >>>If you're using GCC, probably you do not need to copy
    >>>anything, just locate your function to the initialized data
    >>>section:


    >> That works, but it can be a bit of a waste since the function
    >> is sitting in both flash and RAM 100% of the time. If there
    >> are multiple routines that need to be run from RAM at different
    >> points in time, you can save a bit of RAM by overlaying them.


    > The amount of code needed in RAM for Flash writing is pretty
    > small: about 250 bytes on an ARM for garden-variety AMD
    > Flashes.


    But where is the "flash writing" code getting the data?

    In cases I've dealt with the "flash writing" code has to
    impliment some sort of communications protocol in order to
    receive the data to be programmed into flash. In the product
    I'm working with right now, it takes 3KB of code to do a flash
    update. That's a pretty significant chunk out of my 32KB of
    RAM.

    --
    Grant Edwards grante Yow! Xerox your lunch
    at and file it under "sex
    visi.com offenders"!
    Grant Edwards, Nov 1, 2005
    #10
  11. Tosca Berisha

    Tauno Voipio Guest

    Grant Edwards wrote:
    > On 2005-11-01, Tauno Voipio <> wrote:
    >
    >
    >>>>>I need to determine the size of a function or module since I
    >>>>>need to temporary relocate the function or module from flash
    >>>>>into sram for firmware updates.

    >
    >
    >>>>If you're using GCC, probably you do not need to copy
    >>>>anything, just locate your function to the initialized data
    >>>>section:

    >
    >
    >>>That works, but it can be a bit of a waste since the function
    >>>is sitting in both flash and RAM 100% of the time. If there
    >>>are multiple routines that need to be run from RAM at different
    >>>points in time, you can save a bit of RAM by overlaying them.

    >
    >
    >>The amount of code needed in RAM for Flash writing is pretty
    >>small: about 250 bytes on an ARM for garden-variety AMD
    >>Flashes.

    >
    >
    > But where is the "flash writing" code getting the data?
    >
    > In cases I've dealt with the "flash writing" code has to
    > impliment some sort of communications protocol in order to
    > receive the data to be programmed into flash. In the product
    > I'm working with right now, it takes 3KB of code to do a flash
    > update. That's a pretty significant chunk out of my 32KB of
    > RAM.



    You do not need to keep the whole chunk in RAM at the same time.
    Also, only the inner loop of a Flash writer is necessary to be
    kept in RAM, the rest can reside in the Flash. The code responsible
    for the handling from the unlock sequence till the chip responds
    ready to poll has to be in RAM, but this is for erasing a segment
    or writing a single byte. The rest of code can be safely in the
    Flash without any problems.

    The incoming data is usually transferred in some kind of chunks
    (e.g. 128 bytes with Xmodem). It's no too difficult to keep
    one chunk in the RAM and read more when that's written.

    --

    Tauno Voipio
    tauno voipio (at) iki fi
    Tauno Voipio, Nov 1, 2005
    #11
  12. Tosca Berisha

    Guest

    Tosca Berisha wrote:
    > I need to determine the size of a function or module since I need to
    > temporary relocate the function or module from flash into sram for
    > firmware updates.
    >
    > How can I find that out during runtime. The
    > sizeof( myfunction)
    > generates an error saying "size of function unknown".
    >
    > Thanks.


    In ELF files generated by GCC, the symbol table has not only the name,
    type (FUNC), and address of each symbol, but its size as well. Thus the
    symbol table in the ELF file will tell you how big the code for the
    function is; something like objdump usually does not print out this
    information, but it is there.
    , Nov 1, 2005
    #12
  13. On 2005-11-01, Tauno Voipio <> wrote:

    >>>The amount of code needed in RAM for Flash writing is pretty
    >>>small: about 250 bytes on an ARM for garden-variety AMD
    >>>Flashes.

    >>
    >> But where is the "flash writing" code getting the data?
    >>
    >> In cases I've dealt with the "flash writing" code has to
    >> impliment some sort of communications protocol in order to
    >> receive the data to be programmed into flash. In the product
    >> I'm working with right now, it takes 3KB of code to do a flash
    >> update. That's a pretty significant chunk out of my 32KB of
    >> RAM.

    >
    > You do not need to keep the whole chunk in RAM at the same
    > time. Also, only the inner loop of a Flash writer is necessary
    > to be kept in RAM, the rest can reside in the Flash.


    You're right. I could split up the loader and keep part of it
    in flash, but it's extra work and it doesn't buy me anything.
    Once the decision is made to update flash, the entire RAM space
    becomes available. The data that's there belongs to an
    application that's being erased. It's a lot simpler to just
    copy the entire loader into RAM and run it from there. Up
    until that point, the loader is using 0 bytes of RAM.

    > The code responsible for the handling from the unlock sequence
    > till the chip responds ready to poll has to be in RAM, but
    > this is for erasing a segment or writing a single byte. The
    > rest of code can be safely in the Flash without any problems.


    It could, but there's no advantage to doing so.

    > The incoming data is usually transferred in some kind of
    > chunks (e.g. 128 bytes with Xmodem). It's no too difficult to
    > keep one chunk in the RAM and read more when that's written.


    Right.

    --
    Grant Edwards grante Yow! The Osmonds! You are
    at all Osmonds!! Throwing up
    visi.com on a freeway at dawn!!!
    Grant Edwards, Nov 1, 2005
    #13
  14. On 2005-11-01, <> wrote:
    >
    > Tosca Berisha wrote:
    >> I need to determine the size of a function or module since I need to
    >> temporary relocate the function or module from flash into sram for
    >> firmware updates.
    >>
    >> How can I find that out during runtime. The
    >> sizeof( myfunction)
    >> generates an error saying "size of function unknown".
    >>
    >> Thanks.

    >
    > In ELF files generated by GCC, the symbol table has not only
    > the name, type (FUNC), and address of each symbol, but its
    > size as well. Thus the symbol table in the ELF file will tell
    > you how big the code for the function is; something like
    > objdump usually does not print out this information, but it is
    > there.


    The ELF file isn't available to the program at run-time. It's
    quite simple to put global simbols at the beginning and end of
    a section. Then all you have to do in C is declare those
    symbols as external char arrays.

    --
    Grant Edwards grante Yow! I'm having an
    at EMOTIONAL OUTBURST!! But,
    visi.com uh, WHY is there a WAFFLE
    in my PAJAMA POCKET??
    Grant Edwards, Nov 1, 2005
    #14
  15. On Tue, 01 Nov 2005 21:31:35 -0000, Grant Edwards <> wrote:

    >On 2005-11-01, Tauno Voipio <> wrote:
    >
    >>>>The amount of code needed in RAM for Flash writing is pretty
    >>>>small: about 250 bytes on an ARM for garden-variety AMD
    >>>>Flashes.
    >>>
    >>> But where is the "flash writing" code getting the data?
    >>>
    >>> In cases I've dealt with the "flash writing" code has to
    >>> impliment some sort of communications protocol in order to
    >>> receive the data to be programmed into flash. In the product
    >>> I'm working with right now, it takes 3KB of code to do a flash
    >>> update. That's a pretty significant chunk out of my 32KB of
    >>> RAM.

    >>
    >> You do not need to keep the whole chunk in RAM at the same
    >> time. Also, only the inner loop of a Flash writer is necessary
    >> to be kept in RAM, the rest can reside in the Flash.

    >
    >You're right. I could split up the loader and keep part of it
    >in flash, but it's extra work and it doesn't buy me anything.
    >Once the decision is made to update flash, the entire RAM space
    >becomes available. The data that's there belongs to an
    >application that's being erased. It's a lot simpler to just
    >copy the entire loader into RAM and run it from there. Up
    >until that point, the loader is using 0 bytes of RAM.


    .... so just assume the function occupies all the RAM, and copy that many bytes.
    Mike Harrison, Nov 2, 2005
    #15
  16. Tosca Berisha <> wrote:

    > How can I find that out during runtime.


    No way. A portable program has no way at all of finding this out,
    i.e. it cannot be done "in C" at all. And even a non-portable
    program, using features outside the C programming language proper,
    typically won't be able to do this at run-time. Stuff like this has
    to be set up at link time, the latest, and often you'll need to do it
    at compile time already. There's even a non-negligible probability
    that it can't be done at all, or only in assembly.

    Some toolsets have special extensions (#pragma or __attribute__()) in
    the source, or some magic incantation to put in the linker commands)
    that tell the linker a particular function will be stored in a
    location different from the one it's meant to run from.

    --
    Hans-Bernhard Broeker (-aachen.de)
    Even if all the snow were burnt, ashes would remain.
    Hans-Bernhard Broeker, Nov 2, 2005
    #16
  17. On 2005-11-02, Mike Harrison <> wrote:

    >>You're right. I could split up the loader and keep part of it
    >>in flash, but it's extra work and it doesn't buy me anything.
    >>Once the decision is made to update flash, the entire RAM space
    >>becomes available. The data that's there belongs to an
    >>application that's being erased. It's a lot simpler to just
    >>copy the entire loader into RAM and run it from there. Up
    >>until that point, the loader is using 0 bytes of RAM.

    >
    > ... so just assume the function occupies all the RAM, and copy
    > that many bytes.


    Sure, but once you've put in a label so you know where the
    function starts, putting in a second one so you know where it
    ends only takes a couple more keystrokes.

    --
    Grant Edwards grante Yow! An air of FRENCH
    at FRIES permeates my
    visi.com nostrils!!
    Grant Edwards, Nov 2, 2005
    #17
  18. Grant Edwards <> wrote:

    > Sure, but once you've put in a label so you know where the
    > function starts, putting in a second one so you know where it
    > ends only takes a couple more keystrokes.


    Except that unlike the single starting point, which usually must exist
    for the C function to be callable from unrelated translation units,
    there's no particular reason for a given C function to even *have*
    exactly one end where such a label could be put. Nor is there a
    requirement that the entry point be at the start of the code region
    for that function.

    There's not even a requirement that a C compiler would have to
    translate a single function to a single, consequtive block of code.
    Optimization by function tail merging exists.

    As I stated elsewhere in this thread: it's easily possible that on a
    given platform the only way of pulling this off is by coding all the
    relevant parts in assembler.

    --
    Hans-Bernhard Broeker (-aachen.de)
    Even if all the snow were burnt, ashes would remain.
    Hans-Bernhard Broeker, Nov 2, 2005
    #18
  19. On 2005-11-02, Hans-Bernhard Broeker <-aachen.de> wrote:
    > Grant Edwards <> wrote:
    >
    >> Sure, but once you've put in a label so you know where the
    >> function starts, putting in a second one so you know where it
    >> ends only takes a couple more keystrokes.

    >
    > Except that unlike the single starting point, which usually
    > must exist for the C function to be callable from unrelated
    > translation units, there's no particular reason for a given C
    > function to even *have* exactly one end where such a label
    > could be put.


    Nonsense. There is some address X such that all bytes in the
    function have addresses less than X. Unless you've got some
    weird non-linear memory addressing scheme.

    > Nor is there a requirement that the entry point
    > be at the start of the code region for that function.


    That's why adding global labels before and after the function
    is much safer than useing the function pointer for anything.

    > There's not even a requirement that a C compiler would have to
    > translate a single function to a single, consequtive block of
    > code. Optimization by function tail merging exists.


    It may not be a requirement, but I've never seen a C compiler
    that didn't. This is comp.arch.EMBEDDED. We've got to work
    with real-world toolchains here, not some imaginary "could do
    anything the ISO spec allows" toolchain. comp.lang.c is that
    way --->

    > As I stated elsewhere in this thread: it's easily possible
    > that on a given platform the only way of pulling this off is
    > by coding all the relevant parts in assembler.


    I've been doing embedded C for 20 years on a dozen different
    target architectures and at least as many toolchains. I've
    never seen a target/toolchain where what the OP wants isn't
    easily doable with some trivial linker-script hacking.

    --
    Grant Edwards grante Yow! WHOA!! Ken and
    at Barbie are having TOO
    visi.com MUCH FUN!! It must be the
    NEGATIVE IONS!!
    Grant Edwards, Nov 2, 2005
    #19
  20. Tosca Berisha

    Tauno Voipio Guest

    Grant Edwards wrote:
    >
    > I've been doing embedded C for 20 years on a dozen different
    > target architectures and at least as many toolchains. I've
    > never seen a target/toolchain where what the OP wants isn't
    > easily doable with some trivial linker-script hacking.


    OK. Have a look at the Hi-Cross C Compiler. It translates
    every function into a separately linked unit. The units
    are linked in only if there are references to them. The
    addresses allocated by the linker for consecutive functions
    are not consecutive. For the reasons in this discussion
    (Flash writer) I tried to find the function sizes, but
    failed miserably.

    The binary file created was also a jumble of criss-
    crossed function-size pieces, so that I had to make
    an extra pre-sorting and merge pass before writing
    to Flash.

    My guess is that the functions were ordered by the
    stored call tree order collapsed in a weird way.

    --

    Tauno Voipio
    tauno voipio (at) iki fi
    Tauno Voipio, Nov 2, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Arunaabh
    Replies:
    4
    Views:
    514
    Yousuf Khan
    May 6, 2006
  2. Replies:
    14
    Views:
    1,714
    Steve at fivetrees
    Jul 9, 2006
  3. john
    Replies:
    62
    Views:
    1,162
    Albert van der Horst
    Feb 1, 2010
  4. BillW50
    Replies:
    2
    Views:
    706
    Richard Bonner
    Jun 29, 2010
  5. Aaron
    Replies:
    0
    Views:
    695
    Aaron
    Jun 28, 2010
Loading...

Share This Page