diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/MappedSourceLocation.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/MappedSourceLocation.java new file mode 100644 index 00000000000..9c0041b3cca --- /dev/null +++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/MappedSourceLocation.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2007 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.mi.core.cdi.model; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.core.cdi.model.ICDIAddressToSource; +import org.eclipse.cdt.debug.mi.core.output.CLIInfoLineInfo; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class MappedSourceLocation implements ICDIAddressToSource.IMappedSourceLocation { + + private CLIInfoLineInfo lineInfo; + private IAddress address; + private String executable; + + public MappedSourceLocation(IAddress address, CLIInfoLineInfo lineInfo, String executable) { + this.address = address; + this.lineInfo = lineInfo; + this.executable = executable; + } + + public IAddress getAddress() { + return address; + } + + public IPath getExecutable() { + return Path.fromOSString(executable); + } + + public String getFunctionName() { + return lineInfo.getStartLocation(); + } + + public int getLineNumber() { + return lineInfo.getLineNumber(); + } + + public IPath getSourceFile() { + return Path.fromOSString(lineInfo.getFileName()); + } + + public String getUnmangledFunctionName() { + return lineInfo.getStartLocation(); + } + + public int compareTo(Object arg0) { + return address.compareTo(arg0); + } + +} diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Target.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Target.java index d425c099fd4..ea78f70af12 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Target.java +++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/Target.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2006 QNX Software Systems and others. + * Copyright (c) 2000, 2007 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * QNX Software Systems - Initial API and implementation + * Ken Ryall (Nokia) - 175532 support the address to source location API *******************************************************************************/ package org.eclipse.cdt.debug.mi.core.cdi.model; @@ -14,6 +15,7 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.cdi.ICDIAddressLocation; import org.eclipse.cdt.debug.core.cdi.ICDICondition; @@ -21,6 +23,7 @@ import org.eclipse.cdt.debug.core.cdi.ICDIFunctionLocation; import org.eclipse.cdt.debug.core.cdi.ICDILineLocation; import org.eclipse.cdt.debug.core.cdi.ICDILocation; import org.eclipse.cdt.debug.core.cdi.model.ICDIAddressBreakpoint; +import org.eclipse.cdt.debug.core.cdi.model.ICDIAddressToSource; import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpointManagement2; import org.eclipse.cdt.debug.core.cdi.model.ICDIExceptionpoint; @@ -60,6 +63,7 @@ import org.eclipse.cdt.debug.mi.core.cdi.SharedLibraryManager; import org.eclipse.cdt.debug.mi.core.cdi.SignalManager; import org.eclipse.cdt.debug.mi.core.cdi.SourceManager; import org.eclipse.cdt.debug.mi.core.cdi.VariableManager; +import org.eclipse.cdt.debug.mi.core.command.CLIInfoLine; import org.eclipse.cdt.debug.mi.core.command.CLIInfoThreads; import org.eclipse.cdt.debug.mi.core.command.CLIJump; import org.eclipse.cdt.debug.mi.core.command.CLISignal; @@ -78,17 +82,17 @@ import org.eclipse.cdt.debug.mi.core.command.MIThreadSelect; import org.eclipse.cdt.debug.mi.core.event.MIDetachedEvent; import org.eclipse.cdt.debug.mi.core.event.MIThreadCreatedEvent; import org.eclipse.cdt.debug.mi.core.event.MIThreadExitEvent; +import org.eclipse.cdt.debug.mi.core.output.CLIInfoLineInfo; import org.eclipse.cdt.debug.mi.core.output.CLIInfoThreadsInfo; import org.eclipse.cdt.debug.mi.core.output.MIDataEvaluateExpressionInfo; import org.eclipse.cdt.debug.mi.core.output.MIFrame; import org.eclipse.cdt.debug.mi.core.output.MIGDBShowEndianInfo; import org.eclipse.cdt.debug.mi.core.output.MIInfo; import org.eclipse.cdt.debug.mi.core.output.MIThreadSelectInfo; -import org.eclipse.core.runtime.Path; /** */ -public class Target extends SessionObject implements ICDITarget, ICDIBreakpointManagement2 { +public class Target extends SessionObject implements ICDITarget, ICDIBreakpointManagement2, ICDIAddressToSource { public class Lock { @@ -1213,4 +1217,27 @@ public class Target extends SessionObject implements ICDITarget, ICDIBreakpointM BreakpointManager bMgr = ((Session)getSession()).getBreakpointManager(); return bMgr.setWatchpoint(this, type, watchType, expression, condition, enabled); } + + public IMappedSourceLocation getSourceForAddress(IAddress address) throws CDIException { + // Ask gdb for info for this address, use the module list + // to determine the executable. + CommandFactory factory = miSession.getCommandFactory(); + CLIInfoLine cmd = factory.createCLIInfoLine(address); + try { + miSession.postCommand(cmd); + CLIInfoLineInfo info = cmd.getMIInfoLineInfo(); + String fileName = ""; //$NON-NLS-1$ + ICDISharedLibrary[] libs = getSharedLibraries(); + BigInteger sourceAddress = address.getValue(); + for (int i = 0; i < libs.length; i++) { + if (sourceAddress.compareTo(libs[i].getStartAddress()) > 0 && sourceAddress.compareTo(libs[i].getEndAddress()) < 0) + { + fileName = libs[i].getFileName(); + } + } + return new MappedSourceLocation(address, info, fileName); + } catch (MIException e) { + throw new MI2CDIException(e); + } + } } diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CLIInfoLine.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CLIInfoLine.java new file mode 100644 index 00000000000..81bdfc9f4c4 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CLIInfoLine.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.mi.core.command; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.mi.core.MIException; +import org.eclipse.cdt.debug.mi.core.output.CLIInfoLineInfo; +import org.eclipse.cdt.debug.mi.core.output.MIInfo; +import org.eclipse.cdt.debug.mi.core.output.MIOutput; + +public class CLIInfoLine extends CLICommand { + + public CLIInfoLine(IAddress address) { + super("info line *" + address.toHexAddressString()); + } + + public CLIInfoLineInfo getMIInfoLineInfo() throws MIException { + return (CLIInfoLineInfo)getMIInfo(); + } + + public MIInfo getMIInfo() throws MIException { + MIInfo info = null; + MIOutput out = getMIOutput(); + if (out != null) { + info = new CLIInfoLineInfo(out); + if (info.isError()) { + throwMIException(info, out); + } + } + return info; + } + +} diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CommandFactory.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CommandFactory.java index 7934b9a8e1f..82de011c7d0 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CommandFactory.java +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/CommandFactory.java @@ -11,6 +11,8 @@ package org.eclipse.cdt.debug.mi.core.command; +import org.eclipse.cdt.core.IAddress; + /** * Factory to create GDB commands. @@ -359,6 +361,10 @@ public class CommandFactory { return new CLIInfoProgram(); } + public CLIInfoLine createCLIInfoLine(IAddress address) { + return new CLIInfoLine(address); + } + public MIVarCreate createMIVarCreate(String expression) { return new MIVarCreate(getMIVersion(), expression); } diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/CLIInfoLineInfo.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/CLIInfoLineInfo.java new file mode 100644 index 00000000000..2f6675ef72b --- /dev/null +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/CLIInfoLineInfo.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2007 Nokia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nokia - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.mi.core.output; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + + +public class CLIInfoLineInfo extends MIInfo { + + private int lineNumber; + private BigInteger startAddress; + private BigInteger endAddress; + private String startLocation; + private String endLocation; + private String fileName; + + public CLIInfoLineInfo(MIOutput out) { + super(out); + parse(); + } + + public int getLineNumber() { + return lineNumber; + } + + public BigInteger getStartAddress() { + return startAddress; + } + + public BigInteger getEndAddress() { + return endAddress; + } + + public String getStartLocation() { + return startLocation; + } + + public String getEndLocation() { + return endLocation; + } + + public String getFileName() { + return fileName; + } + + protected void parse() { + List aList = new ArrayList(); + if (isDone()) { + MIOutput out = getMIOutput(); + MIOOBRecord[] oobs = out.getMIOOBRecords(); + for (int i = 0; i < oobs.length; i++) { + if (oobs[i] instanceof MIConsoleStreamOutput) { + MIStreamRecord cons = (MIStreamRecord) oobs[i]; + String str = cons.getString(); + // We are interested in finding the current thread + parseLineInfo(str.trim(), aList); + } + } + } + + } + + protected void parseLineInfo(String str, List aList) { + String[] strbits = str.split("\\s"); + for (int i = 0; i < strbits.length; i++) { + if (strbits[i].equals("Line")) + { + lineNumber = Integer.parseInt(strbits[i+1]); + } + else + if (strbits[i].equals("starts")) + { + + startAddress = new BigInteger(strbits[i+3].substring(2), 16); + startLocation = strbits[i+4]; + } + else + if (strbits[i].equals("ends")) + { + endAddress = new BigInteger(strbits[i+2].substring(2), 16); + endLocation = strbits[i+3]; + } + } + strbits = str.split("\""); + for (int i = 0; i < strbits.length; i++) { + fileName = strbits[1]; + } + } + +}