1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 309576 - Memory view doesn't work with 64 bit executables

Change-Id: Ie23f1c28b312a8a1b5705dddf0a20664d48b1a2f
Reviewed-on: https://git.eclipse.org/r/11529
Reviewed-by: Marc Khouzam <marc.khouzam@ericsson.com>
IP-Clean: Marc Khouzam <marc.khouzam@ericsson.com>
Tested-by: Marc Khouzam <marc.khouzam@ericsson.com>
Reviewed-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
IP-Clean: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
Tested-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
This commit is contained in:
Mikhail Khodjaiants 2013-04-09 14:09:40 -04:00
parent 54990da8f6
commit 68dae1a7ec
9 changed files with 386 additions and 5 deletions

View file

@ -27,6 +27,7 @@ import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.cdt.dsf.debug.service.IMemorySpaces;
import org.eclipse.cdt.dsf.debug.service.IMemorySpaces.IMemorySpaceDMContext;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.service.IGDBMemory;
import org.eclipse.cdt.utils.Addr64;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
@ -266,4 +267,25 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
}
return super.getExpression();
}
@Override
public int getAddressSize() throws DebugException {
GdbMemoryBlockRetrieval retrieval = (GdbMemoryBlockRetrieval)getMemoryBlockRetrieval();
IMemoryDMContext context = null;
if (fMemorySpaceID != null) {
IMemorySpaces memorySpacesService = (IMemorySpaces) retrieval.getMemorySpaceServiceTracker().getService();
if (memorySpacesService != null) {
context = new MemorySpaceDMContext(memorySpacesService.getSession().getId(), fMemorySpaceID, getContext());
}
}
else {
context = getContext();
}
IGDBMemory memoryService = (IGDBMemory)retrieval.getServiceTracker().getService();
if (memoryService != null) {
return memoryService.getAddressSize(context);
}
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, Messages.Err_MemoryServiceNotAvailable, null));
}
}

View file

@ -0,0 +1,223 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
* John Dallaway - Add methods to get the endianness and address size (Bug 225609)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IExpressions;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
import org.eclipse.cdt.dsf.debug.service.IMemory;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.MIMemory;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIShowEndianInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataEvaluateExpressionInfo;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.model.MemoryByte;
/**
* @since 4.2
*/
public class GDBMemory extends MIMemory implements IGDBMemory {
private IGDBControl fCommandControl;
/**
* Cache of the address sizes for each memory context.
*/
private Map<IMemoryDMContext, Integer> fAddressSizes = new HashMap<IMemoryDMContext, Integer>();
/**
* We assume the endianness is the same for all processes because GDB supports only one target.
*/
private boolean fIsBigEndian = false;
public GDBMemory(DsfSession session) {
super(session);
}
@Override
public void initialize(final RequestMonitor requestMonitor) {
super.initialize(new ImmediateRequestMonitor(requestMonitor) {
@Override
protected void handleSuccess() {
doInitialize(requestMonitor);
}
});
}
private void doInitialize(final RequestMonitor requestMonitor) {
fCommandControl = getServicesTracker().getService(IGDBControl.class);
getSession().addServiceEventListener(this, null);
register(
new String[] {
IMemory.class.getName(),
MIMemory.class.getName(),
IGDBMemory.class.getName(),
GDBMemory.class.getName(),
},
new Hashtable<String, String>());
requestMonitor.done();
}
@Override
public void shutdown(RequestMonitor requestMonitor) {
unregister();
getSession().removeServiceEventListener(this);
fAddressSizes.clear();
super.shutdown(requestMonitor);
}
@Override
protected void readMemoryBlock(final IDMContext dmc, IAddress address,
long offset, int word_size, int count, final DataRequestMonitor<MemoryByte[]> drm) {
super.readMemoryBlock(
dmc,
address,
offset,
word_size,
count,
new DataRequestMonitor<MemoryByte[]>(ImmediateExecutor.getInstance(), drm) {
@Override
@ConfinedToDsfExecutor("fExecutor")
protected void handleSuccess() {
IMemoryDMContext memDmc = DMContexts.getAncestorOfType(dmc, IMemoryDMContext.class);
if (memDmc != null) {
boolean bigEndian = isBigEndian(memDmc);
for (MemoryByte b : getData()) {
b.setBigEndian(bigEndian);
b.setEndianessKnown(true);
}
}
drm.setData(getData());
drm.done();
}
});
}
@DsfServiceEventHandler
public void eventDispatched(IStartedDMEvent event) {
if (event.getDMContext() instanceof IContainerDMContext) {
IMemoryDMContext memContext = DMContexts.getAncestorOfType(event.getDMContext(), IMemoryDMContext.class);
if (memContext != null) {
readAddressSize(memContext);
readEndianness(memContext);
}
}
}
@DsfServiceEventHandler
public void eventDispatched(IExitedDMEvent event) {
if (event.getDMContext() instanceof IContainerDMContext) {
IMemoryDMContext context = DMContexts.getAncestorOfType(event.getDMContext(), IMemoryDMContext.class);
if (context != null) {
fAddressSizes.remove(context);
}
}
}
@Override
public int getAddressSize(IMemoryDMContext context) {
Integer addressSize = fAddressSizes.get(context);
return (addressSize != null) ? addressSize.intValue() : 8;
}
@Override
public boolean isBigEndian(IMemoryDMContext context) {
return fIsBigEndian;
}
/**
* Retrieves the address size for given memory and execution contexts.
*/
private void readAddressSize(final IMemoryDMContext memContext) {
Integer addrSize = fAddressSizes.get(memContext);
if (addrSize == null) {
doReadAddressSize(
memContext,
new DataRequestMonitor<Integer>(ImmediateExecutor.getInstance(), null) {
@Override
@ConfinedToDsfExecutor("fExecutor")
protected void handleSuccess() {
fAddressSizes.put(memContext, getData());
}
});
}
}
/**
* Retrieves the endianness for given memory and execution contexts.
*/
private void readEndianness(IMemoryDMContext memContext) {
doReadEndianness(
memContext,
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
@Override
@ConfinedToDsfExecutor("fExecutor")
protected void handleSuccess() {
fIsBigEndian = getData();
}
});
}
protected void doReadAddressSize(IMemoryDMContext memContext, final DataRequestMonitor<Integer> drm) {
IExpressions exprService = getServicesTracker().getService(IExpressions.class);
IExpressionDMContext exprContext = exprService.createExpression(memContext, "sizeof (void*)"); //$NON-NLS-1$
CommandFactory commandFactory = fCommandControl.getCommandFactory();
fCommandControl.queueCommand(
commandFactory.createMIDataEvaluateExpression(exprContext),
new DataRequestMonitor<MIDataEvaluateExpressionInfo>(ImmediateExecutor.getInstance(), drm) {
@Override
@ConfinedToDsfExecutor("fExecutor")
protected void handleSuccess() {
try {
drm.setData(Integer.decode(getData().getValue()));
}
catch(NumberFormatException e) {
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, String.format("Invalid address size: %s", getData().getValue()))); //$NON-NLS-1$
}
drm.done();
}
});
}
protected void doReadEndianness(IMemoryDMContext memContext, final DataRequestMonitor<Boolean> drm) {
CommandFactory commandFactory = fCommandControl.getCommandFactory();
fCommandControl.queueCommand(
commandFactory.createCLIShowEndian(memContext),
new DataRequestMonitor<CLIShowEndianInfo>(ImmediateExecutor.getInstance(), drm) {
@Override
@ConfinedToDsfExecutor("fExecutor")
protected void handleSuccess() {
drm.setData(Boolean.valueOf(getData().isBigEndian()));
drm.done();
}
});
}
}

View file

@ -28,7 +28,7 @@ import org.eclipse.cdt.dsf.mi.service.MIMemory;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.debug.core.model.MemoryByte;
public class GDBMemory_7_0 extends MIMemory {
public class GDBMemory_7_0 extends GDBMemory {
public GDBMemory_7_0(DsfSession session) {
super(session);
@ -45,8 +45,15 @@ public class GDBMemory_7_0 extends MIMemory {
}
private void doInitialize(final RequestMonitor requestMonitor) {
register(new String[] { MIMemory.class.getName(), IMemory.class.getName(), GDBMemory_7_0.class.getName()},
new Hashtable<String, String>());
register(
new String[] {
MIMemory.class.getName(),
IMemory.class.getName(),
IGDBMemory.class.getName(),
GDBMemory.class.getName(),
GDBMemory_7_0.class.getName()
},
new Hashtable<String, String>());
requestMonitor.done();
}

View file

@ -61,6 +61,8 @@ public class GDBMemory_7_6 extends GDBMemory_7_0 implements IEventListener {
private void doInitialize(final RequestMonitor requestMonitor) {
register(new String[] { MIMemory.class.getName(),
IMemory.class.getName(),
IGDBMemory.class.getName(),
GDBMemory.class.getName(),
GDBMemory_7_0.class.getName(),
GDBMemory_7_6.class.getName()},
new Hashtable<String, String>());

View file

@ -42,7 +42,6 @@ import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsSynchronizer;
import org.eclipse.cdt.dsf.mi.service.MIDisassembly;
import org.eclipse.cdt.dsf.mi.service.MIExpressions;
import org.eclipse.cdt.dsf.mi.service.MIMemory;
import org.eclipse.cdt.dsf.mi.service.MIModules;
import org.eclipse.cdt.dsf.mi.service.MIRegisters;
import org.eclipse.cdt.dsf.mi.service.MIStack;
@ -186,7 +185,7 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
return new GDBMemory_7_0(session);
}
return new MIMemory(session);
return new GDBMemory(session);
}
@Override

View file

@ -0,0 +1,29 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import org.eclipse.cdt.dsf.debug.service.IMemory;
/**
* @since 4.2
*/
public interface IGDBMemory extends IMemory {
/**
* Returns the address size (in bytes) of the memory specified by the given context.
*/
public int getAddressSize(IMemoryDMContext context);
/**
* Returns whether the memory specified by the given context is big endian.
*/
public boolean isBigEndian(IMemoryDMContext context);
}

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.cdt.dsf.debug.service.IModules.IModuleDMContext;
import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
@ -52,6 +53,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.CLIMaintenance;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIPasscount;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIRecord;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIRemoteGet;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIShowEndian;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLISource;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIThread;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLITrace;
@ -172,6 +174,7 @@ import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoBreakInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoProgramInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoSharedLibraryInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoThreadsInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIShowEndianInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIThreadInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLITraceDumpInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLITraceInfo;
@ -291,6 +294,13 @@ public class CommandFactory {
return new CLIRemoteGet(ctx, remoteFile, localFile);
}
/**
* @since 4.2
*/
public ICommand<CLIShowEndianInfo> createCLIShowEndian(IMemoryDMContext ctx) {
return new CLIShowEndian(ctx);
}
public ICommand<MIInfo> createCLISource(ICommandControlDMContext ctx, String file) {
return new CLISource(ctx, file);
}

View file

@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
* John Dallaway - Add methods to get the endianness and address size (Bug 225609)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIShowEndianInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
/**
* Returns the endianness of the current GDB target.
*
* @since 4.2
*/
public class CLIShowEndian extends MIInterpreterExecConsole<CLIShowEndianInfo> {
private static final String SHOW_ENDIAN = "show endian"; //$NON-NLS-1$
public CLIShowEndian(IMemoryDMContext ctx) {
super(ctx, SHOW_ENDIAN);
}
@Override
public CLIShowEndianInfo getResult(MIOutput miResult) {
return new CLIShowEndianInfo(miResult);
}
}

View file

@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Mentor Graphics - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.output;
/**
* 'show endian' returns the endianness of the current target.
*
* sample output:
*
* (gdb) show endian
* The target endianness is set automatically (currently little endian)
*
* @since 4.2
*/
public class CLIShowEndianInfo extends MIInfo {
final private static String BIG_ENDIAN = "big endian"; //$NON-NLS-1$
private boolean fIsBigEndian = false;
public CLIShowEndianInfo(MIOutput record) {
super(record);
parse();
}
protected void parse() {
if (isDone()) {
MIOutput out = getMIOutput();
for (MIOOBRecord oob : out.getMIOOBRecords()) {
if (oob instanceof MIConsoleStreamOutput) {
String line = ((MIConsoleStreamOutput)oob).getString().trim();
if (line.indexOf(BIG_ENDIAN) >= 0 ) {
fIsBigEndian = true;
break;
}
}
}
}
}
public boolean isBigEndian() {
return fIsBigEndian;
}
}