1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-06 17:26:01 +02:00

New draft implementation of a generic debug framework callback

This commit is contained in:
Alain Magloire 2004-01-24 20:47:11 +00:00
parent c1a633f63d
commit 0f7f7e0b13
30 changed files with 3301 additions and 586 deletions

View file

@ -0,0 +1,35 @@
/**********************************************************************
* 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.debug;
/**
* DebugArrayType
*
*/
public class DebugArrayType extends DebugDerivedType {
int size;
/**
*
*/
public DebugArrayType(DebugType type, int arraySize) {
super(type);
size = arraySize;
}
public int getSize() {
return size;
}
}

View file

@ -0,0 +1,42 @@
/**********************************************************************
* 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.debug;
/**
* DebugType
*
*/
public class DebugBaseType extends DebugType {
String typeName;
int typeSize;
boolean typeUnSigned;
public DebugBaseType(String name, int size, boolean unSigned) {
typeName = name;
typeSize = size;
typeUnSigned = unSigned;
}
public String getTypeName() {
return typeName;
}
public int sizeof() {
return typeSize;
}
public boolean isUnSigned() {
return typeUnSigned;
}
}

View file

@ -0,0 +1,41 @@
/**********************************************************************
* 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.debug;
/**
* DebugCrossRefType
*
*/
public class DebugCrossRefType extends DebugDerivedType {
String name;
String xName;
/**
*
*/
public DebugCrossRefType(DebugType type, String name, String xName) {
super(type);
this.name = name;
this.xName = xName;
}
public String getName() {
return name;
}
public String getCrossRefName() {
return xName;
}
}

View file

@ -0,0 +1,38 @@
/**********************************************************************
* 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.debug;
/**
* DebugDerivedType
*
*/
public abstract class DebugDerivedType extends DebugType {
DebugType component;
/**
*
*/
public DebugDerivedType(DebugType type) {
component = type;
}
public DebugType getComponentType() {
return component;
}
public void setComponentType(DebugType type) {
component = type;
}
}

View file

@ -0,0 +1,292 @@
/**********************************************************************
* 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.debug;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.utils.debug.stabs.Stabs;
/**
* DebugDump
*
*/
public class DebugDump implements IDebugEntryRequestor {
List list = new ArrayList();
BufferedWriter bwriter;
int bracket;
int paramCount = -1;
String currentCU;
/**
*
*/
public DebugDump(OutputStream stream) {
bwriter = new BufferedWriter(new OutputStreamWriter(stream));
}
void write(String s) {
try {
bwriter.write(s, 0, s.length());
} catch (IOException e) {
// ignore.
}
}
void newLine() {
try {
bwriter.newLine();
} catch (IOException e) {
// ignore
}
}
String printTabs() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bracket; i++) {
sb.append('\t');
}
return sb.toString();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterCompilationUnit(java.lang.String, long)
*/
public void enterCompilationUnit(String name, long address) {
write("/* Enter Compilation Unit " + name + " address " + Long.toHexString(address) + " */");
newLine();
currentCU = name;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitCompilationUnit(long)
*/
public void exitCompilationUnit(long address) {
write("/* Exit Compilation Unit ");
if (currentCU != null) {
write(currentCU + " address " + Long.toHexString(address));
}
write(" */");
newLine();newLine();
try {
bwriter.flush();
} catch (IOException e) {
}
currentCU = null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterInclude(java.lang.String)
*/
public void enterInclude(String name) {
write("#include \"" + name + "\" ");
write("/* Enter Include */");
newLine();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitInclude()
*/
public void exitInclude() {
//write("/* Exit Include */");
//newLine();newLine();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterFunction(java.lang.String, int, boolean, long)
*/
public void enterFunction(String name, DebugType type, boolean isGlobal, long address) {
write("/* Func:" + name + " address " + Long.toHexString(address) + " */");
newLine();
if (!isGlobal) {
write("static ");
}
write(type.toString() + " " + name + "(");
paramCount = 0;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitFunction(long)
*/
public void exitFunction(long address) {
if (paramCount > -1) {
paramCount = -1;
write(")");
newLine();
write("{");
newLine();
bracket++;
}
for (; bracket > 0; bracket--) {
write("}");
}
write(" /* Exit Func address " + Long.toHexString(address) + " */");
newLine();newLine();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterCodeBlock(long)
*/
public void enterCodeBlock(long offset) {
if (paramCount > -1) {
paramCount = -1;
write(")");
newLine();
}
write(printTabs() + "{ " + "/* " + offset + " */");
newLine();
bracket++;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitCodeBlock(long)
*/
public void exitCodeBlock(long offset) {
bracket--;
write(printTabs() + "} " + "/* " + offset + " */");
newLine();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptStatement(int, long)
*/
public void acceptStatement(int line, long address) {
if (paramCount > -1) {
write(")");
newLine();
write("{");
newLine();
bracket++;
paramCount = -1;
}
write(printTabs() + "/* line " + line + " address " + address + " */");
newLine();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptIntegerConst(java.lang.String, long)
*/
public void acceptIntegerConst(String name, int value) {
write("const int " + name + " = " + value + ";");
newLine();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptFloatConst(java.lang.String, double)
*/
public void acceptFloatConst(String name, double value) {
write("const float " + name + " = " + value + ";");
newLine();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptTypeConst(java.lang.String,
* org.eclipse.cdt.utils.debug.DebugType, int)
*/
public void acceptTypeConst(String name, DebugType type, int value) {
write("const " + type.toString() + " " + name + " = " + value + ";");
newLine();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptParameter(java.lang.String, int, int, long)
*/
public void acceptParameter(String name, DebugType type, DebugParameterKind kind, long offset) {
if (paramCount > 0) {
write(", ");
}
paramCount++;
write(type.toString() + " " + name + "/* " + offset + " */");
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptVariable(java.lang.String, int, int, long)
*/
public void acceptVariable(String name, DebugType type, DebugVariableKind kind, long address) {
write(printTabs() + type.toString() + " " + name + ";" + "/* " + Long.toHexString(address) + " */");
newLine();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptCaughtException(java.lang.String,
* org.eclipse.cdt.utils.debug.DebugType, long)
*/
public void acceptCaughtException(String name, DebugType type, long address) {
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptTypeDef(java.lang.String, org.eclipse.cdt.utils.debug.DebugType)
*/
public void acceptTypeDef(String name, DebugType type) {
if (!name.equals(type.toString())) {
write("typedef " + type.toString() + " " + name + ";");
newLine();
} else if (type instanceof DebugBaseType){
DebugBaseType baseType =(DebugBaseType)type;
write("/* " + name + ": " + baseType.sizeof() + " bytes */");
newLine();
} else {
int x = 9;
}
}
public static void main(String[] args) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
DebugDump dump = new DebugDump(System.out);
Stabs stabs = new Stabs(args[0]);
stabs.parse(dump);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,40 @@
/**********************************************************************
* 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.debug;
/**
* DebugEnumField
*
*/
public class DebugEnumField {
String name;
int value;
/**
*
*/
public DebugEnumField(String name, int value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public int getValue() {
return value;
}
}

View file

@ -0,0 +1,40 @@
/**********************************************************************
* 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.debug;
/**
* DebugEnumType
*
*/
public class DebugEnumType extends DebugType {
DebugEnumField[] fields;
String name;
/**
*
*/
public DebugEnumType(String name, DebugEnumField[] fields) {
this.name = name;
this.fields = fields;
}
public DebugEnumField[] getDebugEnumFields() {
return fields;
}
public String getName() {
return name;
}
}

View file

@ -0,0 +1,44 @@
/**********************************************************************
* 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.debug;
/**
* DebugEnumField
*
*/
public class DebugField {
String name;
DebugType type;
int offset;
int bits;
/**
*
*/
public DebugField(String name, DebugType type, int offset, int bits) {
this.name = name;
this.type = type;
this.offset = offset;
this.bits = bits;
}
public String getName() {
return name;
}
public DebugType getDebugType() {
return type;
}
}

View file

@ -0,0 +1,34 @@
/**********************************************************************
* 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.debug;
/**
* DebugFunctionType
*
*/
public class DebugFunctionType extends DebugType {
DebugType returnType;
/**
*
*/
public DebugFunctionType(DebugType type) {
returnType = type;
}
public DebugType getReturnType() {
return returnType;
}
}

View file

@ -0,0 +1,46 @@
/**********************************************************************
* 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.debug;
/**
* DebugParameterKind
*
*/
public final class DebugParameterKind {
/* What is it ?? . */
public final static DebugParameterKind UNKNOWN = new DebugParameterKind(0);
/* parameter on the stack*/
public final static DebugParameterKind STACK = new DebugParameterKind(1);
/* parameter in register. */
public final static DebugParameterKind REGISTER = new DebugParameterKind(2);
/* parameter by reference. */
public final static DebugParameterKind REFERENCE = new DebugParameterKind(3);
/* register reference parameter. */
public final static DebugParameterKind REGISTER_REFERENCE = new DebugParameterKind(4);
private int id;
/**
*
*/
private DebugParameterKind(int id) {
this.id = id;
}
public boolean equals(Object obj) {
if (obj instanceof DebugParameterKind) {
DebugParameterKind kind = (DebugParameterKind)obj;
return kind.id == id;
}
return super.equals(obj);
}
}

View file

@ -0,0 +1,28 @@
/**********************************************************************
* 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.debug;
/**
* DebugPointerType
*
*/
public class DebugPointerType extends DebugDerivedType {
/**
*
*/
public DebugPointerType(DebugType type) {
super(type);
}
}

View file

@ -0,0 +1,28 @@
/**********************************************************************
* 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.debug;
/**
* DebugReferenceType
*
*/
public class DebugReferenceType extends DebugDerivedType {
/**
*
*/
public DebugReferenceType(DebugType type) {
super(type);
}
}

View file

@ -0,0 +1,60 @@
/**********************************************************************
* 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.debug;
/**
* DebugStructType
*
*/
public class DebugStructType extends DebugType {
String name;
int size;
boolean isUnion;
final static DebugField[] EMPTY_FIELDS = new DebugField[0];
DebugField[] fields;
/**
*
*/
public DebugStructType(String name, int size, boolean union) {
this.name = name;
this.size = size;
this.isUnion = union;
fields = EMPTY_FIELDS;
}
public int getSize() {
return size;
}
public String getName() {
return name;
}
public boolean isUnion() {
return isUnion;
}
public DebugField[] getDebugFields() {
return fields;
}
public void addField(DebugField field) {
DebugField[] fs = new DebugField[fields.length + 1];
System.arraycopy(fields, 0, fs, 0, fields.length);
fs[fields.length] = field;
fields = fs;
}
}

View file

@ -0,0 +1,97 @@
/**********************************************************************
* 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.debug;
/**
* DebugType
*
*/
public class DebugType {
/**
*
*/
protected DebugType() {
}
public String toString() {
StringBuffer sb = new StringBuffer();
if (this instanceof DebugArrayType) {
DebugArrayType arrayType = (DebugArrayType)this;
int size = arrayType.getSize();
DebugType type = arrayType.getComponentType();
sb.append(type.toString());
sb.append(" [").append(size).append(']');
} else if (this instanceof DebugDerivedType) {
DebugDerivedType derived = (DebugDerivedType)this;
DebugType component = derived.getComponentType();
if (component instanceof DebugStructType) {
DebugStructType structType = (DebugStructType)component;
sb.append(structType.getName());
} else if (component != null){
sb.append(component.toString());
}
if (this instanceof DebugPointerType) {
sb.append(" *");
} else if (this instanceof DebugReferenceType) {
sb.append(" &");
} else if (this instanceof DebugCrossRefType && component == null) {
DebugCrossRefType crossRef = (DebugCrossRefType)this;
sb.append(crossRef.getCrossRefName());
//sb.append(crossRef.getName());
}
} else if (this instanceof DebugBaseType) {
DebugBaseType base = (DebugBaseType)this;
String typeName = base.getTypeName();
sb.append(typeName);
} else if (this instanceof DebugFunctionType) {
DebugFunctionType function = (DebugFunctionType)this;
DebugType type = function.getReturnType();
sb.append(type.toString());
sb.append(" (*())");
} else if (this instanceof DebugEnumType) {
DebugEnumType enum = (DebugEnumType)this;
DebugEnumField[] fields = enum.getDebugEnumFields();
sb.append("enum ").append(enum.getName()).append(" {");
for (int i = 0; i < fields.length; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(' ').append(fields[i].getName());
sb.append(" = ").append(fields[i].getValue());
}
sb.append(" }");
} else if (this instanceof DebugStructType) {
DebugStructType struct = (DebugStructType)this;
if (struct.isUnion()) {
sb.append("union ");
} else {
sb.append("struct ");
}
sb.append(struct.getName()).append(" {");
DebugField[] fields = struct.getDebugFields();
for (int i = 0; i < fields.length; i++) {
if (i > 0) {
sb.append(';');
}
sb.append(' ').append(fields[i].getDebugType());
sb.append(' ').append(fields[i].getName());
}
sb.append(" }");
} else if (this instanceof DebugUnknownType) {
DebugUnknownType unknown = (DebugUnknownType)this;
sb.append(unknown.getName());
}
return sb.toString();
}
}

View file

@ -0,0 +1,34 @@
/**********************************************************************
* 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.debug;
/**
* DebugUnknownType
*
*/
public class DebugUnknownType extends DebugType {
String name;
/**
*
*/
public DebugUnknownType(String unknown) {
super();
name = unknown;
}
public String getName() {
return name;
}
}

View file

@ -0,0 +1,48 @@
/**********************************************************************
* 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.debug;
/**
* DebugVariableKind
*
*/
public final class DebugVariableKind {
/* What is it ?? . */
public final static DebugVariableKind UNKNOWN = new DebugVariableKind(0);
/* global variable */
public final static DebugVariableKind GLOBAL = new DebugVariableKind(1);
/* static variable. */
public final static DebugVariableKind STATIC = new DebugVariableKind(2);
/* local static variable. */
public final static DebugVariableKind LOCAL_STATIC = new DebugVariableKind(3);
/* local variable. */
public final static DebugVariableKind LOCAL = new DebugVariableKind(4);
/* variable is in register. */
public final static DebugVariableKind REGISTER = new DebugVariableKind(5);
private int id;
/**
*
*/
private DebugVariableKind(int id) {
this.id = id;
}
public boolean equals(Object obj) {
if (obj instanceof DebugVariableKind) {
DebugVariableKind kind = (DebugVariableKind)obj;
return kind.id == id;
}
return super.equals(obj);
}
}

View file

@ -0,0 +1,44 @@
/**********************************************************************
* 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.debug;
/**
* DebugVisibility
*
*/
public final class DebugVisibility {
/* What is it ?? . */
public final static DebugVisibility UNKNOWN = new DebugVisibility(0);
/* public field */
public final static DebugVisibility PUBLIC = new DebugVisibility(1);
/* protected field. */
public final static DebugVisibility PROTECTED = new DebugVisibility(2);
/* private field. */
public final static DebugVisibility PRIVATE = new DebugVisibility(3);
private int id;
/**
*
*/
private DebugVisibility(int id) {
this.id = id;
}
public boolean equals(Object obj) {
if (obj instanceof DebugVisibility) {
DebugVisibility kind = (DebugVisibility)obj;
return kind.id == id;
}
return super.equals(obj);
}
}

View file

@ -0,0 +1,128 @@
/**********************************************************************
* 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.debug;
public interface IDebugEntryRequestor {
/**
* Entering a compilation unit.
* @param name
* @param address start of address of the cu.
*/
void enterCompilationUnit(String name, long address);
/**
* Exit the current compilation unit.
* @param address end of compilation unit.
*/
void exitCompilationUnit(long address);
/**
* Entering new include file in a compilation unit.
* @param name
*/
void enterInclude(String name);
/**
* Exit the current include file.
*/
void exitInclude();
/**
* Enter a function.
* @param name of the function/method
* @param type type of the return value.
* @param isGlobal return the visiblity of the function.
* @param address the start address of the function.
*/
void enterFunction(String name, DebugType type, boolean isGlobal, long address);
/**
* Exit the current function.
* @param address the address where the function ends.
*/
void exitFunction(long address);
/**
* Enter a code block in a function.
* @param offset address of the block starts relative to the current function.
*/
void enterCodeBlock(long offset);
/**
* Exit of the current code block.
* @param offset the address of which the blocks ends relative to the current function.
*/
void exitCodeBlock(long offset);
/**
* Statement in the compilation unit with a given address.
* @param line lineno of the statement relative to the current compilation unit.
* @param offset addres of the statement relative to the current function.
*/
void acceptStatement(int line, long address);
/**
* Integer constant.
* @param name
* @param address.
*/
void acceptIntegerConst(String name, int value);
/**
* floating point constant.
* @param name
* @param value
*/
void acceptFloatConst(String name, double value);
/**
* Type constant: "const b = 0", b is a type enum.
* @param name
* @param type
* @param address
*/
void acceptTypeConst(String name, DebugType type, int value);
/**
* Caught Exception.
* @param name
* @param value
*/
void acceptCaughtException(String name, DebugType type, long address);
/**
* Accept a parameter for the current function.
* @param name of the parameter
* @param type of the parameter
* @param kind of the parameter
* @param offset address of the parameter relative to the current function.
*/
void acceptParameter(String name, DebugType type, DebugParameterKind kind, long offset);
/**
* Record a variable.
* @param name
* @param type
* @param kind
* @param address
*/
void acceptVariable(String name, DebugType type, DebugVariableKind kind, long address);
/**
* Type definition.
* IDebugEntryRequestor
* @param name new name
* @param type
*/
void acceptTypeDef(String name, DebugType type);
}

View file

@ -0,0 +1,146 @@
/**********************************************************************
* 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.debug.dwarf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.utils.elf.Elf;
public class Dwarf {
/* Section names. */
final static String DWARF_DEBUG_INFO = ".debug_info";
final static String DWARF_DEBUG_ABBREV = ".debug_abbrev";
final static String DWARF_DEBUG_ARANGES = ".debug_aranges";
final static String DWARF_DEBUG_LINE = ".debug_line";
final static String DWARF_DEBUG_FRAME = ".debug_frame";
final static String DWARF_EH_FRAME = ".eh_frame";
final static String DWARF_DEBUG_LOC = ".debug_loc";
final static String DWARF_DEBUG_PUBNAMES = ".debug_pubnames";
final static String DWARF_DEBUG_STR = ".debug_str";
final static String DWARF_DEBUG_FUNCNAMES = ".debug_funcnames";
final static String DWARF_DEBUG_TYPENAMES = ".debug_typenames";
final static String DWARF_DEBUG_VARNAMES = ".debug_varnames";
final static String DWARF_DEBUG_WEAKNAMES = ".debug_weaknames";
final static String DWARF_DEBUG_MACINFO = ".debug_macinfo";
final static String[] DWARF_SCNNAMES =
{
DWARF_DEBUG_INFO,
DWARF_DEBUG_ABBREV,
DWARF_DEBUG_ARANGES,
DWARF_DEBUG_LINE,
DWARF_DEBUG_FRAME,
DWARF_EH_FRAME,
DWARF_DEBUG_LOC,
DWARF_DEBUG_PUBNAMES,
DWARF_DEBUG_STR,
DWARF_DEBUG_FUNCNAMES,
DWARF_DEBUG_TYPENAMES,
DWARF_DEBUG_VARNAMES,
DWARF_DEBUG_WEAKNAMES,
DWARF_DEBUG_MACINFO
};
public static class DwarfSection {
String name;
byte[] data;
public DwarfSection (String n, byte[] d) {
name = n;
data = d;
}
}
DwarfSection[] dwarfSections;
boolean isLE;
public Dwarf(String file) throws IOException {
Elf exe = new Elf(file);
init(exe);
exe.dispose();
}
public Dwarf(Elf exe) throws IOException {
init(exe);
}
public void init(Elf exe) throws IOException {
Elf.ELFhdr header = exe.getELFhdr();
isLE = header.e_ident[Elf.ELFhdr.EI_DATA] == Elf.ELFhdr.ELFDATA2LSB;
Elf.Section[] sections = exe.getSections();
List list = new ArrayList();
for (int i = 0; i < sections.length; i++) {
String name = sections[i].toString();
for (int j = 0; j < DWARF_SCNNAMES.length; j++) {
if (name.equals(DWARF_SCNNAMES[j])) {
list.add(new DwarfSection(name, sections[i].loadSectionData()));
}
}
}
dwarfSections = new DwarfSection[list.size()];
list.toArray(dwarfSections);
}
int read_4_bytes(byte[] bytes, int offset) {
if (isLE) {
return (((bytes[offset + 3] & 0xff) << 24) + ((bytes[offset + 2] & 0xff) << 16)
+ ((bytes[offset + 1] & 0xff) << 8) + (bytes[offset] & 0xff));
}
return (((bytes[offset] & 0xff) << 24) + ((bytes[offset + 1] & 0xff) << 16) + ((bytes[offset + 2] & 0xff) << 8) + (bytes[offset + 3] & 0xff));
}
short read_2_bytes(byte[] bytes, int offset) {
if (isLE) {
return (short) (((bytes[offset + 1] & 0xff) << 8) + (bytes[offset] & 0xff));
}
return (short) (((bytes[offset] & 0xff) << 8) + (bytes[offset + 1] & 0xff));
}
public void parse() {
for (int i = 0; i < dwarfSections.length; i++) {
if (dwarfSections[i].name.equals(DWARF_DEBUG_INFO)) {
parse_debug_info(dwarfSections[i].data);
}
}
}
void parse_debug_info(byte[] data) {
int offset = 0;
int nentries = data.length / 11;
for (int i = 0; i < nentries; offset += 11) {
int length = read_4_bytes(data, offset);
short version = read_2_bytes(data, offset + 4);
int abbrev_offset = read_4_bytes(data, offset + 4 + 2);
byte address_size = data[offset + 4 + 2 + 4];
System.out.println("Length:" + length);
System.out.println("Version:" + version);
System.out.println("Abbreviation:" + abbrev_offset);
System.out.println("Address size:" + address_size);
}
}
void parse_compilation_unit() {
}
public static void main(String[] args) {
try {
Dwarf dwarf = new Dwarf(args[0]);
dwarf.parse();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -9,7 +9,7 @@
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.utils.stabs;
package org.eclipse.cdt.utils.debug.stabs;
public final class StabConstant {

View file

@ -0,0 +1,53 @@
/**********************************************************************
* 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.debug.stabs;
public class StabSym implements Comparable {
public long addr;
public long size;
public int startLine;
public int endLine;
public String name;
public String type;
public String filename;
public StabSym() {
}
public int compareTo(Object obj) {
long thisVal = 0;
long anotherVal = 0;
if (obj instanceof StabSym) {
StabSym entry = (StabSym) obj;
thisVal = this.addr;
anotherVal = entry.addr;
} else if (obj instanceof Long) {
Long val = (Long) obj;
anotherVal = val.longValue();
thisVal = (long) this.addr;
}
return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("Type:").append(type).append("\n");
buf.append("Name: ").append(name).append("\n");
buf.append("\taddress:").append("0x").append(Long.toHexString(addr)).append("\n");
buf.append("\tstartLine:").append(startLine).append("\n");
buf.append("\tendLine:").append(endLine).append("\n");
buf.append("\tSize:").append(size).append("\n");
return buf.toString();
}
}

View file

@ -0,0 +1,205 @@
/**********************************************************************
* 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.debug.stabs;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.utils.debug.DebugParameterKind;
import org.eclipse.cdt.utils.debug.DebugType;
import org.eclipse.cdt.utils.debug.DebugVariableKind;
import org.eclipse.cdt.utils.debug.IDebugEntryRequestor;
/**
* StabSymsRequestor
*
*/
public class StabSymsRequestor implements IDebugEntryRequestor {
StabSym currentCU;
StabSym currentFunction;
List list = new ArrayList();
/**
*
*/
public StabSymsRequestor() {
super();
}
public StabSym[] getSortedEntries() {
StabSym[] syms = getEntries();
Arrays.sort(syms);
return syms;
}
public StabSym[] getEntries() {
StabSym[] syms = new StabSym[list.size()];
list.toArray(syms);
return syms;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterCompilationUnit(java.lang.String, long)
*/
public void enterCompilationUnit(String name, long address) {
StabSym sym = new StabSym();
sym.name = name;
sym.addr = address;
sym.type = "CU";
sym.filename = name;
currentCU = sym;
list.add(sym);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitCompilationUnit(long)
*/
public void exitCompilationUnit(long address) {
if (currentCU != null) {
currentCU.size = address;
}
currentCU = null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterInclude(java.lang.String)
*/
public void enterInclude(String name) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitInclude()
*/
public void exitInclude() {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterFunction(java.lang.String, int, boolean, long)
*/
public void enterFunction(String name, DebugType type, boolean isGlobal, long address) {
StabSym sym = new StabSym();
sym.name = name;
sym.addr = address;
sym.type = "Func";
if (currentCU != null) {
sym.filename = currentCU.filename;
}
currentFunction = sym;
list.add(sym);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitFunction(long)
*/
public void exitFunction(long address) {
if (currentFunction != null) {
currentFunction.size = address;
}
currentFunction = null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterCodeBlock(long)
*/
public void enterCodeBlock(long offset) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitCodeBlock(long)
*/
public void exitCodeBlock(long offset) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptStatement(int, long)
*/
public void acceptStatement(int line, long address) {
StabSym sym = new StabSym();
sym.name = "";
sym.addr = address;
sym.startLine = line;
sym.type = "SLINE";
if (currentFunction != null) {
if (currentFunction.startLine == 0) {
currentFunction.startLine = line;
}
currentFunction.endLine = line;
}
if (currentCU != null) {
sym.filename = currentCU.filename;
}
list.add(sym);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptIntegerConst(java.lang.String, long)
*/
public void acceptIntegerConst(String name, int value) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptFloatConst(java.lang.String, double)
*/
public void acceptFloatConst(String name, double value) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptTypeConst(java.lang.String, org.eclipse.cdt.utils.debug.DebugType, int)
*/
public void acceptTypeConst(String name, DebugType type, int value) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptParameter(java.lang.String, int, int, long)
*/
public void acceptParameter(String name, DebugType type, DebugParameterKind kind, long offset) {
StabSym sym = new StabSym();
sym.name = name;
sym.addr = offset;
sym.type = "PARAM";
if (currentCU != null) {
sym.filename = currentCU.filename;
}
list.add(sym);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptVariable(java.lang.String, int, int, long)
*/
public void acceptVariable(String name, DebugType type, DebugVariableKind kind, long address) {
StabSym sym = new StabSym();
sym.name = name;
sym.addr = address;
sym.type = "VAR";
if (currentCU != null) {
sym.filename = currentCU.filename;
}
list.add(sym);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptCaughtException(java.lang.String, org.eclipse.cdt.utils.debug.DebugType, long)
*/
public void acceptCaughtException(String name, DebugType type, long address) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptTypeDef(java.lang.String, org.eclipse.cdt.utils.debug.DebugType)
*/
public void acceptTypeDef(String name, DebugType type) {
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,110 @@
/**********************************************************************
* 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.debug.stabs;
import java.io.IOException;
import org.eclipse.cdt.utils.elf.Elf;
/**
* StabsAddr2ine
*
* @author alain
*/
public class StabsAddr2line {
Stabs stabs;
public StabsAddr2line(String file) throws IOException {
stabs = new Stabs(file);
}
public StabsAddr2line(Elf elf) throws IOException {
stabs = new Stabs(elf);
}
/*
* (non-Javadoc)
*
* @see IAddr2line#dispose()
*/
public void dispose() {
}
/*
* (non-Javadoc)
*
* @see IAddr2line#getStartLine(long)
*/
public int getStartLine(long address) throws IOException {
StabSym entry = stabs.getEntry(address);
if (entry != null) {
return entry.startLine;
}
return 0;
}
/*
* (non-Javadoc)
*
* @see IAddr2line#getEndLine(long)
*/
public int getEndLine(long address) throws IOException {
StabSym entry = stabs.getEntry(address);
if (entry != null) {
return entry.endLine;
}
return 0;
}
/*
* (non-Javadoc)
*
* @see IAddr2line#getFunction(long)
*/
public String getFunction(long address) throws IOException {
StabSym entry = stabs.getEntry(address);
if (entry != null) {
return entry.name;
}
return null;
}
/*
* (non-Javadoc)
*
* @see IAddr2line#getFileName(long)
*/
public String getFileName(long address) throws IOException {
StabSym entry = stabs.getEntry(address);
if (entry != null) {
return entry.filename;
}
return null;
}
public static void main(String[] args) {
try {
StabsAddr2line addr2line = new StabsAddr2line(args[0]);
long address = Integer.decode(args[1]).longValue();
int startLine = addr2line.getStartLine(address);
int endLine = addr2line.getEndLine(address);
String function = addr2line.getFunction(address);
String filename = addr2line.getFileName(address);
System.out.println(Long.toHexString(address));
System.out.println(filename + ":" + function + ":" + startLine + ":" + endLine);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,102 @@
/**********************************************************************
* 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.debug.stabs;
/**
* Format: string_field = name ':' symbol-descriptor type-information
*/
public class StringField {
String name;
char symbolDescriptor;
String typeInformation;
public StringField(String s) {
parseStringField(s.toCharArray());
}
public String getName() {
return name;
}
public char getSymbolDescriptor() {
return symbolDescriptor;
}
public String getTypeInformation() {
return typeInformation;
}
/**
* Format: string_field = name ':' symbol-descriptor type-information
*/
void parseStringField(char[] array) {
int index = 0;
// Some String field may contain format like:
// "foo::bar::baz:t5=*6" in that case the name is "foo::bar::baz"
char prev = 0;
for (; index < array.length; index++) {
char c = array[index];
if (c == ':' && prev != ':') {
break;
}
prev = c;
}
if (index < array.length) {
name = new String(array, 0, index);
} else {
name = new String(array);
}
/* FIXME: Sometimes the special C++ names start with '.'. */
if (name.length() > 1 && name.charAt(0) == '$') {
switch (name.charAt(1)) {
case 't' :
name = "this";
break;
case 'v' :
/* Was: name = "vptr"; */
break;
case 'e' :
name = "eh_throw";
break;
case '_' :
/* This was an anonymous type that was never fixed up. */
break;
case 'X' :
/* SunPRO (3.0 at least) static variable encoding. */
break;
default :
name = "unknown C++ encoded name";
break;
}
}
// get the symbol descriptor
if (index < array.length) {
index++;
if (Character.isLetter(array[index])) {
symbolDescriptor = array[index];
index++;
}
}
// get the type-information
if (index < array.length) {
typeInformation = new String(array, index, array.length - index);
} else {
typeInformation = new String();
}
}
}

View file

@ -0,0 +1,75 @@
/**********************************************************************
* 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.debug.stabs;
import java.io.IOException;
import java.io.Reader;
public class TypeInformation {
TypeNumber typeNumber;
char typeDescriptor;
boolean isTypeDefinition;
public TypeInformation(Reader reader) {
parseTypeInformation(reader);
}
public TypeNumber getTypeNumber() {
return typeNumber;
}
public char getTypeDescriptor() {
return typeDescriptor;
}
public boolean isTypeDefinition() {
return isTypeDefinition;
}
/**
* int:t(0,1)=r(0,1);-2147483648;2147483647;
* We receieve as input:
* (0,1)=r(0,1);-2147483648;2147483647;
* typeNumber: (0,1)
* typeDescriptor: r
* attributes: (0,1);-2147483648;2147483647;
* isTypeDefinition = true;
*/
void parseTypeInformation(Reader reader) {
try {
typeNumber = new TypeNumber(reader);
reader.mark(1);
int c = reader.read();
if (c == '=') {
isTypeDefinition = true;
reader.mark(1);
c = reader.read();
if (isTypeDescriptor((char)c)) {
typeDescriptor = (char)c;
} else {
reader.reset();
}
} else {
reader.reset();
}
} catch (IOException e) {
}
}
boolean isTypeDescriptor(char c) {
return Character.isLetter(c) || c == '=' || c == '#' || c =='*'
|| c == '&' || c == '@';
}
}

View file

@ -0,0 +1,106 @@
/**********************************************************************
* 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.debug.stabs;
import java.io.IOException;
import java.io.Reader;
public class TypeNumber {
int typeno;
int fileno;
public TypeNumber(int f, int t) {
fileno = f;
typeno = t;
}
public TypeNumber(Reader reader) {
parseTypeNumber(reader);
}
public int getTypeNo() {
return typeno;
}
public int getFileNo() {
return fileno;
}
public boolean equals(Object obj) {
if (obj instanceof TypeNumber) {
TypeNumber tn = (TypeNumber)obj;
return tn.typeno == typeno && tn.fileno == fileno;
}
return super.equals(obj);
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return fileno*10 + typeno;
}
void parseTypeNumber(Reader reader) {
try {
int c = reader.read();
char ch = (char)c;
if (c == -1) {
return;
} else if (ch == '(') {
StringBuffer sb = new StringBuffer();
while ((c = reader.read()) != -1) {
ch = (char)c;
if (ch == ')') {
try {
typeno = Integer.parseInt(sb.toString());
} catch (NumberFormatException e) {
}
break;
} else if (ch == ',') {
try {
fileno = Integer.parseInt(sb.toString());
} catch (NumberFormatException e) {
}
sb.setLength(0);
} else if (Character.isDigit(ch)) {
sb.append(ch);
} else {
break;
}
}
} else if (Character.isDigit(ch)) {
StringBuffer sb = new StringBuffer();
sb.append(ch);
reader.mark(1);
while ((c = reader.read()) != -1) {
ch = (char)c;
if (Character.isDigit(ch)) {
sb.append(ch);
} else {
reader.reset();
break;
}
}
try {
typeno = Integer.parseInt(sb.toString());
} catch (NumberFormatException e) {
}
}
} catch (IOException e) {
}
}
}

View file

@ -1,458 +0,0 @@
/**********************************************************************
* 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.Arrays;
import java.util.List;
import org.eclipse.cdt.utils.elf.Elf;
public class Stabs {
byte[] stabData;
byte[] stabstrData;
boolean isLe;
Entry[] entries;
public class Entry implements Comparable{
public long addr;
public long size;
public int startLine;
public String string;
public Entry(String s) {
string = s;
}
public int compareTo(Object obj) {
long thisVal = 0;
long anotherVal = 0;
if (obj instanceof Entry) {
Entry entry = (Entry) obj;
thisVal = this.addr;
anotherVal = entry.addr;
} else if (obj instanceof Long) {
Long val = (Long) obj;
anotherVal = val.longValue();
thisVal = (long) this.addr;
}
return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("Name: ").append(string).append("\n");
buf.append("\taddress:").append("0x").append(Long.toHexString(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();
buf.append("Variable: ");
buf.append(super.toString());
buf.append("\tkind:").append(kind).append("\n");
buf.append("\tfilename:").append(filename).append("\n");
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();
buf.append("Function: ");
buf.append(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("[" + i + "]").append("\n");
buf.append("\t\t\t").append(variables.get(i)).append("\n");
}
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";
}
}
// type-information = type-number | type-definition
// type-number = type-reference
// type-reference = number | '(' number ',' number ')'
// type-definition = type_number '=' (type-descriptor | type-reference)
public class TypeInformation {
int typeNumber;
int fileNumber;
boolean isTypeDefinition;
public TypeInformation(String s) {
parserTypeInformation(s.toCharArray());
}
void parserTypeInformation(char[] array) {
}
}
/**
* Format: string_field = name ':' symbol-descriptor type-information
*/
public class StringField {
String name;
char symbolDescriptor;
String typeInformation;
public StringField(String s) {
parseStringField(s.toCharArray());
}
/**
* Format: string_field = name ':' symbol-descriptor type-information
*/
void parseStringField(char[] array) {
int index = 0;
// Some String field may contain format like:
// "foo::bar::baz:t5=*6" in that case the name is "foo::bar::baz"
char prev = 0;
for (int i = 0; index < array.length; index++) {
char c = array[index];
if (prev != ':') {
break;
}
prev = c;
}
if (index < array.length) {
name = new String(array, 0, index);
} else {
name = new String(array);
}
// get the symbol descriptor
if (index < array.length) {
index++;
symbolDescriptor = array[index];
}
// get the type-information
if (index < array.length) {
typeInformation = new String(array, index, array.length);
} else {
typeInformation = new String();
}
}
}
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();
}
return entries;
}
public Entry getEntry(long addr) throws IOException {
if (entries == null) {
parse();
}
int insertion = Arrays.binarySearch(entries, new Long(addr));
if (insertion >= 0) {
return entries[insertion];
}
if (insertion == -1) {
return null;
}
insertion = -insertion - 1;
Entry entry = entries[insertion - 1];
if (addr < (entry.addr + entry.size)) {
return entries[insertion - 1];
}
return null;
}
void parse() throws IOException {
List list = 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;
}
/* FIXME: Sometimes the special C++ names start with '.'. */
if (name.length() > 1 && name.charAt(0) == '$') {
switch (name.charAt(1)) {
case 't' :
name = "this";
break;
case 'v' :
/* Was: name = "vptr"; */
break;
case 'e' :
name = "eh_throw";
break;
case '_' :
/* This was an anonymous type that was never fixed up. */
break;
case 'X' :
/* SunPRO (3.0 at least) static variable encoding. */
break;
default :
name = "unknown C++ encoded name";
break;
}
}
// get the type; 1 byte;
type = 0xff & stabData[offset + 4];
// get the other
other = 0xff & stabData[offset + 5];
// get the desc
if (isLe) {
desc = (short) (((stabData[offset + 7] & 0xff) << 8) + (stabData[offset + 6] & 0xff));
} else {
desc = (short) (((stabData[offset + 6] & 0xff) << 8) + (stabData[offset + 7] & 0xff));
}
// 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;
list.add(variable);
if (currentFunction != null) {
currentFunction.variables.add(variable);
}
break;
case StabConstant.N_SLINE :
if (currentFunction != null) {
if (currentFunction.startLine == 0) {
currentFunction.endLine = currentFunction.startLine = desc;
} else {
currentFunction.endLine = desc;
currentFunction.size = value;
}
currentFunction.lines.add(new Integer(desc));
}
break;
case StabConstant.N_FUN :
if (name.length() == 0) {
name = "anon";
}
currentFunction = null;
currentFunction = new Function(name);
currentFunction.addr = value;
currentFunction.startLine = desc;
currentFunction.filename = currentFile;
list.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++;
list.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);
}
entries = new Entry[list.size()];
list.toArray(entries);
list.clear();
Arrays.sort(entries);
}
public void print() {
for (int i = 0; i < entries.length; i++) {
Entry entry = entries[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();
}
}
}

View file

@ -1,127 +0,0 @@
/**********************************************************************
* 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;
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 {
Stabs.Entry entry = stabs.getEntry(address);
if (entry != null) {
return entry.startLine;
}
return 0;
}
/*
* (non-Javadoc)
*
* @see IAddr2line#getEndLine(long)
*/
public int getEndLine(long address) throws IOException {
Stabs.Entry entry = stabs.getEntry(address);
if (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 {
Stabs.Entry entry = stabs.getEntry(address);
if (entry != null) {
return entry.string;
}
return null;
}
/*
* (non-Javadoc)
*
* @see IAddr2line#getFileName(long)
*/
public String getFileName(long address) throws IOException {
Stabs.Entry entry = stabs.getEntry(address);
if (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();
int startLine = addr2line.getStartLine(address);
int endLine = addr2line.getEndLine(address);
String function = addr2line.getFunction(address);
String filename = addr2line.getFileName(address);
System.out.println(Long.toHexString(address));
System.out.println(filename + ":" + function + ":" + startLine + ":" + endLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}