A shell that runs x86_64 assembly
c
x86-64
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include "shell_cmds_lib.h"
  2. /** Utility function for @ref asmsh_cmd_parse_addr_expr() that parse an expression value.
  3. *
  4. * An expression can be . for rip value or an unsigned long, possibly in hex, etc
  5. * @param const char* The value
  6. * @param unsigned long The value of RIP
  7. * @param unsigned long* A pointer on the result
  8. * @return -1 on error else 0
  9. */
  10. static int addr_expr_val(const char *val, unsigned long rip, unsigned long *res);
  11. void asmsh_log_addr_expr_usage()
  12. {
  13. 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)");
  14. }
  15. int asmsh_cmd_parse_addr_expr(asmsh_cmd_args_t *args, int first,
  16. const unsigned long rip, unsigned long *addr)
  17. {
  18. char * const * argv = args->args + first;
  19. const int argc = args->argc - first;
  20. unsigned long val[2];
  21. switch(argc)
  22. {
  23. case 0:
  24. *addr = rip;
  25. break;
  26. case 1:
  27. if(addr_expr_val(argv[0], rip, addr) < 0)
  28. {
  29. int err = errno;
  30. asmsh_log_error("Invalid expression value '%s': %s",
  31. argv[0], strerror(errno));
  32. errno = err;
  33. return -1;
  34. }
  35. break;
  36. case 3:
  37. for(int i=0; i<2; i++)
  38. {
  39. const char *arg = i ? argv[2]:argv[0];
  40. if(addr_expr_val(arg, rip, &val[i]) < 0)
  41. {
  42. asmsh_log_error("Invalid value '%s' in expression '%s %s %s' : %s",
  43. arg,
  44. argv[0], argv[1], argv[2],
  45. strerror(errno));
  46. return -1;
  47. }
  48. }
  49. const char operator = strlen(argv[1]) == 1 ? argv[1][0]: '\0';
  50. switch(operator)
  51. {
  52. case '+':
  53. *addr = val[0] + val[1];
  54. break;
  55. case '-':
  56. *addr = val[0] - val[1];
  57. break;
  58. default:
  59. asmsh_log_error("Invalid operator '%s' in expression '%s %s %s'",
  60. argv[1],
  61. argv[0], argv[1], argv[2]);
  62. return -1;
  63. }
  64. break;
  65. default:
  66. //USAGE !
  67. asmsh_log_error("Unexexpected argument count for an expression. Expecting one of 0, 1 or 3 but got %d", argc);
  68. return -1;
  69. }
  70. return 0;
  71. }
  72. static int addr_expr_val(const char *val, unsigned long rip, unsigned long *res)
  73. {
  74. if(strcmp(".", val) == 0)
  75. {
  76. *res = rip;
  77. return 0;
  78. }
  79. char *endptr;
  80. errno = 0;
  81. *res = strtoul(val, &endptr, 0);
  82. if(errno != 0)
  83. {
  84. return -1;
  85. }
  86. else if(*endptr != '\0')
  87. {
  88. errno = EINVAL;
  89. return -1;
  90. }
  91. return 0;
  92. }