BL51 User's Guide

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