123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- #include "shell_cmds_lib.h"
-
- /** Utility function for @ref asmsh_cmd_parse_addr_expr() that parse an expression value.
- *
- * An expression can be . for rip value or an unsigned long, possibly in hex, etc
- * @param const char* The value
- * @param unsigned long The value of RIP
- * @param unsigned long* A pointer on the result
- * @return -1 on error else 0
- */
- static int addr_expr_val(const char *val, unsigned long rip, unsigned long *res);
-
-
- void asmsh_log_addr_expr_usage()
- {
- asmsh_log_info("Expected an address expression of the form A + B or A - B with A and B an integer or '.' (for current RIP value)");
- }
-
-
- int asmsh_cmd_parse_addr_expr(asmsh_cmd_args_t *args, int first,
- const unsigned long rip, unsigned long *addr)
- {
- char * const * argv = args->args + first;
- const int argc = args->argc - first;
-
- unsigned long val[2];
-
- switch(argc)
- {
- case 0:
- *addr = rip;
- break;
- case 1:
- if(addr_expr_val(argv[0], rip, addr) < 0)
- {
- int err = errno;
- asmsh_log_error("Invalid expression value '%s': %s",
- argv[0], strerror(errno));
- errno = err;
- return -1;
- }
- break;
- case 3:
-
- for(int i=0; i<2; i++)
- {
- const char *arg = i ? argv[2]:argv[0];
- if(addr_expr_val(arg, rip, &val[i]) < 0)
- {
-
- asmsh_log_error("Invalid value '%s' in expression '%s %s %s' : %s",
- arg,
- argv[0], argv[1], argv[2],
- strerror(errno));
- return -1;
- }
- }
-
- const char operator = strlen(argv[1]) == 1 ? argv[1][0]: '\0';
- switch(operator)
- {
- case '+':
- *addr = val[0] + val[1];
- break;
- case '-':
- *addr = val[0] - val[1];
- break;
- default:
- asmsh_log_error("Invalid operator '%s' in expression '%s %s %s'",
- argv[1],
- argv[0], argv[1], argv[2]);
- return -1;
- }
- break;
- default:
- //USAGE !
- asmsh_log_error("Unexexpected argument count for an expression. Expecting one of 0, 1 or 3 but got %d", argc);
- return -1;
- }
- return 0;
- }
-
-
- static int addr_expr_val(const char *val, unsigned long rip, unsigned long *res)
- {
- if(strcmp(".", val) == 0)
- {
- *res = rip;
- return 0;
- }
-
- char *endptr;
- errno = 0;
- *res = strtoul(val, &endptr, 0);
- if(errno != 0)
- {
- return -1;
- }
- else if(*endptr != '\0')
- {
- errno = EINVAL;
- return -1;
- }
- return 0;
- }
|