Keil Logo

As an Argument

When a function pointer is used as an argument to a function, the call tree generated by the linker is inaccurate. For example, given the following example program:

int direct_func (int a, int b, int c)
{
volatile int total = a+b+c;
return (total);
}

int indirect_func (int a, int b, int c)
{
volatile int total = a+b+c;
return (total);
}

int caller (int (*fp) (int, int, int))
{
int retval;
retval = direct_func(4,5,6);
retval += (*fp) (1,2,3);
return (retval);
}

void main (void)
{
int value;

value = caller(indirect_func);

while (1);
}

The correct Call Tree is illustrated by the following flow chart.

Correct Call Tree

However, since indirect_func is referenced in the main function and not in the caller function, the linker generates the following Call Tree and Overlay Map.

Incorrect Call Tree

FUNCTION/MODULE                       BIT_GROUP   DATA_GROUP
--> CALLED FUNCTION/MODULE           START  STOP  START  STOP
=============================================================
?C_C51STARTUP                        ----- -----  ----- -----
  +--> ?PR?MAIN?MAIN

MAIN/MAIN                            ----- -----  0008H 0009H
  +--> ?PR?_INDIRECT_FUNC?MAIN
  +--> ?PR?_CALLER?MAIN

_INDIRECT_FUNC/MAIN                  ----- -----  000AH 000BH

_CALLER/MAIN                         ----- -----  000AH 000EH
  +--> ?PR?_DIRECT_FUNC?MAIN

_DIRECT_FUNC/MAIN                    ----- -----  000FH 0010H

The linker call tree must be adjusted by removing the reference from main to indirect_func and adding a reference from caller to indirect_func using the following overlay command:

... OVERLAY(main ~ indirect_func, caller ! indirect_func) ...

After adjusting the call tree, the Overlay Map appears as follows:

FUNCTION/MODULE                       BIT_GROUP   DATA_GROUP
--> CALLED FUNCTION/MODULE           START  STOP  START  STOP
=============================================================
?C_C51STARTUP                        ----- -----  ----- -----
  +--> ?PR?MAIN?MAIN

MAIN/MAIN                            ----- -----  0008H 0009H
  +--> ?PR?_CALLER?MAIN

_CALLER/MAIN                         ----- -----  000AH 000EH
  +--> ?PR?_DIRECT_FUNC?MAIN
  +--> ?PR?_INDIRECT_FUNC?MAIN

_DIRECT_FUNC/MAIN                    ----- -----  000FH 0010H

_INDIRECT_FUNC/MAIN                  ----- -----  000FH 0010H
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.