113 lines
2.6 KiB
Java
113 lines
2.6 KiB
Java
/* SymbolLookup.java -- Finds class names by analyzing memory.
|
|
Copyright (C) 2007 Free Software Foundation
|
|
|
|
This file is part of libgcj.
|
|
|
|
This software is copyrighted work licensed under the terms of the
|
|
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
|
details. */
|
|
|
|
package gnu.gcj.tools.gc_analyze;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.IOException;
|
|
|
|
class SymbolLookup
|
|
{
|
|
MemoryMap memoryMap;
|
|
|
|
public SymbolLookup(BufferedReader reader,
|
|
String rawFileName)
|
|
throws IOException
|
|
{
|
|
memoryMap = new MemoryMap(reader, rawFileName);
|
|
}
|
|
|
|
public String decodeUTF8(long address) throws IOException
|
|
{
|
|
return decodeUTF8(address, -1);
|
|
}
|
|
|
|
public String decodeUTF8(long address, int limit) throws IOException
|
|
{
|
|
if (address == 0)
|
|
return null;
|
|
|
|
BytePtr utf8 = memoryMap.getBytePtr(address, 64);
|
|
|
|
if (utf8 == null)
|
|
return null;
|
|
|
|
int len = utf8.getShort(1);
|
|
int hash16 = utf8.getShort(0) & 0xffff;
|
|
|
|
if (len <= 0 || (limit > 0 && len > (limit - 4)))
|
|
return null;
|
|
|
|
if (len > utf8.getsize() + 4)
|
|
utf8 = memoryMap.getBytePtr(address, len + 4);
|
|
|
|
if (utf8 == null)
|
|
return null;
|
|
|
|
StringBuilder sb = new StringBuilder(len);
|
|
int pos = 4;
|
|
len += 4;
|
|
|
|
while (pos < len)
|
|
{
|
|
int f = utf8.getByte(pos++);
|
|
if ((f & 0x80) == 0)
|
|
{
|
|
sb.append((char)f);
|
|
}
|
|
else if ((f & 0xe0) == 0xc0)
|
|
{
|
|
int s = utf8.getByte(pos++);
|
|
char c = (char)(((f & 0x1f) << 6) | (s & 0x80));
|
|
sb.append(c);
|
|
}
|
|
else if ((f & 0xe0) == 0xe0)
|
|
{
|
|
int s = utf8.getByte(pos++);
|
|
int t = utf8.getByte(pos++);
|
|
char c = (char)(((f & 0x0f) << 12)
|
|
| ((s & 0x80) << 6) | (t & 0x80));
|
|
sb.append(c);
|
|
}
|
|
else
|
|
break; // Bad utf8
|
|
}
|
|
String rv = sb.toString();
|
|
if (hash16 == (rv.hashCode() & 0xffff))
|
|
return rv;
|
|
else
|
|
return null;
|
|
}
|
|
|
|
public String getSymbolViaVtable(long address) throws IOException
|
|
{
|
|
return memoryMap.getSymbol(address);
|
|
}
|
|
|
|
public String getSymbol(long address) throws IOException
|
|
{
|
|
String symbol = memoryMap.getSymbol(address);
|
|
if (null != symbol)
|
|
return symbol;
|
|
|
|
BytePtr klass = memoryMap.getBytePtr(address, 3 * memoryMap.wordSize);
|
|
if (klass == null)
|
|
return null;
|
|
|
|
long nameUTF8p = klass.getWord(2);
|
|
|
|
return decodeUTF8(nameUTF8p);
|
|
}
|
|
|
|
BytePtr getBytePtr(long addr, int length) throws IOException
|
|
{
|
|
return memoryMap.getBytePtr(addr, length);
|
|
}
|
|
}
|