1:
9:
10: package ;
11:
12: import ;
13: import ;
14:
15: import ;
16:
17: import ;
18: import ;
19: import ;
20: import ;
21: import ;
22: import ;
23: import ;
24: import ;
25: import ;
26: import ;
27: import ;
28:
29:
30:
51: public class NameFinder
52: {
53:
56: private String binaryFile;
57: private String sourceFile;
58: private int lineNum;
59: private HashMap procs = new HashMap();
60:
63: private static Set blacklist = Collections.synchronizedSet(new HashSet());
64:
65: private static boolean use_addr2line
66: = Boolean.valueOf(System.getProperty
67: ("gnu.gcj.runtime.NameFinder.use_addr2line", "true")
68: ).booleanValue();
69:
70: private static boolean show_raw
71: = Boolean.valueOf(System.getProperty
72: ("gnu.gcj.runtime.NameFinder.show_raw", "false")
73: ).booleanValue();
74:
75:
79: static final boolean showRaw()
80: {
81: return show_raw;
82: }
83:
84: private static final boolean remove_unknown
85: = Boolean.valueOf(System.getProperty
86: ("gnu.gcj.runtime.NameFinder.remove_unknown", "true")
87: ).booleanValue();
88:
89:
93: static final boolean removeUnknown()
94: {
95: return remove_unknown;
96: }
97:
98: class Addr2Line
99: {
100: Process proc;
101: BufferedWriter out;
102: BufferedReader in;
103:
104: Addr2Line(String binaryFile)
105: {
106: try
107: {
108: String[] exec = new String[] {"addr2line", "-e", binaryFile};
109: Runtime runtime = Runtime.getRuntime();
110: proc = runtime.exec(exec);
111: }
112: catch (IOException ioe)
113: {
114: }
115:
116: if (proc != null)
117: {
118: in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
119: out = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
120: }
121: }
122:
123: void close()
124: {
125: try
126: {
127: if (in != null)
128: in.close();
129: if (out != null)
130: out.close();
131: }
132: catch (IOException x) {}
133: if (proc != null)
134: proc.destroy();
135: }
136: }
137:
138:
142: public NameFinder()
143: {
144: }
145:
146:
150: public String getSourceFile()
151: {
152: String file;
153: if (sourceFile != null)
154: file = sourceFile;
155: else
156: file = binaryFile;
157:
158: return file.substring(file.lastIndexOf(File.separator) + 1, file.length());
159: }
160:
161:
165: public int getLineNum()
166: {
167: return lineNum;
168: }
169:
170: public void lookup (String file, long addr)
171: {
172: binaryFile = file;
173: sourceFile = null;
174: lineNum = -1;
175:
176: if (! use_addr2line || blacklist.contains(file))
177: return;
178: Addr2Line addr2line = (Addr2Line) procs.get(file);
179: if (addr2line == null)
180: {
181: addr2line = new Addr2Line(file);
182: procs.put(file, addr2line);
183: }
184:
185: if (addr2line.proc == null)
186: {
187: use_addr2line = false;
188: return;
189: }
190:
191: String hexAddr = "0x" + Long.toHexString(addr);
192: String name;
193:
194: try
195: {
196: addr2line.out.write(hexAddr);
197: addr2line.out.newLine();
198: addr2line.out.flush();
199: String result = addr2line.in.readLine();
200:
201: if (result.indexOf("??") == -1)
202: {
203: int split = result.lastIndexOf(':');
204: sourceFile = result.substring(0, split);
205: String lineNumStr = result.substring(split + 1, result.length());
206: lineNum = Integer.parseInt (lineNumStr);
207: }
208: else
209: {
210:
212: blacklist.add(binaryFile);
213: }
214: }
215: catch (IOException ioe)
216: {
217: addr2line = null;
218: }
219: catch (NumberFormatException x)
220: {
221: }
222: }
223:
224:
228: public static String demangleInterpreterMethod(String m, String cn)
229: {
230: int index = 0;
231: int length = m.length();
232: StringBuffer sb = new StringBuffer(length);
233:
234:
235: if (m.startsWith("<init>"))
236: {
237: String className;
238: int i = cn.lastIndexOf('.');
239: if (i < 0)
240: className = cn;
241: else
242: className = cn.substring(i + 1);
243: sb.append(className);
244: index += 7;
245: }
246: else
247: {
248: int i = m.indexOf('(');
249: if (i > 0)
250: {
251: sb.append(m.substring(0,i));
252: index += i + 1;
253: }
254: }
255:
256: sb.append('(');
257:
258:
259: int arrayDepth = 0;
260: char c = (index < length) ? m.charAt(index) : ')';
261: while (c != ')')
262: {
263: String type;
264: switch(c)
265: {
266: case 'B':
267: type = "byte";
268: break;
269: case 'C':
270: type = "char";
271: break;
272: case 'D':
273: type = "double";
274: break;
275: case 'F':
276: type = "float";
277: break;
278: case 'I':
279: type = "int";
280: break;
281: case 'J':
282: type = "long";
283: break;
284: case 'S':
285: type = "short";
286: break;
287: case 'Z':
288: type = "boolean";
289: break;
290: case 'L':
291: int i = m.indexOf(';', index);
292: if (i > 0)
293: {
294: type = m.substring(index+1, i);
295: index = i;
296: }
297: else
298: type = "<unknown ref>";
299: break;
300: case '[':
301: type = "";
302: arrayDepth++;
303: break;
304: default:
305: type = "<unknown " + c + '>';
306: }
307: sb.append(type);
308:
309:
310: if (c != '[' && arrayDepth > 0)
311: while (arrayDepth > 0)
312: {
313: sb.append("[]");
314: arrayDepth--;
315: }
316:
317: index++;
318: char nc = (index < length) ? m.charAt(index) : ')';
319: if (c != '[' && nc != ')')
320: sb.append(", ");
321: c = nc;
322: }
323:
324:
325: sb.append(')');
326: return sb.toString();
327: }
328:
329:
332: public void close()
333: {
334: Iterator itr = procs.values().iterator();
335: while (itr.hasNext())
336: {
337: Addr2Line proc = (Addr2Line) itr.next();
338: proc.close();
339: }
340: }
341: }