1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
|
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2026-present Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Module Manager */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#define TX_SOURCE_CODE
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
#include "tx_queue.h"
#include "tx_event_flags.h"
#include "tx_semaphore.h"
#include "tx_mutex.h"
#include "tx_block_pool.h"
#include "tx_byte_pool.h"
#include "txm_module.h"
#include "txm_module_manager_util.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_object_memory_check PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks if the object is inside a module's object pool */
/* or, if it's a privileged module, inside the module's data area. */
/* */
/* INPUT */
/* */
/* module_instance Module instance that the object */
/* belongs to */
/* object_ptr Pointer to object to check */
/* object_size Size of the object to check */
/* */
/* OUTPUT */
/* */
/* status Whether the object resides in a */
/* valid location */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_kernel_dispatch Kernel dispatch function */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_memory_check(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size)
{
/* Is the object pointer from the module manager's object pool? */
if ((_txm_module_manager_object_pool_created == TX_TRUE) &&
(object_ptr >= (ALIGN_TYPE) _txm_module_manager_object_pool.tx_byte_pool_start) &&
((object_ptr+object_size) <= (ALIGN_TYPE) (_txm_module_manager_object_pool.tx_byte_pool_start + _txm_module_manager_object_pool.tx_byte_pool_size)))
{
/* Object is from manager object pool. */
return(TX_SUCCESS);
}
/* If memory protection is not required, check if object is in module data. */
else if (!(module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION))
{
if ((object_ptr >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) &&
((object_ptr+object_size) <= (ALIGN_TYPE) module_instance -> txm_module_instance_data_end))
{
/* Object is from the local module memory. */
return(TX_SUCCESS);
}
}
/* Object is from invalid memory. */
return(TXM_MODULE_INVALID_MEMORY);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_created_object_check PORTABLE C */
/* 6.1x */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This functions checks if the specified object was created by the */
/* specified module */
/* */
/* INPUT */
/* */
/* module_instance The module instance to check */
/* object_ptr The object to check */
/* */
/* OUTPUT */
/* */
/* status Whether the module created the */
/* object */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* txm_module_manager*_stop Module manager stop functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* xx-xx-2025 William E. Lamie Modified comment(s), and */
/* removed module local memory */
/* check, resulting in */
/* version 6.1x */
/* */
/**************************************************************************/
UCHAR _txm_module_manager_created_object_check(TXM_MODULE_INSTANCE *module_instance, VOID *object_ptr)
{
TXM_MODULE_ALLOCATED_OBJECT *allocated_object_ptr;
/* Determine if the object pool has been created. */
if (_txm_module_manager_object_pool_created)
{
/* Determine if the current object is from the pool of dynamically allocated objects. */
if ((((UCHAR *) object_ptr) >= _txm_module_manager_object_pool.tx_byte_pool_start) &&
(((UCHAR *) object_ptr) < (_txm_module_manager_object_pool.tx_byte_pool_start + _txm_module_manager_object_pool.tx_byte_pool_size)))
{
/* Pickup object pointer. */
allocated_object_ptr = (TXM_MODULE_ALLOCATED_OBJECT *) object_ptr;
/* Move back to get the header information. */
allocated_object_ptr--;
/* Now determine if this object belongs to this module. */
if (allocated_object_ptr -> txm_module_allocated_object_module_instance == module_instance)
{
return TX_TRUE;
}
}
}
return TX_FALSE;
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_object_size_check PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function checks if the specified object's size matches what is */
/* inside the object pool. */
/* */
/* INPUT */
/* */
/* object_ptr Pointer to object to check */
/* object_size Size of the object to check */
/* */
/* OUTPUT */
/* */
/* status Whether the object's size matches */
/* what's inside the object pool */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_kernel_dispatch Kernel dispatch function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_size_check(ALIGN_TYPE object_ptr, ULONG object_size)
{
TXM_MODULE_ALLOCATED_OBJECT *module_allocated_object_ptr;
UINT return_value;
/* Pickup the allocated object pointer. */
module_allocated_object_ptr = ((TXM_MODULE_ALLOCATED_OBJECT *) object_ptr) - 1;
/* Does the allocated memory match the expected object size? */
if (module_allocated_object_ptr -> txm_module_object_size == object_size)
return_value = TX_SUCCESS;
else
return_value = TXM_MODULE_INVALID_MEMORY;
return(return_value);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_name_compare PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function compares the specified object names. */
/* */
/* INPUT */
/* */
/* search_name String pointer to the object's */
/* name being searched for */
/* search_name_length Length of search_name */
/* object_name String pointer to an object's name*/
/* to compare the search name to */
/* */
/* OUTPUT */
/* */
/* status Whether the names are equal */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* *_object_pointer_get Kernel dispatch function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_name_compare(CHAR *search_name, UINT search_name_length, TX_NAME_CONST CHAR *object_name)
{
CHAR search_name_char;
CHAR object_name_char;
/* Is the object name null? Note that the search name has already been checked
by the caller. */
if (object_name == TX_NULL)
{
/* The strings can't match. */
return(TX_FALSE);
}
/* Loop through the names. */
while (1)
{
/* Get the current characters from each name. */
search_name_char = *search_name;
object_name_char = *object_name;
/* Check for match. */
if (search_name_char == object_name_char)
{
/* Are they null-terminators? */
if (search_name_char == '\0')
{
/* The strings match. */
return(TX_TRUE);
}
}
else
{
/* The strings don't match. */
return(TX_FALSE);
}
/* Are we at the end of the search name? */
if (search_name_length == 0)
{
/* The strings don't match. */
return(TX_FALSE);
}
/* Move to next character. */
search_name++;
object_name++;
search_name_length--;
}
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_param_check_object_for_creation PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* William E. Lamie, RTOSX */
/* */
/* DESCRIPTION */
/* */
/* This function checks to make sure the object pointer for one of the */
/* creation APIs is valid. */
/* */
/* INPUT */
/* */
/* module_instance Requesting module instance pointer*/
/* object_ptr Address of object memory area */
/* ojbect_size Size of object memory area */
/* */
/* OUTPUT */
/* */
/* TX_TRUE Valid object pointer */
/* TX_FALSE Invalid object pointer */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* txm_module_manager_* Module manager functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2025 William E. Lamie Initial Version 6.4.3 */
/* */
/**************************************************************************/
UINT _txm_module_manager_param_check_object_for_creation(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size)
{
/* Determine if the object pointer is NULL. */
if ((void *) object_ptr == TX_NULL)
{
/* Object pointer is NULL, which is invalid. */
return(TX_FALSE);
}
/* Determine if the object pointer is inside the module object pool. */
if (TXM_MODULE_MANAGER_ENSURE_INSIDE_OBJ_POOL(module_instance, object_ptr, object_size) == TX_FALSE)
{
/* Object pointer is not inside the object pool, which is invalid. */
return(TX_FALSE);
}
/* Determine if the object size is correct. */
if (_txm_module_manager_object_size_check(object_ptr, object_size) != TX_SUCCESS)
{
/* Object size is invalid. */
return(TX_FALSE);
}
/* Determine if the ojbect has already been created. */
if (_txm_module_manager_created_object_check(module_instance, (void *) object_ptr) == TX_FALSE)
{
/* Object has already been created, which is invalid. */
return(TX_FALSE);
}
/* Everything is okay with the object, return TX_TRUE. */
return(TX_TRUE);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_param_check_object_for_use PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* William E. Lamie, RTOSX */
/* */
/* DESCRIPTION */
/* */
/* This function checks to make sure the object pointer is valid. */
/* */
/* INPUT */
/* */
/* module_instance Requesting module instance pointer*/
/* object_ptr Address of object memory area */
/* ojbect_size Size of object memory area */
/* */
/* OUTPUT */
/* */
/* TX_TRUE Valid object pointer */
/* TX_FALSE Invalid object pointer */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* txm_module_manager_* Module manager functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2025 William E. Lamie Initial Version 6.4.3 */
/* */
/**************************************************************************/
UINT _txm_module_manager_param_check_object_for_use(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size)
{
/* Determine if the object pointer is NULL. */
if ((void *) object_ptr == TX_NULL)
{
/* Object pointer is NULL, which is invalid. */
return(TX_FALSE);
}
/* Determine if the object is outside the calling module. */
if (TXM_MODULE_MANAGER_ENSURE_OUTSIDE_MODULE(module_instance, object_ptr, object_size) == TX_FALSE)
{
/* Object pointer is not outside the module, which is invalid. */
return(TX_FALSE);
}
/* Being outside the module does not make an address an object. The manager's
object pool is outside every module, so an address shifted into the interior of
one of this module's own privileged allocations satisfies the test above while
denoting no object at all, and the bytes the shifted address then presents as a
control block are bytes the module chose through ordinary create and set
services. An address in the object pool is therefore only usable if it is the
exact address the manager handed out for an allocation of this size.
This function is given a size rather than a type, so it can go no further than
that: it cannot establish which type of object it is, and it cannot authenticate
an application-owned object outside the pool. Dispatchers in this repository use
_txm_module_manager_param_check_typed_object_for_use, which does both. */
if ((_txm_module_manager_object_pool_created == TX_TRUE) &&
(object_ptr >= (ALIGN_TYPE) _txm_module_manager_object_pool.tx_byte_pool_start) &&
(object_ptr < (ALIGN_TYPE) (_txm_module_manager_object_pool.tx_byte_pool_start + _txm_module_manager_object_pool.tx_byte_pool_size)))
{
if (_txm_module_manager_allocated_object_check(module_instance, object_ptr, object_size) == TX_FALSE)
{
/* An address in the object pool that is not the exact start of one of this
module's allocations, which is invalid. */
return(TX_FALSE);
}
}
/* Define application-specific object memory check. */
#ifdef TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_CHECK
/* Bring in the application-spefic objeft memory check, defined by the user. */
TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_CHECK
#endif /* TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_ENABLE */
/* Everything is okay with the object, return TX_TRUE. */
return(TX_TRUE);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_object_type_size_get PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* Eclipse ThreadX contributors */
/* */
/* DESCRIPTION */
/* */
/* This function returns the size of the control block belonging to a */
/* module object type. It is the size a service of that type is */
/* entitled to dereference, and the size the manager recorded when it */
/* allocated object memory for that type. */
/* */
/* INPUT */
/* */
/* object_type Module object type */
/* object_size Destination for the control block */
/* size of that type */
/* */
/* OUTPUT */
/* */
/* TX_TRUE Known object type */
/* TX_FALSE Unknown object type */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_param_check_typed_object_for_use */
/* Module object authentication */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */
/* contributors */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_type_size_get(UINT object_type, ULONG *object_size)
{
UINT status;
/* Assume the type is one this manager knows. */
status = TX_TRUE;
switch (object_type)
{
case TXM_BLOCK_POOL_OBJECT:
*object_size = (ULONG) sizeof(TX_BLOCK_POOL);
break;
case TXM_BYTE_POOL_OBJECT:
*object_size = (ULONG) sizeof(TX_BYTE_POOL);
break;
case TXM_EVENT_FLAGS_OBJECT:
*object_size = (ULONG) sizeof(TX_EVENT_FLAGS_GROUP);
break;
case TXM_MUTEX_OBJECT:
*object_size = (ULONG) sizeof(TX_MUTEX);
break;
case TXM_QUEUE_OBJECT:
*object_size = (ULONG) sizeof(TX_QUEUE);
break;
case TXM_SEMAPHORE_OBJECT:
*object_size = (ULONG) sizeof(TX_SEMAPHORE);
break;
case TXM_THREAD_OBJECT:
*object_size = (ULONG) sizeof(TX_THREAD);
break;
case TXM_TIMER_OBJECT:
*object_size = (ULONG) sizeof(TX_TIMER);
break;
default:
/* Not a type the manager authenticates. Report it rather than guessing a
size, so that a caller cannot be given a range to validate that has no
relationship to the object the service will dereference. */
*object_size = ((ULONG) 0);
status = TX_FALSE;
break;
}
return(status);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_allocated_object_find PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* Eclipse ThreadX contributors */
/* */
/* DESCRIPTION */
/* */
/* This function returns the manager's private header for the object */
/* allocation an address names, or TX_NULL when the address names */
/* none of the specified module's allocations. The size the */
/* allocation was made for is reported to callers that ask for it. */
/* */
/* The allocation list is the manager's own record, built as it hands */
/* object memory out, and it is searched rather than reached through */
/* a header taken from in front of the caller's address. That order */
/* is what makes the answer both correct and safe. */
/* */
/* Correct, because the address immediately after a header is the */
/* only address in an allocation that the manager ever gave out, so */
/* an address chosen inside an allocation is distinguishable from the */
/* start of one. Reading a header cannot make that distinction: the */
/* bytes in front of an interior address are part of the object, and */
/* a module places values there through ordinary services. */
/* */
/* Safe, because the caller's address is only ever compared, never */
/* dereferenced. An address that belongs to no allocation of this */
/* module -- an object the application owns, an object another module */
/* owns, or an address nowhere near the object pool -- is rejected */
/* without a privileged read of the words in front of it. */
/* */
/* INPUT */
/* */
/* module_instance Requesting module instance pointer*/
/* object_ptr Address of object memory area */
/* object_size_ptr Address to return the size the */
/* allocation was made for, or */
/* TX_NULL to not return it */
/* */
/* OUTPUT */
/* */
/* allocation The allocation's private header, */
/* or TX_NULL when the address */
/* names none of this module's */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_allocated_object_check */
/* Module object ownership check */
/* _txm_module_manager_object_deallocate Module object deallocation */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */
/* contributors */
/* */
/**************************************************************************/
TXM_MODULE_ALLOCATED_OBJECT *_txm_module_manager_allocated_object_find(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG *object_size_ptr)
{
TX_INTERRUPT_SAVE_AREA
TXM_MODULE_ALLOCATED_OBJECT *allocated_object_ptr;
TXM_MODULE_ALLOCATED_OBJECT *found_object_ptr;
ULONG objects_examined;
/* Assume the address names none of this module's allocations. */
found_object_ptr = TX_NULL;
/* Determine if there is a module whose allocations can be searched. A request
that does not come from a module owns no allocation. */
if (module_instance == TX_NULL)
{
/* Nothing to search, and nothing to report. */
return(TX_NULL);
}
/* Disable interrupts. The allocation list is maintained by threads holding the
manager protection mutex, so a scan that runs to completion with interrupts
disabled cannot observe it being changed, and unlike taking the mutex it adds
no blocking point and no priority inversion to a kernel request. */
TX_DISABLE
allocated_object_ptr = module_instance -> txm_module_instance_object_list_head;
objects_examined = ((ULONG) 0);
/* Loop through the objects allocated to this module. The loop is bounded by the
count the manager maintains alongside the list, so the cost of one search is
bounded by the number of objects this module has allocated, and a list whose
links have been damaged cannot make the scan run on. */
while ((objects_examined < module_instance -> txm_module_instance_object_list_count) &&
(allocated_object_ptr != TX_NULL))
{
/* The address the module was given is the one immediately after the private
header, so that is the only address in this allocation that names it. */
if (((ALIGN_TYPE) (allocated_object_ptr + 1)) == object_ptr)
{
/* Found it. An address matches at most one allocation, so there is
nothing further to look at. */
found_object_ptr = allocated_object_ptr;
/* Report the size this allocation was made for, if the caller asked for
it. It is read here, inside the scan, so that the answer cannot be
taken from a header that stopped being one after the search. */
if (object_size_ptr != TX_NULL)
{
*object_size_ptr = allocated_object_ptr -> txm_module_object_size;
}
break;
}
/* Move to the next allocated object. */
objects_examined++;
allocated_object_ptr = allocated_object_ptr -> txm_module_allocated_object_next;
}
/* Restore interrupts. */
TX_RESTORE
return(found_object_ptr);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_allocated_object_check PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* Eclipse ThreadX contributors */
/* */
/* DESCRIPTION */
/* */
/* This function determines whether an address is the exact address */
/* the manager handed the specified module for one of its object */
/* allocations, and whether that allocation is the size the caller */
/* expects. */
/* */
/* This is the question of ownership, and it is deliberately a */
/* separate question from whether an object is there at all. A */
/* module may hold, and legitimately use, a pointer to an object it */
/* does not own: the manager hands application-owned objects to */
/* modules by name through its object lookup service, and sharing an */
/* object is what that service is for. Destroying one is not sharing */
/* it, so the delete services ask this question in addition to the */
/* ones that establish that the address denotes a usable object. */
/* */
/* INPUT */
/* */
/* module_instance Requesting module instance pointer*/
/* object_ptr Address of object memory area */
/* object_size Expected size of the allocation */
/* */
/* OUTPUT */
/* */
/* TX_TRUE An exact allocation of that size */
/* TX_FALSE Anything else */
/* */
/* CALLS */
/* */
/* _txm_module_manager_allocated_object_find */
/* Find the module's allocation */
/* */
/* CALLED BY */
/* */
/* txm_module_manager_* Module manager functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */
/* contributors */
/* */
/**************************************************************************/
UINT _txm_module_manager_allocated_object_check(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size)
{
ULONG allocated_size;
UINT status;
/* Assume the address is not one of this module's allocations. */
status = TX_FALSE;
/* Initialize the size, so that nothing is read if no allocation is found. */
allocated_size = ((ULONG) 0);
/* Determine if the address is the exact start of one of this module's
allocations. */
if (_txm_module_manager_allocated_object_find(module_instance, object_ptr, &allocated_size) != TX_NULL)
{
/* Is the allocation the size the caller expects? An allocation made for a
smaller object does not become a larger one because a service was asked
to treat it as one. */
if (allocated_size == object_size)
{
status = TX_TRUE;
}
}
return(status);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_param_check_typed_object_for_use */
/* PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* Eclipse ThreadX contributors */
/* */
/* DESCRIPTION */
/* */
/* This function authenticates a kernel object a module has named, */
/* before a privileged service is allowed to dereference it. It */
/* establishes that the address is the exact address of a live kernel */
/* object of the type the service expects. */
/* */
/* The address is accepted only if it is on the kernel's created list */
/* for that type. That list is the record the create and delete */
/* services maintain, so being on it establishes at once that the */
/* address is an object start rather than an address inside an object, */
/* that the object is of this type, and that it has not been deleted. */
/* It is also how an object the application created and shared with a */
/* module is authenticated, since the manager allocated no such object */
/* and has no record of its own to consult. */
/* */
/* Nothing a module can influence is used to establish a type. In */
/* particular the control block ID is not, on its own, evidence of */
/* anything: a module can arrange for the value of an ID to appear */
/* inside an object it legitimately owns, which is what lets a shifted */
/* pointer pass an ID test, and distinct object types of equal size */
/* exist, so an ID is not even a type at an address known to be an */
/* object start. It is checked, after the created list has settled the */
/* question, because it is the check the _txe_ services make and it is */
/* compiled away with them under TX_DISABLE_ERROR_CHECKING. */
/* */
/* INPUT */
/* */
/* module_instance Requesting module instance pointer*/
/* object_ptr Address of object memory area */
/* object_type Module object type the service */
/* expects */
/* */
/* OUTPUT */
/* */
/* TX_TRUE Authenticated object pointer */
/* TX_FALSE Invalid object pointer */
/* */
/* CALLS */
/* */
/* _txm_module_manager_object_type_size_get */
/* Get control block size */
/* _txm_module_manager_created_object_type_check */
/* Check kernel created list */
/* _txm_module_manager_object_id_check Check control block ID */
/* */
/* CALLED BY */
/* */
/* txm_module_manager_* Module manager functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */
/* contributors */
/* */
/**************************************************************************/
UINT _txm_module_manager_param_check_typed_object_for_use(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, UINT object_type)
{
ULONG object_size;
UINT exact_object;
/* Determine if the object pointer is NULL. */
if ((void *) object_ptr == TX_NULL)
{
/* Object pointer is NULL, which is invalid. */
return(TX_FALSE);
}
/* Pickup the size of the control block this type of service dereferences. */
if (_txm_module_manager_object_type_size_get(object_type, &object_size) == TX_FALSE)
{
/* Not an object type this manager authenticates, so it cannot be used. */
return(TX_FALSE);
}
/* Determine if the object is outside the calling module. A kernel object inside
the module's own memory is one the module can write behind the kernel's back,
so it is rejected here as it always has been. This also rejects a size that
wraps when added to the address. */
if (TXM_MODULE_MANAGER_ENSURE_OUTSIDE_MODULE(module_instance, object_ptr, object_size) == TX_FALSE)
{
/* Object pointer is not outside the module, which is invalid. */
return(TX_FALSE);
}
/* Establish that the address is the exact address of a live object of this type,
from the kernel's created list for the type. That list is the record the create
and delete services maintain, so being on it establishes at once that the
address is an object start, that the object is of this type, and that it has not
been deleted.
It is deliberately the only ground on which an address is accepted. The
manager's own allocation list would establish the address and the size of an
object a module allocated, and would do it by walking a shorter list, but it
records no type, and the type cannot then be taken from the control block
itself: distinct object types of equal size exist -- on a 32-bit target a byte
pool, a mutex and a timer are all the same size -- so a control block whose ID
has been made to read as one of them would be accepted as that type. Nothing a
module can influence is used to establish a type.
The address is not dereferenced to reach this decision. An address a module
named is not read until a kernel record says there is an object there. */
exact_object = _txm_module_manager_created_object_type_check(object_ptr, object_type);
if (exact_object == TX_FALSE)
{
/* The address is not the start of a live object of this type. */
return(TX_FALSE);
}
/* The address is a live object of the requested type. Confirm it against the
control block's own ID, which is the check the _txe_ services would make and
which is compiled away with them under TX_DISABLE_ERROR_CHECKING. */
if (_txm_module_manager_object_id_check(object_ptr, object_type) == TX_FALSE)
{
/* The created list and the control block disagree, so the object is not in a
state the manager is prepared to vouch for. */
return(TX_FALSE);
}
/* Define application-specific object memory check. */
#ifdef TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_CHECK
/* Bring in the application-spefic objeft memory check, defined by the user. */
TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_CHECK
#endif /* TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_ENABLE */
/* Everything is okay with the object, return TX_TRUE. */
return(TX_TRUE);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_created_object_type_check PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* Eclipse ThreadX contributors */
/* */
/* DESCRIPTION */
/* */
/* This function determines whether an address is the exact address */
/* of an object on the kernel's created list for a module object type. */
/* */
/* The created list is the record the create and delete services */
/* maintain, so being on it establishes at once that the address is an */
/* object start rather than an address inside an object, that the */
/* object is of this type, and that it has not been deleted. It is */
/* also the only record of an object the application created and */
/* shared with a module, since the manager allocated no such object. */
/* */
/* Nothing the module can influence is consulted. In particular the */
/* control block ID is not: a module can arrange for the value of an */
/* ID to appear inside memory it owns, and distinct object types of */
/* equal size exist, so an ID is not evidence that an object is there */
/* nor of what type it is. */
/* */
/* INPUT */
/* */
/* object_ptr Address of object memory area */
/* object_type Module object type */
/* */
/* OUTPUT */
/* */
/* TX_TRUE A created object of that type */
/* TX_FALSE Anything else */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_live_object_check Module object liveness check */
/* _txm_module_manager_param_check_typed_object_for_use */
/* Module object authentication */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */
/* contributors */
/* */
/**************************************************************************/
UINT _txm_module_manager_created_object_type_check(ALIGN_TYPE object_ptr, UINT object_type)
{
TX_INTERRUPT_SAVE_AREA
ULONG objects_examined;
ULONG objects_created;
ALIGN_TYPE candidate_ptr;
UINT status;
TX_BLOCK_POOL *block_pool_ptr;
TX_BYTE_POOL *byte_pool_ptr;
TX_EVENT_FLAGS_GROUP *event_flags_ptr;
TX_MUTEX *mutex_ptr;
TX_QUEUE *queue_ptr;
TX_SEMAPHORE *semaphore_ptr;
TX_THREAD *thread_ptr;
TX_TIMER *timer_ptr;
/* Assume the address is not on the created list for this type. */
status = TX_FALSE;
/* Disable interrupts. The created lists are maintained with interrupts disabled,
so a scan that runs to completion this way sees a consistent list, and it adds
no blocking point to a kernel request. The cost of one check is bounded by the
number of objects of this type the system has created, which is the price of
authenticating an object the manager did not allocate; a module using its own
allocated objects does not reach this function. */
TX_DISABLE
/* Start each list from its head and pick up the count that bounds the walk, so a
list whose links have been damaged cannot make the scan run on. */
switch (object_type)
{
case TXM_BLOCK_POOL_OBJECT:
block_pool_ptr = _tx_block_pool_created_ptr;
objects_created = _tx_block_pool_created_count;
objects_examined = ((ULONG) 0);
while ((objects_examined < objects_created) && (block_pool_ptr != TX_NULL))
{
candidate_ptr = (ALIGN_TYPE) block_pool_ptr;
if (candidate_ptr == object_ptr)
{
status = TX_TRUE;
break;
}
objects_examined++;
block_pool_ptr = block_pool_ptr -> tx_block_pool_created_next;
}
break;
case TXM_BYTE_POOL_OBJECT:
byte_pool_ptr = _tx_byte_pool_created_ptr;
objects_created = _tx_byte_pool_created_count;
objects_examined = ((ULONG) 0);
while ((objects_examined < objects_created) && (byte_pool_ptr != TX_NULL))
{
candidate_ptr = (ALIGN_TYPE) byte_pool_ptr;
if (candidate_ptr == object_ptr)
{
status = TX_TRUE;
break;
}
objects_examined++;
byte_pool_ptr = byte_pool_ptr -> tx_byte_pool_created_next;
}
break;
case TXM_EVENT_FLAGS_OBJECT:
event_flags_ptr = _tx_event_flags_created_ptr;
objects_created = _tx_event_flags_created_count;
objects_examined = ((ULONG) 0);
while ((objects_examined < objects_created) && (event_flags_ptr != TX_NULL))
{
candidate_ptr = (ALIGN_TYPE) event_flags_ptr;
if (candidate_ptr == object_ptr)
{
status = TX_TRUE;
break;
}
objects_examined++;
event_flags_ptr = event_flags_ptr -> tx_event_flags_group_created_next;
}
break;
case TXM_MUTEX_OBJECT:
mutex_ptr = _tx_mutex_created_ptr;
objects_created = _tx_mutex_created_count;
objects_examined = ((ULONG) 0);
while ((objects_examined < objects_created) && (mutex_ptr != TX_NULL))
{
candidate_ptr = (ALIGN_TYPE) mutex_ptr;
if (candidate_ptr == object_ptr)
{
status = TX_TRUE;
break;
}
objects_examined++;
mutex_ptr = mutex_ptr -> tx_mutex_created_next;
}
break;
case TXM_QUEUE_OBJECT:
queue_ptr = _tx_queue_created_ptr;
objects_created = _tx_queue_created_count;
objects_examined = ((ULONG) 0);
while ((objects_examined < objects_created) && (queue_ptr != TX_NULL))
{
candidate_ptr = (ALIGN_TYPE) queue_ptr;
if (candidate_ptr == object_ptr)
{
status = TX_TRUE;
break;
}
objects_examined++;
queue_ptr = queue_ptr -> tx_queue_created_next;
}
break;
case TXM_SEMAPHORE_OBJECT:
semaphore_ptr = _tx_semaphore_created_ptr;
objects_created = _tx_semaphore_created_count;
objects_examined = ((ULONG) 0);
while ((objects_examined < objects_created) && (semaphore_ptr != TX_NULL))
{
candidate_ptr = (ALIGN_TYPE) semaphore_ptr;
if (candidate_ptr == object_ptr)
{
status = TX_TRUE;
break;
}
objects_examined++;
semaphore_ptr = semaphore_ptr -> tx_semaphore_created_next;
}
break;
case TXM_THREAD_OBJECT:
thread_ptr = _tx_thread_created_ptr;
objects_created = _tx_thread_created_count;
objects_examined = ((ULONG) 0);
while ((objects_examined < objects_created) && (thread_ptr != TX_NULL))
{
candidate_ptr = (ALIGN_TYPE) thread_ptr;
if (candidate_ptr == object_ptr)
{
status = TX_TRUE;
break;
}
objects_examined++;
thread_ptr = thread_ptr -> tx_thread_created_next;
}
break;
case TXM_TIMER_OBJECT:
timer_ptr = _tx_timer_created_ptr;
objects_created = _tx_timer_created_count;
objects_examined = ((ULONG) 0);
while ((objects_examined < objects_created) && (timer_ptr != TX_NULL))
{
candidate_ptr = (ALIGN_TYPE) timer_ptr;
if (candidate_ptr == object_ptr)
{
status = TX_TRUE;
break;
}
objects_examined++;
timer_ptr = timer_ptr -> tx_timer_created_next;
}
break;
default:
/* Not a type the manager authenticates. */
break;
}
/* Restore interrupts. */
TX_RESTORE
return(status);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_object_id_check PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* Eclipse ThreadX contributors */
/* */
/* DESCRIPTION */
/* */
/* This function determines whether the control block at an object */
/* start carries the ID of a module object type. The kernel writes */
/* that ID when it creates an object and clears it when it deletes */
/* one, so at an address already established to be an object start the */
/* ID reports both the type and whether the object is still created. */
/* */
/* This check must not be used on its own to decide that an address is */
/* an object. A module can place the value of an ID inside an object */
/* it legitimately owns, so an ID found at an address the manager has */
/* not otherwise authenticated proves nothing. */
/* */
/* The check matters most where the error checking layer is absent: */
/* with TX_DISABLE_ERROR_CHECKING the _txe_ services that would */
/* otherwise test the ID are compiled away, and this is then the only */
/* ID test between a module and a privileged dereference. */
/* */
/* INPUT */
/* */
/* object_ptr Address of an object start */
/* object_type Module object type */
/* */
/* OUTPUT */
/* */
/* TX_TRUE A created object of that type */
/* TX_FALSE Anything else */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_param_check_typed_object_for_use */
/* Module object authentication */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */
/* contributors */
/* */
/**************************************************************************/
UINT _txm_module_manager_object_id_check(ALIGN_TYPE object_ptr, UINT object_type)
{
TX_INTERRUPT_SAVE_AREA
ULONG object_id;
ULONG expected_id;
UINT status;
/* Read the ID through a pointer to the type the caller named, so that the field
read is the one that type declares rather than an assumed offset. */
TX_DISABLE
switch (object_type)
{
case TXM_BLOCK_POOL_OBJECT:
object_id = ((TX_BLOCK_POOL *) object_ptr) -> tx_block_pool_id;
expected_id = TX_BLOCK_POOL_ID;
break;
case TXM_BYTE_POOL_OBJECT:
object_id = ((TX_BYTE_POOL *) object_ptr) -> tx_byte_pool_id;
expected_id = TX_BYTE_POOL_ID;
break;
case TXM_EVENT_FLAGS_OBJECT:
object_id = ((TX_EVENT_FLAGS_GROUP *) object_ptr) -> tx_event_flags_group_id;
expected_id = TX_EVENT_FLAGS_ID;
break;
case TXM_MUTEX_OBJECT:
object_id = ((TX_MUTEX *) object_ptr) -> tx_mutex_id;
expected_id = TX_MUTEX_ID;
break;
case TXM_QUEUE_OBJECT:
object_id = ((TX_QUEUE *) object_ptr) -> tx_queue_id;
expected_id = TX_QUEUE_ID;
break;
case TXM_SEMAPHORE_OBJECT:
object_id = ((TX_SEMAPHORE *) object_ptr) -> tx_semaphore_id;
expected_id = TX_SEMAPHORE_ID;
break;
case TXM_THREAD_OBJECT:
object_id = ((TX_THREAD *) object_ptr) -> tx_thread_id;
expected_id = TX_THREAD_ID;
break;
case TXM_TIMER_OBJECT:
object_id = ((TX_TIMER *) object_ptr) -> tx_timer_id;
expected_id = TX_TIMER_ID;
break;
default:
/* Not a type the manager authenticates. Choose values that cannot match. */
object_id = TX_CLEAR_ID;
expected_id = ~((ULONG) TX_CLEAR_ID);
break;
}
/* Restore interrupts. */
TX_RESTORE
if (object_id == expected_id)
{
status = TX_TRUE;
}
else
{
status = TX_FALSE;
}
return(status);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_live_object_check PORTABLE C */
/* 6.4.3 */
/* AUTHOR */
/* */
/* Eclipse ThreadX contributors */
/* */
/* DESCRIPTION */
/* */
/* This function determines whether an address is the exact address */
/* of a live kernel object of any type the Module Manager knows. */
/* */
/* It answers the question object deallocation has to ask before it */
/* gives memory back: is the kernel still going to use these bytes as */
/* a control block. Deallocation is told an address and nothing else, */
/* so unlike the checks a typed service makes it cannot be given the */
/* type to look for, and every type has to be looked for in turn. */
/* */
/* The eight created lists are searched whatever the size of the */
/* allocation at the address. Skipping a type whose control block is */
/* larger than the allocation would be sound only if every object had */
/* been created through a size-checked path, and a module running */
/* without memory protection creates objects without one. */
/* */
/* Each list is searched in its own interrupts-disabled window rather */
/* than all of them in one, so the longest window is bounded by the */
/* number of objects of a single type. The whole search costs one pass */
/* over the objects the system has created, and is paid once per */
/* object deallocation. */
/* */
/* INPUT */
/* */
/* object_ptr Address of object memory area */
/* */
/* OUTPUT */
/* */
/* TX_TRUE A live kernel object is there */
/* TX_FALSE Anything else */
/* */
/* CALLS */
/* */
/* _txm_module_manager_created_object_type_check */
/* Check one kernel created list */
/* */
/* CALLED BY */
/* */
/* _txm_module_manager_object_deallocate Deallocate object memory */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */
/* contributors */
/* */
/**************************************************************************/
UINT _txm_module_manager_live_object_check(ALIGN_TYPE object_ptr)
{
UINT object_type;
UINT status;
/* Assume no live object is there. */
status = TX_FALSE;
/* The eight module object types that have a kernel created list occupy a
contiguous range, so each is asked in turn by walking the range. A value in
the range that the per-type check does not recognise answers TX_FALSE, so a
type the manager stops knowing does not silently pass this search. */
for (object_type = ((UINT) TXM_BLOCK_POOL_OBJECT); object_type <= ((UINT) TXM_TIMER_OBJECT); object_type++)
{
if (_txm_module_manager_created_object_type_check(object_ptr, object_type) == TX_TRUE)
{
/* An address is the start of at most one object, so there is nothing
further to look for. */
status = TX_TRUE;
break;
}
}
return(status);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_util_code_allocation_size_and_alignment_get */
/* PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function returns the required alignment and allocation size */
/* for a module's code area. */
/* */
/* INPUT */
/* */
/* module_preamble Preamble of module to return code */
/* values for */
/* code_alignment_dest Address to return code alignment */
/* code_allocation_size_desk Address to return code allocation */
/* size */
/* */
/* OUTPUT */
/* */
/* status Success if no math overflow */
/* occurred during calculation */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* txm_module_manager_*_load Module load functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* */
/**************************************************************************/
UINT _txm_module_manager_util_code_allocation_size_and_alignment_get(TXM_MODULE_PREAMBLE *module_preamble,
ULONG *code_alignment_dest, ULONG *code_allocation_size_dest)
{
ULONG code_size;
ULONG code_alignment;
ULONG data_size_ignored;
ULONG data_alignment_ignored;
/* Pickup the module code size. */
code_size = module_preamble -> txm_module_preamble_code_size;
/* Adjust the size of the module elements to be aligned to the default alignment. */
TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(code_size, TXM_MODULE_CODE_ALIGNMENT, code_size);
code_size = ((code_size - 1)/TXM_MODULE_CODE_ALIGNMENT) * TXM_MODULE_CODE_ALIGNMENT;
/* Setup the default code and data alignments. */
code_alignment = (ULONG) TXM_MODULE_CODE_ALIGNMENT;
/* Get the port-specific alignment for the code size. Note we only want code so we pass 'null' values for data. */
data_size_ignored = 1;
data_alignment_ignored = 1;
TXM_MODULE_MANAGER_ALIGNMENT_ADJUST(module_preamble, code_size, code_alignment, data_size_ignored, data_alignment_ignored)
/* Calculate the code memory allocation size. */
TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(code_size, code_alignment, *code_allocation_size_dest);
/* Write the alignment result into the caller's destination address. */
*code_alignment_dest = code_alignment;
/* Return success. */
return(TX_SUCCESS);
}
|