Skip to content
Snippets Groups Projects
Commit 97a783a1 authored by Fonenantsoa Maurica's avatar Fonenantsoa Maurica
Browse files

Memory initialization for constructors. TODO:

 - safe locations (standard streams)
 - memory operations other than malloc that require memory_init to be called beforehand
 - bittree model
parent 9e8c2fd2
No related branches found
No related tags found
No related merge requests found
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
/tests/no-main/result/* /tests/no-main/result/*
/tests/full-mmodel/result/* /tests/full-mmodel/result/*
/tests/full-mmodel-only/result/* /tests/full-mmodel-only/result/*
/tests/segment-only/result/*
/tests/bts/result/* /tests/bts/result/*
/tests/gmp/result/* /tests/gmp/result/*
/tests/reject/result/* /tests/reject/result/*
......
...@@ -84,6 +84,7 @@ ...@@ -84,6 +84,7 @@
/* Memory state initialization */ /* Memory state initialization */
#define memory_clean export_alias(memory_clean) #define memory_clean export_alias(memory_clean)
#define mspaces_init export_alias(mspaces_init)
#define memory_init export_alias(memory_init) #define memory_init export_alias(memory_init)
/* Heap size */ /* Heap size */
...@@ -175,6 +176,10 @@ int posix_memalign(void **memptr, size_t alignment, size_t size) ...@@ -175,6 +176,10 @@ int posix_memalign(void **memptr, size_t alignment, size_t size)
/*** Memory tracking {{{ ***/ /*** Memory tracking {{{ ***/
/************************************************************************/ /************************************************************************/
/*! \brief Initialize memory locations. */
void mspaces_init(int *argc_ref, char *** argv_ref)
__attribute__((FC_BUILTIN));
/*! \brief Initialize memory tracking state. /*! \brief Initialize memory tracking state.
* Called before any other statement in \p main */ * Called before any other statement in \p main */
/*@ assigns \nothing; */ /*@ assigns \nothing; */
......
...@@ -69,9 +69,11 @@ extern FILE *stderr; /* Standard error output stream. */ ...@@ -69,9 +69,11 @@ extern FILE *stderr; /* Standard error output stream. */
static void collect_safe_locations() { static void collect_safe_locations() {
/* Tracking of errno and standard streams */ /* Tracking of errno and standard streams */
add_safe_location((uintptr_t)&errno, sizeof(int), "errno"); /* TODO: how to corrrectly add the following locations
add_safe_location((uintptr_t)stdout, sizeof(FILE), "stdout"); in presence of contructors? */
add_safe_location((uintptr_t)stderr, sizeof(FILE), "stderr"); // add_safe_location((uintptr_t)&errno, sizeof(int), "errno");
add_safe_location((uintptr_t)stdin, sizeof(FILE), "stdin"); // add_safe_location((uintptr_t)stdout, sizeof(FILE), "stdout");
// add_safe_location((uintptr_t)stderr, sizeof(FILE), "stderr");
// add_safe_location((uintptr_t)stdin, sizeof(FILE), "stdin");
} }
#endif #endif
...@@ -193,15 +193,12 @@ static void argv_alloca(int *argc_ref, char *** argv_ref) { ...@@ -193,15 +193,12 @@ static void argv_alloca(int *argc_ref, char *** argv_ref) {
/* Program initialization {{{ */ /* Program initialization {{{ */
extern int main(void); extern int main(void);
void memory_init(int *argc_ref, char *** argv_ref, size_t ptr_size) { int MSPACES_INIT = 0;
void mspaces_init(int *argc_ref, char *** argv_ref) {
if(MSPACES_INIT) return;
describe_run(); describe_run();
/** Verify that the given size of a pointer matches the one in the present
* architecture. This is a guard against Frama-C instrumentations using
* architectures different to the given one. */
make_memory_spaces(64*MB, get_heap_size()); make_memory_spaces(64*MB, get_heap_size());
arch_assert(ptr_size);
/* Initialize report file with debug logs (only in debug mode). */
initialize_report_file(argc_ref, argv_ref);
/* Lift stack limit to account for extra stack memory overhead. */ /* Lift stack limit to account for extra stack memory overhead. */
increase_stack_limit(get_stack_size()*2); increase_stack_limit(get_stack_size()*2);
/* Allocate and log shadow memory layout of the execution */ /* Allocate and log shadow memory layout of the execution */
...@@ -209,6 +206,17 @@ void memory_init(int *argc_ref, char *** argv_ref, size_t ptr_size) { ...@@ -209,6 +206,17 @@ void memory_init(int *argc_ref, char *** argv_ref, size_t ptr_size) {
//DEBUG_PRINT_LAYOUT; //DEBUG_PRINT_LAYOUT;
/* Make sure the layout holds */ /* Make sure the layout holds */
DVALIDATE_SHADOW_LAYOUT; DVALIDATE_SHADOW_LAYOUT;
MSPACES_INIT = 1;
}
void memory_init(int *argc_ref, char *** argv_ref, size_t ptr_size) {
mspaces_init(argc_ref, argv_ref);
/** Verify that the given size of a pointer matches the one in the present
* architecture. This is a guard against Frama-C instrumentations using
* architectures different to the given one. */
arch_assert(ptr_size);
/* Initialize report file with debug logs (only in debug mode). */
initialize_report_file(argc_ref, argv_ref);
/* Track program arguments. */ /* Track program arguments. */
if (argc_ref && argv_ref) if (argc_ref && argv_ref)
argv_alloca(argc_ref, argv_ref); argv_alloca(argc_ref, argv_ref);
......
...@@ -880,6 +880,7 @@ static void set_heap_segment(void *ptr, size_t size, size_t alloc_size, ...@@ -880,6 +880,7 @@ static void set_heap_segment(void *ptr, size_t size, size_t alloc_size,
} }
} }
extern int MSPACES_INIT;
/*! \brief Replacement for a malloc function that additionally tracks the /*! \brief Replacement for a malloc function that additionally tracks the
* allocated memory block. * allocated memory block.
* *
...@@ -893,6 +894,10 @@ static void set_heap_segment(void *ptr, size_t size, size_t alloc_size, ...@@ -893,6 +894,10 @@ static void set_heap_segment(void *ptr, size_t size, size_t alloc_size,
* behaviour is as if the size were some non-zero value, except that the * behaviour is as if the size were some non-zero value, except that the
* returned pointer shall not be used to access an object." */ * returned pointer shall not be used to access an object." */
void* malloc(size_t size) { void* malloc(size_t size) {
if(! MSPACES_INIT) {
mspaces_init(0, 0); // arguments of main are not (?) known at this point
MSPACES_INIT = 1;
}
size_t alloc_size = ALLOC_SIZE(size); size_t alloc_size = ALLOC_SIZE(size);
/* Return NULL if the size is too large to be aligned */ /* Return NULL if the size is too large to be aligned */
......
/* run.config
COMMENT: bts #2405. Memory not initialized for code executed before main.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
__attribute__((constructor))
void f() {
printf("f\n");
char *buf = (char*)malloc(10*sizeof(char));
free(buf);
}
int main() {
printf("main\n");
int *p = &errno;
// TODO: see e_acsl_safe_locations.h regarding the standard streams
/*@ assert ! \valid(p); */ ;
/*@ assert ! \valid(stderr); */ ;
/*@ assert ! \valid(stdin); */ ;
/*@ assert ! \valid(stdout); */ ;
return 0;
}
\ No newline at end of file
[e-acsl] beginning translation.
[e-acsl] Warning: annotating undefined function `printf_va_1':
the generated program may miss memory instrumentation
if there are memory-related annotations.
[e-acsl] Warning: annotating undefined function `printf_va_2':
the generated program may miss memory instrumentation
if there are memory-related annotations.
[e-acsl] tests/segment-only/constructor.c:17: Warning:
E-ACSL construct `logic function application' is not yet supported.
Ignoring annotation.
[e-acsl] tests/segment-only/constructor.c:17: Warning:
E-ACSL construct `assigns clause in behavior' is not yet supported.
Ignoring annotation.
[e-acsl] tests/segment-only/constructor.c:11: Warning:
E-ACSL construct `logic function application' is not yet supported.
Ignoring annotation.
[e-acsl] tests/segment-only/constructor.c:11: Warning:
E-ACSL construct `assigns clause in behavior' is not yet supported.
Ignoring annotation.
[e-acsl] translation done in project "e-acsl".
[eva:alarm] tests/segment-only/constructor.c:19: Warning:
assertion got status invalid (stopping propagation).
/* Generated by Frama-C */
#include "errno.h"
#include "stdio.h"
#include "stdlib.h"
char *__gen_e_acsl_literal_string_2;
char *__gen_e_acsl_literal_string;
void f(void) __attribute__((__constructor__));
void f(void)
{
__gen_e_acsl_printf_va_1(__gen_e_acsl_literal_string);
char *buf = malloc((unsigned long)10 * sizeof(char));
free((void *)buf);
return;
}
void __e_acsl_globals_init(void)
{
__gen_e_acsl_literal_string_2 = "main\n";
__e_acsl_store_block((void *)__gen_e_acsl_literal_string_2,
sizeof("main\n"));
__e_acsl_full_init((void *)__gen_e_acsl_literal_string_2);
__e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_2);
__gen_e_acsl_literal_string = "f\n";
__e_acsl_store_block((void *)__gen_e_acsl_literal_string,sizeof("f\n"));
__e_acsl_full_init((void *)__gen_e_acsl_literal_string);
__e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string);
__e_acsl_store_block((void *)(& stdout),(size_t)8);
__e_acsl_full_init((void *)(& stdout));
__e_acsl_store_block((void *)(& stdin),(size_t)8);
__e_acsl_full_init((void *)(& stdin));
__e_acsl_store_block((void *)(& stderr),(size_t)8);
__e_acsl_full_init((void *)(& stderr));
__e_acsl_store_block((void *)(& errno),(size_t)4);
__e_acsl_full_init((void *)(& errno));
return;
}
int main(void)
{
int __retres;
__e_acsl_memory_init((int *)0,(char ***)0,(size_t)8);
__e_acsl_globals_init();
__gen_e_acsl_printf_va_2(__gen_e_acsl_literal_string_2);
int *p = & errno;
__e_acsl_store_block((void *)(& p),(size_t)8);
__e_acsl_full_init((void *)(& p));
/*@ assert ¬\valid(p); */
{
int __gen_e_acsl_initialized;
int __gen_e_acsl_and;
__gen_e_acsl_initialized = __e_acsl_initialized((void *)(& p),
sizeof(int *));
if (__gen_e_acsl_initialized) {
int __gen_e_acsl_valid;
__gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),(void *)p,
(void *)(& p));
__gen_e_acsl_and = __gen_e_acsl_valid;
}
else __gen_e_acsl_and = 0;
__e_acsl_assert(! __gen_e_acsl_and,(char *)"Assertion",(char *)"main",
(char *)"!\\valid(p)",19);
}
/*@ assert ¬\valid(__fc_stderr); */
{
int __gen_e_acsl_valid_2;
__gen_e_acsl_valid_2 = __e_acsl_valid((void *)stderr,sizeof(FILE),
(void *)stderr,(void *)(& stderr));
__e_acsl_assert(! __gen_e_acsl_valid_2,(char *)"Assertion",
(char *)"main",(char *)"!\\valid(__fc_stderr)",20);
}
/*@ assert ¬\valid(__fc_stdin); */
{
int __gen_e_acsl_valid_3;
__gen_e_acsl_valid_3 = __e_acsl_valid((void *)stdin,sizeof(FILE),
(void *)stdin,(void *)(& stdin));
__e_acsl_assert(! __gen_e_acsl_valid_3,(char *)"Assertion",
(char *)"main",(char *)"!\\valid(__fc_stdin)",21);
}
/*@ assert ¬\valid(__fc_stdout); */
{
int __gen_e_acsl_valid_4;
__gen_e_acsl_valid_4 = __e_acsl_valid((void *)stdout,sizeof(FILE),
(void *)stdout,(void *)(& stdout));
__e_acsl_assert(! __gen_e_acsl_valid_4,(char *)"Assertion",
(char *)"main",(char *)"!\\valid(__fc_stdout)",22);
}
__retres = 0;
__e_acsl_delete_block((void *)(& stdout));
__e_acsl_delete_block((void *)(& stdin));
__e_acsl_delete_block((void *)(& stderr));
__e_acsl_delete_block((void *)(& errno));
__e_acsl_delete_block((void *)(& p));
__e_acsl_memory_clean();
return __retres;
}
LOG: gen_@PTEST_NAME@.c
OPT: -machdep gcc_x86_64 -check -e-acsl -then-last -load-script tests/print.cmxs -print -ocode tests/segment-only/result/gen_@PTEST_NAME@.c -kernel-verbose 0 -eva -eva-verbose 0
EXEC: ./scripts/testrun.sh @PTEST_NAME@ segment-only "" "--frama-c=@frama-c@" "segment"
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment