Skip to content

Commit 0a6a76d

Browse files
borneoaerhankur
authored andcommitted
target: arc: rewrite command 'arc add-reg-type-struct' as COMMAND_HANDLER
Use a COMMAND_HELPER() to avoid memory leaks when the helper COMMAND_PARSE_NUMBER() returns due to an error. While there: - fix potential SIGSEGV due to dereference 'type' before checking it's not NULL; - fix an incorrect NUL byte termination while copying to type->data_type.id and to bitfields[cur_field].name; - fix some coding style error; - remove the now unused function jim_arc_read_reg_type_field(). Change-Id: I7158fd93b5d4742f11654b8ae4a7abd409ad06e2 Signed-off-by: Antonio Borneo <[email protected]> Reviewed-on: https://review.openocd.org/c/openocd/+/7425 Tested-by: jenkins Reviewed-by: Evgeniy Didin <[email protected]>
1 parent 95a0b64 commit 0a6a76d

File tree

1 file changed

+101
-151
lines changed

1 file changed

+101
-151
lines changed

src/target/arc_cmd.c

Lines changed: 101 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -70,51 +70,6 @@ static int jim_arc_read_reg_name_field(struct jim_getopt_info *goi,
7070
return e;
7171
}
7272

73-
/* Helper function to read bitfields/flags of register type. */
74-
static int jim_arc_read_reg_type_field(struct jim_getopt_info *goi, const char **field_name, int *field_name_len,
75-
struct arc_reg_bitfield *bitfields, int cur_field, int type)
76-
{
77-
jim_wide start_pos, end_pos;
78-
79-
int e = JIM_OK;
80-
if ((type == CFG_ADD_REG_TYPE_STRUCT && goi->argc < 3) ||
81-
(type == CFG_ADD_REG_TYPE_FLAG && goi->argc < 2)) {
82-
Jim_SetResultFormatted(goi->interp, "Not enough arguments after -flag/-bitfield");
83-
return JIM_ERR;
84-
}
85-
86-
e = jim_getopt_string(goi, field_name, field_name_len);
87-
if (e != JIM_OK)
88-
return e;
89-
90-
/* read start position of bitfield/flag */
91-
e = jim_getopt_wide(goi, &start_pos);
92-
if (e != JIM_OK)
93-
return e;
94-
95-
end_pos = start_pos;
96-
97-
/* Check if any arguments remain,
98-
* set bitfields[cur_field].end if flag is multibit */
99-
if (goi->argc > 0)
100-
/* Check current argv[0], if it is equal to "-flag",
101-
* than bitfields[cur_field].end remains start */
102-
if ((strcmp(Jim_String(goi->argv[0]), "-flag") && type == CFG_ADD_REG_TYPE_FLAG)
103-
|| (type == CFG_ADD_REG_TYPE_STRUCT)) {
104-
e = jim_getopt_wide(goi, &end_pos);
105-
if (e != JIM_OK) {
106-
Jim_SetResultFormatted(goi->interp, "Error reading end position");
107-
return e;
108-
}
109-
}
110-
111-
bitfields[cur_field].bitfield.start = start_pos;
112-
bitfields[cur_field].bitfield.end = end_pos;
113-
if ((end_pos != start_pos) || (type == CFG_ADD_REG_TYPE_STRUCT))
114-
bitfields[cur_field].bitfield.type = REG_TYPE_INT;
115-
return e;
116-
}
117-
11873
static COMMAND_HELPER(arc_handle_add_reg_type_flags_ops, struct arc_reg_data_type *type)
11974
{
12075
struct reg_data_type_flags_field *fields = type->reg_type_flags_field;
@@ -255,7 +210,7 @@ enum add_reg_type_struct {
255210
CFG_ADD_REG_TYPE_STRUCT_BITFIELD,
256211
};
257212

258-
static struct jim_nvp nvp_add_reg_type_struct_opts[] = {
213+
static const struct nvp nvp_add_reg_type_struct_opts[] = {
259214
{ .name = "-name", .value = CFG_ADD_REG_TYPE_STRUCT_NAME },
260215
{ .name = "-bitfield", .value = CFG_ADD_REG_TYPE_STRUCT_BITFIELD },
261216
{ .name = NULL, .value = -1 }
@@ -424,53 +379,117 @@ static const struct command_registration arc_jtag_command_group[] = {
424379

425380

426381
/* This function supports only bitfields. */
427-
static int jim_arc_add_reg_type_struct(Jim_Interp *interp, int argc,
428-
Jim_Obj * const *argv)
382+
static COMMAND_HELPER(arc_handle_add_reg_type_struct_opts, struct arc_reg_data_type *type)
429383
{
430-
struct jim_getopt_info goi;
431-
JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1));
384+
struct reg_data_type_struct_field *fields = type->reg_type_struct_field;
385+
struct arc_reg_bitfield *bitfields = type->bitfields;
386+
struct reg_data_type_struct *struct_type = &type->data_type_struct;
387+
unsigned int cur_field = 0;
432388

433-
LOG_DEBUG("-");
389+
while (CMD_ARGC) {
390+
const struct nvp *n = nvp_name2value(nvp_add_reg_type_struct_opts, CMD_ARGV[0]);
391+
CMD_ARGC--;
392+
CMD_ARGV++;
393+
switch (n->value) {
394+
case CFG_ADD_REG_TYPE_STRUCT_NAME:
395+
if (!CMD_ARGC)
396+
return ERROR_COMMAND_ARGUMENT_INVALID;
434397

435-
struct command_context *ctx;
436-
struct target *target;
398+
const char *name = CMD_ARGV[0];
399+
CMD_ARGC--;
400+
CMD_ARGV++;
437401

438-
ctx = current_command_context(interp);
439-
assert(ctx);
440-
target = get_current_target(ctx);
441-
if (!target) {
442-
Jim_SetResultFormatted(goi.interp, "No current target");
443-
return JIM_ERR;
402+
if (strlen(name) >= REG_TYPE_MAX_NAME_LENGTH) {
403+
command_print(CMD, "Reg type name is too big.");
404+
return ERROR_COMMAND_ARGUMENT_INVALID;
405+
}
406+
407+
strcpy((void *)type->data_type.id, name);
408+
break;
409+
410+
case CFG_ADD_REG_TYPE_STRUCT_BITFIELD:
411+
if (CMD_ARGC < 3)
412+
return ERROR_COMMAND_ARGUMENT_INVALID;
413+
414+
uint32_t start_pos, end_pos;
415+
const char *field_name = CMD_ARGV[0];
416+
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], start_pos);
417+
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], end_pos);
418+
CMD_ARGC -= 3;
419+
CMD_ARGV += 3;
420+
bitfields[cur_field].bitfield.start = start_pos;
421+
bitfields[cur_field].bitfield.end = end_pos;
422+
bitfields[cur_field].bitfield.type = REG_TYPE_INT;
423+
424+
if (strlen(field_name) >= REG_TYPE_MAX_NAME_LENGTH) {
425+
command_print(CMD, "Reg type field_name is too big.");
426+
return ERROR_COMMAND_ARGUMENT_INVALID;
427+
}
428+
429+
fields[cur_field].name = bitfields[cur_field].name;
430+
strcpy(bitfields[cur_field].name, field_name);
431+
432+
fields[cur_field].bitfield = &bitfields[cur_field].bitfield;
433+
fields[cur_field].use_bitfields = true;
434+
if (cur_field > 0)
435+
fields[cur_field - 1].next = &fields[cur_field];
436+
else
437+
struct_type->fields = fields;
438+
439+
cur_field += 1;
440+
441+
break;
442+
443+
default:
444+
nvp_unknown_command_print(CMD, nvp_add_reg_type_struct_opts, NULL, CMD_ARGV[-1]);
445+
return ERROR_COMMAND_ARGUMENT_INVALID;
446+
}
444447
}
445448

446-
int e = JIM_OK;
449+
if (!type->data_type.id) {
450+
command_print(CMD, "-name is a required option");
451+
return ERROR_COMMAND_ARGUMENT_INVALID;
452+
}
447453

448-
/* Check if the amount of arguments is not zero */
449-
if (goi.argc <= 0) {
450-
Jim_SetResultFormatted(goi.interp, "The command has no arguments");
451-
return JIM_ERR;
454+
return ERROR_OK;
455+
}
456+
457+
COMMAND_HANDLER(arc_handle_add_reg_type_struct)
458+
{
459+
int retval;
460+
461+
LOG_DEBUG("-");
462+
463+
struct target *target = get_current_target(CMD_CTX);
464+
if (!target) {
465+
command_print(CMD, "No current target");
466+
return ERROR_FAIL;
452467
}
453468

469+
/* Check if the amount of arguments is not zero */
470+
if (CMD_ARGC == 0)
471+
return ERROR_COMMAND_SYNTAX_ERROR;
472+
454473
/* Estimate number of registers as (argc - 2)/4 as each -bitfield option has 3
455474
* arguments while -name is required. */
456-
unsigned int fields_sz = (goi.argc - 2) / 4;
457-
unsigned int cur_field = 0;
475+
unsigned int fields_sz = (CMD_ARGC - 2) / 4;
458476

459477
/* The maximum amount of bitfields is 32 */
460478
if (fields_sz > 32) {
461-
Jim_SetResultFormatted(goi.interp, "The amount of bitfields exceed 32");
462-
return JIM_ERR;
479+
command_print(CMD, "The amount of bitfields exceed 32");
480+
return ERROR_COMMAND_ARGUMENT_INVALID;
463481
}
464482

465483
struct arc_reg_data_type *type = calloc(1, sizeof(*type));
466-
struct reg_data_type_struct *struct_type = &type->data_type_struct;
467484
struct reg_data_type_struct_field *fields = calloc(fields_sz, sizeof(*fields));
468-
type->reg_type_struct_field = fields;
469485
struct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*bitfields));
470-
if (!(type && fields && bitfields)) {
471-
Jim_SetResultFormatted(goi.interp, "Failed to allocate memory.");
486+
if (!type || !fields || !bitfields) {
487+
LOG_ERROR("Out of memory");
488+
retval = ERROR_FAIL;
472489
goto fail;
473490
}
491+
struct reg_data_type_struct *struct_type = &type->data_type_struct;
492+
type->reg_type_struct_field = fields;
474493

475494
/* Initialize type */
476495
type->data_type.id = type->data_type_id;
@@ -480,91 +499,22 @@ static int jim_arc_add_reg_type_struct(Jim_Interp *interp, int argc,
480499
type->data_type.reg_type_struct = struct_type;
481500
struct_type->size = 4; /* For now ARC has only 32-bit registers */
482501

483-
while (goi.argc > 0 && e == JIM_OK) {
484-
struct jim_nvp *n;
485-
e = jim_getopt_nvp(&goi, nvp_add_reg_type_struct_opts, &n);
486-
if (e != JIM_OK) {
487-
jim_getopt_nvp_unknown(&goi, nvp_add_reg_type_struct_opts, 0);
488-
continue;
489-
}
490-
491-
switch (n->value) {
492-
case CFG_ADD_REG_TYPE_STRUCT_NAME:
493-
{
494-
const char *name = NULL;
495-
int name_len = 0;
496-
497-
e = jim_arc_read_reg_name_field(&goi, &name, &name_len);
498-
if (e != JIM_OK) {
499-
Jim_SetResultFormatted(goi.interp, "Unable to read reg name.");
500-
goto fail;
501-
}
502-
503-
if (name_len > REG_TYPE_MAX_NAME_LENGTH) {
504-
Jim_SetResultFormatted(goi.interp, "Reg type name is too big.");
505-
goto fail;
506-
}
507-
508-
strncpy((void *)type->data_type.id, name, name_len);
509-
if (!type->data_type.id) {
510-
Jim_SetResultFormatted(goi.interp, "Unable to setup reg type name.");
511-
goto fail;
512-
}
513-
514-
break;
515-
}
516-
case CFG_ADD_REG_TYPE_STRUCT_BITFIELD:
517-
{
518-
const char *field_name = NULL;
519-
int field_name_len = 0;
520-
e = jim_arc_read_reg_type_field(&goi, &field_name, &field_name_len, bitfields,
521-
cur_field, CFG_ADD_REG_TYPE_STRUCT);
522-
if (e != JIM_OK) {
523-
Jim_SetResultFormatted(goi.interp, "Unable to add reg_type_struct field.");
524-
goto fail;
525-
}
526-
527-
if (field_name_len > REG_TYPE_MAX_NAME_LENGTH) {
528-
Jim_SetResultFormatted(goi.interp, "Reg type field_name_len is too big.");
529-
goto fail;
530-
}
531-
532-
fields[cur_field].name = bitfields[cur_field].name;
533-
strncpy(bitfields[cur_field].name, field_name, field_name_len);
534-
if (!fields[cur_field].name) {
535-
Jim_SetResultFormatted(goi.interp, "Unable to setup field name. ");
536-
goto fail;
537-
}
538-
539-
fields[cur_field].bitfield = &(bitfields[cur_field].bitfield);
540-
fields[cur_field].use_bitfields = true;
541-
if (cur_field > 0)
542-
fields[cur_field - 1].next = &(fields[cur_field]);
543-
else
544-
struct_type->fields = fields;
545-
546-
cur_field += 1;
547-
548-
break;
549-
}
550-
}
551-
}
552-
553-
if (!type->data_type.id) {
554-
Jim_SetResultFormatted(goi.interp, "-name is a required option");
502+
retval = CALL_COMMAND_HANDLER(arc_handle_add_reg_type_struct_opts, type);
503+
if (retval != ERROR_OK)
555504
goto fail;
556-
}
557505

558506
arc_reg_data_type_add(target, type);
507+
559508
LOG_DEBUG("added struct type {name=%s}", type->data_type.id);
560-
return JIM_OK;
509+
510+
return ERROR_OK;
561511

562512
fail:
563-
free(type);
564-
free(fields);
565-
free(bitfields);
513+
free(type);
514+
free(fields);
515+
free(bitfields);
566516

567-
return JIM_ERR;
517+
return retval;
568518
}
569519

570520
/* Add register */
@@ -925,7 +875,7 @@ static const struct command_registration arc_core_command_handlers[] = {
925875
},
926876
{
927877
.name = "add-reg-type-struct",
928-
.jim_handler = jim_arc_add_reg_type_struct,
878+
.handler = arc_handle_add_reg_type_struct,
929879
.mode = COMMAND_CONFIG,
930880
.usage = "-name <string> -bitfield <name> <start> <end> "
931881
"[-bitfield <name> <start> <end>]...",

0 commit comments

Comments
 (0)