1 /* SymbolTable.java -- Maintains a mapping of addresses to names.
2 Copyright (C) 2007 Free Software Foundation
4 This file is part of libgcj.
6 This software is copyrighted work licensed under the terms of the
7 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
10 package gnu.gcj.tools.gc_analyze;
12 import java.io.BufferedReader;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.InputStreamReader;
16 import java.util.HashMap;
18 import java.util.regex.Matcher;
19 import java.util.regex.Pattern;
23 // Long address->String name
24 private HashMap<Long, String> map = new HashMap<Long, String>();
27 // String name -> Long address
28 // used for RelocateImage
29 private HashMap<String, Long> reverse = new HashMap<String, Long>();
34 static Matcher interestingSymbol =
35 Pattern.compile("^([0-9a-fA-F]+)\\s+\\S+\\s+(_Z\\S+)").matcher("");
36 static Matcher readelfLoadMatcher =
37 Pattern.compile("^\\s+LOAD\\s+(\\S+)\\s+(\\S+)\\s.*").matcher("");
39 public SymbolTable(String filename) throws IOException
41 Process p = Runtime.getRuntime().exec(ToolPrefix.toolPrefix
43 InputStream es = p.getErrorStream();
44 InputStream is = p.getInputStream();
46 BufferedReader reader = new BufferedReader(new InputStreamReader(is));
50 while ((line = reader.readLine()) != null)
52 interestingSymbol.reset(line);
53 if (interestingSymbol.matches())
57 String name = interestingSymbol.group(2);
58 String addr = interestingSymbol.group(1);
59 if (name.startsWith("_ZTVN") || name.endsWith("6class$E"))
61 long address = MemoryMap.parseHexLong(addr);
62 Long l = new Long(address);
68 catch (NumberFormatException e)
80 // Assume nm read some symbols from it and that
81 // readelf can tell us something about how it is loaded.
82 p = Runtime.getRuntime().exec(ToolPrefix.toolPrefix
83 + "readelf -l " + filename);
84 es = p.getErrorStream();
85 is = p.getInputStream();
87 reader = new BufferedReader(new InputStreamReader(is));
88 while ((line = reader.readLine()) != null)
90 readelfLoadMatcher.reset(line);
91 if (readelfLoadMatcher.matches())
94 = Long.decode(readelfLoadMatcher.group(2)).longValue();
103 System.out.println(ToolPrefix.toolPrefix + "nm " + filename
104 + " -> " + count + " symbols");
107 public static void main(String args[])
111 SymbolTable st = new SymbolTable(args[0]);
116 ex.printStackTrace();
120 public static String demangleVTName(String n)
122 if (n.startsWith("_ZTVN") && n.endsWith("E"))
123 return demangle(n.substring(5, n.length() - 1));
130 for (Map.Entry<Long, String> me : map.entrySet())
132 long address = me.getKey();
133 String symbol = me.getValue();
134 System.out.println(Long.toHexString(address) + " -> " + symbol);
135 if (symbol.startsWith("_ZN") && symbol.endsWith("6class$E"))
137 System.out.println(" Class: "
138 + demangle(symbol.substring(3, symbol.length()
141 else if (symbol.startsWith("_ZTVN") && symbol.endsWith("E"))
143 System.out.println(" VT: "
144 + demangle(symbol.substring(5, symbol.length()
150 private static String demangle(String symbol)
152 StringBuilder sb = new StringBuilder();
153 for (int i=0; i<symbol.length(); )
156 while (i < symbol.length())
158 int d = symbol.charAt(i);
159 if (d < '0' || d > '9')
161 l = 10 * l + (d - '0');
169 while (l > 0 && i < symbol.length())
171 sb.append(symbol.charAt(i));
176 return sb.toString();
179 public String getSymbol(long address)
181 String symbol = map.get(address);
185 if (symbol.startsWith("_ZN") && symbol.endsWith("6class$E"))
186 symbol = demangle(symbol.substring(3, symbol.length() - 8));
190 // will return -1 if not found
191 public long getAddress(String symbol)
193 Long address = reverse.get(symbol);
196 return address.longValue();