Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compilation error when using MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_C #1642

Closed
RonEld opened this issue May 22, 2018 · 5 comments · Fixed by #2079
Closed

compilation error when using MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_C #1642

RonEld opened this issue May 22, 2018 · 5 comments · Fixed by #2079
Labels
bug component-platform Portability layer and build scripts

Comments

@RonEld
Copy link
Contributor

RonEld commented May 22, 2018

Description

  • Type: Bug
  • Priority: Minor

Rasied by Eric Tung by Email


Bug

OS
linux|windows|

mbed TLS build:
Version: development branch
Configuration: define MBEDTLS_PLATFORM_CALLOC_MACRO, MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_C

Expected behavior
compilation to succeed
Actual behavior
compilation error:
Windows:

1>mbedtls\library\platform.c(54): error C2365: 'calloc' : redefinition; previous definition was 'function'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdlib.h(598) : see declaration of 'calloc'
1>mbedtls\library\platform.c(55): error C2365: 'free' : redefinition; previous definition was 'function'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdlib.h(599) : see declaration of 'free'
1>mbedtls\library\platform.c(60): error C2106: '=' : left operand must be l-value
1>mbedtls\library\platform.c(60): warning C4550: expression evaluates to a function which is missing an argument list
1>mbedtls\library\platform.c(61): error C2106: '=' : left operand must be l-value
1>mbedtls\library\platform.c(61): warning C4550: expression evaluates to a function which is missing an argument list

Linux:

In file included from platform.c:23:0:
../include/mbedtls/config.h:2784:39: error: \u2018calloc\u2019 redeclared as different kind of symbol
 #define MBEDTLS_PLATFORM_CALLOC_MACRO calloc
                                       ^
../include/mbedtls/platform.h:120:28: note: in expansion of macro \u2018MBEDTLS_PLATFORM_CALLOC_MACRO\u2019
 #define mbedtls_calloc     MBEDTLS_PLATFORM_CALLOC_MACRO
                            ^
platform.c:54:10: note: in expansion of macro \u2018mbedtls_calloc\u2019
 void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
          ^
In file included from ../include/mbedtls/platform.h:60:0,
                 from platform.c:30:
/usr/include/stdlib.h:468:14: note: previous declaration of \u2018calloc\u2019 was here
 extern void *calloc (size_t __nmemb, size_t __size)
              ^
In file included from platform.c:30:0:
../include/mbedtls/platform.h:76:39: error: initializer element is not constant
 #define MBEDTLS_PLATFORM_STD_CALLOC   calloc /**< The default \c calloc function to use. */
                                       ^
platform.c:54:46: note: in expansion of macro \u2018MBEDTLS_PLATFORM_STD_CALLOC\u2019
 void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
                                              ^
In file included from platform.c:23:0:
../include/mbedtls/config.h:2785:37: error: \u2018free\u2019 redeclared as different kind of symbol
 #define MBEDTLS_PLATFORM_FREE_MACRO free
                                     ^
../include/mbedtls/platform.h:119:28: note: in expansion of macro \u2018MBEDTLS_PLATFORM_FREE_MACRO\u2019
 #define mbedtls_free       MBEDTLS_PLATFORM_FREE_MACRO
                            ^
platform.c:55:8: note: in expansion of macro \u2018mbedtls_free\u2019
 void (*mbedtls_free)( void * )     = MBEDTLS_PLATFORM_STD_FREE;
        ^
In file included from ../include/mbedtls/platform.h:60:0,
                 from platform.c:30:
/usr/include/stdlib.h:483:13: note: previous declaration of \u2018free\u2019 was here
 extern void free (void *__ptr) __THROW;
             ^
In file included from platform.c:30:0:
../include/mbedtls/platform.h:79:41: error: initializer element is not constant
 #define MBEDTLS_PLATFORM_STD_FREE       free /**< The default \c free function to use. */
                                         ^
platform.c:55:38: note: in expansion of macro \u2018MBEDTLS_PLATFORM_STD_FREE\u2019
 void (*mbedtls_free)( void * )     = MBEDTLS_PLATFORM_STD_FREE;

Steps to reproduce
define MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_CALLOC_MACRO as the default macros.

*Although this is not the regular use, as platform calloc and free should be used when no platform calloc \ free are available, there shouldn't be a compilation error, or at least update documentation accordingly

@RonEld RonEld added bug tracking component-platform Portability layer and build scripts labels May 22, 2018
@ciarmcom
Copy link

ARM Internal Ref: IOTSSL-2312

@RonEld RonEld changed the title compilation error when using MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_CALLOC_MACRO compilation error when using MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_C Aug 19, 2018
@hanno-becker
Copy link

Where does

 void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;

come from? It says it's platform.c L54 but this line instead is:

static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;

@RonEld Can you clarify and show how to reproduce this? The current steps to reproduce have a typo, and I cannot guess what was originally meant.

@upbeat27
Copy link

@hanno-arm, I'm not OP but I have run into the same issue. Also,

 void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;

is from an older version of mbedtls.

The problem is this:
In order to use MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_CALLOC_MACRO one must define MBEDTLS_PLATFORM_MEMORY and MBEDTLS_PLATFORM_C as required by check_config.h:

#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
    ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites"
#endif

#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
    ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites"
#endif

So if you do this, in platform.h this does what you expect:

#define mbedtls_free       MBEDTLS_PLATFORM_FREE_MACRO
#define mbedtls_calloc     MBEDTLS_PLATFORM_CALLOC_MACRO

But in platform.c, you do not get what you expect:

static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE;

void * mbedtls_calloc( size_t nmemb, size_t size )
{
    return (*mbedtls_calloc_func)( nmemb, size );
}

void mbedtls_free( void * ptr )
{
    (*mbedtls_free_func)( ptr );
}

int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
                              void (*free_func)( void * ) )
{
    mbedtls_calloc_func = calloc_func;
    mbedtls_free_func = free_func;
    return( 0 );
}

and therein lies the conflict. You get a macro, yet the functions are still there, you get previous declaration errors and redeclared errors.

So the steps to reproduce are try to use MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_CALLOC_MACRO, there is no combination of configuration options which will allow them to be used, unless I am missing something. If I am missing something let me know, because I can't seem to place what it is!

@hanno-becker
Copy link

@upbeat27 Thanks for the detailed information and for pointing out the recent code change. In fact, the line in question was changed in 7decfe8, but I think the issue is agnostic to that.

@upbeat27 @RonEld It seems that the code in platform.c that @upbeat27 quotes above should be guarded by !( defined(MBEDTLS_PLATFORM_FREE_MACRO) && defined(MBEDTLS_PLATFORM_CALLOC_MACRO) ). If these macros are defined, there's no need for mbedtls_calloc, mbedtls_free, mbedtls_platform_set_calloc_free(), and platform.h indeed makes no mention of them. Actually, if I try to compile with MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO defined, I get the compiler error error: no previous prototype for ‘mbedtls_platform_set_calloc_free’ reflecting that. The documentation is also clear on that:

/*
* By default mbed TLS uses the system-provided calloc() and free().
 * This allows different allocators (self-implemented or provided) to be
 * provided to the platform abstraction layer.
 *
 * Enabling MBEDTLS_PLATFORM_MEMORY without the
 * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
 * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
 * free() function pointer at runtime.
 *
 * Enabling MBEDTLS_PLATFORM_MEMORY and specifying
 * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
 * alternate function at compile time.
*/

I will create a PR guarding the mentioned code in platform.c.

hanno-becker pushed a commit to hanno-becker/mbedtls that referenced this issue Oct 11, 2018
This commit removes the definition of the API function

`mbedtls_platform_set_calloc_free()`

from `library/platform.c` in case the macros

`MBEDTLS_PLATFORM_CALLOC_MACRO`
`MBEDTLS_PLATFORM_FREE_MACRO`

for compile time configuration of calloc/free are set.

This is in line with the corresponding header `mbedtls/platform.h`
which declares `mbedtls_platform_set_calloc_free()` only if
`MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO` are not defined.

Fixes Mbed-TLS#1642.
hanno-becker pushed a commit to hanno-becker/mbedtls that referenced this issue Oct 11, 2018
This commit removes the definition of the API function

`mbedtls_platform_set_calloc_free()`

from `library/platform.c` in case the macros

`MBEDTLS_PLATFORM_CALLOC_MACRO`
`MBEDTLS_PLATFORM_FREE_MACRO`

for compile time configuration of calloc/free are set.

This is in line with the corresponding header `mbedtls/platform.h`
which declares `mbedtls_platform_set_calloc_free()` only if
`MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO` are not defined.

Fixes Mbed-TLS#1642.
hanno-becker pushed a commit to hanno-becker/mbedtls that referenced this issue Oct 11, 2018
This commit removes the definition of the API function

`mbedtls_platform_set_calloc_free()`

from `library/platform.c` in case the macros

`MBEDTLS_PLATFORM_CALLOC_MACRO`
`MBEDTLS_PLATFORM_FREE_MACRO`

for compile time configuration of calloc/free are set.

This is in line with the corresponding header `mbedtls/platform.h`
which declares `mbedtls_platform_set_calloc_free()` only if
`MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO` are not defined.

Fixes Mbed-TLS#1642.
@RonEld
Copy link
Contributor Author

RonEld commented Oct 23, 2018

Closing this issue, as the OP, @dhhome2006 submitted the same issue in #1706

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug component-platform Portability layer and build scripts
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants