blob: b06a23703404ee6399e74492e0231305756c51e5 [file] [log] [blame]
Lawrence Tang02c801a2022-07-18 14:43:52 +01001/**
2 * Functions for generating psuedo-random CPER IA32/x64 sections.
3 *
4 * Author: Lawrence.Tang@arm.com
5 **/
6
7#include <stdlib.h>
8#include <string.h>
9#include "../../edk/Cper.h"
10#include "../gen-utils.h"
11#include "gen-section-ia32x64.h"
12
13void* generate_ia32x64_error_structure();
14size_t generate_ia32x64_context_structure(void** location);
15
16//Generates a single psuedo-random IA32/x64 section, saving the resulting address to the given
17//location. Returns the size of the newly created section.
18size_t generate_section_ia32x64(void** location)
19{
20 //Set up for generation of error/context structures.
21 UINT16 error_structure_num = rand() % 5;
22 UINT16 context_structure_num = rand() % 5;
23 void* error_structures[error_structure_num];
24 void* context_structures[context_structure_num];
25 size_t context_structure_lengths[context_structure_num];
26
27 //Generate the structures.
28 for (int i=0; i<error_structure_num; i++)
29 error_structures[i] = generate_ia32x64_error_structure();
30 for (int i=0; i<context_structure_num; i++)
31 context_structure_lengths[i] = generate_ia32x64_context_structure(context_structures + i);
32
33 //Create a valid IA32/x64 section.
34 size_t total_len = 64 + (IA32X64_ERROR_STRUCTURE_SIZE * error_structure_num);
35 for (int i=0; i<context_structure_num; i++)
36 total_len += context_structure_lengths[i];
37 UINT8* section = generate_random_bytes(total_len);
38
39 //Set header information.
40 UINT64* validation = (UINT64*)section;
41 *validation &= 0b11;
42 *validation |= error_structure_num << 2;
43 *validation |= context_structure_num << 8;
44
45 //Copy in structures, free resources.
46 UINT8* cur_pos = section + 64;
47 for (int i=0; i<error_structure_num; i++)
48 {
49 memcpy(cur_pos, error_structures[i], IA32X64_ERROR_STRUCTURE_SIZE);
50 free(error_structures[i]);
51 cur_pos += IA32X64_ERROR_STRUCTURE_SIZE;
52 }
53 for (int i=0; i<context_structure_num; i++)
54 {
55 memcpy(cur_pos, context_structures[i], context_structure_lengths[i]);
56 free(context_structures[i]);
57 cur_pos += context_structure_lengths[i];
58 }
59
60 //Set return values, exist.
61 *location = section;
62 return total_len;
63}
64
65//Generates a single IA32/x64 error structure. Must later be freed.
66void* generate_ia32x64_error_structure()
67{
68 UINT8* error_structure = generate_random_bytes(IA32X64_ERROR_STRUCTURE_SIZE);
69
70 //Create a random type of error structure.
71 EFI_GUID* guid = (EFI_GUID*)error_structure;
72 int error_structure_type = rand() % 4;
73 switch (error_structure_type)
74 {
75 //Cache
76 case 0:
77 memcpy(guid, &gEfiIa32x64ErrorTypeCacheCheckGuid, sizeof(guid));
78 memset(error_structure + 30, 0, 34);
79 break;
80
81 //TLB
82 case 1:
83 memcpy(guid, &gEfiIa32x64ErrorTypeTlbCheckGuid, sizeof(guid));
84 memset(error_structure + 30, 0, 34);
85 break;
86
87 //Bus
88 case 2:
89 memcpy(guid, &gEfiIa32x64ErrorTypeBusCheckGuid, sizeof(guid));
90 memset(error_structure + 35, 0, 29);
91 break;
92
93 //MS
94 case 3:
95 memcpy(guid, &gEfiIa32x64ErrorTypeMsCheckGuid, sizeof(guid));
96 memset(error_structure + 24, 0, 38);
97 break;
98 }
99
100 return error_structure;
101}
102
103//Generates a single IA32/x64 context structure. Must later be freed.
104size_t generate_ia32x64_context_structure(void** location)
105{
106 //Initial length is 16 bytes. Add extra based on type.
107 int reg_type = rand() % 8;
108 int reg_size = 0;
109
110 //Set register size.
111 if (reg_type == 2)
112 reg_size = 92; //IA32 registers.
113 if (reg_type == 3)
114 reg_size = 244; //x64 registers.
115 else
116 reg_size = rand() % 64; //Not table defined.
117
118 //Create structure randomly.
119 int total_size = 16 + reg_size;
120 UINT16* context_structure = (UINT16*)generate_random_bytes(total_size);
121
122 //Set header information.
123 *(context_structure) = reg_type;
124 *(context_structure + 1) = reg_size;
125
126 //Set return values and exit.
127 *location = context_structure;
128 return total_size;
129}