1 /* Standard includes. */
2 #include <stdint.h>
3 #include <stdio.h>
4
5 /* FreeRTOS includes. */
6 #include "FreeRTOS.h"
7 #include "queue.h"
8 #include "semphr.h"
9 #include "event_groups.h"
10
11 /* FreeRTOS+TCP includes. */
12 #include "FreeRTOS_IP.h"
13 #include "FreeRTOS_IP_Private.h"
14 #include "FreeRTOS_Sockets.h"
15
16 #include "memory_assignments.c"
17
18
19 /*********************************************************************************
20 *
21 * The below structure definitions are just copy pasted from the FreeRTOS-Kernel.
22 * To understand the proof, you need not understand the structures and they can
23 * be ignored safely.
24 *
25 ********************************************************************************/
26
27 /* Define the bits used by Kernel. */
28 #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
29
30 typedef struct EventGroupDef_t
31 {
32 EventBits_t uxEventBits;
33 List_t xTasksWaitingForBits;
34
35 #if ( configUSE_TRACE_FACILITY == 1 )
36 UBaseType_t uxEventGroupNumber;
37 #endif
38
39 #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
40 uint8_t ucStaticallyAllocated;
41 #endif
42 } EventGroup_t;
43
44 typedef struct QueuePointers
45 {
46 int8_t * pcTail;
47 int8_t * pcReadFrom;
48 } QueuePointers_t;
49
50 typedef struct SemaphoreData
51 {
52 TaskHandle_t xMutexHolder;
53 UBaseType_t uxRecursiveCallCount;
54 } SemaphoreData_t;
55
56 typedef struct QueueDefinition
57 {
58 int8_t * pcHead;
59 int8_t * pcWriteTo;
60
61 union
62 {
63 QueuePointers_t xQueue;
64 SemaphoreData_t xSemaphore;
65 } u;
66
67 List_t xTasksWaitingToSend;
68 List_t xTasksWaitingToReceive;
69
70 volatile UBaseType_t uxMessagesWaiting;
71 UBaseType_t uxLength;
72 UBaseType_t uxItemSize;
73
74 volatile int8_t cRxLock;
75 volatile int8_t cTxLock;
76
77 #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
78 uint8_t ucStaticallyAllocated;
79 #endif
80
81 #if ( configUSE_QUEUE_SETS == 1 )
82 struct QueueDefinition * pxQueueSetContainer;
83 #endif
84
85 #if ( configUSE_TRACE_FACILITY == 1 )
86 UBaseType_t uxQueueNumber;
87 uint8_t ucQueueType;
88 #endif
89 } xQUEUE;
90
91 /********************************************************/
92 /********* End Kernel cut-paste section *****************/
93 /********************************************************/
94
95
96 /* The memory safety of xQueueGenericSend has been proved before.
97 * See github.com/FreeRTOS/FreeRTOS/FreeRTOS/Test/CBMC/proofs/Queue/QueueGenericSend.
98 */
xQueueGenericSend(QueueHandle_t xQueue,const void * const pvItemToQueue,TickType_t xTicksToWait,const BaseType_t xCopyPosition)99 BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
100 const void * const pvItemToQueue,
101 TickType_t xTicksToWait,
102 const BaseType_t xCopyPosition )
103 {
104 BaseType_t xResult;
105
106 /* These asserts are copied over from the original function itself. */
107 __CPROVER_assert( xQueue != NULL, "xQueue cannot be NULL" );
108 __CPROVER_assert( !( ( pvItemToQueue == NULL ) && ( xQueue->uxItemSize != ( UBaseType_t ) 0U ) ),
109 "If itemsize is non-zero, then pvItemToQueue cannot be NULL." );
110 __CPROVER_assert( !( ( xCopyPosition == queueOVERWRITE ) && ( xQueue->uxLength != 1 ) ),
111 "If length is one, then check the copy position" );
112
113 /* Return any random value. */
114 return xResult;
115 }
116
117
xEventGroupSetBits(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet)118 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
119 const EventBits_t uxBitsToSet )
120 {
121 EventBits_t uxReturnBits;
122
123 /* The below asserts are copied over from the original function itself. */
124 __CPROVER_assert( xEventGroup != NULL,
125 "The event group cannot be NULL" );
126 __CPROVER_assert( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0,
127 "Cannot set Kernel bits" );
128
129 /* Return any random value. */
130 return uxReturnBits;
131 }
132
SocketWakeupCallback_Stub(struct xSOCKET * pxSocket)133 void SocketWakeupCallback_Stub( struct xSOCKET * pxSocket )
134 {
135 __CPROVER_assert( pxSocket != NULL,
136 "The pxSocket cannot be NULL" );
137 }
138
harness()139 void harness()
140 {
141 FreeRTOS_Socket_t * pxSocket = ensure_FreeRTOS_Socket_t_is_allocated();
142
143 __CPROVER_assume( pxSocket != NULL );
144 __CPROVER_assume( pxSocket != FREERTOS_INVALID_SOCKET );
145
146 pxSocket->pxUserWakeCallback = SocketWakeupCallback_Stub;
147
148 pxSocket->pxSocketSet = safeMalloc( sizeof( struct xSOCKET_SET ) );
149
150 if( pxSocket->pxSocketSet != NULL )
151 {
152 pxSocket->pxSocketSet->xSelectGroup = safeMalloc( sizeof( struct EventGroupDef_t ) );
153
154 /* The event group cannot be NULL. */
155 __CPROVER_assume( pxSocket->pxSocketSet->xSelectGroup != NULL );
156 }
157
158 pxSocket->pxUserSemaphore = safeMalloc( sizeof( xQUEUE ) );
159
160 if( pxSocket->pxUserSemaphore != NULL )
161 {
162 /* The item size must be zero since this queue will act as a semaphore. */
163 __CPROVER_assume( pxSocket->pxUserSemaphore->uxItemSize == 0 );
164 }
165
166 pxSocket->xEventGroup = safeMalloc( sizeof( struct EventGroupDef_t ) );
167
168 /* Call to init the socket list. */
169 vNetworkSocketsInit();
170
171 vSocketWakeUpUser( pxSocket );
172 }
173