SymbolLookup.java 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* SymbolLookup.java -- Finds class names by analyzing memory.
  2. Copyright (C) 2007 Free Software Foundation
  3. This file is part of libgcj.
  4. This software is copyrighted work licensed under the terms of the
  5. Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
  6. details. */
  7. package gnu.gcj.tools.gc_analyze;
  8. import java.io.BufferedReader;
  9. import java.io.IOException;
  10. class SymbolLookup
  11. {
  12. MemoryMap memoryMap;
  13. public SymbolLookup(BufferedReader reader,
  14. String rawFileName)
  15. throws IOException
  16. {
  17. memoryMap = new MemoryMap(reader, rawFileName);
  18. }
  19. public String decodeUTF8(long address) throws IOException
  20. {
  21. return decodeUTF8(address, -1);
  22. }
  23. public String decodeUTF8(long address, int limit) throws IOException
  24. {
  25. if (address == 0)
  26. return null;
  27. BytePtr utf8 = memoryMap.getBytePtr(address, 64);
  28. if (utf8 == null)
  29. return null;
  30. int len = utf8.getShort(1);
  31. int hash16 = utf8.getShort(0) & 0xffff;
  32. if (len <= 0 || (limit > 0 && len > (limit - 4)))
  33. return null;
  34. if (len > utf8.getsize() + 4)
  35. utf8 = memoryMap.getBytePtr(address, len + 4);
  36. if (utf8 == null)
  37. return null;
  38. StringBuilder sb = new StringBuilder(len);
  39. int pos = 4;
  40. len += 4;
  41. while (pos < len)
  42. {
  43. int f = utf8.getByte(pos++);
  44. if ((f & 0x80) == 0)
  45. {
  46. sb.append((char)f);
  47. }
  48. else if ((f & 0xe0) == 0xc0)
  49. {
  50. int s = utf8.getByte(pos++);
  51. char c = (char)(((f & 0x1f) << 6) | (s & 0x80));
  52. sb.append(c);
  53. }
  54. else if ((f & 0xe0) == 0xe0)
  55. {
  56. int s = utf8.getByte(pos++);
  57. int t = utf8.getByte(pos++);
  58. char c = (char)(((f & 0x0f) << 12)
  59. | ((s & 0x80) << 6) | (t & 0x80));
  60. sb.append(c);
  61. }
  62. else
  63. break; // Bad utf8
  64. }
  65. String rv = sb.toString();
  66. if (hash16 == (rv.hashCode() & 0xffff))
  67. return rv;
  68. else
  69. return null;
  70. }
  71. public String getSymbolViaVtable(long address) throws IOException
  72. {
  73. return memoryMap.getSymbol(address);
  74. }
  75. public String getSymbol(long address) throws IOException
  76. {
  77. String symbol = memoryMap.getSymbol(address);
  78. if (null != symbol)
  79. return symbol;
  80. BytePtr klass = memoryMap.getBytePtr(address, 3 * memoryMap.wordSize);
  81. if (klass == null)
  82. return null;
  83. long nameUTF8p = klass.getWord(2);
  84. return decodeUTF8(nameUTF8p);
  85. }
  86. BytePtr getBytePtr(long addr, int length) throws IOException
  87. {
  88. return memoryMap.getBytePtr(addr, length);
  89. }
  90. }