Skip to content

Commit 65e1b73

Browse files
committed
tests: Add config table support
This adds a simple implementation of ST->ConfigurationTable, ST->NumberOfTableEntries, and BS->InstallConfigurationTable to our test harness. Currently it is limited at 1024 entries, but that should be well more than enough for any tests we've currently considered. Signed-off-by: Peter Jones <pjones@redhat.com>
1 parent 1cb2168 commit 65e1b73

File tree

3 files changed

+599
-2
lines changed

3 files changed

+599
-2
lines changed

include/mock-variables.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ EFI_STATUS EFIAPI mock_query_variable_info(UINT32 attrs,
2121
UINT64 *remaining_var_storage,
2222
UINT64 *max_var_size);
2323

24+
EFI_STATUS EFIAPI mock_install_configuration_table(EFI_GUID *guid, VOID *table);
25+
2426
struct mock_variable_limits {
2527
UINT32 attrs;
2628
UINT64 *max_var_storage;
@@ -40,6 +42,7 @@ typedef enum {
4042
} mock_sort_policy_t;
4143

4244
extern mock_sort_policy_t mock_variable_sort_policy;
45+
extern mock_sort_policy_t mock_config_table_sort_policy;
4346

4447
#define MOCK_VAR_DELETE_ATTR_ALLOW_ZERO 0x01
4548
#define MOCK_VAR_DELETE_ATTR_ALOW_MISMATCH 0x02
@@ -110,7 +113,8 @@ void mock_load_variables(const char *const dirname, const char *filters[],
110113
void mock_install_query_variable_info(void);
111114
void mock_uninstall_query_variable_info(void);
112115
void mock_reset_variables(void);
113-
void mock_finalize_vars(void);
116+
void mock_reset_config_table(void);
117+
void mock_finalize_vars_and_configs(void);
114118

115119
typedef enum {
116120
NONE = 0,
@@ -171,5 +175,8 @@ typedef void (mock_query_variable_info_post_hook_t)(
171175
const int line, const char * const func);
172176
extern mock_query_variable_info_post_hook_t *mock_query_variable_info_post_hook;
173177

178+
#define MOCK_CONFIG_TABLE_ENTRIES 1024
179+
extern EFI_CONFIGURATION_TABLE mock_config_table[MOCK_CONFIG_TABLE_ENTRIES];
180+
174181
#endif /* !SHIM_MOCK_VARIABLES_H_ */
175182
// vim:fenc=utf-8:tw=75:noet

mock-variables.c

+170-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ list_t *mock_sv_limits = &mock_default_variable_limits;
2626
list_t mock_variables = LIST_HEAD_INIT(mock_variables);
2727

2828
mock_sort_policy_t mock_variable_sort_policy = MOCK_SORT_APPEND;
29+
mock_sort_policy_t mock_config_table_sort_policy = MOCK_SORT_APPEND;
2930

3031
UINT32 mock_variable_delete_attr_policy;
3132

@@ -1165,6 +1166,140 @@ mock_uninstall_query_variable_info(void)
11651166
RT->QueryVariableInfo = mock_efi_unsupported;
11661167
}
11671168

1169+
EFI_CONFIGURATION_TABLE mock_config_table[MOCK_CONFIG_TABLE_ENTRIES] = {
1170+
{
1171+
.VendorGuid = { 0, },
1172+
.VendorTable = NULL
1173+
},
1174+
};
1175+
1176+
int
1177+
mock_config_table_cmp(const void *p0, const void *p1)
1178+
{
1179+
EFI_CONFIGURATION_TABLE *entry0, *entry1;
1180+
long cmp;
1181+
1182+
if (!p0 || !p1) {
1183+
cmp = (int)((intptr_t)p0 - (intptr_t)p1);
1184+
} else {
1185+
entry0 = (EFI_CONFIGURATION_TABLE *)p0;
1186+
entry1 = (EFI_CONFIGURATION_TABLE *)p1;
1187+
#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0)
1188+
printf("comparing %p to %p\n", p0, p1);
1189+
#endif
1190+
cmp = CompareGuid(&entry0->VendorGuid, &entry1->VendorGuid);
1191+
}
1192+
1193+
if (mock_config_table_sort_policy == MOCK_SORT_DESCENDING) {
1194+
cmp = -cmp;
1195+
}
1196+
1197+
return cmp;
1198+
}
1199+
1200+
EFI_STATUS EFIAPI
1201+
mock_install_configuration_table(EFI_GUID *guid, VOID *table)
1202+
{
1203+
bool found = false;
1204+
EFI_CONFIGURATION_TABLE *entry;
1205+
int idx = 0;
1206+
size_t sz;
1207+
1208+
if (!guid)
1209+
return EFI_INVALID_PARAMETER;
1210+
1211+
for (UINTN i = 0; i < ST->NumberOfTableEntries; i++) {
1212+
EFI_CONFIGURATION_TABLE *entry = &ST->ConfigurationTable[i];
1213+
1214+
if (CompareGuid(guid, &entry->VendorGuid) == 0) {
1215+
found = true;
1216+
if (table) {
1217+
// replace it
1218+
entry->VendorTable = table;
1219+
} else {
1220+
// delete it
1221+
ST->NumberOfTableEntries -= 1;
1222+
sz = ST->NumberOfTableEntries - i;
1223+
sz *= sizeof(*entry);
1224+
memmove(&entry[0], &entry[1], sz);
1225+
}
1226+
return EFI_SUCCESS;
1227+
}
1228+
}
1229+
if (!found && table == NULL)
1230+
return EFI_NOT_FOUND;
1231+
if (ST->NumberOfTableEntries == MOCK_CONFIG_TABLE_ENTRIES - 1) {
1232+
/*
1233+
* If necessary, we could allocate another table and copy
1234+
* the data, but I'm lazy and we probably don't need to.
1235+
*/
1236+
return EFI_OUT_OF_RESOURCES;
1237+
}
1238+
1239+
switch (mock_config_table_sort_policy) {
1240+
case MOCK_SORT_DESCENDING:
1241+
case MOCK_SORT_ASCENDING:
1242+
case MOCK_SORT_APPEND:
1243+
idx = ST->NumberOfTableEntries;
1244+
break;
1245+
case MOCK_SORT_PREPEND:
1246+
sz = ST->NumberOfTableEntries ? ST->NumberOfTableEntries : 0;
1247+
sz *= sizeof(ST->ConfigurationTable[0]);
1248+
memmove(&ST->ConfigurationTable[1], &ST->ConfigurationTable[0], sz);
1249+
idx = 0;
1250+
break;
1251+
default:
1252+
break;
1253+
}
1254+
1255+
entry = &ST->ConfigurationTable[idx];
1256+
memcpy(&entry->VendorGuid, guid, sizeof(EFI_GUID));
1257+
entry->VendorTable = table;
1258+
#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0)
1259+
printf("%s:%d:%s(): installing entry %p={%p,%p} as entry %d\n",
1260+
__FILE__, __LINE__, __func__,
1261+
entry, &entry->VendorGuid, entry->VendorTable, idx);
1262+
#endif
1263+
ST->NumberOfTableEntries += 1;
1264+
1265+
#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0)
1266+
printf("%s:%d:%s():ST->ConfigurationTable:%p\n"
1267+
"\t[%d]:%p\n"
1268+
"\t[%d]:%p\n",
1269+
__FILE__, __LINE__, __func__, ST->ConfigurationTable,
1270+
0, &ST->ConfigurationTable[0],
1271+
1, &ST->ConfigurationTable[1]);
1272+
#endif
1273+
switch (mock_config_table_sort_policy) {
1274+
case MOCK_SORT_DESCENDING:
1275+
case MOCK_SORT_ASCENDING:
1276+
#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0)
1277+
printf("%s:%d:%s(): entries before sorting:\n", __FILE__, __LINE__, __func__);
1278+
for (UINTN i = 0; i < ST->NumberOfTableEntries; i++) {
1279+
printf("\t[%d] = %p = {", i, &ST->ConfigurationTable[i]);
1280+
printf(".VendorGuid=" GUID_FMT, GUID_ARGS(ST->ConfigurationTable[i].VendorGuid));
1281+
printf(".VendorTable=%p}\n", ST->ConfigurationTable[i].VendorTable);
1282+
}
1283+
#endif
1284+
qsort(&ST->ConfigurationTable[0], ST->NumberOfTableEntries,
1285+
sizeof(ST->ConfigurationTable[0]),
1286+
mock_config_table_cmp);
1287+
break;
1288+
default:
1289+
break;
1290+
}
1291+
#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0)
1292+
printf("%s:%d:%s(): entries:\n", __FILE__, __LINE__, __func__);
1293+
for (UINTN i = 0; i < ST->NumberOfTableEntries; i++) {
1294+
printf("\t[%d] = %p = {", i, &ST->ConfigurationTable[i]);
1295+
printf(".VendorGuid=" GUID_FMT, GUID_ARGS(ST->ConfigurationTable[i].VendorGuid));
1296+
printf(".VendorTable=%p}\n", ST->ConfigurationTable[i].VendorTable);
1297+
}
1298+
#endif
1299+
1300+
return EFI_SUCCESS;
1301+
}
1302+
11681303
void CONSTRUCTOR
11691304
mock_reset_variables(void)
11701305
{
@@ -1222,10 +1357,44 @@ mock_reset_variables(void)
12221357
mock_uninstall_query_variable_info();
12231358
}
12241359

1360+
void CONSTRUCTOR
1361+
mock_reset_config_table(void)
1362+
{
1363+
init_efi_system_table();
1364+
1365+
/*
1366+
* Note that BS->InstallConfigurationTable() is *not* defined as
1367+
* freeing these. If a test case installs non-malloc()ed tables,
1368+
* it needs to call BS->InstallConfigurationTable(guid, NULL) to
1369+
* clear them.
1370+
*/
1371+
for (UINTN i = 0; i < ST->NumberOfTableEntries; i++) {
1372+
EFI_CONFIGURATION_TABLE *entry = &ST->ConfigurationTable[i];
1373+
1374+
if (entry->VendorTable)
1375+
free(entry->VendorTable);
1376+
}
1377+
1378+
SetMem(ST->ConfigurationTable,
1379+
ST->NumberOfTableEntries * sizeof(EFI_CONFIGURATION_TABLE),
1380+
0);
1381+
1382+
ST->NumberOfTableEntries = 0;
1383+
1384+
if (ST->ConfigurationTable != mock_config_table) {
1385+
free(ST->ConfigurationTable);
1386+
ST->ConfigurationTable = mock_config_table;
1387+
SetMem(mock_config_table, sizeof(mock_config_table), 0);
1388+
}
1389+
1390+
BS->InstallConfigurationTable = mock_install_configuration_table;
1391+
}
1392+
12251393
void DESTRUCTOR
1226-
mock_finalize_vars(void)
1394+
mock_finalize_vars_and_configs(void)
12271395
{
12281396
mock_reset_variables();
1397+
mock_reset_config_table();
12291398
}
12301399

12311400
// vim:fenc=utf-8:tw=75:noet

0 commit comments

Comments
 (0)