diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/ProgramModuleIndexer.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/ProgramModuleIndexer.java index 5b0e3580d3..9ef125e0c8 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/ProgramModuleIndexer.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/ProgramModuleIndexer.java @@ -4,9 +4,9 @@ * 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. @@ -26,8 +26,7 @@ import ghidra.app.plugin.core.debug.utils.ProgramURLUtils; import ghidra.framework.model.*; import ghidra.framework.options.Options; import ghidra.framework.plugintool.PluginTool; -import ghidra.program.model.address.AddressRangeImpl; -import ghidra.program.model.address.AddressSpace; +import ghidra.program.model.address.*; import ghidra.program.model.listing.Program; import ghidra.trace.model.modules.TraceModule; @@ -73,8 +72,7 @@ public class ProgramModuleIndexer implements DomainFolderChangeListener { // TODO: Note language and prefer those from the same processor? // Will get difficult with new OBTR, since I'd need a platform // There's also the WoW64 issue.... - protected record IndexEntry(String name, String dfID, NameSource source) { - } + protected record IndexEntry(String name, String dfID, NameSource source) {} protected class ModuleChangeListener implements DomainObjectListener, DomainObjectClosedListener { @@ -383,7 +381,11 @@ public class ProgramModuleIndexer implements DomainFolderChangeListener { public DomainFile getBestMatch(TraceModule module, Program currentProgram, Collection entries) { - return getBestMatch(module.getBase().getAddressSpace(), module, currentProgram, entries); + Address base = module.getBase(); + AddressSpace space = base == null + ? module.getTrace().getBaseAddressFactory().getDefaultAddressSpace() + : base.getAddressSpace(); + return getBestMatch(space, module, currentProgram, entries); } public List getBestEntries(TraceModule module) { diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java index 923ab2b4ec..5e3547b92c 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java @@ -4,9 +4,9 @@ * 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. @@ -69,6 +69,43 @@ import ghidra.util.table.GhidraTable; @Category(NightlyCategory.class) public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerTest { + public static final String CTX_XML = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """; + DebuggerModulesProvider provider; protected TraceObjectModule modExe; @@ -94,42 +131,7 @@ public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerTes public void activateObjectsMode() throws Exception { // NOTE the use of index='1' allowing object-based managers to ID unique path - ctx = XmlSchemaContext.deserialize(""" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - """); + ctx = XmlSchemaContext.deserialize(CTX_XML); try (Transaction tx = tb.startTransaction()) { tb.trace.getObjectManager().createRootObject(ctx.getSchema(new SchemaName("Session"))); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingServiceTest.java index 15f288504c..e5e358a1a6 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingServiceTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingServiceTest.java @@ -25,18 +25,26 @@ import org.junit.Test; import db.Transaction; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerTest; +import ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesProviderTest; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerStaticMappingService.MappedAddressRange; +import ghidra.dbg.target.schema.SchemaContext; +import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; +import ghidra.dbg.target.schema.XmlSchemaContext; import ghidra.framework.model.DomainFile; import ghidra.program.model.address.*; import ghidra.program.model.listing.Program; import ghidra.program.util.ProgramLocation; import ghidra.trace.database.ToyDBTraceBuilder; import ghidra.trace.database.memory.DBTraceMemoryManager; +import ghidra.trace.database.target.DBTraceObject; +import ghidra.trace.database.target.DBTraceObjectManager; import ghidra.trace.model.*; import ghidra.trace.model.memory.TraceMemoryFlag; import ghidra.trace.model.memory.TraceMemoryRegion; import ghidra.trace.model.modules.*; +import ghidra.trace.model.target.TraceObject.ConflictResolution; +import ghidra.trace.model.target.TraceObjectKeyPath; import ghidra.util.Msg; // Not technically a GUI test, but must be carried out in the context of a plugin tool @@ -667,4 +675,21 @@ public class DebuggerStaticMappingServiceTest extends AbstractGhidraHeadedDebugg assertMapsTwoWay(Long.MAX_VALUE, Long.MAX_VALUE); assertMapsTwoWay(Long.MIN_VALUE, Long.MIN_VALUE); } + + @Test + public void testProposeModuleMappingNullBase() throws Throwable { + DBTraceObject objModBash; + try (Transaction tx = tb.startTransaction()) { + SchemaContext ctx = XmlSchemaContext.deserialize(DebuggerModulesProviderTest.CTX_XML); + DBTraceObjectManager objects = tb.trace.getObjectManager(); + objects.createRootObject(ctx.getSchema(new SchemaName("Session"))); + objModBash = + objects.createObject(TraceObjectKeyPath.parse("Processes[1].Modules[/bin/bash]")); + objModBash.insert(Lifespan.nowOn(0), ConflictResolution.DENY); + } + + TraceModule modBash = objModBash.queryInterface(TraceObjectModule.class); + assertEquals(Map.of(), + mappingService.proposeModuleMaps(List.of(modBash), List.of(program))); + } }