From 28ea0386703035f99cb52c53a105fb4be4a6a174 Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Fri, 25 Mar 2005 05:00:10 +0000 Subject: [PATCH] 2005-03-24 Alain Magloire * cdi/org/eclipse/cdt/debug/mi/core/cdi/MemoryManager.java * cdi/org/eclipse/cdt/debug/mi/core/cdi/Memoryblock.java * cdi/org/eclipse/cdt/debug/mi/core/cdi/Target.java * mi/org/eclipse/cdt/debug/mi/core/command/MIShowEndian.java * mi/org/eclipse/cdt/debug/mi/core/output/MIShowEndianInfo.java --- debug/org.eclipse.cdt.debug.mi.core/ChangeLog | 7 ++ .../cdt/debug/mi/core/cdi/MemoryManager.java | 6 +- .../debug/mi/core/cdi/model/MemoryBlock.java | 85 +++++++++++++++++-- .../cdt/debug/mi/core/cdi/model/Target.java | 21 +++++ .../debug/mi/core/command/MIShowEndian.java | 41 +++++++++ .../mi/core/output/MIShowEndianInfo.java | 55 ++++++++++++ 6 files changed, 205 insertions(+), 10 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/MIShowEndian.java create mode 100644 debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/MIShowEndianInfo.java diff --git a/debug/org.eclipse.cdt.debug.mi.core/ChangeLog b/debug/org.eclipse.cdt.debug.mi.core/ChangeLog index dc58781eecc..29719ec8745 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/ChangeLog +++ b/debug/org.eclipse.cdt.debug.mi.core/ChangeLog @@ -1,3 +1,10 @@ +2005-03-24 Alain Magloire + * cdi/org/eclipse/cdt/debug/mi/core/cdi/MemoryManager.java + * cdi/org/eclipse/cdt/debug/mi/core/cdi/Memoryblock.java + * cdi/org/eclipse/cdt/debug/mi/core/cdi/Target.java + * mi/org/eclipse/cdt/debug/mi/core/command/MIShowEndian.java + * mi/org/eclipse/cdt/debug/mi/core/output/MIShowEndianInfo.java + 2005-03-23 Alain Magloire Changes in the CDI ICDIMemoryBlock && ICDIMemoryBlockManagement API. * cdi/org/eclipse/cdt/debug/mi/core/cdi/MemoryManager.java diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/MemoryManager.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/MemoryManager.java index 9041c22ef83..dffa114bb94 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/MemoryManager.java +++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/MemoryManager.java @@ -135,8 +135,9 @@ public class MemoryManager extends Manager { Target target = (Target)block.getTarget(); String exp = block.getExpression(); int wordSize = block.getWordSize(); + boolean little = target.isLittleEndian(); MIDataReadMemoryInfo info = createMIDataReadMemoryInfo(target.getMISession(), exp, (int)block.getLength(), wordSize); - return new MemoryBlock(target, exp, wordSize, info); + return new MemoryBlock(target, exp, wordSize, little, info); } /** @@ -158,8 +159,9 @@ public class MemoryManager extends Manager { } public ICDIMemoryBlock createMemoryBlock(Target target, String address, int units, int wordSize) throws CDIException { + boolean little = target.isLittleEndian(); MIDataReadMemoryInfo info = createMIDataReadMemoryInfo(target.getMISession(), address, units, wordSize); - ICDIMemoryBlock block = new MemoryBlock(target, address, wordSize, info); + ICDIMemoryBlock block = new MemoryBlock(target, address, wordSize, little, info); List blockList = getMemoryBlockList(target); blockList.add(block); MISession miSession = target.getMISession(); diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/MemoryBlock.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/MemoryBlock.java index 8b656115474..e8f9bb2f5b5 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/MemoryBlock.java +++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/model/MemoryBlock.java @@ -41,12 +41,14 @@ public class MemoryBlock extends CObject implements ICDIMemoryBlock { private BigInteger cStartAddress; //cached start address private byte[] cBytes; //cached bytes private int[] badOffsets; + private boolean fIsLittleEndian; - public MemoryBlock(Target target, String exp, int wordSize, MIDataReadMemoryInfo info) { + public MemoryBlock(Target target, String exp, int wordSize, boolean isLittle, MIDataReadMemoryInfo info) { super(target); expression = exp; fWordSize = wordSize; frozen = true; + fIsLittleEndian = isLittle; setMIDataReadMemoryInfo(info); } @@ -136,14 +138,23 @@ public class MemoryBlock extends CObject implements ICDIMemoryBlock { MIMemory[] miMem = m.getMemories(); for (int i = 0; i < miMem.length; ++i) { long[] data = miMem[i].getData(); - if (data.length > 0) { - int blen = bytes.length; - byte[] newBytes = new byte[blen + data.length]; - System.arraycopy(bytes, 0, newBytes, 0, blen); - for (int j = 0; j < data.length; ++j, ++blen) { - newBytes[blen] = (byte)data[j]; + if (data != null && data.length > 0) { +// int blen = bytes.length; +// byte[] newBytes = new byte[blen + data.length]; +// System.arraycopy(bytes, 0, newBytes, 0, blen); +// for (int j = 0; j < data.length; ++j, ++blen) { +// newBytes[blen] = (byte)data[j]; +// } +// bytes = newBytes; + for (int j = 0; j < data.length; ++j) { + byte[] bs = longToBytes(data[j]); + // grow the array + int blen = bytes.length; + byte[] newBytes = new byte[blen + bs.length]; + System.arraycopy(bytes, 0, newBytes, 0, blen); + System.arraycopy(bs, 0, newBytes, blen, bs.length); + bytes = newBytes; } - bytes = newBytes; } } return bytes; @@ -201,6 +212,14 @@ public class MemoryBlock extends CObject implements ICDIMemoryBlock { * @see org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock#getLength() */ public long getLength() { + try { + // use this instead. If the wordSize + // given does not match the hardware, + // counting the bytes will be correct. + return getBytes().length; + } catch (CDIException e) { + // ignore. + } return mem.getTotalBytes(); } @@ -273,4 +292,54 @@ public class MemoryBlock extends CObject implements ICDIMemoryBlock { return VALID; } + + /** + * We should use the wordSize ... but ... + * The problem: the user may not have the right wordsize + * For example on some DSP the user set the wordSize to be 1 byte + * but in fact GDB is reading 2 bytes. + * So let do some guessing since the data(long) may have a bigger value then one byte. + */ + private byte[] longToBytes(long v) { + // Calculate the number of bytes needed + int count = 1; + long value = v; + for (count = 1; (value /= 0x100) > 0; ++count) + ; + + // Reset the wordSize if incorrect. + if (fWordSize != count) { + fWordSize = count; + } + + byte[] bytes = new byte[count]; + if (fIsLittleEndian) { + for (int i = count - 1; i >= 0; --i) { + int shift = i * count; + bytes[i] = (byte)((v >>> shift) & 0xFF); + } +// bytes[7] = (byte)((v >>> 56) & 0xFF); +// bytes[6] = (byte)((v >>> 48) & 0xFF); +// bytes[5] = (byte)((v >>> 40) & 0xFF); +// bytes[4] = (byte)((v >>> 32) & 0xFF); +// bytes[3] = (byte)((v >>> 24) & 0xFF); +// bytes[2] = (byte)((v >>> 16) & 0xFF); +// bytes[1] = (byte)((v >>> 8) & 0xFF); +// bytes[0] = (byte)((v >>> 0) & 0xFF); + } else { + for (int i = 0; i < count; ++i) { + int shift = (count - i - 1) * count; + bytes[i] = (byte)((v >>> shift) & 0xFF); + } +// bytes[0] = (byte)((v >>> 56) & 0xFF); +// bytes[1] = (byte)((v >>> 48) & 0xFF); +// bytes[2] = (byte)((v >>> 40) & 0xFF); +// bytes[3] = (byte)((v >>> 32) & 0xFF); +// bytes[4] = (byte)((v >>> 24) & 0xFF); +// bytes[5] = (byte)((v >>> 16) & 0xFF); +// bytes[6] = (byte)((v >>> 8) & 0xFF); +// bytes[7] = (byte)((v >>> 0) & 0xFF); + } + return bytes; + } } 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 1cec48b9ab9..14948289016 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 @@ -60,6 +60,7 @@ import org.eclipse.cdt.debug.mi.core.command.MIExecStepInstruction; import org.eclipse.cdt.debug.mi.core.command.MIExecUntil; import org.eclipse.cdt.debug.mi.core.command.MIInfoThreads; import org.eclipse.cdt.debug.mi.core.command.MIJump; +import org.eclipse.cdt.debug.mi.core.command.MIShowEndian; import org.eclipse.cdt.debug.mi.core.command.MISignal; import org.eclipse.cdt.debug.mi.core.command.MITargetDetach; import org.eclipse.cdt.debug.mi.core.command.MIThreadSelect; @@ -70,6 +71,7 @@ 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.MIInfo; import org.eclipse.cdt.debug.mi.core.output.MIInfoThreadsInfo; +import org.eclipse.cdt.debug.mi.core.output.MIShowEndianInfo; import org.eclipse.cdt.debug.mi.core.output.MIThreadSelectInfo; /** @@ -81,6 +83,7 @@ public class Target extends SessionObject implements ICDITarget { Thread[] noThreads = new Thread[0]; Thread[] currentThreads; int currentThreadId; + String fEndian = null; public Target(Session s, MISession mi) { super(s); @@ -335,6 +338,24 @@ public class Target extends SessionObject implements ICDITarget { return th; } + public boolean isLittleEndian() throws CDIException { + if (fEndian == null) { + CommandFactory factory = miSession.getCommandFactory(); + MIShowEndian endian = new MIShowEndian(); + try { + miSession.postCommand(endian); + MIShowEndianInfo info = endian.getMIShowEndianInfo(); + if (info == null) { + throw new CDIException(CdiResources.getString("cdi.model.Target.Target_not_responding")); //$NON-NLS-1$ + } + fEndian = info.isLittleEndian() ? "le" : "be"; //$NON-NLS-1$ //$NON-NLS-2$ + } catch (MIException e) { + throw new MI2CDIException(e); + } + } + return fEndian.equals("le"); //$NON-NLS-1$ + } + /** * @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#restart() */ diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/MIShowEndian.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/MIShowEndian.java new file mode 100644 index 00000000000..1a17fffd4b1 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/MIShowEndian.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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.debug.mi.core.command; + +import org.eclipse.cdt.debug.mi.core.MIException; +import org.eclipse.cdt.debug.mi.core.output.MIInfo; +import org.eclipse.cdt.debug.mi.core.output.MIOutput; +import org.eclipse.cdt.debug.mi.core.output.MIShowEndianInfo; + +public class MIShowEndian extends CLICommand { + + public MIShowEndian() { + super("show endian"); //$NON-NLS-1$ + } + + public MIShowEndianInfo getMIShowEndianInfo() throws MIException { + return (MIShowEndianInfo)getMIInfo(); + } + + public MIInfo getMIInfo() throws MIException { + MIInfo info = null; + MIOutput out = getMIOutput(); + if (out != null) { + info = new MIShowEndianInfo(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/output/MIShowEndianInfo.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/MIShowEndianInfo.java new file mode 100644 index 00000000000..e904d6182ca --- /dev/null +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/output/MIShowEndianInfo.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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.debug.mi.core.output; + +/** + * show endian +&"show endian\n" +~"The target endianness is set automatically (currently little endian)\n" +^done + * + */ +public class MIShowEndianInfo extends MIInfo { + + boolean littleEndian; + + public MIShowEndianInfo(MIOutput out) { + super(out); + parse(); + } + + public boolean isLittleEndian() { + return littleEndian; + } + + void parse() { + 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 the signal info + parseLine(str); + } + } + } + } + + void parseLine(String str) { + if (str != null && str.length() > 0) { + littleEndian = (str.indexOf("little") != -1); + } + } + +}