gcc/libjava/gnu/gcj/tools/gc_analyze/SymbolTable.java

199 lines
5.4 KiB
Java
Raw Normal View History

Make-lang.in (JAVA_MANFILES): Add doc/gc-analyze.1. gcc/java: 2007-02-15 David Daney <ddaney@avtrex.com> * Make-lang.in (JAVA_MANFILES): Add doc/gc-analyze.1. (java.maintainer-clean):Add gc-analyze.1. (.INTERMEDIATE): Add gc-analyze.pod. (gc-analyze.pod): New rule. (java.install-man): Install gc-analyze.1 * gcj.texi: Add new section for the gc-analyze program. libjava: 2007-02-15 Johannes Schmidt <jschmidt@avtrex.com> David Daney <ddaney@avtrex.com> * configure.ac: Create vm-tools-packages file. Add gnu/gcj/tools/gc_analyze to standard.omit and vm-tools-packages. Check for /proc/self/maps. * Makefile.am (bin_PROGRAMS): Added gc-analyze. (gc_analyze_SOURCES): New. (gc_analyze_LDFLAGS): New. (gc_analyze_LINK): New. (gc_analyze_LDADD): New. (gc_analyze_DEPENDENCIES): New. (nat_source_files): Add gnu/gcj/util/natGCInfo.cc. * Makefile.in: Regenerated. * configure: Regenerated. * include/config.h.in: Regenerated. * sources.am: Regenerated. * scripts/makemake.tcl: Don't include gc-analyze classes in libgcj. * gnu/gcj/tools/gc_analyze/SymbolLookup.java: New. * gnu/gcj/tools/gc_analyze/ObjectMap.java: New. * gnu/gcj/tools/gc_analyze/MemoryMap.java: New. * gnu/gcj/tools/gc_analyze/SymbolTable.java: New. * gnu/gcj/tools/gc_analyze/BlockMap.java: New. * gnu/gcj/tools/gc_analyze/BytePtr.java: New. * gnu/gcj/tools/gc_analyze/ItemList.java: New. * gnu/gcj/tools/gc_analyze/ToolPrefix.java: New. * gnu/gcj/tools/gc_analyze/MemoryAnalyze.java: New. * gnu/gcj/util/GCInfo.java: New. * gnu/gcj/util/GCInfo.h: New. * gnu/gcj/util/natGCInfo.cc: New. * gnu/gcj/util/UtilPermission.java: New. * gnu/gcj/util/UtilPermission.h: New. * classpath/tools/gnu/gcj/tools/gc_analyze/SymbolTable.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/ObjectMap$ObjectItem.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryMap$RangeComparator.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/BlockMap$PtrMarks.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryMap$Range.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/BlockMap.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/BytePtr.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryAnalyze$SubstringComparator.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/ItemList.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/ToolPrefix.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryAnalyze.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryAnalyze$1$Info.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryAnalyze$1.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryAnalyze$2.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryAnalyze$3.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryAnalyze$4.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryAnalyze$OptionParser.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/BlockMap$SizeKind.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/SymbolLookup.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/ObjectMap.class: New. * classpath/tools/gnu/gcj/tools/gc_analyze/MemoryMap.class: New. * classpath/lib/gnu/gcj/util/GCInfo.class: New. * classpath/lib/gnu/gcj/util/UtilPermission.class: New. libjava/classpath: 2007-02-15 David Daney <ddaney@avtrex.com> * tools/Makefile.am (TOOLS_ZIP): Add classes from vm-tools-packages. * tools/Makefile.in: Regenerated. From-SVN: r122007
2007-02-15 18:25:24 +01:00
/* SymbolTable.java -- Maintains a mapping of addresses to names.
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;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class SymbolTable
{
// Long address->String name
private HashMap<Long, String> map = new HashMap<Long, String>();
// Reverse
// String name -> Long address
// used for RelocateImage
private HashMap<String, Long> reverse = new HashMap<String, Long>();
long loadAddr;
long relocation;
static Matcher interestingSymbol =
Pattern.compile("^([0-9a-fA-F]+)\\s+\\S+\\s+(_Z\\S+)").matcher("");
static Matcher readelfLoadMatcher =
Pattern.compile("^\\s+LOAD\\s+(\\S+)\\s+(\\S+)\\s.*").matcher("");
public SymbolTable(String filename) throws IOException
{
Process p = Runtime.getRuntime().exec(ToolPrefix.toolPrefix
+ "nm " + filename);
InputStream es = p.getErrorStream();
InputStream is = p.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
int count = 0;
String line;
while ((line = reader.readLine()) != null)
{
interestingSymbol.reset(line);
if (interestingSymbol.matches())
{
try
{
String name = interestingSymbol.group(2);
String addr = interestingSymbol.group(1);
if (name.startsWith("_ZTVN") || name.endsWith("6class$E"))
{
long address = MemoryMap.parseHexLong(addr);
Long l = new Long(address);
map.put(l, name);
count++;
reverse.put(name, l);
}
}
catch (NumberFormatException e)
{
// ignore it
}
}
}
es.close();
is.close();
p.destroy();
if (count > 0)
{
// Assume nm read some symbols from it and that
// readelf can tell us something about how it is loaded.
p = Runtime.getRuntime().exec(ToolPrefix.toolPrefix
+ "readelf -l " + filename);
es = p.getErrorStream();
is = p.getInputStream();
reader = new BufferedReader(new InputStreamReader(is));
while ((line = reader.readLine()) != null)
{
readelfLoadMatcher.reset(line);
if (readelfLoadMatcher.matches())
{
loadAddr
= Long.decode(readelfLoadMatcher.group(2)).longValue();
break;
}
}
es.close();
is.close();
p.destroy();
}
System.out.println(ToolPrefix.toolPrefix + "nm " + filename
+ " -> " + count + " symbols");
}
public static void main(String args[])
{
try
{
SymbolTable st = new SymbolTable(args[0]);
st.dump();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public static String demangleVTName(String n)
{
if (n.startsWith("_ZTVN") && n.endsWith("E"))
return demangle(n.substring(5, n.length() - 1));
else
return null;
}
public void dump()
{
for (Map.Entry<Long, String> me : map.entrySet())
{
long address = me.getKey();
String symbol = me.getValue();
System.out.println(Long.toHexString(address) + " -> " + symbol);
if (symbol.startsWith("_ZN") && symbol.endsWith("6class$E"))
{
System.out.println(" Class: "
+ demangle(symbol.substring(3, symbol.length()
- 8)));
}
else if (symbol.startsWith("_ZTVN") && symbol.endsWith("E"))
{
System.out.println(" VT: "
+ demangle(symbol.substring(5, symbol.length()
- 1)));
}
}
}
private static String demangle(String symbol)
{
StringBuilder sb = new StringBuilder();
for (int i=0; i<symbol.length(); )
{
int l = 0;
while (i < symbol.length())
{
int d = symbol.charAt(i);
if (d < '0' || d > '9')
break;
l = 10 * l + (d - '0');
i++;
}
if (l == 0)
break;
// copy
if (sb.length() > 0)
sb.append('.');
while (l > 0 && i < symbol.length())
{
sb.append(symbol.charAt(i));
l--;
i++;
}
}
return sb.toString();
}
public String getSymbol(long address)
{
String symbol = map.get(address);
if (symbol == null)
return null;
if (symbol.startsWith("_ZN") && symbol.endsWith("6class$E"))
symbol = demangle(symbol.substring(3, symbol.length() - 8));
return symbol;
}
// will return -1 if not found
public long getAddress(String symbol)
{
Long address = reverse.get(symbol);
if (address == null)
return -1;
return address.longValue();
}
}