diff --git a/Ghidra/Features/Base/src/test/java/ghidra/app/cmd/data/CreateDataCmdTest.java b/Ghidra/Features/Base/src/test/java/ghidra/app/cmd/data/CreateDataCmdTest.java index 57acf82b85..f3a7e61497 100644 --- a/Ghidra/Features/Base/src/test/java/ghidra/app/cmd/data/CreateDataCmdTest.java +++ b/Ghidra/Features/Base/src/test/java/ghidra/app/cmd/data/CreateDataCmdTest.java @@ -25,6 +25,7 @@ import ghidra.program.database.ProgramBuilder; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.data.*; +import ghidra.program.model.data.DataUtilities.ClearDataMode; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.RefType; import ghidra.program.model.symbol.SourceType; @@ -130,7 +131,7 @@ public class CreateDataCmdTest extends AbstractGenericTest { assertTrue(d.getDataType() instanceof ByteDataType); // Byte becomes Word and consumes next Default data byte - cmd = new CreateDataCmd(addr, new WordDataType()); + cmd = new CreateDataCmd(addr, new WordDataType(), false, ClearDataMode.CLEAR_SINGLE_DATA); cmd.applyTo(program); d = listing.getDataAt(addr); @@ -161,7 +162,7 @@ public class CreateDataCmdTest extends AbstractGenericTest { assertTrue(d.getDataType() instanceof WordDataType); // Word becomes Byte immediately followed by Default data - cmd = new CreateDataCmd(addr, new ByteDataType()); + cmd = new CreateDataCmd(addr, new ByteDataType(), false, ClearDataMode.CLEAR_SINGLE_DATA); cmd.applyTo(program); d = listing.getDataAt(addr); @@ -376,6 +377,36 @@ public class CreateDataCmdTest extends AbstractGenericTest { } + @Test + public void testCreatePointerOnMultipleUndefined1Data() { + + Address addr = addr(UNDEFINED_AREA); + CreateDataCmd cmd = new CreateDataCmd(addr, new Undefined1DataType()); + cmd.applyTo(program); + cmd = new CreateDataCmd(addr.next(), new Undefined1DataType()); + cmd.applyTo(program); + + // two Undefined1 data becomes Pointer + cmd = new CreateDataCmd(addr, false, true, new PointerDataType()); + cmd.applyTo(program); + + Data d = listing.getDataAt(addr); + assertNotNull(d); + assertTrue(d.isDefined()); + assertEquals(4, d.getLength()); + DataType dt = d.getDataType(); + assertTrue(dt instanceof Pointer); + assertEquals(addr.getPointerSize(), dt.getLength()); + Pointer pdt = (Pointer) dt; + assertNull(pdt.getDataType()); + + d = listing.getDataAfter(addr); + assertNotNull(d); + assertTrue(!d.isDefined()); + assertEquals(4, d.getMinAddress().getOffset() - UNDEFINED_AREA); + + } + @Test public void testCreatePointerOnPointer() { @@ -693,7 +724,7 @@ public class CreateDataCmdTest extends AbstractGenericTest { assertEquals(10, dt.getLength()); // Byte[] becomes Byte - CreateDataCmd cmd = new CreateDataCmd(addr, new ByteDataType()); + CreateDataCmd cmd = new CreateDataCmd(addr, new ByteDataType(), false, ClearDataMode.CLEAR_SINGLE_DATA); cmd.applyTo(program); d = listing.getDataAt(addr); @@ -761,7 +792,7 @@ public class CreateDataCmdTest extends AbstractGenericTest { assertEquals(10, dt.getLength()); // struct becomes Byte - CreateDataCmd cmd = new CreateDataCmd(addr, new ByteDataType()); + CreateDataCmd cmd = new CreateDataCmd(addr, new ByteDataType(), false, ClearDataMode.CLEAR_SINGLE_DATA); cmd.applyTo(program); d = listing.getDataAt(addr); diff --git a/Ghidra/Features/FileFormats/Module.manifest b/Ghidra/Features/FileFormats/Module.manifest index 02fdc56e59..f414a0bcc2 100644 --- a/Ghidra/Features/FileFormats/Module.manifest +++ b/Ghidra/Features/FileFormats/Module.manifest @@ -5,7 +5,7 @@ MODULE FILE LICENSE: lib/dex-reader-api-2.0.jar Apache License 2.0 MODULE FILE LICENSE: lib/dex-translator-2.0.jar Apache License 2.0 MODULE FILE LICENSE: lib/asm-debug-all-4.1.jar Apache License 2.0 MODULE FILE LICENSE: lib/baksmali-1.4.0.jar Apache License 2.0 -MODULE FILE LICENSE: lib/sevenzipjbinding-9.20-2.00beta.jar Apache License 2.0 -MODULE FILE LICENSE: lib/sevenzipjbinding-all-platforms-9.20-2.00beta.jar Apache License 2.0 +MODULE FILE LICENSE: lib/sevenzipjbinding-16.02-2.01.jar LGPL 2.1 +MODULE FILE LICENSE: lib/sevenzipjbinding-all-platforms-16.02-2.01.jar LGPL 2.1 MODULE FILE LICENSE: lib/AXMLPrinter2.jar Apache License 2.0 MODULE FILE LICENSE: lib/util-1.4.0.jar BSD diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataUtilities.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataUtilities.java index 07d800bd6a..a6c19049a2 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataUtilities.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataUtilities.java @@ -129,13 +129,14 @@ public final class DataUtilities { return data; } - if (clearMode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA && + if (!stackPointers && clearMode == ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA && !Undefined.isUndefined(existingDT)) { throw new CodeUnitInsertionException("Could not create Data at address " + addr); } // Check for external reference on pointer - if (existingDT instanceof Pointer) { + if ((stackPointers || newDataType instanceof Pointer) && + existingDT instanceof Pointer) { // TODO: This can probably be eliminated Reference[] refs = refMgr.getReferencesFrom(addr); for (Reference ref : refs) { @@ -174,19 +175,26 @@ public final class DataUtilities { throw new CodeUnitInsertionException( "Could not create DataType " + newDataType.getDisplayName()); } + + if (stackPointers && existingDT instanceof Pointer && newDataType instanceof Pointer) { + listing.clearCodeUnits(addr, addr, false); + } + + Data newData; try { - return listing.createData(addr, dti.getDataType(), dti.getLength()); + newData = listing.createData(addr, dti.getDataType(), dti.getLength()); } catch (CodeUnitInsertionException e) { // ok lets see if we need to clear some code units + if (clearMode == ClearDataMode.CLEAR_SINGLE_DATA) { + listing.clearCodeUnits(addr, addr, false); + } + else { + checkEnoughSpace(program, addr, existingDataLen, dti, clearMode); + } + newData = listing.createData(addr, dti.getDataType(), dti.getLength()); } - if (clearMode == ClearDataMode.CLEAR_SINGLE_DATA) { - listing.clearCodeUnits(addr, addr, false); - } - else { - checkEnoughSpace(program, addr, existingDataLen, dti, clearMode); - } - Data newData = listing.createData(addr, dti.getDataType(), dti.getLength()); + // if this was a pointer and had an external reference, put it back! if ((newDataType instanceof Pointer) && extRef != null) { ExternalLocation extLoc = ((ExternalReference) extRef).getExternalLocation(); @@ -203,6 +211,7 @@ public final class DataUtilities { private static void checkEnoughSpace(Program program, Address addr, int existingDataLen, DataTypeInstance dti, ClearDataMode mode) throws CodeUnitInsertionException { + // NOTE: method not invoked when clearMode == ClearDataMode.CLEAR_SINGLE_DATA Listing listing = program.getListing(); try { Address end = addr.addNoWrap(existingDataLen - 1);