instructions.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include <linux/compiler.h>
  2. #include <sys/types.h>
  3. #include <regex.h>
  4. struct arm_annotate {
  5. regex_t call_insn,
  6. jump_insn;
  7. };
  8. static struct ins_ops *arm__associate_instruction_ops(struct arch *arch, const char *name)
  9. {
  10. struct arm_annotate *arm = arch->priv;
  11. struct ins_ops *ops;
  12. regmatch_t match[2];
  13. if (!regexec(&arm->call_insn, name, 2, match, 0))
  14. ops = &call_ops;
  15. else if (!regexec(&arm->jump_insn, name, 2, match, 0))
  16. ops = &jump_ops;
  17. else
  18. return NULL;
  19. arch__associate_ins_ops(arch, name, ops);
  20. return ops;
  21. }
  22. static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
  23. {
  24. struct arm_annotate *arm;
  25. int err;
  26. if (arch->initialized)
  27. return 0;
  28. arm = zalloc(sizeof(*arm));
  29. if (!arm)
  30. return -1;
  31. #define ARM_CONDS "(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl|vc|vs)"
  32. err = regcomp(&arm->call_insn, "^blx?" ARM_CONDS "?$", REG_EXTENDED);
  33. if (err)
  34. goto out_free_arm;
  35. err = regcomp(&arm->jump_insn, "^bx?" ARM_CONDS "?$", REG_EXTENDED);
  36. if (err)
  37. goto out_free_call;
  38. #undef ARM_CONDS
  39. arch->initialized = true;
  40. arch->priv = arm;
  41. arch->associate_instruction_ops = arm__associate_instruction_ops;
  42. arch->objdump.comment_char = ';';
  43. arch->objdump.skip_functions_char = '+';
  44. return 0;
  45. out_free_call:
  46. regfree(&arm->call_insn);
  47. out_free_arm:
  48. free(arm);
  49. return -1;
  50. }