mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 10:46:02 +02:00
First implementation of STABS debug format parsing
This commit is contained in:
parent
e63680bf70
commit
24e017a04a
4 changed files with 724 additions and 0 deletions
|
@ -1,3 +1,11 @@
|
|||
2004-01-06 Alain Magloire
|
||||
|
||||
Simple draft implementation of stabs debug format parsing.
|
||||
Not ready.
|
||||
|
||||
* utils/org/eclipse/cdt/utils/stabs: New package implementing
|
||||
Stabs debug format parsing.
|
||||
|
||||
2003-12-29 Hoda Amer
|
||||
Content Assist Work : Moved ICompletionRequestor from core to ui
|
||||
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2002,2003 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
***********************************************************************/
|
||||
|
||||
package org.eclipse.cdt.utils.stabs;
|
||||
|
||||
public final class StabConstant {
|
||||
|
||||
// Stab Symbol Types
|
||||
public final static int N_UNDF = 0x00;
|
||||
public final static int N_GSYM = 0x20;
|
||||
public final static int N_FNAME = 0x22;
|
||||
public final static int N_FUN = 0x24;
|
||||
public final static int N_STSYM = 0x26;
|
||||
public final static int N_LCSYM = 0x28;
|
||||
public final static int N_MAIN = 0x2a;
|
||||
public final static int N_ROSYM = 0x2c;
|
||||
public final static int N_PC = 0x30;
|
||||
public final static int N_NSYMS = 0x32;
|
||||
public final static int N_NOMAP = 0x34;
|
||||
public final static int N_OBJ = 0x38;
|
||||
public final static int N_OPT = 0x3c;
|
||||
public final static int N_RSYM = 0x40;
|
||||
public final static int N_M2C = 0x42;
|
||||
public final static int N_SLINE = 0x44;
|
||||
public final static int N_DSLINE = 0x46;
|
||||
public final static int N_BSLINE = 0x48;
|
||||
public final static int N_DEFD = 0x4a;
|
||||
public final static int N_FLINE = 0x4c;
|
||||
public final static int N_EHDECL = 0x50;
|
||||
public final static int N_CATCH = 0x54;
|
||||
public final static int N_SSYM = 0x60;
|
||||
public final static int N_ENDM = 0x62;
|
||||
public final static int N_SO = 0x64;
|
||||
public final static int N_LSYM = 0x80;
|
||||
public final static int N_BINCL = 0x82;
|
||||
public final static int N_SOL = 0x84;
|
||||
public final static int N_PSYM = 0xa0;
|
||||
public final static int N_EINCL = 0xa2;
|
||||
public final static int N_ENTRY = 0xa4;
|
||||
public final static int N_LBRAC = 0xc0;
|
||||
public final static int N_EXCL = 0xc2;
|
||||
public final static int N_SCOPE = 0xc4;
|
||||
public final static int N_RBRAC = 0xe0;
|
||||
public final static int N_BCOMM = 0xe2;
|
||||
public final static int N_ECOMM = 0xe4;
|
||||
public final static int N_ECOML = 0xe8;
|
||||
public final static int N_WITH = 0xea;
|
||||
public final static int N_NBTEXT = 0xef;
|
||||
public final static int N_NBDATA = 0xf2;
|
||||
public final static int N_NBBSS = 0xf4;
|
||||
public final static int N_NBSTS = 0xf6;
|
||||
public final static int N_NBLCS = 0xf8;
|
||||
|
||||
public final static int SIZE = 12; // 4 + 1 + 1 + 2 + 4
|
||||
|
||||
public static String type2String(int t) {
|
||||
switch (t) {
|
||||
case N_UNDF :
|
||||
return "UNDF";
|
||||
case N_GSYM :
|
||||
return "GSYM";
|
||||
case N_FNAME :
|
||||
return "FNAME";
|
||||
case N_FUN :
|
||||
return "FUN";
|
||||
case N_STSYM :
|
||||
return "STSYM";
|
||||
case N_LCSYM :
|
||||
return "LCSYM";
|
||||
case N_MAIN :
|
||||
return "MAIN";
|
||||
case N_ROSYM :
|
||||
return "ROSYM";
|
||||
case N_PC :
|
||||
return "PC";
|
||||
case N_NSYMS :
|
||||
return "SSYMS";
|
||||
case N_NOMAP :
|
||||
return "NOMAP";
|
||||
case N_OBJ :
|
||||
return "OBJ";
|
||||
case N_OPT :
|
||||
return "OPT";
|
||||
case N_RSYM :
|
||||
return "RSYM";
|
||||
case N_M2C :
|
||||
return "M2C";
|
||||
case N_SLINE :
|
||||
return "SLINE";
|
||||
case N_DSLINE :
|
||||
return "DSLINE";
|
||||
case N_BSLINE :
|
||||
return "BSLINE";
|
||||
case N_DEFD :
|
||||
return "DEFD";
|
||||
case N_FLINE :
|
||||
return "FLINE";
|
||||
case N_EHDECL :
|
||||
return "EHDECL";
|
||||
case N_CATCH :
|
||||
return "CATCH";
|
||||
case N_SSYM :
|
||||
return "SSYM";
|
||||
case N_ENDM :
|
||||
return "ENDM";
|
||||
case N_SO :
|
||||
return "SO";
|
||||
case N_LSYM :
|
||||
return "LSYM";
|
||||
case N_BINCL :
|
||||
return "BINCL";
|
||||
case N_SOL :
|
||||
return "SOL";
|
||||
case N_PSYM :
|
||||
return "PSYM";
|
||||
case N_EINCL :
|
||||
return "EINCL";
|
||||
case N_ENTRY :
|
||||
return "ENTRY";
|
||||
case N_LBRAC :
|
||||
return "LBRAC";
|
||||
case N_EXCL :
|
||||
return "EXCL";
|
||||
case N_SCOPE:
|
||||
return "SCOPE";
|
||||
case N_RBRAC :
|
||||
return "RBRAC";
|
||||
case N_BCOMM :
|
||||
return "COMM";
|
||||
case N_ECOMM :
|
||||
return "ECOMM";
|
||||
case N_ECOML :
|
||||
return "ECOML";
|
||||
case N_WITH :
|
||||
return "WITH";
|
||||
case N_NBTEXT :
|
||||
return "NBTEXT";
|
||||
case N_NBDATA :
|
||||
return "NBDATA";
|
||||
case N_NBBSS :
|
||||
return "NBBSS";
|
||||
case N_NBSTS :
|
||||
return "NBSTS";
|
||||
case N_NBLCS :
|
||||
return "NBLCS";
|
||||
}
|
||||
return "" + t;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,399 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2002,2003 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
***********************************************************************/
|
||||
|
||||
package org.eclipse.cdt.utils.stabs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.utils.elf.Elf;
|
||||
|
||||
public class Stabs {
|
||||
|
||||
byte[] stabData;
|
||||
byte[] stabstrData;
|
||||
boolean isLe;
|
||||
List entries;
|
||||
|
||||
public class Entry {
|
||||
public long addr;
|
||||
public int startLine;
|
||||
public String string;
|
||||
|
||||
public Entry(String s) {
|
||||
string = s;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("Name:").append(string).append("\n");
|
||||
buf.append("\taddress:").append(addr).append("\n");
|
||||
buf.append("\tstartLine:").append(startLine).append("\n");
|
||||
//buf.append("\tName:").append(string).append("\n");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class LocatableEntry extends Entry {
|
||||
public String filename;
|
||||
|
||||
public LocatableEntry(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
public class Variable extends LocatableEntry {
|
||||
public int kind;
|
||||
public Function function;
|
||||
|
||||
public Variable(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer(super.toString());
|
||||
buf.append("\tkind:").append(kind).append("\n");
|
||||
buf.append("\tfilename:").append(filename).append("\n");
|
||||
buf.append("\tVariable");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public class Function extends LocatableEntry {
|
||||
public int endLine;
|
||||
public ArrayList lines;
|
||||
public ArrayList variables;
|
||||
|
||||
public Function(String s) {
|
||||
super(s);
|
||||
variables = new ArrayList();
|
||||
lines = new ArrayList();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer(super.toString());
|
||||
buf.append("\tendLine:").append(endLine).append("\n");
|
||||
buf.append("\tfilename:").append(filename).append("\n");
|
||||
buf.append("\tSource code: ");
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
buf.append(" ").append(lines.get(i));
|
||||
}
|
||||
buf.append("\n");
|
||||
buf.append("\tVariables\n");
|
||||
for (int i = 0; i < variables.size(); i++) {
|
||||
buf.append("\t\t").append(variables.get(i)).append("\n");
|
||||
}
|
||||
buf.append("\tFunction");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public class Include extends Entry {
|
||||
int index;
|
||||
|
||||
public Include(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + "\tindex:" + index + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeDef extends Entry {
|
||||
String type;
|
||||
|
||||
public TypeDef(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeDefinition extends Entry {
|
||||
int typeNumber;
|
||||
String name;
|
||||
|
||||
public TypeDefinition(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
public class StringField extends Entry {
|
||||
String name;
|
||||
String symbolDescriptor;
|
||||
String typeDefinition;
|
||||
int typeNumber;
|
||||
|
||||
public StringField(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
public String makeString(long offset) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (; offset < stabstrData.length; offset++) {
|
||||
byte b = stabstrData[(int) offset];
|
||||
if (b == 0) {
|
||||
break;
|
||||
}
|
||||
buf.append((char) b);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public Stabs(byte[] stab, byte[] stabstr, boolean le) {
|
||||
stabData = stab;
|
||||
stabstrData = stabstr;
|
||||
isLe = le;
|
||||
}
|
||||
|
||||
public Entry[] getEntries() throws IOException {
|
||||
if (entries == null) {
|
||||
parse();
|
||||
}
|
||||
Entry[] array = new Entry[entries.size()];
|
||||
entries.toArray(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
void parse() throws IOException {
|
||||
|
||||
entries = new ArrayList();
|
||||
|
||||
long nstab = stabData.length / StabConstant.SIZE;
|
||||
int i, offset, bracket;
|
||||
int includeCount = 0;
|
||||
Function currentFunction = null;
|
||||
String currentFile = "";
|
||||
String holder = null;
|
||||
|
||||
for (bracket = i = offset = 0; i < nstab; i++, offset += StabConstant.SIZE) {
|
||||
|
||||
long stroff = 0;
|
||||
int type = 0;
|
||||
int other = 0;
|
||||
short desc = 0;
|
||||
long value = 0;
|
||||
String name = new String();
|
||||
|
||||
// get the offset for the string; 4 bytes
|
||||
if (isLe) {
|
||||
stroff =
|
||||
(((stabData[offset + 3] & 0xff) << 24)
|
||||
+ ((stabData[offset + 2] & 0xff) << 16)
|
||||
+ ((stabData[offset + 1] & 0xff) << 8)
|
||||
+ (stabData[offset] & 0xff));
|
||||
} else {
|
||||
stroff =
|
||||
(((stabData[offset] & 0xff) << 24)
|
||||
+ ((stabData[offset + 1] & 0xff) << 16)
|
||||
+ ((stabData[offset + 2] & 0xff) << 8)
|
||||
+ (stabData[offset + 3] & 0xff));
|
||||
}
|
||||
|
||||
if (stroff > 0) {
|
||||
name = makeString(stroff);
|
||||
}
|
||||
|
||||
// Check for continuation and if any go to the next stab
|
||||
// until we find a string that is not terminated with a continuation line '\\'
|
||||
// According to the spec all the other fields are duplicated so we still have the data.
|
||||
// From the spec continuation line on AIX is '?'
|
||||
if (name.endsWith("\\") || name.endsWith("?")) {
|
||||
name = name.substring(0, name.length() - 1);
|
||||
if (holder == null) {
|
||||
holder = name;
|
||||
} else {
|
||||
holder += name;
|
||||
}
|
||||
continue;
|
||||
} else if (holder != null) {
|
||||
name = holder + name;
|
||||
holder = null;
|
||||
}
|
||||
|
||||
// get the type; 1 byte;
|
||||
type = 0xff & stabData[offset + 4];
|
||||
|
||||
// get the other
|
||||
other = 0xff & stabData[offset + 5];
|
||||
|
||||
// get the desc
|
||||
if (isLe) {
|
||||
int a = stabData[offset + 8] << 8;
|
||||
int b = stabData[offset + 7];
|
||||
int c = a + b;
|
||||
//desc = (short) ((stabData[offset + 7] << 8) + stabData[offset + 6]);
|
||||
desc = (short) ((stabData[offset + 8] << 8) + stabData[offset + 7]);
|
||||
} else {
|
||||
desc = (short) ((stabData[offset + 6] << 8) + stabData[offset + 7]);
|
||||
}
|
||||
|
||||
// get the value
|
||||
if (isLe) {
|
||||
value =
|
||||
(((stabData[offset + 11] & 0xff) << 24)
|
||||
+ ((stabData[offset + 10] & 0xff) << 16)
|
||||
+ ((stabData[offset + 9] & 0xff) << 8)
|
||||
+ (stabData[offset + 8] & 0xff));
|
||||
} else {
|
||||
value =
|
||||
(((stabData[offset + 8] & 0xff) << 24)
|
||||
+ ((stabData[offset + 9] & 0xff) << 16)
|
||||
+ ((stabData[offset + 10] & 0xff) << 8)
|
||||
+ (stabData[offset + 11] & 0xff));
|
||||
}
|
||||
|
||||
// Parse the string
|
||||
switch (type) {
|
||||
case StabConstant.N_GSYM :
|
||||
case StabConstant.N_LSYM :
|
||||
case StabConstant.N_PSYM :
|
||||
Variable variable = new Variable(name);
|
||||
variable.kind = type;
|
||||
variable.addr = value;
|
||||
variable.startLine = desc;
|
||||
variable.function = currentFunction;
|
||||
variable.filename = currentFile;
|
||||
entries.add(variable);
|
||||
if (currentFunction != null) {
|
||||
currentFunction.variables.add(variable);
|
||||
}
|
||||
break;
|
||||
case StabConstant.N_SLINE :
|
||||
if (currentFunction != null) {
|
||||
currentFunction.endLine = desc;
|
||||
currentFunction.lines.add(new Integer(desc));
|
||||
}
|
||||
break;
|
||||
case StabConstant.N_FUN :
|
||||
if (name.length() == 0 || desc == 0) {
|
||||
currentFunction = null;
|
||||
} else {
|
||||
currentFunction = new Function(name);
|
||||
currentFunction.addr = value;
|
||||
currentFunction.startLine = desc;
|
||||
currentFunction.filename = currentFile;
|
||||
entries.add(currentFunction);
|
||||
}
|
||||
break;
|
||||
case StabConstant.N_LBRAC :
|
||||
bracket++;
|
||||
break;
|
||||
case StabConstant.N_RBRAC :
|
||||
bracket--;
|
||||
break;
|
||||
case StabConstant.N_BINCL :
|
||||
Include include = new Include(name);
|
||||
include.index = includeCount++;
|
||||
entries.add(include);
|
||||
break;
|
||||
case StabConstant.N_EINCL :
|
||||
break;
|
||||
case StabConstant.N_SO :
|
||||
if (name.length() == 0) {
|
||||
currentFile = name;
|
||||
} else {
|
||||
if (currentFile != null && currentFile.endsWith("/")) {
|
||||
currentFile += name;
|
||||
} else {
|
||||
currentFile = name;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
//System.out.println(" " + i + "\t" + Stab.type2String(type) + "\t" + other + "\t\t" +
|
||||
// desc + "\t" + Long.toHexString(value) + "\t" + + stroff + "\t\t" +name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format: string_field = name ':' symbol-descriptor type-information type-information = type_number [ '=' ( type_description |
|
||||
* type_reference )] type_number = number | '(' number ',' number ')' type_reference type_descriptor =
|
||||
*/
|
||||
private void parseString(String s, StringField field) {
|
||||
// Some String field may contain format like:
|
||||
// "foo::bar::baz:t5=*6" in that case the name is "foo::bar::baz"
|
||||
int index = s.lastIndexOf(':');
|
||||
|
||||
if (index > 0) {
|
||||
field.name = s.substring(0, index).trim();
|
||||
index++;
|
||||
// Advance the string.
|
||||
s = s.substring(index);
|
||||
} else {
|
||||
field.name = s;
|
||||
s = new String();
|
||||
}
|
||||
|
||||
// get the symbol descriptor
|
||||
for (index = 0; index < s.length(); index++) {
|
||||
char c = s.charAt(index);
|
||||
if (!(Character.isLetter(c) || c == ':' || c == '-')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index > 0) {
|
||||
field.symbolDescriptor = s.substring(0, index);
|
||||
index++;
|
||||
// Advance the string.
|
||||
s = s.substring(index);
|
||||
} else {
|
||||
field.symbolDescriptor = new String();
|
||||
}
|
||||
|
||||
field.typeDefinition = s;
|
||||
|
||||
}
|
||||
|
||||
private void parseType(String s) {
|
||||
int index = s.indexOf(':');
|
||||
if (index != -1) {
|
||||
}
|
||||
// "name:symbol-descriptor type-information"
|
||||
}
|
||||
|
||||
public void print() {
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
Entry entry = (Entry) entries.get(i);
|
||||
System.out.println(entry);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Elf.Section stab = null;
|
||||
Elf.Section stabstr = null;
|
||||
Elf exe = new Elf(args[0]);
|
||||
Elf.Section[] sections = exe.getSections();
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
String name = sections[i].toString();
|
||||
if (name.equals(".stab")) {
|
||||
stab = sections[i];
|
||||
} else if (name.equals(".stabstr")) {
|
||||
stabstr = sections[i];
|
||||
}
|
||||
}
|
||||
if (stab != null && stabstr != null) {
|
||||
long nstab = stab.sh_size / StabConstant.SIZE;
|
||||
System.out.println("Number of stabs" + nstab);
|
||||
byte[] array = stab.loadSectionData();
|
||||
byte[] strtab = stabstr.loadSectionData();
|
||||
Stabs stabs = new Stabs(array, strtab, true);
|
||||
stabs.parse();
|
||||
stabs.print();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2002,2003 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
***********************************************************************/
|
||||
|
||||
package org.eclipse.cdt.utils.stabs;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.utils.elf.Elf;
|
||||
|
||||
/**
|
||||
* StabsAddr2ine
|
||||
*
|
||||
* @author alain
|
||||
*/
|
||||
public class StabsAddr2line {
|
||||
|
||||
Stabs stabs;
|
||||
long lastAddress;
|
||||
Stabs.Entry entry;
|
||||
|
||||
public StabsAddr2line(byte[] stab, byte[] stabstr, boolean le) throws IOException {
|
||||
stabs = new Stabs(stab, stabstr, le);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see IAddr2line#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see IAddr2line#getStartLine(long)
|
||||
*/
|
||||
public int getStartLine(long address) throws IOException {
|
||||
if (address != lastAddress || entry == null) {
|
||||
Stabs.Entry[] entries = stabs.getEntries();
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
if (entries[i].addr == address) {
|
||||
lastAddress = address;
|
||||
entry = entries[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (address == lastAddress && entry != null) {
|
||||
return entry.startLine;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see IAddr2line#getEndLine(long)
|
||||
*/
|
||||
public int getEndLine(long address) throws IOException {
|
||||
if (address != lastAddress || entry == null) {
|
||||
Stabs.Entry[] entries = stabs.getEntries();
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
if (entries[i].addr == address) {
|
||||
lastAddress = address;
|
||||
entry = entries[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (address == lastAddress && entry != null) {
|
||||
if (entry instanceof Stabs.Function) {
|
||||
return ((Stabs.Function)entry).endLine;
|
||||
}
|
||||
return entry.startLine;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see IAddr2line#getFunction(long)
|
||||
*/
|
||||
public String getFunction(long address) throws IOException {
|
||||
if (address != lastAddress || entry == null) {
|
||||
Stabs.Entry[] entries = stabs.getEntries();
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
if (entries[i].addr == address) {
|
||||
lastAddress = address;
|
||||
entry = entries[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (address == lastAddress && entry != null) {
|
||||
return entry.string;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see IAddr2line#getFileName(long)
|
||||
*/
|
||||
public String getFileName(long address) throws IOException {
|
||||
if (address != lastAddress || entry == null) {
|
||||
Stabs.Entry[] entries = stabs.getEntries();
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
if (entries[i].addr == address) {
|
||||
lastAddress = address;
|
||||
entry = entries[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (address == lastAddress && entry instanceof Stabs.LocatableEntry) {
|
||||
return ((Stabs.LocatableEntry)entry).filename;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Elf.Section stab = null;
|
||||
Elf.Section stabstr = null;
|
||||
Elf exe = new Elf(args[0]);
|
||||
Elf.Section[] sections = exe.getSections();
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
String name = sections[i].toString();
|
||||
if (name.equals(".stab")) {
|
||||
stab = sections[i];
|
||||
} else if (name.equals(".stabstr")) {
|
||||
stabstr = sections[i];
|
||||
}
|
||||
}
|
||||
if (stab != null && stabstr != null) {
|
||||
long nstab = stab.sh_size / StabConstant.SIZE;
|
||||
System.out.println("Number of stabs" + nstab);
|
||||
byte[] array = stab.loadSectionData();
|
||||
byte[] strtab = stabstr.loadSectionData();
|
||||
StabsAddr2line addr2line = new StabsAddr2line(array, strtab, true);
|
||||
long address = Integer.decode(args[1]).longValue();
|
||||
addr2line.getStartLine(address);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue