mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-20 09:51:55 +08:00
GP-1768A: limits on initial loads; fix for possible id/pid/tid mismatch
GP-1768A: check for symbols; misc fixes GP-1768A: suppress descent for kernel mode GP-1768A: undoing a few things GP-1768A: undoing a few things again GP-1768A: added data offset methods intending to replace pids/tids for kernel lookups GP-1768A: resorting to CLI for state GP-1768A: resorting to CLI for state GP-1768A: add ability to set implicit thread/process GP-1768A: cleanup GP-1768A: default to ALIVE ofr kernel GP-1768A: better setActive implementations GP-1768A: NPE fix GP-1768A: cleanup post-review
This commit is contained in:
+4
-4
@@ -26,15 +26,15 @@ package agent.dbgeng.dbgeng;
|
||||
* PIDs.
|
||||
*/
|
||||
public class DebugProcessId implements Comparable<DebugProcessId> {
|
||||
public final int id;
|
||||
public final long id;
|
||||
|
||||
public DebugProcessId(int id) {
|
||||
public DebugProcessId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Integer.hashCode(id);
|
||||
return Long.hashCode(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,7 +51,7 @@ public class DebugProcessId implements Comparable<DebugProcessId> {
|
||||
|
||||
@Override
|
||||
public int compareTo(DebugProcessId that) {
|
||||
return Integer.compare(this.id, that.id);
|
||||
return Long.compare(this.id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
@@ -99,4 +99,16 @@ public interface DebugSystemObjects {
|
||||
|
||||
DebugProcessId getProcessIdBySystemId(int systemId);
|
||||
|
||||
long getCurrentThreadDataOffset();
|
||||
|
||||
long getCurrentProcessDataOffset();
|
||||
|
||||
long getImplicitThreadDataOffset();
|
||||
|
||||
long getImplicitProcessDataOffset();
|
||||
|
||||
void setImplicitThreadDataOffset(long systemOffset);
|
||||
|
||||
void setImplicitProcessDataOffset(long systemOffset);
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -26,15 +26,15 @@ package agent.dbgeng.dbgeng;
|
||||
* TIDs.
|
||||
*/
|
||||
public class DebugThreadId implements Comparable<DebugThreadId> {
|
||||
public final int id;
|
||||
public final long id;
|
||||
|
||||
public DebugThreadId(int id) {
|
||||
public DebugThreadId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Integer.hashCode(id);
|
||||
return Long.hashCode(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,7 +51,7 @@ public class DebugThreadId implements Comparable<DebugThreadId> {
|
||||
|
||||
@Override
|
||||
public int compareTo(DebugThreadId that) {
|
||||
return Integer.compare(this.id, that.id);
|
||||
return Long.compare(this.id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+44
@@ -228,6 +228,28 @@ public class DebugSystemObjectsImpl1 implements DebugSystemObjectsInternal {
|
||||
return pulSysId.getValue().intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentThreadDataOffset() {
|
||||
ULONGLONGByReference pulSysOffset = new ULONGLONGByReference();
|
||||
HRESULT hr = jnaSysobj.GetCurrentThreadDataOffset(pulSysOffset);
|
||||
if (hr.equals(COMUtilsExtra.E_UNEXPECTED) || hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) {
|
||||
return -1;
|
||||
}
|
||||
COMUtils.checkRC(hr);
|
||||
return pulSysOffset.getValue().longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentProcessDataOffset() {
|
||||
ULONGLONGByReference pulSysOffset = new ULONGLONGByReference();
|
||||
HRESULT hr = jnaSysobj.GetCurrentProcessDataOffset(pulSysOffset);
|
||||
if (hr.equals(COMUtilsExtra.E_UNEXPECTED) || hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) {
|
||||
return -1;
|
||||
}
|
||||
COMUtils.checkRC(hr);
|
||||
return pulSysOffset.getValue().longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DebugSessionId getEventSystem() {
|
||||
throw new UnsupportedOperationException("Not supported by this interface");
|
||||
@@ -252,4 +274,26 @@ public class DebugSystemObjectsImpl1 implements DebugSystemObjectsInternal {
|
||||
public List<DebugSessionId> getSystems(int start, int count) {
|
||||
throw new UnsupportedOperationException("Not supported by this interface");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getImplicitThreadDataOffset() {
|
||||
throw new UnsupportedOperationException("Not supported by this interface");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getImplicitProcessDataOffset() {
|
||||
throw new UnsupportedOperationException("Not supported by this interface");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitThreadDataOffset(long offset) {
|
||||
throw new UnsupportedOperationException("Not supported by this interface");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitProcessDataOffset(long offset) {
|
||||
throw new UnsupportedOperationException("Not supported by this interface");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+47
@@ -15,6 +15,12 @@
|
||||
*/
|
||||
package agent.dbgeng.impl.dbgeng.sysobj;
|
||||
|
||||
import com.sun.jna.platform.win32.COM.COMUtils;
|
||||
import com.sun.jna.platform.win32.WinDef.ULONGLONG;
|
||||
import com.sun.jna.platform.win32.WinDef.ULONGLONGByReference;
|
||||
import com.sun.jna.platform.win32.WinNT.HRESULT;
|
||||
|
||||
import agent.dbgeng.dbgeng.COMUtilsExtra;
|
||||
import agent.dbgeng.jna.dbgeng.sysobj.IDebugSystemObjects2;
|
||||
|
||||
public class DebugSystemObjectsImpl2 extends DebugSystemObjectsImpl1 {
|
||||
@@ -25,4 +31,45 @@ public class DebugSystemObjectsImpl2 extends DebugSystemObjectsImpl1 {
|
||||
super(jnaSysobj);
|
||||
this.jnaSysobj = jnaSysobj;
|
||||
}
|
||||
|
||||
public long getImplicitThreadDataOffset() {
|
||||
ULONGLONGByReference pulSysOffset = new ULONGLONGByReference();
|
||||
HRESULT hr = jnaSysobj.GetImplicitThreadDataOffset(pulSysOffset);
|
||||
if (hr.equals(COMUtilsExtra.E_UNEXPECTED) || hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) {
|
||||
return -1;
|
||||
}
|
||||
COMUtils.checkRC(hr);
|
||||
return pulSysOffset.getValue().longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getImplicitProcessDataOffset() {
|
||||
ULONGLONGByReference pulSysOffset = new ULONGLONGByReference();
|
||||
HRESULT hr = jnaSysobj.GetImplicitProcessDataOffset(pulSysOffset);
|
||||
if (hr.equals(COMUtilsExtra.E_UNEXPECTED) || hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) {
|
||||
return -1;
|
||||
}
|
||||
COMUtils.checkRC(hr);
|
||||
return pulSysOffset.getValue().longValue();
|
||||
}
|
||||
|
||||
public void setImplicitThreadDataOffset(long offset) {
|
||||
ULONGLONG ulSysOffset = new ULONGLONG(offset);
|
||||
HRESULT hr = jnaSysobj.SetImplicitThreadDataOffset(ulSysOffset);
|
||||
if (hr.equals(COMUtilsExtra.E_UNEXPECTED) || hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) {
|
||||
return;
|
||||
}
|
||||
COMUtils.checkRC(hr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitProcessDataOffset(long offset) {
|
||||
ULONGLONG ulSysOffset = new ULONGLONG(offset);
|
||||
HRESULT hr = jnaSysobj.SetImplicitProcessDataOffset(ulSysOffset);
|
||||
if (hr.equals(COMUtilsExtra.E_UNEXPECTED) || hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) {
|
||||
return;
|
||||
}
|
||||
COMUtils.checkRC(hr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
@@ -98,4 +98,9 @@ public interface IDebugSystemObjects extends IUnknown {
|
||||
HRESULT GetThreadIdBySystemId(ULONG SystemId, ULONGByReference Id);
|
||||
|
||||
HRESULT GetProcessIdBySystemId(ULONG SystemId, ULONGByReference Id);
|
||||
|
||||
HRESULT GetCurrentThreadDataOffset(ULONGLONGByReference SysOffset);
|
||||
|
||||
HRESULT GetCurrentProcessDataOffset(ULONGLONGByReference SysOffset);
|
||||
|
||||
}
|
||||
|
||||
+12
@@ -16,6 +16,9 @@
|
||||
package agent.dbgeng.jna.dbgeng.sysobj;
|
||||
|
||||
import com.sun.jna.platform.win32.Guid.IID;
|
||||
import com.sun.jna.platform.win32.WinDef.ULONGLONG;
|
||||
import com.sun.jna.platform.win32.WinDef.ULONGLONGByReference;
|
||||
import com.sun.jna.platform.win32.WinNT.HRESULT;
|
||||
|
||||
import agent.dbgeng.jna.dbgeng.UnknownWithUtils.VTableIndex;
|
||||
|
||||
@@ -37,4 +40,13 @@ public interface IDebugSystemObjects2 extends IDebugSystemObjects {
|
||||
return this.ordinal() + start;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT GetImplicitThreadDataOffset(ULONGLONGByReference SysOffset);
|
||||
|
||||
HRESULT GetImplicitProcessDataOffset(ULONGLONGByReference SysOffset);
|
||||
|
||||
HRESULT SetImplicitThreadDataOffset(ULONGLONG SysOffset);
|
||||
|
||||
HRESULT SetImplicitProcessDataOffset(ULONGLONG SysOffset);
|
||||
|
||||
}
|
||||
|
||||
+12
@@ -21,6 +21,7 @@ import com.sun.jna.platform.win32.WinDef.*;
|
||||
import com.sun.jna.platform.win32.WinNT.HRESULT;
|
||||
|
||||
import agent.dbgeng.jna.dbgeng.UnknownWithUtils;
|
||||
import agent.dbgeng.jna.dbgeng.sysobj.IDebugSystemObjects2.VTIndices2;
|
||||
|
||||
public class WrapIDebugSystemObjects extends UnknownWithUtils implements IDebugSystemObjects {
|
||||
public static class ByReference extends WrapIDebugSystemObjects
|
||||
@@ -120,4 +121,15 @@ public class WrapIDebugSystemObjects extends UnknownWithUtils implements IDebugS
|
||||
public HRESULT GetCurrentProcessSystemId(ULONGByReference SysId) {
|
||||
return _invokeHR(VTIndices.GET_CURRENT_PROCESS_SYSTEM_ID, getPointer(), SysId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HRESULT GetCurrentThreadDataOffset(ULONGLONGByReference SysOffset) {
|
||||
return _invokeHR(VTIndices.GET_CURRENT_THREAD_DATA_OFFSET, getPointer(), SysOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HRESULT GetCurrentProcessDataOffset(ULONGLONGByReference SysOffset) {
|
||||
return _invokeHR(VTIndices.GET_CURRENT_PROCESS_DATA_OFFSET, getPointer(), SysOffset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+26
@@ -17,6 +17,11 @@ package agent.dbgeng.jna.dbgeng.sysobj;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
import com.sun.jna.platform.win32.WinDef.ULONGLONG;
|
||||
import com.sun.jna.platform.win32.WinDef.ULONGLONGByReference;
|
||||
import com.sun.jna.platform.win32.WinNT.HRESULT;
|
||||
|
||||
import agent.dbgeng.jna.dbgeng.sysobj.IDebugSystemObjects2.VTIndices2;
|
||||
|
||||
public class WrapIDebugSystemObjects2 extends WrapIDebugSystemObjects
|
||||
implements IDebugSystemObjects2 {
|
||||
@@ -30,4 +35,25 @@ public class WrapIDebugSystemObjects2 extends WrapIDebugSystemObjects
|
||||
public WrapIDebugSystemObjects2(Pointer pvInstance) {
|
||||
super(pvInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HRESULT GetImplicitThreadDataOffset(ULONGLONGByReference SysOffset) {
|
||||
return _invokeHR(VTIndices2.GET_IMPLICIT_THREAD_DATA_OFFSET, getPointer(), SysOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HRESULT GetImplicitProcessDataOffset(ULONGLONGByReference SysOffset) {
|
||||
return _invokeHR(VTIndices2.GET_IMPLICIT_PROCESS_DATA_OFFSET, getPointer(), SysOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HRESULT SetImplicitThreadDataOffset(ULONGLONG SysOffset) {
|
||||
return _invokeHR(VTIndices2.SET_IMPLICIT_THREAD_DATA_OFFSET, getPointer(), SysOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HRESULT SetImplicitProcessDataOffset(ULONGLONG SysOffset) {
|
||||
return _invokeHR(VTIndices2.SET_IMPLICIT_PROCESS_DATA_OFFSET, getPointer(), SysOffset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -163,4 +163,4 @@ public interface DbgThread
|
||||
*/
|
||||
Machine getExecutingProcessorType();
|
||||
|
||||
}
|
||||
}
|
||||
+4
@@ -22,6 +22,7 @@ import agent.dbgeng.manager.*;
|
||||
import agent.dbgeng.manager.evt.AbstractDbgCompletedCommandEvent;
|
||||
import agent.dbgeng.manager.evt.DbgProcessCreatedEvent;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
/**
|
||||
* Implementation of {@link DbgProcess#fileExecAndSymbols(String)}
|
||||
@@ -59,6 +60,9 @@ public class DbgAttachKernelCommand extends AbstractDbgCommand<DbgThread> {
|
||||
|
||||
@Override
|
||||
public void invoke() {
|
||||
if (!System.getenv().containsKey("_NT_SYMBOL_PATH")) {
|
||||
Msg.warn(this, "_NT_SYMBOL_PATH is undefined - you may need to define it or run .sympath");
|
||||
}
|
||||
DebugClient dbgeng = manager.getClient();
|
||||
long flags = (Long) args.get("Flags");
|
||||
String options = (String) args.get("Options");
|
||||
|
||||
+62
-4
@@ -15,14 +15,22 @@
|
||||
*/
|
||||
package agent.dbgeng.manager.cmd;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import agent.dbgeng.dbgeng.DebugControl;
|
||||
import agent.dbgeng.dbgeng.DebugProcessId;
|
||||
import agent.dbgeng.dbgeng.DebugSystemObjects;
|
||||
import agent.dbgeng.manager.DbgEvent;
|
||||
import agent.dbgeng.manager.DbgProcess;
|
||||
import agent.dbgeng.manager.evt.AbstractDbgCompletedCommandEvent;
|
||||
import agent.dbgeng.manager.evt.DbgConsoleOutputEvent;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.manager.impl.DbgProcessImpl;
|
||||
|
||||
public class DbgSetActiveProcessCommand extends AbstractDbgCommand<Void> {
|
||||
|
||||
private DbgProcess process;
|
||||
private DbgProcessImpl process;
|
||||
private Long offset;
|
||||
|
||||
/**
|
||||
* Set the active process
|
||||
@@ -32,7 +40,47 @@ public class DbgSetActiveProcessCommand extends AbstractDbgCommand<Void> {
|
||||
*/
|
||||
public DbgSetActiveProcessCommand(DbgManagerImpl manager, DbgProcess process) {
|
||||
super(manager);
|
||||
this.process = process;
|
||||
this.process = (DbgProcessImpl) process;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(DbgEvent<?> evt, DbgPendingCommand<?> pending) {
|
||||
if (evt instanceof AbstractDbgCompletedCommandEvent && pending.getCommand().equals(this)) {
|
||||
return true;
|
||||
}
|
||||
else if (evt instanceof DbgConsoleOutputEvent) {
|
||||
pending.steal(evt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void complete(DbgPendingCommand<?> pending) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (DbgConsoleOutputEvent out : pending.findAllOf(DbgConsoleOutputEvent.class)) {
|
||||
builder.append(out.getOutput());
|
||||
}
|
||||
parse(builder.toString());
|
||||
if (offset != null) {
|
||||
manager.getSystemObjects().setImplicitThreadDataOffset(offset);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void parse(String result) {
|
||||
String[] lines = result.split("\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String line = lines[i];
|
||||
if (line.contains("PROCESS")) {
|
||||
String[] fields = line.trim().split("\\s+");
|
||||
if (fields.length > 1 && fields[0].equals("PROCESS")) {
|
||||
BigInteger val = new BigInteger(fields[1], 16);
|
||||
offset = val.longValue();
|
||||
process.setOffset(offset);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,9 +89,19 @@ public class DbgSetActiveProcessCommand extends AbstractDbgCommand<Void> {
|
||||
DebugProcessId id = process.getId();
|
||||
if (id != null) {
|
||||
DebugSystemObjects so = manager.getSystemObjects();
|
||||
DebugProcessId currentProcessId = so.getCurrentProcessId();
|
||||
if (id.id != currentProcessId.id) {
|
||||
if (manager.isKernelMode()) {
|
||||
offset = process.getOffset();
|
||||
if (offset == null || offset == 0L) {
|
||||
DebugControl control = manager.getControl();
|
||||
control.execute("!process "+Long.toHexString(process.getPid()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
so.setCurrentProcessId(id);
|
||||
DebugProcessId currentProcessId = so.getCurrentProcessId();
|
||||
if (id.id != currentProcessId.id) {
|
||||
so.setCurrentProcessId(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+60
-3
@@ -15,14 +15,22 @@
|
||||
*/
|
||||
package agent.dbgeng.manager.cmd;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import agent.dbgeng.dbgeng.DebugControl;
|
||||
import agent.dbgeng.dbgeng.DebugThreadId;
|
||||
import agent.dbgeng.manager.DbgEvent;
|
||||
import agent.dbgeng.manager.DbgThread;
|
||||
import agent.dbgeng.manager.evt.AbstractDbgCompletedCommandEvent;
|
||||
import agent.dbgeng.manager.evt.DbgConsoleOutputEvent;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.manager.impl.DbgThreadImpl;
|
||||
|
||||
public class DbgSetActiveThreadCommand extends AbstractDbgCommand<Void> {
|
||||
|
||||
private DbgThread thread;
|
||||
private DbgThreadImpl thread;
|
||||
private Integer frameId;
|
||||
private Long offset;
|
||||
|
||||
/**
|
||||
* Set the active thread
|
||||
@@ -33,15 +41,64 @@ public class DbgSetActiveThreadCommand extends AbstractDbgCommand<Void> {
|
||||
*/
|
||||
public DbgSetActiveThreadCommand(DbgManagerImpl manager, DbgThread thread, Integer frameId) {
|
||||
super(manager);
|
||||
this.thread = thread;
|
||||
this.thread = (DbgThreadImpl) thread;
|
||||
this.frameId = frameId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(DbgEvent<?> evt, DbgPendingCommand<?> pending) {
|
||||
if (evt instanceof AbstractDbgCompletedCommandEvent && pending.getCommand().equals(this)) {
|
||||
return true;
|
||||
}
|
||||
else if (evt instanceof DbgConsoleOutputEvent) {
|
||||
pending.steal(evt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void complete(DbgPendingCommand<?> pending) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (DbgConsoleOutputEvent out : pending.findAllOf(DbgConsoleOutputEvent.class)) {
|
||||
builder.append(out.getOutput());
|
||||
}
|
||||
parse(builder.toString());
|
||||
if (offset != null) {
|
||||
manager.getSystemObjects().setImplicitThreadDataOffset(offset);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void parse(String result) {
|
||||
String[] lines = result.split("\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String line = lines[i];
|
||||
if (line.contains("THREAD")) {
|
||||
String[] fields = line.trim().split("\\s+");
|
||||
if (fields.length > 1 && fields[0].equals("THREAD")) {
|
||||
BigInteger val = new BigInteger(fields[1], 16);
|
||||
offset = val.longValue();
|
||||
thread.setOffset(offset);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke() {
|
||||
DebugThreadId id = thread.getId();
|
||||
if (id != null) {
|
||||
manager.getSystemObjects().setCurrentThreadId(id);
|
||||
if (!manager.isKernelMode()) {
|
||||
manager.getSystemObjects().setCurrentThreadId(id);
|
||||
}
|
||||
else {
|
||||
offset = thread.getOffset();
|
||||
if (offset == null || offset == 0L) {
|
||||
DebugControl control = manager.getControl();
|
||||
control.execute("!thread -t "+Long.toHexString(thread.getTid()));
|
||||
}
|
||||
}
|
||||
if (frameId != null) {
|
||||
manager.getSymbols().setCurrentScopeFrameIndex(frameId);
|
||||
}
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package agent.dbgeng.manager.cmd;
|
||||
|
||||
import agent.dbgeng.dbgeng.DebugControl;
|
||||
import agent.dbgeng.dbgeng.DebugProcessId;
|
||||
import agent.dbgeng.dbgeng.DebugSystemObjects;
|
||||
import agent.dbgeng.dbgeng.DebugThreadId;
|
||||
import agent.dbgeng.manager.DbgEvent;
|
||||
import agent.dbgeng.manager.DbgThread;
|
||||
import agent.dbgeng.manager.evt.AbstractDbgCompletedCommandEvent;
|
||||
import agent.dbgeng.manager.evt.DbgConsoleOutputEvent;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.manager.impl.DbgProcessImpl;
|
||||
import agent.dbgeng.manager.impl.DbgThreadImpl;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class DbgSetCurrentState extends AbstractDbgCommand<DbgThread> {
|
||||
|
||||
private long pid;
|
||||
private long tid;
|
||||
private DebugProcessId pID;
|
||||
private DebugThreadId tID;
|
||||
|
||||
public DbgSetCurrentState(DbgManagerImpl manager) {
|
||||
super(manager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(DbgEvent<?> evt, DbgPendingCommand<?> pending) {
|
||||
if (evt instanceof AbstractDbgCompletedCommandEvent && pending.getCommand().equals(this)) {
|
||||
return true;
|
||||
}
|
||||
else if (evt instanceof DbgConsoleOutputEvent) {
|
||||
pending.steal(evt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DbgThread complete(DbgPendingCommand<?> pending) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (DbgConsoleOutputEvent out : pending.findAllOf(DbgConsoleOutputEvent.class)) {
|
||||
builder.append(out.getOutput());
|
||||
}
|
||||
parse(builder.toString());
|
||||
|
||||
if (pID == null) {
|
||||
return null;
|
||||
}
|
||||
DbgProcessImpl proc = manager.getProcessComputeIfAbsent(pID, pid, true);
|
||||
DbgThreadImpl thread = manager.getThreadComputeIfAbsent(tID, proc, tid, true);
|
||||
try {
|
||||
DebugSystemObjects so = manager.getSystemObjects();
|
||||
proc.setOffset(so.getCurrentProcessDataOffset());
|
||||
thread.setOffset(so.getCurrentThreadDataOffset());
|
||||
} catch (Exception e) {
|
||||
Msg.error(this, e.getMessage());
|
||||
}
|
||||
return thread;
|
||||
}
|
||||
|
||||
private void parse(String result) {
|
||||
String[] lines = result.split("\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String line = lines[i];
|
||||
if (line.contains("THREAD")) {
|
||||
String[] fields = line.trim().split("\\s+");
|
||||
if (fields.length > 3 && fields[2].equals("Cid")) {
|
||||
String[] split = fields[3].split("\\.");
|
||||
if (split.length == 2) {
|
||||
pid = Long.parseLong(split[0], 16);
|
||||
tid = Long.parseLong(split[1], 16);
|
||||
pID = new DebugProcessId(pid);
|
||||
tID = new DebugThreadId(tid);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke() {
|
||||
DebugControl control = manager.getControl();
|
||||
control.execute("!thread");
|
||||
}
|
||||
|
||||
}
|
||||
+206
-44
@@ -15,9 +15,20 @@
|
||||
*/
|
||||
package agent.dbgeng.manager.impl;
|
||||
|
||||
import static ghidra.async.AsyncUtils.*;
|
||||
import static ghidra.async.AsyncUtils.sequence;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -26,31 +37,114 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.sun.jna.platform.win32.COM.COMException;
|
||||
|
||||
import agent.dbgeng.dbgeng.*;
|
||||
import agent.dbgeng.dbgeng.DbgEng;
|
||||
import agent.dbgeng.dbgeng.DebugAdvanced;
|
||||
import agent.dbgeng.dbgeng.DebugBreakpoint;
|
||||
import agent.dbgeng.dbgeng.DebugBreakpoint.BreakFlags;
|
||||
import agent.dbgeng.dbgeng.DebugBreakpoint.BreakType;
|
||||
import agent.dbgeng.dbgeng.DebugClient.*;
|
||||
import agent.dbgeng.dbgeng.DebugClient;
|
||||
import agent.dbgeng.dbgeng.DebugClient.ChangeDebuggeeState;
|
||||
import agent.dbgeng.dbgeng.DebugClient.ChangeEngineState;
|
||||
import agent.dbgeng.dbgeng.DebugClient.DebugCreateFlags;
|
||||
import agent.dbgeng.dbgeng.DebugClient.DebugEndSessionFlags;
|
||||
import agent.dbgeng.dbgeng.DebugClient.DebugEngCreateFlags;
|
||||
import agent.dbgeng.dbgeng.DebugClient.DebugStatus;
|
||||
import agent.dbgeng.dbgeng.DebugClient.DebugVerifierFlags;
|
||||
import agent.dbgeng.dbgeng.DebugClient.ExecutionState;
|
||||
import agent.dbgeng.dbgeng.DebugClientReentrant;
|
||||
import agent.dbgeng.dbgeng.DebugControl;
|
||||
import agent.dbgeng.dbgeng.DebugControl.DebugInterrupt;
|
||||
import agent.dbgeng.dbgeng.DebugDataSpaces;
|
||||
import agent.dbgeng.dbgeng.DebugEventInformation;
|
||||
import agent.dbgeng.dbgeng.DebugExceptionRecord64;
|
||||
import agent.dbgeng.dbgeng.DebugModuleInfo;
|
||||
import agent.dbgeng.dbgeng.DebugProcessId;
|
||||
import agent.dbgeng.dbgeng.DebugProcessInfo;
|
||||
import agent.dbgeng.dbgeng.DebugRegisters;
|
||||
import agent.dbgeng.dbgeng.DebugSessionId;
|
||||
import agent.dbgeng.dbgeng.DebugSymbols;
|
||||
import agent.dbgeng.dbgeng.DebugSystemObjects;
|
||||
import agent.dbgeng.dbgeng.DebugThreadId;
|
||||
import agent.dbgeng.dbgeng.DebugThreadInfo;
|
||||
import agent.dbgeng.gadp.impl.AbstractClientThreadExecutor;
|
||||
import agent.dbgeng.gadp.impl.DbgEngClientThreadExecutor;
|
||||
import agent.dbgeng.impl.dbgeng.DbgEngUtil;
|
||||
import agent.dbgeng.jna.dbgeng.WinNTExtra;
|
||||
import agent.dbgeng.manager.*;
|
||||
import agent.dbgeng.manager.DbgCause;
|
||||
import agent.dbgeng.manager.DbgCause.Causes;
|
||||
import agent.dbgeng.manager.DbgCommand;
|
||||
import agent.dbgeng.manager.DbgEvent;
|
||||
import agent.dbgeng.manager.DbgEventsListener;
|
||||
import agent.dbgeng.manager.DbgManager;
|
||||
import agent.dbgeng.manager.DbgModuleMemory;
|
||||
import agent.dbgeng.manager.DbgProcess;
|
||||
import agent.dbgeng.manager.DbgSession;
|
||||
import agent.dbgeng.manager.DbgState;
|
||||
import agent.dbgeng.manager.DbgStateListener;
|
||||
import agent.dbgeng.manager.DbgThread;
|
||||
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
||||
import agent.dbgeng.manager.breakpoint.DbgBreakpointType;
|
||||
import agent.dbgeng.manager.cmd.*;
|
||||
import agent.dbgeng.manager.evt.*;
|
||||
import agent.dbgeng.manager.cmd.DbgAddProcessCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgAddSessionCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgAttachKernelCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgCommandError;
|
||||
import agent.dbgeng.manager.cmd.DbgConsoleExecCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgDeleteBreakpointsCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgDisableBreakpointsCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgEnableBreakpointsCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgInsertBreakpointCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgLaunchProcessCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgListAvailableProcessesCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgListBreakpointsCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgListProcessesCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgOpenDumpCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgPendingCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgRemoveProcessCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgRemoveSessionCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgRequestActivationCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgRequestFocusCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgSetActiveProcessCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgSetActiveSessionCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgSetActiveThreadCommand;
|
||||
import agent.dbgeng.manager.cmd.DbgSetCurrentState;
|
||||
import agent.dbgeng.manager.evt.AbstractDbgEvent;
|
||||
import agent.dbgeng.manager.evt.DbgBreakpointCreatedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgBreakpointDeletedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgBreakpointEvent;
|
||||
import agent.dbgeng.manager.evt.DbgBreakpointModifiedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgCommandDoneEvent;
|
||||
import agent.dbgeng.manager.evt.DbgConsoleOutputEvent;
|
||||
import agent.dbgeng.manager.evt.DbgDebuggeeStateChangeEvent;
|
||||
import agent.dbgeng.manager.evt.DbgExceptionEvent;
|
||||
import agent.dbgeng.manager.evt.DbgModuleLoadedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgModuleUnloadedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgProcessCreatedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgProcessExitedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgProcessSelectedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgPromptChangedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgRunningEvent;
|
||||
import agent.dbgeng.manager.evt.DbgSessionSelectedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgStateChangedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgStoppedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgSystemErrorEvent;
|
||||
import agent.dbgeng.manager.evt.DbgSystemsEvent;
|
||||
import agent.dbgeng.manager.evt.DbgThreadCreatedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgThreadExitedEvent;
|
||||
import agent.dbgeng.manager.evt.DbgThreadSelectedEvent;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetActiveScope;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetFocusScope;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetObject;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetThread;
|
||||
import ghidra.async.*;
|
||||
import ghidra.async.AsyncClaimQueue;
|
||||
import ghidra.async.AsyncReference;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.async.TypeSpec;
|
||||
import ghidra.comm.util.BitmaskSet;
|
||||
import ghidra.dbg.target.TargetLauncher.CmdLineParser;
|
||||
import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.dbg.util.HandlerMap;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
import ghidra.lifecycle.Internal;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.datastruct.ListenerSet;
|
||||
@@ -141,8 +235,19 @@ public class DbgManagerImpl implements DbgManager {
|
||||
}
|
||||
}
|
||||
|
||||
public DbgThreadImpl getThreadComputeIfAbsent(String key, DbgProcessImpl proc, boolean fire) {
|
||||
String index = PathUtils.parseIndex(key);
|
||||
Integer tid = Integer.decode(index);
|
||||
DebugThreadId id = getSystemObjects().getThreadIdBySystemId(tid);
|
||||
if (id == null) {
|
||||
id = new DebugThreadId(tid);
|
||||
return getThreadComputeIfAbsent(id, proc, tid, fire);
|
||||
}
|
||||
return getThreadComputeIfAbsent(id, proc, tid, fire);
|
||||
}
|
||||
|
||||
public DbgThreadImpl getThreadComputeIfAbsent(DebugThreadId id, DbgProcessImpl process,
|
||||
int tid, boolean fire) {
|
||||
long tid, boolean fire) {
|
||||
synchronized (threads) {
|
||||
if (threads.containsKey(id)) {
|
||||
DbgThreadImpl existingThread = threads.get(id);
|
||||
@@ -220,7 +325,18 @@ public class DbgManagerImpl implements DbgManager {
|
||||
}
|
||||
}
|
||||
|
||||
public DbgProcessImpl getProcessComputeIfAbsent(DebugProcessId id, int pid, boolean fire) {
|
||||
public DbgProcessImpl getProcessComputeIfAbsent(String key, boolean fire) {
|
||||
String index = PathUtils.parseIndex(key);
|
||||
Integer pid = Integer.decode(index);
|
||||
DebugProcessId id = getSystemObjects().getProcessIdBySystemId(pid);
|
||||
if (id == null) {
|
||||
id = new DebugProcessId(pid);
|
||||
return getProcessComputeIfAbsent(id, pid, fire);
|
||||
}
|
||||
return getProcessComputeIfAbsent(id, pid, fire);
|
||||
}
|
||||
|
||||
public DbgProcessImpl getProcessComputeIfAbsent(DebugProcessId id, long pid, boolean fire) {
|
||||
synchronized (processes) {
|
||||
if (processes.containsKey(id)) {
|
||||
DbgProcessImpl existingProc = processes.get(id);
|
||||
@@ -642,7 +758,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
DebugThreadId etid = so.getEventThread();
|
||||
DebugProcessId epid = so.getEventProcess();
|
||||
DebugSessionId esid = so.getCurrentSystemId();
|
||||
|
||||
|
||||
DebugControl control = dbgeng.getControl();
|
||||
int execType = WinNTExtra.Machine.IMAGE_FILE_MACHINE_AMD64.val;
|
||||
try {
|
||||
@@ -657,15 +773,11 @@ public class DbgManagerImpl implements DbgManager {
|
||||
lastEventInformation = control.getLastEventInformation();
|
||||
lastEventInformation.setSession(esid);
|
||||
lastEventInformation.setExecutingProcessorType(execType);
|
||||
currentSession = eventSession = getSessionComputeIfAbsent(esid, true);
|
||||
currentProcess =
|
||||
eventProcess = getProcessComputeIfAbsent(epid, so.getCurrentProcessSystemId(), true);
|
||||
currentThread = eventThread = getThreadComputeIfAbsent(etid, (DbgProcessImpl) eventProcess,
|
||||
so.getCurrentThreadSystemId(), false);
|
||||
updateStateFromSystemObject(etid, epid, esid);
|
||||
if (eventThread != null) {
|
||||
((DbgThreadImpl) eventThread).setInfo(lastEventInformation);
|
||||
}
|
||||
return etid;
|
||||
return currentThread.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -710,7 +822,6 @@ public class DbgManagerImpl implements DbgManager {
|
||||
* @return retval handling/break status
|
||||
*/
|
||||
protected DebugStatus processException(DbgExceptionEvent evt, Void v) {
|
||||
DebugThreadId eventId = updateState();
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.threadSelected(eventThread, null, evt.getCause());
|
||||
|
||||
@@ -730,18 +841,15 @@ public class DbgManagerImpl implements DbgManager {
|
||||
* @return retval handling/break status
|
||||
*/
|
||||
protected DebugStatus processThreadCreated(DbgThreadCreatedEvent evt, Void v) {
|
||||
DebugClient dbgeng = engThread.getClient();
|
||||
DebugSystemObjects so = dbgeng.getSystemObjects();
|
||||
|
||||
DebugThreadId eventId = updateState();
|
||||
DbgProcessImpl process = getCurrentProcess();
|
||||
int tid = so.getCurrentThreadSystemId();
|
||||
DbgThreadImpl thread = getThreadComputeIfAbsent(eventId, process, tid, true);
|
||||
DbgThreadImpl thread = getThreadFromDebugProcessInfo(process, evt.getInfo());
|
||||
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.threadCreated(thread, DbgCause.Causes.UNCLAIMED);
|
||||
getEventListeners().fire.threadSelected(thread, null, evt.getCause());
|
||||
|
||||
String key = Integer.toHexString(eventId.id);
|
||||
String key = Long.toHexString(eventId.id);
|
||||
if (statusByNameMap.containsKey(key)) {
|
||||
return statusByNameMap.get(key);
|
||||
}
|
||||
@@ -766,7 +874,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.threadExited(eventId, process, evt.getCause());
|
||||
|
||||
String key = Integer.toHexString(eventId.id);
|
||||
String key = Long.toHexString(eventId.id);
|
||||
if (statusByNameMap.containsKey(key)) {
|
||||
return statusByNameMap.get(key);
|
||||
}
|
||||
@@ -787,7 +895,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
currentThread.setState(evt.getState(), evt.getCause(), evt.getReason());
|
||||
getEventListeners().fire.threadSelected(currentThread, evt.getFrame(), evt.getCause());
|
||||
|
||||
String key = Integer.toHexString(eventId.id);
|
||||
String key = Long.toHexString(eventId.id);
|
||||
if (statusByNameMap.containsKey(key)) {
|
||||
return statusByNameMap.get(key);
|
||||
}
|
||||
@@ -802,31 +910,20 @@ public class DbgManagerImpl implements DbgManager {
|
||||
* @return retval handling/break status
|
||||
*/
|
||||
protected DebugStatus processProcessCreated(DbgProcessCreatedEvent evt, Void v) {
|
||||
DebugThreadId eventId = updateState();
|
||||
DebugClient dbgeng = engThread.getClient();
|
||||
DebugSystemObjects so = dbgeng.getSystemObjects();
|
||||
|
||||
DebugProcessInfo info = evt.getInfo();
|
||||
long handle = info.handle;
|
||||
DebugProcessId id = so.getProcessIdByHandle(handle);
|
||||
//so.setCurrentProcessId(id);
|
||||
int pid = so.getCurrentProcessSystemId();
|
||||
DbgProcessImpl proc = getProcessComputeIfAbsent(id, pid, true);
|
||||
DbgProcessImpl proc = getProcessFromDebugProcessInfo(info);
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.processAdded(proc, evt.getCause());
|
||||
getEventListeners().fire.processSelected(proc, evt.getCause());
|
||||
|
||||
handle = info.initialThreadInfo.handle;
|
||||
DebugThreadId idt = so.getThreadIdByHandle(handle);
|
||||
int tid = so.getCurrentThreadSystemId();
|
||||
getThreadComputeIfAbsent(idt, proc, tid, true);
|
||||
getThreadFromDebugProcessInfo(proc, info.initialThreadInfo);
|
||||
//getEventListeners().fire.threadCreated(thread, evt.getCause());
|
||||
//getEventListeners().fire.threadSelected(thread, null, evt.getCause());
|
||||
|
||||
//proc.moduleLoaded(info.moduleInfo);
|
||||
//getEventListeners().fire.moduleLoaded(proc, info.moduleInfo, evt.getCause());
|
||||
|
||||
String key = Integer.toHexString(id.id);
|
||||
String key = Long.toHexString(proc.getId().id);
|
||||
if (statusByNameMap.containsKey(key)) {
|
||||
return statusByNameMap.get(key);
|
||||
}
|
||||
@@ -859,7 +956,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
process.remove(evt.getCause());
|
||||
getEventListeners().fire.processRemoved(process.getId(), evt.getCause());
|
||||
|
||||
String key = Integer.toHexString(process.getId().id);
|
||||
String key = Long.toHexString(process.getId().id);
|
||||
if (statusByNameMap.containsKey(key)) {
|
||||
return statusByNameMap.get(key);
|
||||
}
|
||||
@@ -879,7 +976,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
currentProcess = evt.getProcess();
|
||||
getEventListeners().fire.processSelected(currentProcess, evt.getCause());
|
||||
|
||||
String key = Integer.toHexString(eventId.id);
|
||||
String key = Long.toHexString(eventId.id);
|
||||
if (statusByNameMap.containsKey(key)) {
|
||||
return statusByNameMap.get(key);
|
||||
}
|
||||
@@ -1036,7 +1133,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
currentSession = evt.getSession();
|
||||
getEventListeners().fire.sessionSelected(currentSession, evt.getCause());
|
||||
|
||||
String key = Integer.toHexString(eventId.id);
|
||||
String key = Long.toHexString(eventId.id);
|
||||
if (statusByNameMap.containsKey(key)) {
|
||||
return statusByNameMap.get(key);
|
||||
}
|
||||
@@ -1063,7 +1160,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||
}
|
||||
DebugProcessId id = new DebugProcessId(info.intValue());
|
||||
|
||||
String key = Integer.toHexString(id.id);
|
||||
String key = Long.toHexString(id.id);
|
||||
if (statusByNameMap.containsKey(key)) {
|
||||
return statusByNameMap.get(key);
|
||||
}
|
||||
@@ -1553,12 +1650,18 @@ public class DbgManagerImpl implements DbgManager {
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> setActiveThread(DbgThread thread) {
|
||||
if (thread == null) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
currentThread = thread;
|
||||
currentProcess = thread.getProcess();
|
||||
return execute(new DbgSetActiveThreadCommand(this, thread, null));
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> setActiveProcess(DbgProcess process) {
|
||||
if (process == null) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
currentProcess = process;
|
||||
return execute(new DbgSetActiveProcessCommand(this, process));
|
||||
}
|
||||
@@ -1683,4 +1786,63 @@ public class DbgManagerImpl implements DbgManager {
|
||||
public long getProcessCount() {
|
||||
return processCount;
|
||||
}
|
||||
|
||||
public DebugThreadId getThreadIdBySystemId(Integer tid) {
|
||||
return getSystemObjects().getThreadIdBySystemId(tid);
|
||||
}
|
||||
|
||||
public DebugProcessId getProcessIdBySystemId(Integer pid) {
|
||||
return getSystemObjects().getProcessIdBySystemId(pid);
|
||||
}
|
||||
|
||||
private DbgProcessImpl getProcessFromDebugProcessInfo(DebugProcessInfo info) {
|
||||
DebugSystemObjects so = getSystemObjects();
|
||||
DebugProcessId id = so.getProcessIdByHandle(info.handle);
|
||||
if (kernelMode) {
|
||||
// try {
|
||||
// return (DbgProcessImpl) execute(new DbgSetCurrentState(this)).get().getProcess();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// return null;
|
||||
// }
|
||||
return null;
|
||||
} else {
|
||||
int pid = so.getCurrentProcessSystemId();
|
||||
return getProcessComputeIfAbsent(id, pid, true);
|
||||
}
|
||||
}
|
||||
|
||||
private DbgThreadImpl getThreadFromDebugProcessInfo(DbgProcessImpl proc, DebugThreadInfo info) {
|
||||
DebugSystemObjects so = getSystemObjects();
|
||||
DebugThreadId id = so.getThreadIdByHandle(info.handle);
|
||||
if (kernelMode) {
|
||||
// try {
|
||||
// return (DbgThreadImpl) execute(new DbgSetCurrentState(this)).get();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// return null;
|
||||
// }
|
||||
return null;
|
||||
} else {
|
||||
int pid = so.getCurrentThreadSystemId();
|
||||
return getThreadComputeIfAbsent(id, proc, pid, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStateFromSystemObject(DebugThreadId etid, DebugProcessId epid, DebugSessionId esid) {
|
||||
DebugSystemObjects so = getSystemObjects();
|
||||
currentSession = eventSession = getSessionComputeIfAbsent(esid, true);
|
||||
if (kernelMode) {
|
||||
execute(new DbgSetCurrentState(this)).thenAccept(thread -> {
|
||||
currentThread = eventThread = thread;
|
||||
currentProcess = eventProcess = thread.getProcess();
|
||||
});
|
||||
} else {
|
||||
currentProcess =
|
||||
eventProcess = getProcessComputeIfAbsent(epid, so.getCurrentProcessSystemId(), true);
|
||||
currentThread = eventThread = getThreadComputeIfAbsent(etid, (DbgProcessImpl) eventProcess,
|
||||
so.getCurrentThreadSystemId(), false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
@@ -51,6 +51,7 @@ public class DbgProcessImpl implements DbgProcess {
|
||||
private DebugProcessId id;
|
||||
private Long pid;
|
||||
private Long exitCode;
|
||||
private Long offset;
|
||||
|
||||
/**
|
||||
* Construct a new inferior
|
||||
@@ -373,4 +374,13 @@ public class DbgProcessImpl implements DbgProcess {
|
||||
public CompletableFuture<String> evaluate(String expression) {
|
||||
return manager.execute(new DbgEvaluateCommand(manager, expression));
|
||||
}
|
||||
|
||||
public Long getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(long offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-1
@@ -40,8 +40,9 @@ public class DbgThreadImpl implements DbgThread {
|
||||
DbgManagerImpl manager;
|
||||
private DbgProcessImpl process;
|
||||
private DebugThreadId id;
|
||||
private long tid;
|
||||
private Long tid;
|
||||
private DebugEventInformation info;
|
||||
private Long offset;
|
||||
|
||||
private final AsyncReference<DbgState, CauseReasonPair> state =
|
||||
new AsyncReference<>(DbgState.STOPPED);
|
||||
@@ -284,4 +285,13 @@ public class DbgThreadImpl implements DbgThread {
|
||||
int executingProcessorType = info.getExecutingProcessorType();
|
||||
return WinNTExtra.Machine.getByNumber(executingProcessorType);
|
||||
}
|
||||
|
||||
public Long getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(long offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-1
@@ -19,6 +19,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import agent.dbgeng.manager.DbgManager.ExecSuffix;
|
||||
import agent.dbgeng.manager.DbgProcess;
|
||||
import agent.dbgeng.manager.DbgThread;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import ghidra.dbg.target.TargetSteppable;
|
||||
@@ -68,8 +69,12 @@ public interface DbgModelTargetSteppable extends DbgModelTargetObject, TargetSte
|
||||
}
|
||||
if (this instanceof DbgModelTargetProcess) {
|
||||
DbgModelTargetProcess targetProcess = (DbgModelTargetProcess) this;
|
||||
DbgProcess process = targetProcess.getProcess();
|
||||
if (process == null) {
|
||||
process = getManager().getCurrentProcess();
|
||||
}
|
||||
return getModel()
|
||||
.gateFuture(targetProcess.getProcess().step(convertToDbg(kind)));
|
||||
.gateFuture(process.step(convertToDbg(kind)));
|
||||
}
|
||||
return getModel().gateFuture(thread.step(convertToDbg(kind)));
|
||||
}
|
||||
|
||||
+1
-8
@@ -58,15 +58,8 @@ public interface DbgModelTargetProcess extends //
|
||||
|
||||
public default DbgProcess getProcess(boolean fire) {
|
||||
DbgManagerImpl manager = getManager();
|
||||
DebugSystemObjects so = manager.getSystemObjects();
|
||||
try {
|
||||
String index = PathUtils.parseIndex(getName());
|
||||
Integer pid = Integer.decode(index);
|
||||
DebugProcessId id = so.getProcessIdBySystemId(pid);
|
||||
if (id == null) {
|
||||
id = so.getCurrentProcessId();
|
||||
}
|
||||
return manager.getProcessComputeIfAbsent(id, pid, fire);
|
||||
return manager.getProcessComputeIfAbsent(getName(), fire);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
return manager.getCurrentProcess();
|
||||
|
||||
+2
-9
@@ -42,17 +42,10 @@ public interface DbgModelTargetThread extends //
|
||||
|
||||
public default DbgThread getThread(boolean fire) {
|
||||
DbgManagerImpl manager = getManager();
|
||||
DebugSystemObjects so = manager.getSystemObjects();
|
||||
try {
|
||||
String index = PathUtils.parseIndex(getName());
|
||||
int tid = Integer.decode(index);
|
||||
DebugThreadId id = so.getThreadIdBySystemId(tid);
|
||||
if (id == null) {
|
||||
id = so.getCurrentThreadId();
|
||||
}
|
||||
DbgModelTargetProcess parentProcess = getParentProcess();
|
||||
DbgProcessImpl process = (DbgProcessImpl) parentProcess.getProcess();
|
||||
DbgThreadImpl thread = manager.getThreadComputeIfAbsent(id, process, tid, fire);
|
||||
DbgProcessImpl process = parentProcess == null ? null : (DbgProcessImpl) parentProcess.getProcess();
|
||||
DbgThreadImpl thread = manager.getThreadComputeIfAbsent(getName(), process, fire);
|
||||
return thread;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
|
||||
+2
-2
@@ -57,7 +57,7 @@ public class DbgModelTargetProcessContainerImpl extends DbgModelTargetObjectImpl
|
||||
session.setAccessible(true);
|
||||
DbgModelTargetProcess process = getTargetProcess(proc);
|
||||
changeElements(List.of(), List.of(process), Map.of(), "Added");
|
||||
process.processStarted(proc.getPid());
|
||||
process.processStarted(Long.valueOf(proc.getPid()));
|
||||
broadcast().event(getProxy(), null, TargetEventType.PROCESS_CREATED,
|
||||
"Process " + proc.getId() + " started " + process.getName() + "pid=" + proc.getPid(),
|
||||
List.of(process));
|
||||
@@ -66,7 +66,7 @@ public class DbgModelTargetProcessContainerImpl extends DbgModelTargetObjectImpl
|
||||
@Override
|
||||
public void processStarted(DbgProcess proc, DbgCause cause) {
|
||||
DbgModelTargetProcess process = getTargetProcess(proc);
|
||||
process.processStarted(proc.getPid());
|
||||
process.processStarted(Long.valueOf(proc.getPid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+30
-2
@@ -721,13 +721,41 @@ public class WrappedDbgModel
|
||||
@Override
|
||||
public int getCurrentThreadSystemId() { // used by impl
|
||||
return client.getSystemObjects().getCurrentThreadSystemId();
|
||||
//return getCurrentThreadId().id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentProcessSystemId() { // used by impl
|
||||
return client.getSystemObjects().getCurrentProcessSystemId();
|
||||
//return getCurrentProcessId().id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentThreadDataOffset() { // used by impl
|
||||
return client.getSystemObjects().getCurrentThreadDataOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentProcessDataOffset() { // used by impl
|
||||
return client.getSystemObjects().getCurrentProcessDataOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getImplicitThreadDataOffset() { // used by impl
|
||||
return client.getSystemObjects().getImplicitThreadDataOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getImplicitProcessDataOffset() { // used by impl
|
||||
return client.getSystemObjects().getImplicitProcessDataOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitThreadDataOffset(long offset) { // used by impl
|
||||
client.getSystemObjects().setImplicitThreadDataOffset(offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitProcessDataOffset(long offset) { // used by impl
|
||||
client.getSystemObjects().setImplicitProcessDataOffset(offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
@@ -28,6 +28,7 @@ import agent.dbgmodel.dbgmodel.main.*;
|
||||
import agent.dbgmodel.impl.dbgmodel.main.ModelIteratorInternal;
|
||||
import agent.dbgmodel.jna.dbgmodel.concept.IIterableConcept;
|
||||
import agent.dbgmodel.jna.dbgmodel.main.WrapIModelIterator;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class IterableConceptImpl implements IterableConceptInternal {
|
||||
@SuppressWarnings("unused")
|
||||
@@ -63,6 +64,10 @@ public class IterableConceptImpl implements IterableConceptInternal {
|
||||
if (hr.equals(COMUtilsExtra.E_FAIL)) {
|
||||
return null;
|
||||
}
|
||||
if (hr.equals(COMUtilsExtra.E_BOUNDS)) {
|
||||
Msg.error(this, "iterator out of bounds - check symbol path");
|
||||
return null;
|
||||
}
|
||||
if (hr.equals(COMUtilsExtra.E_COM_EXC)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ public class RawEnumeratorImpl extends UnknownExImpl implements RawEnumeratorInt
|
||||
ULONGByReference ulKind = new ULONGByReference();
|
||||
PointerByReference ppValue = new PointerByReference();
|
||||
HRESULT hr = jnaData.GetNext(bref, ulKind, ppValue);
|
||||
if (hr.equals(COMUtilsExtra.E_BOUNDS)) {
|
||||
if (hr.equals(COMUtilsExtra.E_BOUNDS) || hr.equals(COMUtilsExtra.E_CANNOT_READ)) {
|
||||
return null;
|
||||
}
|
||||
COMUtils.checkRC(hr);
|
||||
|
||||
+12
-9
@@ -15,14 +15,12 @@
|
||||
*/
|
||||
package agent.dbgmodel.model.impl;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import agent.dbgeng.manager.DbgEventsListener;
|
||||
import agent.dbgeng.manager.DbgStateListener;
|
||||
import agent.dbgeng.manager.*;
|
||||
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
||||
import agent.dbgeng.model.AbstractDbgModel;
|
||||
import agent.dbgeng.model.iface1.DbgModelSelectableObject;
|
||||
@@ -38,7 +36,6 @@ import ghidra.dbg.target.*;
|
||||
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind;
|
||||
import ghidra.dbg.target.TargetBreakpointSpecContainer.TargetBreakpointKindSet;
|
||||
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
|
||||
import ghidra.dbg.target.TargetMethod.AnnotatedTargetMethod;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
import ghidra.dbg.util.PathUtils.TargetObjectKeyComparator;
|
||||
@@ -253,6 +250,11 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
||||
if (isValid()) {
|
||||
TargetExecutionStateful stateful = (TargetExecutionStateful) proxy;
|
||||
TargetExecutionState state = stateful.getExecutionState();
|
||||
if (getManager().isKernelMode()) {
|
||||
if (state.equals(TargetExecutionState.INACTIVE)) {
|
||||
state = TargetExecutionState.ALIVE;
|
||||
}
|
||||
}
|
||||
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME, state);
|
||||
}
|
||||
}
|
||||
@@ -300,11 +302,12 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
|
||||
}
|
||||
if (proxy instanceof TargetThread) {
|
||||
DbgModelTargetThread targetThread = (DbgModelTargetThread) proxy;
|
||||
String executionType =
|
||||
targetThread.getThread().getExecutingProcessorType().description;
|
||||
attrs.put(TargetEnvironment.ARCH_ATTRIBUTE_NAME, executionType);
|
||||
attrs.putAll(
|
||||
AnnotatedTargetMethod.collectExports(MethodHandles.lookup(), model, proxy));
|
||||
DbgThread thread = targetThread.getThread();
|
||||
if (thread != null) {
|
||||
String executionType =
|
||||
thread.getExecutingProcessorType().description;
|
||||
attrs.put(TargetEnvironment.ARCH_ATTRIBUTE_NAME, executionType);
|
||||
}
|
||||
}
|
||||
if (proxy instanceof TargetRegister) {
|
||||
DbgModelTargetObject bank = (DbgModelTargetObject) getParent();
|
||||
|
||||
-4
@@ -176,7 +176,6 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
||||
getObject(proc).thenAccept(obj -> {
|
||||
DbgModelTargetProcess targetProcess = (DbgModelTargetProcess) obj;
|
||||
if (targetProcess == null) {
|
||||
System.err.println("processAdded - null");
|
||||
return;
|
||||
}
|
||||
DbgModelTargetProcessContainer container =
|
||||
@@ -196,7 +195,6 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
||||
getObject(thread).thenAccept(obj -> {
|
||||
DbgModelTargetThread targetThread = (DbgModelTargetThread) obj;
|
||||
if (targetThread == null) {
|
||||
System.err.println("threadCreated - null");
|
||||
return;
|
||||
}
|
||||
DbgModelTargetThreadContainer container =
|
||||
@@ -270,12 +268,10 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
|
||||
getModel().fetchModelObject(objPath).handle(seq::next);
|
||||
}, TypeSpec.cls(TargetObject.class)).then((pobj, seq) -> {
|
||||
DbgModelTargetObject pimpl = (DbgModelTargetObject) pobj;
|
||||
getModel().addModelObject(object, pimpl);
|
||||
seq.exit(pimpl);
|
||||
}).finish();
|
||||
}
|
||||
|
||||
//TODO: fix this
|
||||
private CompletableFuture<DbgModelTargetObject> getObjectRevisited(Object object,
|
||||
List<String> ext, Object info) {
|
||||
List<String> objPath = findObject(object);
|
||||
|
||||
+59
-5
@@ -18,16 +18,55 @@ package agent.dbgmodel.model.impl;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.ref.Cleaner;
|
||||
import java.lang.ref.Cleaner.Cleanable;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import agent.dbgeng.manager.*;
|
||||
import agent.dbgeng.manager.DbgCause;
|
||||
import agent.dbgeng.manager.DbgEventsListener;
|
||||
import agent.dbgeng.manager.DbgReason;
|
||||
import agent.dbgeng.manager.DbgState;
|
||||
import agent.dbgeng.manager.DbgStateListener;
|
||||
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
||||
import agent.dbgeng.model.iface1.*;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetAccessConditioned;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetBptHelper;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetExecutionStateful;
|
||||
import agent.dbgeng.model.iface1.DbgModelTargetMethod;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetAvailable;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetAvailableContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetBreakpointContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetBreakpointSpec;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetDebugContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetMemoryContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetModule;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetModuleContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetObject;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetProcess;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetProcessContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetRegister;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetRegisterBank;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetRegisterContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetSession;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetSessionAttributes;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetSessionContainer;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetStack;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetStackFrame;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetTTD;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetThread;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetThreadContainer;
|
||||
import agent.dbgmodel.dbgmodel.main.ModelObject;
|
||||
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.ModelObjectKind;
|
||||
import ghidra.dbg.target.*;
|
||||
import ghidra.dbg.target.TargetAccessConditioned;
|
||||
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointAction;
|
||||
import ghidra.dbg.target.TargetExecutionStateful;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
import ghidra.dbg.target.TargetRegisterBank;
|
||||
import ghidra.dbg.target.TargetRegisterContainer;
|
||||
import ghidra.dbg.target.TargetStack;
|
||||
import ghidra.dbg.target.TargetStackFrame;
|
||||
import ghidra.dbg.target.TargetThread;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
import ghidra.util.datastruct.ListenerSet;
|
||||
|
||||
@@ -303,9 +342,18 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
||||
DbgModelTargetThread targetThread = (DbgModelTargetThread) proxy;
|
||||
targetThread.getThread(false);
|
||||
}
|
||||
|
||||
boolean kernelMode = getModel().getManager().isKernelMode();
|
||||
if (kernelMode) {
|
||||
if (proxy instanceof DbgModelTargetProcess || //
|
||||
proxy instanceof DbgModelTargetThread) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (getModel().isSuppressDescent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (proxy instanceof DbgModelTargetSession || //
|
||||
proxy instanceof DbgModelTargetProcess || //
|
||||
proxy instanceof DbgModelTargetThread) {
|
||||
@@ -416,9 +464,15 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
|
||||
}
|
||||
DbgModelTargetRegisterContainer container =
|
||||
(DbgModelTargetRegisterContainer) getCachedAttribute("Registers");
|
||||
if (container == null) {
|
||||
return;
|
||||
}
|
||||
delegates.add((DelegateDbgModel2TargetObject) container.getDelegate());
|
||||
DbgModelTargetRegisterBank bank =
|
||||
(DbgModelTargetRegisterBank) container.getCachedAttribute("User");
|
||||
if (bank == null) {
|
||||
return;
|
||||
}
|
||||
delegates.add((DelegateDbgModel2TargetObject) bank.getDelegate());
|
||||
for (DelegateDbgModel2TargetObject delegate : delegates) {
|
||||
delegate.threadStateChangedSpecific(state, reason);
|
||||
|
||||
+4
-4
@@ -144,7 +144,7 @@
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
|
||||
<attribute name="_state" schema="EXECUTION_STATE" required="no" hidden="yes" />
|
||||
<attribute name="_prompt" schema="STRING" required="yes" hidden="yes" />
|
||||
<attribute name="Attributes" schema="SessionAttributes" fixed="yes" />
|
||||
<attribute name="Devices" schema="OBJECT" />
|
||||
@@ -239,7 +239,7 @@
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
|
||||
<attribute name="_state" schema="EXECUTION_STATE" required="no" hidden="yes" />
|
||||
<attribute name="_accessible" schema="BOOL" required="yes" hidden="yes" />
|
||||
<attribute name="_supported_attach_kinds" schema="SET_ATTACH_KIND" required="yes" hidden="yes" />
|
||||
<attribute name="_supported_step_kinds" schema="SET_STEP_KIND" required="yes" fixed="yes" hidden="yes" />
|
||||
@@ -296,7 +296,7 @@
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="Breakpoints" schema="BreakpointContainer" required="yes" fixed="yes" />
|
||||
<attribute name="Breakpoints" schema="BreakpointContainer" required="yes" fixed="no" />
|
||||
<attribute schema="ANY" />
|
||||
</schema>
|
||||
<schema name="ThreadContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
||||
@@ -357,7 +357,7 @@
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_accessible" schema="BOOL" required="yes" hidden="yes" />
|
||||
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
|
||||
<attribute name="_state" schema="EXECUTION_STATE" required="no" hidden="yes" />
|
||||
<attribute name="_supported_step_kinds" schema="SET_STEP_KIND" required="yes" fixed="yes" hidden="yes" />
|
||||
<attribute name="Registers" schema="RegisterContainer" required="yes" fixed="yes" />
|
||||
<attribute name="Stack" schema="Stack" required="yes" fixed="yes" />
|
||||
|
||||
Reference in New Issue
Block a user