disassemble.c 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*===-- disassemble.c - tool for testing libLLVM and llvm-c API -----------===*\
  2. |* *|
  3. |* The LLVM Compiler Infrastructure *|
  4. |* *|
  5. |* This file is distributed under the University of Illinois Open Source *|
  6. |* License. See LICENSE.TXT for details. *|
  7. |* *|
  8. |*===----------------------------------------------------------------------===*|
  9. |* *|
  10. |* This file implements the --disassemble command in llvm-c-test. *|
  11. |* --disassemble reads lines from stdin, parses them as a triple and hex *|
  12. |* machine code, and prints disassembly of the machine code. *|
  13. |* *|
  14. \*===----------------------------------------------------------------------===*/
  15. #include "llvm-c-test.h"
  16. #include "llvm-c/Disassembler.h"
  17. #include "llvm-c/Target.h"
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. static void pprint(int pos, unsigned char *buf, int len, const char *disasm) {
  22. int i;
  23. printf("%04x: ", pos);
  24. for (i = 0; i < 8; i++) {
  25. if (i < len) {
  26. printf("%02x ", buf[i]);
  27. } else {
  28. printf(" ");
  29. }
  30. }
  31. printf(" %s\n", disasm);
  32. }
  33. static void do_disassemble(const char *triple, const char *features,
  34. unsigned char *buf, int siz) {
  35. LLVMDisasmContextRef D = LLVMCreateDisasmCPUFeatures(triple, "", features,
  36. NULL, 0, NULL, NULL);
  37. char outline[1024];
  38. int pos;
  39. if (!D) {
  40. printf("ERROR: Couldn't create disassembler for triple %s\n", triple);
  41. return;
  42. }
  43. pos = 0;
  44. while (pos < siz) {
  45. size_t l = LLVMDisasmInstruction(D, buf + pos, siz - pos, 0, outline,
  46. sizeof(outline));
  47. if (!l) {
  48. pprint(pos, buf + pos, 1, "\t???");
  49. pos++;
  50. } else {
  51. pprint(pos, buf + pos, l, outline);
  52. pos += l;
  53. }
  54. }
  55. LLVMDisasmDispose(D);
  56. }
  57. static void handle_line(char **tokens, int ntokens) {
  58. unsigned char disbuf[128];
  59. size_t disbuflen = 0;
  60. const char *triple = tokens[0];
  61. const char *features = tokens[1];
  62. int i;
  63. printf("triple: %s, features: %s\n", triple, features);
  64. if (!strcmp(features, "NULL"))
  65. features = "";
  66. for (i = 2; i < ntokens; i++) {
  67. disbuf[disbuflen++] = strtol(tokens[i], NULL, 16);
  68. if (disbuflen >= sizeof(disbuf)) {
  69. fprintf(stderr, "Warning: Too long line, truncating\n");
  70. break;
  71. }
  72. }
  73. do_disassemble(triple, features, disbuf, disbuflen);
  74. }
  75. int disassemble(void) {
  76. LLVMInitializeAllTargetInfos();
  77. LLVMInitializeAllTargetMCs();
  78. LLVMInitializeAllDisassemblers();
  79. tokenize_stdin(handle_line);
  80. return 0;
  81. }