Skip to content

Commit ab742da

Browse files
roblablayellows8
authored andcommitted
Add array-style kernel_capabilities to npdms.
The array-style kernel caps look like: "kernel_capabilities": [ { type: "irq_pair", value: [1, 2] }, // ... ] Deprecates duplicate-key style.
1 parent 23b1993 commit ab742da

File tree

2 files changed

+70
-13
lines changed

2 files changed

+70
-13
lines changed

src/elf2kip.c

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ uint8_t* ReadEntireFile(const char* fn, size_t* len_out) {
6060
return buf;
6161
}
6262

63+
int cJSON_GetString(const cJSON *obj, const char *field, const char **out) {
64+
const cJSON *config = cJSON_GetObjectItemCaseSensitive(obj, field);
65+
if (cJSON_IsString(config)) {
66+
*out = config->valuestring;
67+
return 1;
68+
} else {
69+
fprintf(stderr, "Failed to get %s (field not present).\n", field);
70+
return 0;
71+
}
72+
}
73+
6374
int cJSON_GetU8(const cJSON *obj, const char *field, u8 *out) {
6475
const cJSON *config = cJSON_GetObjectItemCaseSensitive(obj, field);
6576
if (cJSON_IsNumber(config)) {
@@ -237,19 +248,37 @@ int ParseKipConfiguration(const char *json, KipHeader *kip_hdr) {
237248

238249
/* Parse capabilities. */
239250
capabilities = cJSON_GetObjectItemCaseSensitive(npdm_json, "kernel_capabilities");
240-
if (!cJSON_IsObject(capabilities)) {
241-
fprintf(stderr, "Kernel Capabilities must be an object!\n");
251+
if (!(cJSON_IsArray(capabilities) || cJSON_IsObject(capabilities))) {
252+
fprintf(stderr, "Kernel Capabilities must be an array!\n");
242253
status = 0;
243254
goto PARSE_CAPS_END;
244255
}
245-
256+
257+
int kac_obj = 0;
258+
if (cJSON_IsObject(capabilities)) {
259+
kac_obj = 1;
260+
fprintf(stderr, "Using deprecated kernel_capabilities format. Please turn it into an array.\n");
261+
}
262+
246263
u32 cur_cap = 0;
247264
u32 desc;
248265
cJSON_ArrayForEach(capability, capabilities) {
249266
desc = 0;
250-
const char *type_str = capability->string;
251-
252-
const cJSON *value = capability;
267+
const char *type_str;
268+
const cJSON *value;
269+
270+
if (kac_obj) {
271+
type_str = capability->string;
272+
value = capability;
273+
} else {
274+
if (!cJSON_GetString(capability, "type", &type_str)) {
275+
status = 0;
276+
goto PARSE_CAPS_END;
277+
}
278+
value = cJSON_GetObjectItemCaseSensitive(capability, "value");
279+
}
280+
281+
253282
if (!strcmp(type_str, "kernel_flags")) {
254283
if (cur_cap + 1 > 0x20) {
255284
fprintf(stderr, "Error: Too many capabilities!\n");

src/npdmtool.c

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,17 @@ uint8_t* ReadEntireFile(const char* fn, size_t* len_out) {
113113
return buf;
114114
}
115115

116+
int cJSON_GetString(const cJSON *obj, const char *field, const char **out) {
117+
const cJSON *config = cJSON_GetObjectItemCaseSensitive(obj, field);
118+
if (cJSON_IsString(config)) {
119+
*out = config->valuestring;
120+
return 1;
121+
} else {
122+
fprintf(stderr, "Failed to get %s (field not present).\n", field);
123+
return 0;
124+
}
125+
}
126+
116127
int cJSON_GetU8(const cJSON *obj, const char *field, u8 *out) {
117128
const cJSON *config = cJSON_GetObjectItemCaseSensitive(obj, field);
118129
if (cJSON_IsNumber(config)) {
@@ -409,20 +420,37 @@ int CreateNpdm(const char *json, void **dst, u32 *dst_size) {
409420

410421
/* Parse capabilities. */
411422
capabilities = cJSON_GetObjectItemCaseSensitive(npdm_json, "kernel_capabilities");
412-
if (!cJSON_IsObject(capabilities)) {
413-
fprintf(stderr, "Kernel Capabilities must be an object!\n");
423+
if (!(cJSON_IsArray(capabilities) || cJSON_IsObject(capabilities))) {
424+
fprintf(stderr, "Kernel Capabilities must be an array!\n");
414425
status = 0;
415426
goto NPDM_BUILD_END;
416427
}
417-
428+
429+
int kac_obj = 0;
430+
if (cJSON_IsObject(capabilities)) {
431+
kac_obj = 1;
432+
fprintf(stderr, "Using deprecated kernel_capabilities format. Please turn it into an array.\n");
433+
}
434+
418435
u32 *caps = (u32 *)((u8 *)aci0 + aci0->KacOffset);
419436
u32 cur_cap = 0;
420437
u32 desc;
421438
cJSON_ArrayForEach(capability, capabilities) {
422439
desc = 0;
423-
const char *type_str = capability->string;
424-
425-
const cJSON *value = capability;
440+
const char *type_str;
441+
const cJSON *value;
442+
443+
if (kac_obj) {
444+
type_str = capability->string;
445+
value = capability;
446+
} else {
447+
if (!cJSON_GetString(capability, "type", &type_str)) {
448+
status = 0;
449+
goto NPDM_BUILD_END;
450+
}
451+
value = cJSON_GetObjectItemCaseSensitive(capability, "value");
452+
}
453+
426454
if (!strcmp(type_str, "kernel_flags")) {
427455
if (!cJSON_IsObject(value)) {
428456
fprintf(stderr, "Kernel Flags Capability value must be object!\n");
@@ -542,7 +570,7 @@ int CreateNpdm(const char *json, void **dst, u32 *dst_size) {
542570
} else if (!strcmp(type_str, "min_kernel_version")) {
543571
u64 kern_ver = 0;
544572
if (cJSON_IsNumber(value)) {
545-
kern_ver = (u64)value->valueint;
573+
kern_ver = (u64)value->valueint;
546574
} else if (!cJSON_IsString(value) || !cJSON_GetU64FromObjectValue(value, &kern_ver)) {
547575
fprintf(stderr, "Error: Kernel version must be integer or hex strings.\n");
548576
status = 0;

0 commit comments

Comments
 (0)