Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock functions in headerfiles?

What I am doing:

I am using cmocka to run unit tests for large embedded project. The embedded project is compiled with a arm-gcc-compiler. The unit tests are compiled with the normal gcc using fragments of the embedded code and the cmocka library.

Normally cmocka recommends to use the -Wl,--wrap=functionName flag to mock (replace) some unneeded sub-functions. This works pretty good.

The Problem:

Well, within my embedded code there is one header file (foo.h), which contains some functions (declared as inline). One of these functions contains some assembler code for the arm-gcc-compiler, which, of course, cannot be compiled by the gcc.

Stupidly the wrap-flag seems not to work on functions which are placed in header files.

Question:

How to mock this function in the headerfile away?

How I tried to solve the Problem:

I thought about inserting some #idef macros to exclude the mentioned assembler section. But this cannot be done because this file belongs to a licensed library and I am not allowed to change its content.

I could extract my function-under-test into an additional files so that foo.h doesn't need to be included anymore. But this would confuse the embedded source codes structure.

Exact lines of problem

The exact code is placed in portmacro.h of freeRtos at line 233:

portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI;

    __asm volatile
    (
        "   mov %0, %1                                              \n" \
        "   msr basepri, %0                                         \n" \
        "   isb                                                     \n" \
        "   dsb                                                     \n" \
        :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
    );
}

where as portFORCE_INLINE is defined as:

#define portFORCE_INLINE inline __attribute__(( always_inline))
like image 887
eDeviser Avatar asked Oct 30 '22 12:10

eDeviser


1 Answers

Stupidly the wrap-flag seems not to work on functions which are placed in header files.

It's not the fault of wrap, the function has been inlined by compiler so there's nothing linker can do.

How to mock this function in the headerfile away?

One option is to use sed to automatically patch the offending code before passing it to gcc. E.g. to change

portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
  uint32_t ulNewBASEPRI;
  ...
}

portFORCE_INLINE static void vPortRaiseBASEPRI_2( void )
{
  uint32_t ulNewBASEPRI;
  ...
}

from your example to

portFORCE_INLINE static void vPortRaiseBASEPRI( void );

portFORCE_INLINE static void vPortRaiseBASEPRI_2( void );

do

cat tmp.c | sed '/inline\|INLINE/,/^}$/{ s/^\(.*\(inline\|INLINE\).*\)/\1;/; /inline\|INLINE/!d }'

The regex is quite sloppy, it relies on the fact that all definitions in header will have the INLINE marker but should probably be enough in your case.

You can embed above command into your Makefile to generate custom header in a temp folder and then override default header with -Ipath/to/temp/folder flag.

like image 73
yugr Avatar answered Nov 15 '22 06:11

yugr