mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 18:56: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
|
2003-12-29 Hoda Amer
|
||||||
Content Assist Work : Moved ICompletionRequestor from core to ui
|
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