1#include <platformdefines.h>
2#include <xplatform.h>
3
4inline char* CoStrDup(const char* str)
5{
6 size_t size = strlen(str) + 1;
7 char* dup = (char *)CoreClrAlloc(size);
8 if (dup != nullptr)
9 {
10 strcpy_s(dup, size, str);
11 }
12 return dup;
13}
14
15const int NumArrElements = 2;
16struct InnerSequential
17{
18 int f1;
19 float f2;
20 LPCSTR f3;
21};
22void PrintInnerSequential(InnerSequential* p, char const * name)
23{
24 printf("\t%s.f1 = %d\n", name, p->f1);
25 printf("\t%s.f2 = %f\n", name, p->f2);
26 printf("\t%s.f3 = %s\n", name, p->f3);
27}
28
29void ChangeInnerSequential(InnerSequential* p)
30{
31 p->f1 = 77;
32 p->f2 = 77.0;
33 p->f3 = CoStrDup("changed string");
34}
35
36bool IsCorrectInnerSequential(InnerSequential* p)
37{
38 if(p->f1 != 1)
39 return false;
40 if(p->f2 != 1.0)
41 return false;
42 if(strcmp(p->f3, "") != 0)
43 return false;
44
45 return true;
46}
47
48#ifndef WINDOWS
49typedef int INT;
50typedef unsigned int UINT;
51typedef short SHORT;
52typedef char CHAR;
53typedef unsigned short WORD;
54typedef short SHORT;
55typedef float FLOAT;
56typedef double DOUBLE;
57#endif
58
59struct INNER2 // size = 12 bytes
60{
61 INT f1;
62 FLOAT f2;
63 LPCSTR f3;
64};
65void ChangeINNER2(INNER2* p)
66{
67 p->f1 = 77;
68 p->f2 = 77.0;
69 p->f3 = CoStrDup("changed string");
70}
71void PrintINNER2(INNER2* p, char const * name)
72{
73 printf("\t%s.f1 = %d\n", name, p->f1);
74 printf("\t%s.f2 = %f\n", name, p->f2);
75 printf("\t%s.f3 = %s\n", name, p->f3);
76}
77bool IsCorrectINNER2(INNER2* p)
78{
79 if(p->f1 != 1)
80 return false;
81 if(p->f2 != 1.0)
82 return false;
83 if(memcmp(p->f3, "some string",11*sizeof(char)) != 0 )
84 return false;
85 return true;
86}
87
88
89struct InnerExplicit
90{
91 #ifdef WINDOWS
92 union
93 {
94 INT f1;
95 FLOAT f2;
96 };
97 CHAR _unused0[4];
98 LPCSTR f3;
99 #endif
100
101 #ifndef WINDOWS
102 union
103 {
104 INT f1;
105 FLOAT f2;
106 };
107 INT _unused0;
108 LPCSTR f3;
109 #endif
110};
111
112
113void PrintInnerExplicit(InnerExplicit* p, char const * name)
114{
115 printf("\t%s.f1 = %d\n", name, p->f1);
116 printf("\t%s.f2 = %f\n", name, p->f2);
117 printf("\t%s.f3 = %s\n", name, p->f3);
118}
119
120void ChangeInnerExplicit(InnerExplicit* p)
121{
122 p->f1 = 77;
123 p->f3 = CoStrDup("changed string");
124}
125
126struct InnerArraySequential
127{
128 InnerSequential arr[NumArrElements];
129};
130
131void PrintInnerArraySequential(InnerArraySequential* p, char const * name)
132{
133 for(int i = 0; i < NumArrElements; i++)
134 {
135 printf("\t%s.arr[%d].f1 = %d\n", name, i, (p->arr)[i].f1);
136 printf("\t%s.arr[%d].f2 = %f\n", name, i, (p->arr)[i].f2);
137 printf("\t%s.arr[%d].f3 = %s\n", name, i, (p->arr)[i].f3);
138 }
139}
140
141void ChangeInnerArraySequential(InnerArraySequential* p)
142{
143 for(int i = 0; i < NumArrElements; i++)
144 {
145 (p->arr)[i].f1 = 77;
146 (p->arr)[i].f2 = 77.0;
147 (p->arr)[i].f3 = CoStrDup("changed string");
148 }
149}
150
151bool IsCorrectInnerArraySequential(InnerArraySequential* p)
152{
153 for(int i = 0; i < NumArrElements; i++)
154 {
155 if( (p->arr)[i].f1 != 1 )
156 return false;
157 if( (p->arr)[i].f2 != 1.0 )
158 return false;
159 }
160 return true;
161}
162
163
164union InnerArrayExplicit // size = 32 bytes
165{
166 struct InnerSequential arr[2];
167 struct
168 {
169 LONG64 _unused0;
170 LPCSTR f4;
171 } s;
172};
173
174
175#ifdef WINDOWS
176 #ifdef _WIN64
177 #pragma warning(push)
178 #pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union
179 union OUTER3 // size = 32 bytes
180 {
181 struct InnerSequential arr[2];
182 struct
183 {
184 CHAR _unused0[24];
185 LPCSTR f4;
186 };
187 };
188 #pragma warning(pop)
189 #else
190 struct OUTER3 // size = 28 bytes
191 {
192 struct InnerSequential arr[2];
193 LPCSTR f4;
194 };
195 #endif
196#endif
197
198#ifndef WINDOWS
199 struct OUTER3 // size = 28 bytes
200 {
201 struct InnerSequential arr[2];
202 LPCSTR f4;
203 };
204#endif
205
206void PrintOUTER3(OUTER3* p, char const * name)
207{
208 for(int i = 0; i < NumArrElements; i++)
209 {
210 printf("\t%s.arr[%d].f1 = %d\n", name, i, (p->arr)[i].f1);
211 printf("\t%s.arr[%d].f2 = %f\n", name, i, (p->arr)[i].f2);
212 printf("\t%s.arr[%d].f3 = %s\n", name, i, (p->arr)[i].f3);
213 }
214 printf("\t%s.f4 = %s\n",name,p->f4);
215}
216void ChangeOUTER3(OUTER3* p)
217{
218 for(int i = 0; i < NumArrElements; i++)
219 {
220 (p->arr)[i].f1 = 77;
221 (p->arr)[i].f2 = 77.0;
222 (p->arr)[i].f3 = CoStrDup("changed string");
223 }
224
225 p->f4 = CoStrDup("changed string");
226}
227bool IsCorrectOUTER3(OUTER3* p)
228{
229 for(int i = 0; i < NumArrElements; i++)
230 {
231 if( (p->arr)[i].f1 != 1 )
232 return false;
233 if( (p->arr)[i].f2 != 1.0 )
234 return false;
235 if( memcmp((p->arr)[i].f3, "some string",11*sizeof(char)) != 0 )
236 return false;
237 }
238 if(memcmp(p->f4,"some string",11*sizeof(char)) != 0)
239 {
240 return false;
241 }
242 return true;
243}
244
245struct CharSetAnsiSequential
246{
247 LPCSTR f1;
248 char f2;
249};
250
251void PrintCharSetAnsiSequential(CharSetAnsiSequential* p, char const * name)
252{
253 printf("\t%s.f1 = %s\n", name, p->f1);
254 printf("\t%s.f2 = %c\n", name, p->f2);
255}
256
257void ChangeCharSetAnsiSequential(CharSetAnsiSequential* p)
258{
259 p->f1 = CoStrDup("change string");
260 p->f2 = 'n';
261}
262
263bool IsCorrectCharSetAnsiSequential(CharSetAnsiSequential* p)
264{
265 if(strcmp((char*)p->f1, (char*)"some string") != 0 )
266 return false;
267 if(p->f2 != 'c')
268 return false;
269 return true;
270}
271
272
273struct CharSetUnicodeSequential
274{
275 LPCWSTR f1;
276 WCHAR f2;
277};
278void PrintCharSetUnicodeSequential(CharSetUnicodeSequential* p, char const * name)
279{
280#ifdef _WIN32
281 wprintf(L"\t%S.f1 = %s\n", name, p->f1);
282#else
283 wprintf(L"\t%s.f1 = %S\n", name, p->f1);
284#endif
285 printf("\t%s.f2 = %c\n", name, p->f2);
286}
287
288void ChangeCharSetUnicodeSequential(CharSetUnicodeSequential* p)
289{
290#ifdef _WIN32
291 LPCWSTR strSource = L"change string";
292#else
293 LPCWSTR strSource = u"change string";
294#endif
295 size_t len = wcslen(strSource);
296 LPCWSTR temp = (LPCWSTR)CoreClrAlloc(sizeof(WCHAR)*(len+1));
297 if(temp != NULL)
298 {
299 wcscpy_s((WCHAR*)temp, (len+1), strSource);
300 p->f1 = temp;
301 p->f2 = L'n';
302 }
303 else
304 {
305 printf("Memory Allocated Failed!");
306 }
307}
308
309bool IsCorrectCharSetUnicodeSequential(CharSetUnicodeSequential* p)
310{
311#ifdef _WIN32
312 LPCWSTR expected= L"some string";
313#else
314 LPCWSTR expected= u"some string";
315#endif
316 LPCWSTR actual = p->f1;
317 if(0 != TP_wcmp_s((WCHAR*)actual, (WCHAR*)expected))
318 {
319 return false;
320 }
321 if(p->f2 != L'c')
322 {
323 return false;
324 }
325 return true;
326}
327
328
329struct NumberSequential // size = 64 bytes
330{
331 LONG64 i64;
332 ULONG64 ui64;
333 DOUBLE d;
334 INT i32;
335 UINT ui32;
336 SHORT s1;
337 WORD us1;
338 SHORT i16;
339 WORD ui16;
340 FLOAT sgl;
341 BYTE b;
342 CHAR sb;
343};
344void PrintNumberSequential(NumberSequential* str, char const * name)
345{
346 printf("\t%s.i32 = %d\n", name, str->i32);
347 printf("\t%s.ui32 = %d\n", name, str->ui32);
348 printf("\t%s.s1 = %d\n", name, str->s1);
349 printf("\t%s.us1 = %u\n", name, str->us1);
350 printf("\t%s.b = %u\n", name, str->b);
351 printf("\t%s.sb = %d\n", name, str->sb);
352 printf("\t%s.i16 = %d\n", name, str->i16);
353 printf("\t%s.ui16 = %u\n", name, str->ui16);
354 printf("\t%s.i64 = %lld\n", name, str->i64);
355 printf("\t%s.ui64 = %llu\n", name, str->ui64);
356 printf("\t%s.sgl = %f\n", name, str->sgl);
357 printf("\t%s.d = %f\n",name, str->d);
358}
359void ChangeNumberSequential(NumberSequential* p)
360{
361 p->i32 = 0;
362 p->ui32 = 32;
363 p->s1 = 0;
364 p->us1 = 16;
365 p->b = 0;
366 p->sb = 8;
367 p->i16 = 0;
368 p->ui16 = 16;
369 p->i64 = 0;
370 p->ui64 = 64;
371 p->sgl = 64.0;
372 p->d = 6.4;
373}
374
375bool IsCorrectNumberSequential(NumberSequential* p)
376{
377 if(p->i32 != (-0x7fffffff - 1) || p->ui32 != 0xffffffff || p->s1 != -0x8000 || p->us1 != 0xffff || p->b != 0 ||
378 p->sb != 0x7f ||p->i16 != -0x8000 || p->ui16 != 0xffff || p->i64 != -1234567890 ||
379 p->ui64 != 1234567890 || (p->sgl) != 32.0 || p->d != 3.2)
380 {
381 return false;
382 }
383 return true;
384}
385
386struct S3 // size = 1032 bytes
387{
388 BOOL flag;
389 LPCSTR str;
390 INT vals[256];
391};
392
393void PrintS3(S3* str, char const * name)
394{
395 printf("\t%s.flag = %d\n", name, str->flag);
396 printf("\t%s.str = %s\n", name, str->str);
397 for(int i = 0; i<256 ;i++)
398 {
399 printf("\t%s.vals[%d] = %d\n",name,i,str->vals[i]);
400 }
401}
402
403void ChangeS3(S3* p)
404{
405 p->flag = false;
406
407 /*CoreClrFree((void *)p->str);*/
408 p->str = CoStrDup("change string");
409
410 for(int i = 1;i<257;i++)
411 {
412 p->vals[i-1] = i;
413 }
414}
415
416bool IsCorrectS3(S3* p)
417{
418 int iflag = 0;
419
420 if (!p->flag || strcmp(p->str, "") != 0)
421 return false;
422 for (int i = 0; i < 256; i++)
423 {
424 if (p->vals[i] != i)
425 {
426 printf("\tThe Index of %i is not expected",i);
427 iflag++;
428 }
429 }
430 if (iflag != 0)
431 {
432 return false;
433 }
434 return true;
435}
436
437struct S4 // size = 8 bytes
438{
439 INT age;
440 LPCSTR name;
441};
442enum Enum1
443{
444 e1 = 1,
445 e2 = 3
446};
447struct S5 // size = 8 bytes
448{
449 struct S4 s4;
450 Enum1 ef;
451};
452
453void PrintS5(S5* str, char const * name)
454{
455 printf("\t%s.s4.age = %d", name, str->s4.age);
456 printf("\t%s.s4.name = %s", name, str->s4.name);
457 printf("\t%s.ef = %d", name, str->ef);
458}
459void ChangeS5(S5* str)
460{
461 str->s4.name = CoStrDup("change string");
462 str->s4.age = 64;
463 str->ef = e2;
464}
465bool IsCorrectS5(S5* str)
466{
467 if(str->s4.age != 32 || strcmp(str->s4.name, "") != 0)
468 return false;
469 if(str->ef != e1)
470 return false;
471 return true;
472}
473
474struct StringStructSequentialAnsi // size = 8 bytes
475{
476 LPCSTR first;
477 LPCSTR last;
478};
479
480void PrintStringStructSequentialAnsi(StringStructSequentialAnsi* str, char const * name)
481{
482 printf("\t%s.first = %s\n", name, str->first);
483 printf("\t%s.last = %s\n", name, str->last);
484}
485
486bool IsCorrectStringStructSequentialAnsi(StringStructSequentialAnsi* str)
487{
488 char strOne[512];
489 char strTwo[512];
490 for(int i = 0;i<512;i++)
491 {
492 strOne[i] = 'a';
493 strTwo[i] = 'b';
494 }
495
496 if(memcmp(str->first,strOne,512)!= 0)
497 return false;
498
499 if(memcmp(str->last,strTwo,512)!= 0)
500 return false;
501
502 return true;
503}
504
505void ChangeStringStructSequentialAnsi(StringStructSequentialAnsi* str)
506{
507 char* newFirst = (char*)CoreClrAlloc(sizeof(char)*513);
508 char* newLast = (char*)CoreClrAlloc(sizeof(char)*513);
509 for (int i = 0; i < 512; ++i)
510 {
511 newFirst[i] = 'b';
512 newLast[i] = 'a';
513 }
514 newFirst[512] = '\0';
515 newLast[512] = '\0';
516
517 str->first = newFirst;
518 str->last = newLast;
519}
520
521struct StringStructSequentialUnicode // size = 8 bytes
522{
523 LPCWSTR first;
524 LPCWSTR last;
525};
526
527void PrintStringStructSequentialUnicode(StringStructSequentialUnicode* str, char const * name)
528{
529#ifdef _WIN32
530 wprintf(L"\t%S.first = %s\n", name, str->first);
531 wprintf(L"\t%S.last = %s\n", name, str->last);
532#else
533 wprintf(L"\t%s.first = %s\n", name, str->first);
534 wprintf(L"\t%s.last = %s\n", name, str->last);
535#endif
536}
537
538bool IsCorrectStringStructSequentialUnicode(StringStructSequentialUnicode* str)
539{
540 WCHAR strOne[256+1];
541 WCHAR strTwo[256+1];
542
543 for(int i = 0;i<256;++i)
544 {
545 strOne[i] = L'a';
546 strTwo[i] = L'b';
547 }
548 strOne[256] = L'\0';
549 strTwo[256] = L'\0';
550
551 if(memcmp(str->first,strOne,256*sizeof(WCHAR)) != 0)
552 return false;
553 if(memcmp(str->last,strTwo,256*sizeof(WCHAR)) != 0)
554 return false;
555 return true;
556}
557
558void ChangeStringStructSequentialUnicode(StringStructSequentialUnicode* str)
559{
560 WCHAR* newFirst = (WCHAR*)CoreClrAlloc(sizeof(WCHAR)*257);
561 WCHAR* newLast = (WCHAR*)CoreClrAlloc(sizeof(WCHAR)*257);
562 for (int i = 0; i < 256; ++i)
563 {
564 newFirst[i] = L'b';
565 newLast[i] = L'a';
566 }
567 newFirst[256] = L'\0';
568 newLast[256] = L'\0';
569 str->first = (const WCHAR*)newFirst;
570 str->last = (const WCHAR*)newLast;
571}
572
573
574struct S8 // size = 32 bytes
575{
576 LPCSTR name;
577 BOOL gender;
578 INT i32;
579 UINT ui32;
580 WORD jobNum;
581 CHAR mySByte;
582};
583void PrintS8(S8* str, char const * name)
584{
585 printf("\t%s.name = %s\n",name, str->name);
586 printf("\t%s.gender = %d\n", name, str->gender);
587 printf("\t%s.jobNum = %d\n",name, str->jobNum);
588 printf("\t%s.i32 = %d\n", name, str->i32);
589 printf("\t%s.ui32 = %u\n", name, str->ui32);
590 printf("\t%s.mySByte = %c\n", name, str->mySByte);
591}
592bool IsCorrectS8(S8* str)
593{
594 if(memcmp( str->name,"hello", strlen("hello")*sizeof(char)+1 )!= 0)
595 return false;
596 if(!str->gender)
597 return false;
598 if(str->jobNum != 10)
599 return false;
600 if(str->i32!= 128 || str->ui32 != 128)
601 return false;
602 if(str->mySByte != 32)
603 return false;
604 return true;
605}
606
607void ChangeS8(S8* str)
608{
609 str->name = CoStrDup("world");
610 str->gender = false;
611 str->jobNum = 1;
612 str->i32 = 256;
613 str->ui32 = 256;
614 str->mySByte = 64;
615}
616#pragma pack (8)
617struct S_int // size = 4 bytes
618{
619 INT i;
620};
621
622struct S9;
623typedef void (*TestDelegate1)(struct S9 myStruct);
624
625struct S9 // size = 8 bytes
626{
627 INT i32;
628 TestDelegate1 myDelegate1;
629};
630
631struct S101 // size = 8 bytes
632{
633 INT i;
634 struct S_int s_int;
635};
636
637struct S10 // size = 8 bytes
638{
639 struct S101 s;
640};
641void PrintS10(S10* str, char const * name)
642{
643 printf("\t%s.s.s_int.i = %d\n", name, str->s.s_int.i);
644 printf("\t%s.s.i = %d\n", name, str->s.i);
645}
646bool IsCorrectS10(S10* str)
647{
648 if(str->s.s_int.i != 32)
649 return false;
650 if(str->s.i != 32)
651 return false;
652 return true;
653}
654void ChangeS10(S10* str)
655{
656 str->s.s_int.i = 64;
657 str->s.i = 64;
658}
659
660#ifndef WINDOWS
661typedef int* LPINT;
662#endif
663
664struct S11 // size = 8 bytes
665{
666 LPINT i32;
667 INT i;
668};
669
670union U // size = 8 bytes
671{
672 INT i32;
673 UINT ui32;
674 LPVOID iPtr;
675 LPVOID uiPtr;
676 SHORT s;
677 WORD us;
678 BYTE b;
679 CHAR sb;
680 LONG64 l;
681 ULONG64 ul;
682 FLOAT f;
683 DOUBLE d;
684};
685
686void PrintU(U* str, char const * name)
687{
688 printf("\t%s.i32 = %d\n", name, str->i32);
689 printf("\t%s.ui32 = %u\n", name, str->ui32);
690 printf("\t%s.iPtr = %p\n", name, str->iPtr);
691 printf("\t%s.uiPtr = %p\n", name, str->uiPtr);
692 printf("\t%s.s = %d\n", name, str->s);
693 printf("\t%s.us = %u\n", name, str->us);
694 printf("\t%s.b = %u\n", name, str->b);
695 printf("\t%s.sb = %d\n", name, str->sb);
696 printf("\t%s.l = %lld\n", name, str->l);
697 printf("\t%s.ul = %llu\n", name, str->ul);
698 printf("\t%s.f = %f\n", name, str->f);
699 printf("\t%s.d = %f\n", name, str->d);
700}
701
702void ChangeU(U* p)
703{
704 p->i32 = 2147483647;
705 p->ui32 = 0;
706 p->iPtr = (LPVOID)(-64);
707 p->uiPtr = (LPVOID)(64);
708 p->s = 32767;
709 p->us = 0;
710 p->b = 255;
711 p->sb = -128;
712 p->l = -1234567890;
713 p->ul = 0;
714 p->f = 64.0;
715 p->d = 6.4;
716}
717
718bool IsCorrectU(U* p)
719{
720 if(p->d != 3.2)
721 {
722 return false;
723 }
724 return true;
725}
726
727struct ByteStructPack2Explicit // size = 2 bytes
728{
729 BYTE b1;
730 BYTE b2;
731};
732void PrintByteStructPack2Explicit(ByteStructPack2Explicit* str, char const * name)
733{
734 printf("\t%s.b1 = %d", name, str->b1);
735 printf("\t%s.b2 = %d", name, str->b2);
736}
737
738void ChangeByteStructPack2Explicit(ByteStructPack2Explicit* p)
739{
740 p->b1 = 64;
741 p->b2 = 64;
742}
743bool IsCorrectByteStructPack2Explicit(ByteStructPack2Explicit* p)
744{
745 if(p->b1 != 32 || p->b2 != 32)
746 return false;
747 return true;
748}
749
750
751
752struct ShortStructPack4Explicit // size = 4 bytes
753{
754 SHORT s1;
755 SHORT s2;
756};
757
758void PrintShortStructPack4Explicit(ShortStructPack4Explicit* str, char const * name)
759{
760 printf("\t%s.s1 = %d", name, str->s1);
761 printf("\t%s.s2 = %d", name, str->s2);
762}
763void ChangeShortStructPack4Explicit(ShortStructPack4Explicit* p)
764{
765 p->s1 = 64;
766 p->s2 = 64;
767}
768bool IsCorrectShortStructPack4Explicit(ShortStructPack4Explicit* p)
769{
770 if(p->s1 != 32 || p->s2 != 32)
771 return false;
772 return true;
773}
774
775
776struct IntStructPack8Explicit // size = 8 bytes
777{
778 INT i1;
779 INT i2;
780};
781
782void PrintIntStructPack8Explicit(IntStructPack8Explicit* str, char const * name)
783{
784 printf("\t%s.i1 = %d", name, str->i1);
785 printf("\t%s.i2 = %d", name, str->i2);
786}
787void ChangeIntStructPack8Explicit(IntStructPack8Explicit* p)
788{
789 p->i1 = 64;
790 p->i2 = 64;
791}
792bool IsCorrectIntStructPack8Explicit(IntStructPack8Explicit* p)
793{
794 if(p->i1 != 32 || p->i2 != 32)
795 return false;
796 return true;
797}
798
799struct LongStructPack16Explicit // size = 16 bytes
800{
801 LONG64 l1;
802 LONG64 l2;
803};
804
805void PrintLongStructPack16Explicit(LongStructPack16Explicit* str, char const * name)
806{
807 printf("\t%s.l1 = %lld", name, str->l1);
808 printf("\t%s.l2 = %lld", name, str->l2);
809}
810void ChangeLongStructPack16Explicit(LongStructPack16Explicit* p)
811{
812 p->l1 = 64;
813 p->l2 = 64;
814}
815bool IsCorrectLongStructPack16Explicit(LongStructPack16Explicit* p)
816{
817 if(p->l1 != 32 || p->l2 != 32)
818 return false;
819 return true;
820}
821