mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-01-09 14:08:03 -05:00
GP-6039 Address parsing docs. Allow ProgramUtilities.parseAddress to handle external address and removed support for parsing block-name style addresses
This commit is contained in:
@@ -35,7 +35,6 @@ import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.util.DiffUtility;
|
||||
import ghidra.program.util.ProgramMerge;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.datastruct.ObjectIntHashtable;
|
||||
@@ -2179,8 +2178,9 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
||||
// new FunctionDetailChangeListener(FUNC_RETURN_TYPE, entryPt, panel, monitor));
|
||||
// }
|
||||
if (((conflicts & FUNC_RETURN_ADDRESS_OFFSET) != 0)) {
|
||||
String latest = DiffUtility.toSignedHexString(latestStack.getReturnAddressOffset());
|
||||
String my = DiffUtility.toSignedHexString(myStack.getReturnAddressOffset());
|
||||
String latest =
|
||||
NumericUtilities.toSignedHexString(latestStack.getReturnAddressOffset());
|
||||
String my = NumericUtilities.toSignedHexString(myStack.getReturnAddressOffset());
|
||||
panel.addSingleChoice("Return Address Offset", new String[] { latest, my },
|
||||
new FunctionDetailChangeListener(FUNC_RETURN_ADDRESS_OFFSET, functions, panel,
|
||||
monitor));
|
||||
@@ -2202,8 +2202,8 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
||||
// }
|
||||
if ((conflicts & FUNC_STACK_PURGE_SIZE) != 0) {
|
||||
String latest =
|
||||
DiffUtility.toSignedHexString(functions[LATEST].getStackPurgeSize());
|
||||
String my = DiffUtility.toSignedHexString(functions[MY].getStackPurgeSize());
|
||||
NumericUtilities.toSignedHexString(functions[LATEST].getStackPurgeSize());
|
||||
String my = NumericUtilities.toSignedHexString(functions[MY].getStackPurgeSize());
|
||||
panel.addSingleChoice("Stack Purge Size", new String[] { latest, my },
|
||||
new FunctionDetailChangeListener(FUNC_STACK_PURGE_SIZE, functions, panel,
|
||||
monitor));
|
||||
|
||||
@@ -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.
|
||||
@@ -32,8 +32,8 @@ import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.scalar.Scalar;
|
||||
import ghidra.program.model.symbol.Equate;
|
||||
import ghidra.program.model.symbol.EquateTable;
|
||||
import ghidra.program.util.DiffUtility;
|
||||
import ghidra.program.util.ProgramDiffFilter;
|
||||
import ghidra.util.NumericUtilities;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
@@ -306,8 +306,8 @@ class EquateMerger extends AbstractListingMerger {
|
||||
*/
|
||||
@Override
|
||||
public void mergeConflicts(ListingMergePanel listingPanel, Address addr,
|
||||
int chosenConflictOption, TaskMonitor monitor) throws CancelledException,
|
||||
MemoryAccessException {
|
||||
int chosenConflictOption, TaskMonitor monitor)
|
||||
throws CancelledException, MemoryAccessException {
|
||||
if (!hasConflict(addr)) {
|
||||
return;
|
||||
}
|
||||
@@ -332,8 +332,8 @@ class EquateMerger extends AbstractListingMerger {
|
||||
monitor.checkCancelled();
|
||||
}
|
||||
else {
|
||||
merge(equateConflict.address, equateConflict.opIndex,
|
||||
equateConflict.scalar, chosenConflictOption);
|
||||
merge(equateConflict.address, equateConflict.opIndex, equateConflict.scalar,
|
||||
chosenConflictOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -459,7 +459,7 @@ class EquateMerger extends AbstractListingMerger {
|
||||
}
|
||||
if (equate != null) {
|
||||
info[1] = equate.getDisplayName();
|
||||
info[2] = DiffUtility.toSignedHexString(equate.getValue());
|
||||
info[2] = NumericUtilities.toSignedHexString(equate.getValue());
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -17,8 +17,8 @@ package ghidra.app.merge.util;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.util.DiffUtility;
|
||||
import ghidra.util.HTMLUtilities;
|
||||
import ghidra.util.NumericUtilities;
|
||||
|
||||
/**
|
||||
* <code>ConflictUtility</code> provides some constants and static methods
|
||||
@@ -280,7 +280,7 @@ public class ConflictUtility {
|
||||
* @return the message string containing HTML tags.
|
||||
*/
|
||||
public static String getOffsetString(int offset) {
|
||||
return colorString(OFFSET_COLOR, DiffUtility.toSignedHexString(offset));
|
||||
return colorString(OFFSET_COLOR, NumericUtilities.toSignedHexString(offset));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.
|
||||
@@ -23,6 +23,7 @@ import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.NumericUtilities;
|
||||
import ghidra.util.exception.*;
|
||||
|
||||
/**
|
||||
@@ -529,29 +530,6 @@ public class DiffUtility extends SimpleDiffUtility {
|
||||
return cu.getMaxAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signed hex string representing the int value.
|
||||
* Positive values are represented beginning with 0x. (i.e. value of 12 would be 0xc)
|
||||
* Negative values are represented beginning with -0x. (i.e. value of -12 would be -0xc)
|
||||
* @param value the value
|
||||
* @return the signed hex string
|
||||
*/
|
||||
public static String toSignedHexString(int value) {
|
||||
return (value >= 0 ? "0x" + Integer.toHexString(value)
|
||||
: "-0x" + Integer.toHexString(-value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signed hex string representing the long value.
|
||||
* Positive values are represented beginning with 0x. (i.e. value of 12 would be 0xc)
|
||||
* Negative values are represented beginning with -0x. (i.e. value of -12 would be -0xc)
|
||||
* @param value the value
|
||||
* @return the signed hex string
|
||||
*/
|
||||
public static String toSignedHexString(long value) {
|
||||
return (value >= 0 ? "0x" + Long.toHexString(value) : "-0x" + Long.toHexString(-value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of the specified reference's "to" address.
|
||||
* @param program the program containing the reference
|
||||
@@ -571,13 +549,14 @@ public class DiffUtility extends SimpleDiffUtility {
|
||||
|
||||
if (ref.isStackReference()) {
|
||||
int offset = ((StackReference) ref).getStackOffset();
|
||||
return "Stack[" + toSignedHexString(offset) + "]";
|
||||
return GenericAddress.STACK_ADDRESS_PREFIX +
|
||||
NumericUtilities.toSignedHexString(offset) + GenericAddress.STACK_ADDRESS_SUFFIX;
|
||||
}
|
||||
else if (ref.isOffsetReference()) {
|
||||
OffsetReference oref = (OffsetReference) ref;
|
||||
return toAddr.toString() + " " + "base:" +
|
||||
DiffUtility.getUserToAddressString(program, oref.getBaseAddress()) + " " +
|
||||
"offset:" + DiffUtility.toSignedHexString(oref.getOffset());
|
||||
"offset:" + NumericUtilities.toSignedHexString(oref.getOffset());
|
||||
|
||||
}
|
||||
else if (ref.isShiftedReference()) {
|
||||
@@ -619,7 +598,7 @@ public class DiffUtility extends SimpleDiffUtility {
|
||||
}
|
||||
}
|
||||
else if (address.isStackAddress()) {
|
||||
return "stack:" + toSignedHexString(address.getOffset());
|
||||
return "stack:" + NumericUtilities.toSignedHexString(address.getOffset());
|
||||
}
|
||||
return address.toString();
|
||||
}
|
||||
|
||||
@@ -899,11 +899,12 @@ public class ProgramDiffDetails {
|
||||
fieldName = dtc.getDefaultFieldName();
|
||||
}
|
||||
// TODO: how should we display bitfields?
|
||||
buf.append(indent + "Offset=" + DiffUtility.toSignedHexString(offset) + " " + "Ordinal=" +
|
||||
ordinal + " " + fieldName + " " + actualDt.getMnemonic(actualDt.getDefaultSettings()) +
|
||||
" " + getCategoryName(actualDt) + " " + "DataTypeSize=" +
|
||||
(actualDt.isZeroLength() ? 0 : actualDt.getLength()) + " " + "ComponentSize=" +
|
||||
dtc.getLength() + " " + ((comment != null) ? comment : "") + " " + newLine);
|
||||
buf.append(indent + "Offset=" + NumericUtilities.toSignedHexString(offset) + " " +
|
||||
"Ordinal=" + ordinal + " " + fieldName + " " +
|
||||
actualDt.getMnemonic(actualDt.getDefaultSettings()) + " " + getCategoryName(actualDt) +
|
||||
" " + "DataTypeSize=" + (actualDt.isZeroLength() ? 0 : actualDt.getLength()) + " " +
|
||||
"ComponentSize=" + dtc.getLength() + " " + ((comment != null) ? comment : "") + " " +
|
||||
newLine);
|
||||
return actualDt;
|
||||
}
|
||||
|
||||
@@ -1862,7 +1863,7 @@ public class ProgramDiffDetails {
|
||||
|
||||
private void addReturnOffset(StyledDocument doc, StackFrame frame) {
|
||||
addFrameInfo(doc, "Return Address Offset: ",
|
||||
DiffUtility.toSignedHexString(frame.getReturnAddressOffset()));
|
||||
NumericUtilities.toSignedHexString(frame.getReturnAddressOffset()));
|
||||
}
|
||||
|
||||
private void addReturnOffset(StyledDocument doc1, StyledDocument doc2, StackFrame frame1,
|
||||
@@ -1870,14 +1871,16 @@ public class ProgramDiffDetails {
|
||||
int offset1 = frame1.getReturnAddressOffset();
|
||||
int offset2 = frame2.getReturnAddressOffset();
|
||||
if (offset1 != offset2) {
|
||||
addFrameInfo(doc1, "Return Address Offset: ", DiffUtility.toSignedHexString(offset1));
|
||||
addFrameInfo(doc2, "Return Address Offset: ", DiffUtility.toSignedHexString(offset2));
|
||||
addFrameInfo(doc1, "Return Address Offset: ",
|
||||
NumericUtilities.toSignedHexString(offset1));
|
||||
addFrameInfo(doc2, "Return Address Offset: ",
|
||||
NumericUtilities.toSignedHexString(offset2));
|
||||
}
|
||||
}
|
||||
|
||||
private void addParameterOffset(StyledDocument doc, StackFrame frame) {
|
||||
addFrameInfo(doc, "Parameter Offset: ",
|
||||
DiffUtility.toSignedHexString(frame.getParameterOffset()));
|
||||
NumericUtilities.toSignedHexString(frame.getParameterOffset()));
|
||||
}
|
||||
|
||||
private void addParameterOffset(StyledDocument doc1, StyledDocument doc2, StackFrame frame1,
|
||||
@@ -1885,8 +1888,8 @@ public class ProgramDiffDetails {
|
||||
int offset1 = frame1.getParameterOffset();
|
||||
int offset2 = frame2.getParameterOffset();
|
||||
if (offset1 != offset2) {
|
||||
addFrameInfo(doc1, "Parameter Offset: ", DiffUtility.toSignedHexString(offset1));
|
||||
addFrameInfo(doc2, "Parameter Offset: ", DiffUtility.toSignedHexString(offset2));
|
||||
addFrameInfo(doc1, "Parameter Offset: ", NumericUtilities.toSignedHexString(offset1));
|
||||
addFrameInfo(doc2, "Parameter Offset: ", NumericUtilities.toSignedHexString(offset2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1925,7 +1928,7 @@ public class ProgramDiffDetails {
|
||||
vl.dtLen = Math.max(vl.dtLen, var.getDataType().getPathName().length());
|
||||
vl.offsetLen = Math.max(vl.offsetLen, var.getVariableStorage().toString().length());
|
||||
vl.firstUseLen = Math.max(vl.firstUseLen,
|
||||
DiffUtility.toSignedHexString(var.getFirstUseOffset()).length());
|
||||
NumericUtilities.toSignedHexString(var.getFirstUseOffset()).length());
|
||||
vl.nameLen = Math.max(vl.nameLen, var.getName().length());
|
||||
vl.sizeLen = Math.max(vl.sizeLen, Integer.toString(var.getLength()).length());
|
||||
vl.sourceLen = Math.max(vl.sourceLen, var.getSource().toString().length());
|
||||
@@ -2125,7 +2128,7 @@ public class ProgramDiffDetails {
|
||||
else {
|
||||
String dt = var.getDataType().getPathName();
|
||||
String offset = var.getVariableStorage().toString();
|
||||
String firstUse = DiffUtility.toSignedHexString(var.getFirstUseOffset());
|
||||
String firstUse = NumericUtilities.toSignedHexString(var.getFirstUseOffset());
|
||||
String name = var.getName();
|
||||
String size = "" + var.getLength();
|
||||
String source = var.getSource().toString();
|
||||
|
||||
@@ -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.
|
||||
@@ -15,14 +15,14 @@
|
||||
*/
|
||||
package ghidra.util.table.field;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.listing.CodeUnitFormatOptions.ShowBlockName;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.NumericUtilities;
|
||||
import ghidra.util.SystemUtilities;
|
||||
|
||||
/**
|
||||
@@ -195,17 +195,13 @@ public class AddressBasedLocation implements Comparable<AddressBasedLocation> {
|
||||
}
|
||||
|
||||
private static String getStackAddressRepresentation(Address address) {
|
||||
int offset = (int) address.getOffset();
|
||||
boolean neg = (offset < 0);
|
||||
return "Stack[" + (neg ? "-" : "+") + "0x" + Integer.toHexString(neg ? -offset : offset) +
|
||||
"]";
|
||||
return GenericAddress.STACK_ADDRESS_PREFIX +
|
||||
NumericUtilities.toSignedHexString(address.getOffset()) +
|
||||
GenericAddress.STACK_ADDRESS_SUFFIX;
|
||||
}
|
||||
|
||||
private static String getConstantAddressRepresentation(Address address) {
|
||||
int offset = (int) address.getOffset();
|
||||
boolean neg = (offset < 0);
|
||||
return "Constant[" + (neg ? "-" : "+") + "0x" +
|
||||
Integer.toHexString(neg ? -offset : offset) + "]";
|
||||
return "Constant[" + NumericUtilities.toSignedHexString(address.getOffset()) + "]";
|
||||
}
|
||||
|
||||
private static String getVariableAddressRepresentation() {
|
||||
|
||||
@@ -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.
|
||||
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
package ghidra.program.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import ghidra.program.database.ProgramBuilder;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.test.TestEnv;
|
||||
@@ -34,37 +34,99 @@ public class ProgramUtilitiesTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
super();
|
||||
}
|
||||
|
||||
@Before
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
env = new TestEnv();
|
||||
builder = new ProgramBuilder("notepad", ProgramBuilder._TOY);
|
||||
builder.createMemory("test1", Long.toHexString(0x1001000), 0x2000);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
@After
|
||||
public void tearDown() {
|
||||
env.dispose();
|
||||
builder.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAddress() throws Exception {
|
||||
@Test
|
||||
public void testParseAddress() throws Exception {
|
||||
Program p = builder.getProgram();
|
||||
|
||||
p.withTransaction("Add Overlay Block", () -> {
|
||||
Address addr = ProgramUtilities.parseAddress(p, "100");
|
||||
p.getMemory().createUninitializedBlock("OVLY", addr, 0x100, true);
|
||||
});
|
||||
|
||||
AddressFactory addressFactory = p.getAddressFactory();
|
||||
|
||||
// Verify that special spaces were defined for TOY language
|
||||
assertNotNull(addressFactory.getAddressSpace("const"));
|
||||
assertNotNull(addressFactory.getAddressSpace("unique"));
|
||||
assertNotNull(addressFactory.getAddressSpace("register"));
|
||||
|
||||
//
|
||||
// Stack addresses (signed decimal and hex offsets)
|
||||
//
|
||||
|
||||
Address addr = ProgramUtilities.parseAddress(p, "Stack[54]");
|
||||
assertEquals(p.getAddressFactory().getStackSpace(), addr.getAddressSpace());
|
||||
assertEquals(addressFactory.getStackSpace(), addr.getAddressSpace());
|
||||
assertEquals(54, addr.getOffset());
|
||||
|
||||
addr = ProgramUtilities.parseAddress(p, "Stack[0x54]");
|
||||
assertEquals(p.getAddressFactory().getStackSpace(), addr.getAddressSpace());
|
||||
assertEquals(addressFactory.getStackSpace(), addr.getAddressSpace());
|
||||
assertEquals(0x54, addr.getOffset());
|
||||
|
||||
addr = ProgramUtilities.parseAddress(p, "Stack[-54]");
|
||||
assertEquals(p.getAddressFactory().getStackSpace(), addr.getAddressSpace());
|
||||
assertEquals(addressFactory.getStackSpace(), addr.getAddressSpace());
|
||||
assertEquals(-54, addr.getOffset());
|
||||
|
||||
addr = ProgramUtilities.parseAddress(p, "Stack[-0x54]");
|
||||
assertEquals(p.getAddressFactory().getStackSpace(), addr.getAddressSpace());
|
||||
assertEquals(addressFactory.getStackSpace(), addr.getAddressSpace());
|
||||
assertEquals(-0x54, addr.getOffset());
|
||||
|
||||
//
|
||||
// Memory address
|
||||
//
|
||||
|
||||
addr = ProgramUtilities.parseAddress(p, "ram:00001234");
|
||||
assertEquals(addressFactory.getAddressSpace("ram"), addr.getAddressSpace());
|
||||
assertEquals(0x1234, addr.getOffset());
|
||||
|
||||
//
|
||||
// Overlay address
|
||||
//
|
||||
|
||||
addr = ProgramUtilities.parseAddress(p, "OVLY::0x010");
|
||||
assertEquals(addressFactory.getAddressSpace("OVLY"), addr.getAddressSpace());
|
||||
assertEquals(0x10, addr.getOffset());
|
||||
assertTrue(addr.getAddressSpace().isOverlaySpace());
|
||||
|
||||
addr = ProgramUtilities.parseAddress(p, "OVLY::0x2000"); // outside overlay block range
|
||||
assertEquals(addressFactory.getAddressSpace("OVLY"), addr.getAddressSpace());
|
||||
assertEquals(0x2000, addr.getOffset());
|
||||
assertTrue(addr.getAddressSpace().isOverlaySpace());
|
||||
|
||||
//
|
||||
// External address
|
||||
//
|
||||
|
||||
addr = ProgramUtilities.parseAddress(p, "EXTERNAL:00001234");
|
||||
assertEquals(AddressSpace.EXTERNAL_SPACE, addr.getAddressSpace());
|
||||
assertEquals(0x1234, addr.getOffset());
|
||||
|
||||
//
|
||||
// Block-name style address (Not supported)
|
||||
//
|
||||
|
||||
assertNull(ProgramUtilities.parseAddress(p, "test1:00001001000"));
|
||||
assertNull(ProgramUtilities.parseAddress(p, "test1:00001234"));
|
||||
|
||||
//
|
||||
// Special spaces (Not supported)
|
||||
//
|
||||
|
||||
assertNull(ProgramUtilities.parseAddress(p, "register:00000000"));
|
||||
assertNull(ProgramUtilities.parseAddress(p, "const:00000000"));
|
||||
assertNull(ProgramUtilities.parseAddress(p, "unique:00000000"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -25,6 +25,7 @@ import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.graph.ProgramGraphDisplayOptions;
|
||||
import ghidra.graph.ProgramGraphType;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.GenericAddress;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.pcode.*;
|
||||
@@ -423,7 +424,9 @@ public class PCodeCfgGraphTask extends Task {
|
||||
return var.getName();
|
||||
}
|
||||
}
|
||||
return "Stack[" + NumericUtilities.toSignedHexString(addr.getOffset()) + "]";
|
||||
return GenericAddress.STACK_ADDRESS_PREFIX +
|
||||
NumericUtilities.toSignedHexString(addr.getOffset()) +
|
||||
GenericAddress.STACK_ADDRESS_SUFFIX;
|
||||
}
|
||||
else if (addr.isMemoryAddress()) {
|
||||
return addr.toString(true);
|
||||
|
||||
@@ -205,14 +205,15 @@ public class ProgramAddressFactory extends DefaultAddressFactory {
|
||||
@Override
|
||||
public Address getAddress(String addrString) {
|
||||
Address addr = null;
|
||||
if (addrString.startsWith("Stack[") && addrString.endsWith("]")) {
|
||||
if (addrString.startsWith(GenericAddress.STACK_ADDRESS_PREFIX) &&
|
||||
addrString.endsWith(GenericAddress.STACK_ADDRESS_SUFFIX)) {
|
||||
try {
|
||||
long stackOffset =
|
||||
NumericUtilities.parseHexLong(addrString.substring(6, addrString.length() - 1));
|
||||
addr = stackSpace.getAddress(stackOffset);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// bad string
|
||||
catch (AddressOutOfBoundsException | NumberFormatException e) {
|
||||
// bad stack address string
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -820,9 +820,15 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Support for trailing 'h' should be dropped since it is not consistently
|
||||
// supported by other parse methods (block-based above and within AddressFactory).
|
||||
// AbstractAddressSpace.getAddress allows for '0x' or '0X' offset prefix but not
|
||||
// a trailing 'h'.
|
||||
if (addrStr.endsWith("h")) {
|
||||
addrStr = addrStr.substring(0, addrStr.length() - 1);
|
||||
}
|
||||
|
||||
return addressFactory.getAllAddresses(addrStr, caseSensitive);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -19,25 +19,41 @@ public interface AddressFactory {
|
||||
|
||||
/**
|
||||
* Create an address from String. Attempts to use the "default" address space
|
||||
* first. Otherwise loops through each addressSpace, returning the first valid
|
||||
* address that any addressSpace creates from the string.
|
||||
* Returns an Address if the string is valid, otherwise null.
|
||||
* first. Otherwise factory will loop through each defined address space, returning the first
|
||||
* valid address that any address space creates from the string. For this reason, only the
|
||||
* default memory address space should be specified with an offset only. All other
|
||||
* address space addresses should be specified with the space name prefix and hex offset
|
||||
* (e.g., MYSPACE:abcd). In addition to all define memory and overlay address spaces,
|
||||
* special purpose address spaces known to this address factory will be considered
|
||||
* (e.g., CONST, UNIQUE, etc.).
|
||||
* @param addrString the address string to parse.
|
||||
* @return an Address if the string is valid, otherwise null.
|
||||
*/
|
||||
public Address getAddress(String addrString);
|
||||
|
||||
/**
|
||||
* Generates all reasonable addresses that can be interpreted from
|
||||
* the given string. Each Address Space is given a change to parse
|
||||
* the string and all the valid results are return in the array.
|
||||
* Generates all reasonable memory addresses that can be interpreted from the given string.
|
||||
* Each defined memory Address Space is given a change to parse the string and all the valid
|
||||
* results are returned in the array.
|
||||
* <p>
|
||||
* NOTE: Only when unable to parse any valid loaded memory addresses (see
|
||||
* {@link AddressSpace#isLoadedMemorySpace()}) will one uniquely specified non-loaded memory
|
||||
* address be considered and returned.
|
||||
*
|
||||
* @param addrString the address string to parse.
|
||||
* @return Address[] The list of addresses generated from the string.
|
||||
*/
|
||||
public Address[] getAllAddresses(String addrString);
|
||||
|
||||
/**
|
||||
* Generates all reasonable addresses that can be interpreted from
|
||||
* the given string. Each Address Space is given a change to parse
|
||||
* the string and all the valid results are return in the array.
|
||||
* Generates all reasonable memory addresses that can be interpreted from the given string.
|
||||
* Each defined memory Address Space is given a change to parse the string and all the valid
|
||||
* results are returned in the array.
|
||||
* <p>
|
||||
* NOTE: Only when unable to parse any valid loaded memory addresses (see
|
||||
* {@link AddressSpace#isLoadedMemorySpace()}) will one uniquely specified non-loaded memory
|
||||
* address be considered and returned.
|
||||
*
|
||||
* @param addrString the address string to parse.
|
||||
* @param caseSensitive determines if addressSpace names must be case sensitive to match.
|
||||
* @return Address[] The list of addresses generated from the string.
|
||||
@@ -45,12 +61,12 @@ public interface AddressFactory {
|
||||
public Address[] getAllAddresses(String addrString, boolean caseSensitive);
|
||||
|
||||
/**
|
||||
* Returns the default AddressSpace
|
||||
* {@return the default AddressSpace}
|
||||
*/
|
||||
public AddressSpace getDefaultAddressSpace();
|
||||
|
||||
/**
|
||||
* Get the array of all "physical" AddressSpaces.
|
||||
* {@return the array of all "physical" AddressSpaces.}
|
||||
*/
|
||||
public AddressSpace[] getAddressSpaces();
|
||||
|
||||
@@ -61,18 +77,20 @@ public interface AddressFactory {
|
||||
public AddressSpace[] getAllAddressSpaces();
|
||||
|
||||
/**
|
||||
* Returns the space with the given name or null if no space
|
||||
* exists with that name.
|
||||
* {@return the space with the given name or null if no space
|
||||
* exists with that name.}
|
||||
* @param name address space name
|
||||
*/
|
||||
public AddressSpace getAddressSpace(String name);
|
||||
|
||||
/**
|
||||
* Returns the space with the given spaceID or null if none exists
|
||||
* {@return the space with the given spaceID or null if none exists}
|
||||
* @param spaceID address space unique ID
|
||||
*/
|
||||
public AddressSpace getAddressSpace(int spaceID);
|
||||
|
||||
/**
|
||||
* Returns the number of physical AddressSpaces.
|
||||
* {@return the number of physical AddressSpaces.}
|
||||
*/
|
||||
public int getNumAddressSpaces();
|
||||
|
||||
@@ -84,14 +102,11 @@ public interface AddressFactory {
|
||||
*/
|
||||
public boolean isValidAddress(Address addr);
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#equals(Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o);
|
||||
|
||||
/**
|
||||
* Returns the index (old encoding) for the given address.
|
||||
* {@return the index (old encoding) for the given address.}
|
||||
* @param addr the address to encode.
|
||||
*/
|
||||
public long getIndex(Address addr);
|
||||
@@ -119,22 +134,22 @@ public interface AddressFactory {
|
||||
public Address getAddress(int spaceID, long offset);
|
||||
|
||||
/**
|
||||
* Returns the "constant" address space.
|
||||
* {@return the "constant" address space.}
|
||||
*/
|
||||
public AddressSpace getConstantSpace();
|
||||
|
||||
/**
|
||||
* Returns the "unique" address space.
|
||||
* {@return the "unique" address space.}
|
||||
*/
|
||||
public AddressSpace getUniqueSpace();
|
||||
|
||||
/**
|
||||
* Returns the "stack" address space.
|
||||
* {@return the "stack" address space.}
|
||||
*/
|
||||
public AddressSpace getStackSpace();
|
||||
|
||||
/**
|
||||
* Returns the "register" address space.
|
||||
* {@return the "register" address space.}
|
||||
*/
|
||||
public AddressSpace getRegisterSpace();
|
||||
|
||||
@@ -157,18 +172,18 @@ public interface AddressFactory {
|
||||
public AddressSet getAddressSet(Address min, Address max);
|
||||
|
||||
/**
|
||||
* Returns an addressSet containing all possible "real" addresses for this address factory.
|
||||
* {@return an addressSet containing all possible "real" addresses for this address factory.}
|
||||
*/
|
||||
public AddressSet getAddressSet();
|
||||
|
||||
/**
|
||||
* Returns the address using the old encoding format.
|
||||
* {@return the address using the old encoding format.}
|
||||
* @param value to decode into an address.
|
||||
*/
|
||||
public Address oldGetAddressFromLong(long value);
|
||||
|
||||
/**
|
||||
* Returns true if there is more than one memory address space
|
||||
* {@return true if there is more than one memory address space}
|
||||
*/
|
||||
public boolean hasMultipleMemorySpaces();
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -147,9 +147,6 @@ public class DefaultAddressFactory implements AddressFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.address.AddressFactory#getAddress(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Address getAddress(String addrString) {
|
||||
try {
|
||||
@@ -218,7 +215,6 @@ public class DefaultAddressFactory implements AddressFactory {
|
||||
}
|
||||
|
||||
Address[] addrs = new Address[loadedMemoryList.size()];
|
||||
|
||||
return loadedMemoryList.toArray(addrs);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ public class GenericAddress implements Address {
|
||||
|
||||
protected static final String zeros = "0000000000000000";
|
||||
|
||||
public final static String STACK_ADDRESS_PREFIX = "Stack[";
|
||||
public final static String STACK_ADDRESS_SUFFIX = "]"; // parse code assumes length == 1
|
||||
|
||||
protected AddressSpace addrSpace;
|
||||
protected long offset;
|
||||
|
||||
@@ -245,7 +248,7 @@ public class GenericAddress implements Address {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (addrSpace.isStackSpace()) {
|
||||
stackFormat = true;
|
||||
buf.append("Stack[");
|
||||
buf.append(STACK_ADDRESS_PREFIX);
|
||||
minNumDigits = 1;
|
||||
}
|
||||
else if (showAddressSpace) {
|
||||
@@ -287,7 +290,7 @@ public class GenericAddress implements Address {
|
||||
buf.append(mod);
|
||||
}
|
||||
if (stackFormat) {
|
||||
buf.append("]");
|
||||
buf.append(STACK_ADDRESS_SUFFIX);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -93,25 +93,16 @@ public class GenericAddressSpace extends AbstractAddressSpace {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.address.AddressSpace#getAddress(long)
|
||||
*/
|
||||
@Override
|
||||
public Address getAddress(long offset) throws AddressOutOfBoundsException {
|
||||
return new GenericAddress(this, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.address.AddressSpace#getAddressInThisSpaceOnly(long)
|
||||
*/
|
||||
@Override
|
||||
public Address getAddressInThisSpaceOnly(long offset) {
|
||||
return new GenericAddress(this, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.address.AbstractAddressSpace#getUncheckedAddress(long)
|
||||
*/
|
||||
@Override
|
||||
protected Address getUncheckedAddress(long offset) {
|
||||
return new GenericAddress(offset, this);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -349,19 +349,45 @@ public interface Program extends DataTypeManagerDomainObject, ProgramArchitectur
|
||||
public AddressFactory getAddressFactory();
|
||||
|
||||
/**
|
||||
* Return an array of Addresses that could represent the given
|
||||
* string.
|
||||
* @param addrStr the string to parse.
|
||||
* Return an array of memory Addresses that could correspond to the given
|
||||
* string. Non-memory spaces are not considered. Since this method allows
|
||||
* memory-block style addresses first it can be slower to parse than using
|
||||
* {@link AddressFactory#getAddress(String)} or {@link AddressFactory#getAllAddresses(String)}
|
||||
* if block-name based address need not be handled.
|
||||
* <p>
|
||||
* Supported addresses include (order also indicates precedence):
|
||||
* <ul>
|
||||
* <li>Memory block-name based address (e.g., 'MyBlk:abcd', 'MyBlk::abcd' ; only one address
|
||||
* will be returned)</li>
|
||||
* <li>Default memory space (hex-offset only or with space-name, e.g., 'abcd', '0xabcd')</li>
|
||||
* <li>Memory space-name based address (with hex-offset, e.g., 'ram:abc')</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* NOTE: Names are case-sensitive.
|
||||
*
|
||||
* @param addrStr the string to parse (memory block style addresses are also supported).
|
||||
* @return zero length array if addrStr is properly formatted but
|
||||
* no matching addresses were found or if the address is improperly formatted.
|
||||
*/
|
||||
public Address[] parseAddress(String addrStr);
|
||||
|
||||
/**
|
||||
* Return an array of Addresses that could represent the given
|
||||
* string.
|
||||
* @param addrStr the string to parse.
|
||||
* @param caseSensitive whether or not to process any addressSpace names as case sensitive.
|
||||
* Return an array of memory Addresses that could correspond to the given
|
||||
* string. Non-memory spaces are not considered. Since this method allows
|
||||
* memory-block style addresses first it can be slower to parse than using
|
||||
* {@link AddressFactory#getAddress(String)} or {@link AddressFactory#getAllAddresses(String)}
|
||||
* if block-name based address need not be handled.
|
||||
* <p>
|
||||
* Supported addresses include (order also indicates precedence):
|
||||
* <ul>
|
||||
* <li>Memory block-name based address (e.g., 'MyBlk:abcd', 'MyBlk::abcd' ; only one address
|
||||
* will be returned)</li>
|
||||
* <li>Default memory space (hex-offset only or with space-name, e.g., 'abcd', '0xabcd')</li>
|
||||
* <li>Memory space-name based address (with hex-offset, e.g., 'ram:abc')</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param addrStr the string to parse (memory block style addresses are also supported).
|
||||
* @param caseSensitive whether or not to process space/block names as case sensitive.
|
||||
* @return zero length array if addrStr is properly formatted but
|
||||
* no matching addresses were found or if the address is improperly formatted.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
@@ -17,7 +17,7 @@ package ghidra.program.util;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.symbol.*;
|
||||
@@ -31,6 +31,8 @@ import ghidra.util.exception.InvalidInputException;
|
||||
*/
|
||||
public class ProgramUtilities {
|
||||
|
||||
private final static String EXTERNAL_ADDRESS_PREFIX = AddressSpace.EXTERNAL_SPACE.toString();
|
||||
|
||||
private ProgramUtilities() {
|
||||
}
|
||||
|
||||
@@ -66,25 +68,72 @@ public class ProgramUtilities {
|
||||
return Collections.unmodifiableSet(openProgramsWeakMap.keySet()).iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an {@link Address} string which corresponds to the specified program.
|
||||
* Supported addresses include (order also indicates precedence):
|
||||
* <ul>
|
||||
* <li>Default loaded memory space (hex-offset only or with space-name, e.g., 'abcd', '0xabcd')</li>
|
||||
* <li>Memory space-name based address (with hex-offset, e.g., 'ram:abc', see Note-1)</li>
|
||||
* <li>External address (e.g., EXTERNAL:00001234, see Note-2)</li>
|
||||
* <li>Stack address (e.g., Stack[0xa], Stack[-0xa], Stack[10], Stack[-10])</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* NOTES:
|
||||
* <ol>
|
||||
* <li>Specifying only a hex offset should be restricted to a valid default address space offset
|
||||
* to avoid having an arbitrary address space address returned. A non-default space address
|
||||
* should include the appropriate address space name prefix.</li>
|
||||
* <li>If an external address is returned it does not indicate that it is defined by the
|
||||
* program.</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param program program whose memory spaces should be considered
|
||||
* @param addressString address string to be parsed (use of address space name prefix is
|
||||
* case-sensitive).
|
||||
* @return parsed address or null if parse failed
|
||||
*/
|
||||
public static Address parseAddress(Program program, String addressString) {
|
||||
Address[] addrs = program.parseAddress(addressString);
|
||||
Address[] addrs = program.getAddressFactory().getAllAddresses(addressString);
|
||||
if (addrs != null && addrs.length > 0) {
|
||||
return addrs[0];
|
||||
}
|
||||
String stackPrefix = "Stack[";
|
||||
if (addressString.startsWith(stackPrefix)) {
|
||||
String offsetString =
|
||||
addressString.substring(stackPrefix.length(), addressString.length() - 1);
|
||||
Address addr = tryParseExternalAddress(addressString);
|
||||
if (addr == null) {
|
||||
addr = tryParseStackAddress(program, addressString);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
private static Address tryParseStackAddress(Program program, String addressString) {
|
||||
if (addressString.startsWith(GenericAddress.STACK_ADDRESS_PREFIX) &&
|
||||
addressString.endsWith(GenericAddress.STACK_ADDRESS_SUFFIX)) {
|
||||
try {
|
||||
AddressSpace stackSpace = program.getAddressFactory().getStackSpace();
|
||||
String offsetString = // hex (0x) or decimal
|
||||
addressString.substring(GenericAddress.STACK_ADDRESS_PREFIX.length(),
|
||||
addressString.length() - 1);
|
||||
long offset = NumericUtilities.parseLong(offsetString);
|
||||
return program.getAddressFactory().getStackSpace().getAddress(offset);
|
||||
return stackSpace.getAddress(offset);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return null;
|
||||
catch (AddressOutOfBoundsException | NumberFormatException e) {
|
||||
// ignore - return null below
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Address tryParseExternalAddress(String addressString) {
|
||||
if (addressString.startsWith(EXTERNAL_ADDRESS_PREFIX)) {
|
||||
try {
|
||||
String offsetString = addressString.substring(EXTERNAL_ADDRESS_PREFIX.length());
|
||||
long offset = Long.parseLong(offsetString, 16); // hex offset only
|
||||
return AddressSpace.EXTERNAL_SPACE.getAddress(offset);
|
||||
}
|
||||
catch (AddressOutOfBoundsException | NumberFormatException e) {
|
||||
// ignore - return null below
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,6 +168,7 @@ public class ProgramUtilities {
|
||||
/**
|
||||
* Convert old function wrapped external pointers. Migrate function to
|
||||
* external function.
|
||||
* @param functionSymbol old fake IAT function to be migrated
|
||||
*/
|
||||
public static void convertFunctionWrappedExternalPointer(Symbol functionSymbol) {
|
||||
if (functionSymbol.getSymbolType() != SymbolType.FUNCTION) {
|
||||
|
||||
@@ -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.
|
||||
@@ -25,23 +25,28 @@ public class AddressFactoryTest extends AbstractGenericTest {
|
||||
AddressSpace space = null;
|
||||
AddressFactory factory = null;
|
||||
boolean isValidAddress = false;
|
||||
final int ADDRESS_SPACES = 5;
|
||||
final int ADDRESSES = 13;
|
||||
final int ADDRESSES = 14;
|
||||
final int PHYSICAL_ADDRESS_SPACES = 5; // first 5 in spaces and ADDRESS_SPACE_NAMES
|
||||
|
||||
AddressSpace[] spaces = new AddressSpace[ADDRESS_SPACES];
|
||||
final String[] ADDRESS_SPACE_NAMES =
|
||||
{ "ONE", "TWO", "THREE", "SegSpaceOne", "SegSpaceTwo", "register", "const", "unique" };
|
||||
|
||||
AddressSpace[] spaces = new AddressSpace[ADDRESS_SPACE_NAMES.length];
|
||||
Address[] addrs = new Address[ADDRESSES];
|
||||
|
||||
final String[] spaceName = { "ONE", "TWO", "THREE", "SegSpaceOne", "SegSpaceTwo" };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
@Before
|
||||
public void setUp() {
|
||||
spaces[0] = new GenericAddressSpace(spaceName[0], 8, AddressSpace.TYPE_RAM, 0);
|
||||
spaces[1] = new GenericAddressSpace(spaceName[1], 16, AddressSpace.TYPE_RAM, 1);
|
||||
spaces[2] = new GenericAddressSpace(spaceName[2], 32, AddressSpace.TYPE_RAM, 2);
|
||||
spaces[0] = new GenericAddressSpace(ADDRESS_SPACE_NAMES[0], 8, AddressSpace.TYPE_RAM, 0);
|
||||
spaces[1] = new GenericAddressSpace(ADDRESS_SPACE_NAMES[1], 16, AddressSpace.TYPE_RAM, 1);
|
||||
spaces[2] = new GenericAddressSpace(ADDRESS_SPACE_NAMES[2], 32, AddressSpace.TYPE_RAM, 2);
|
||||
|
||||
spaces[3] = new SegmentedAddressSpace(spaceName[3], 3);
|
||||
spaces[4] = new SegmentedAddressSpace(spaceName[4], 4);
|
||||
spaces[3] = new SegmentedAddressSpace(ADDRESS_SPACE_NAMES[3], 3);
|
||||
spaces[4] = new SegmentedAddressSpace(ADDRESS_SPACE_NAMES[4], 4);
|
||||
|
||||
spaces[5] = new GenericAddressSpace("register", 32, AddressSpace.TYPE_REGISTER, 0); // not physical
|
||||
spaces[6] = new GenericAddressSpace("const", 32, AddressSpace.TYPE_CONSTANT, 0); // not physical
|
||||
spaces[7] = new GenericAddressSpace("unique", 32, AddressSpace.TYPE_UNIQUE, 0); // not physical
|
||||
|
||||
factory = new DefaultAddressFactory(spaces);
|
||||
}
|
||||
@@ -62,8 +67,8 @@ public class AddressFactoryTest extends AbstractGenericTest {
|
||||
isValidAddress = factory.isValidAddress(new GenericAddress(space, 0));
|
||||
assertTrue(!isValidAddress);
|
||||
|
||||
for (int i = 0; i < ADDRESS_SPACES; i++) {
|
||||
isValidAddress = factory.isValidAddress(new GenericAddress(spaces[i], 0));
|
||||
for (AddressSpace element : spaces) {
|
||||
isValidAddress = factory.isValidAddress(new GenericAddress(element, 0));
|
||||
assertTrue(isValidAddress);
|
||||
}
|
||||
|
||||
@@ -90,37 +95,75 @@ public class AddressFactoryTest extends AbstractGenericTest {
|
||||
// //////////////////////////////////////////////////////////////////////////////////
|
||||
@Test
|
||||
public void testGetAllAddresses() {
|
||||
|
||||
// Limited to memory address spaces only
|
||||
|
||||
Address[] addresses;
|
||||
|
||||
addresses = factory.getAllAddresses("SegSpace*:0");
|
||||
Assert.assertEquals(addresses.length, 0);
|
||||
assertEquals(0, addresses.length);
|
||||
|
||||
addresses = factory.getAllAddresses("SegSpaceOne:0");
|
||||
Assert.assertEquals(addresses.length, 1);
|
||||
assertEquals(1, addresses.length);
|
||||
|
||||
addresses = factory.getAllAddresses("segspaceOne:0");
|
||||
assertEquals(0, addresses.length);
|
||||
|
||||
addresses = factory.getAllAddresses("0");
|
||||
assertEquals(5, addresses.length);
|
||||
assertEquals("ONE:00", addresses[0].toString());
|
||||
assertEquals("TWO:0000", addresses[1].toString());
|
||||
assertEquals("THREE:00000000", addresses[2].toString());
|
||||
assertEquals("SegSpaceOne:0000:0000", addresses[3].toString());
|
||||
assertEquals("SegSpaceTwo:0000:0000", addresses[4].toString());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllAddressesCaseInsensitive() {
|
||||
Address[] addresses;
|
||||
|
||||
addresses = factory.getAllAddresses("SegSpace*:0", false);
|
||||
assertEquals(0, addresses.length);
|
||||
|
||||
addresses = factory.getAllAddresses("SegSpaceOne:0", false);
|
||||
assertEquals(1, addresses.length);
|
||||
|
||||
addresses = factory.getAllAddresses("segspaceOne:0", false);
|
||||
assertEquals(1, addresses.length);
|
||||
|
||||
addresses = factory.getAllAddresses("0", false);
|
||||
assertEquals(5, addresses.length);
|
||||
assertEquals("ONE:00", addresses[0].toString());
|
||||
assertEquals("TWO:0000", addresses[1].toString());
|
||||
assertEquals("THREE:00000000", addresses[2].toString());
|
||||
assertEquals("SegSpaceOne:0000:0000", addresses[3].toString());
|
||||
assertEquals("SegSpaceTwo:0000:0000", addresses[4].toString());
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Test
|
||||
public void testGetAddressSpce() {
|
||||
space = factory.getAddressSpace(spaceName[0]);
|
||||
public void testGetAddressSpace() {
|
||||
space = factory.getAddressSpace(ADDRESS_SPACE_NAMES[0]);
|
||||
space = factory.getAddressSpace("xyz");
|
||||
|
||||
AddressSpace[] as = factory.getAddressSpaces();
|
||||
|
||||
assertTrue(as.length == ADDRESS_SPACES);
|
||||
assertTrue(as.length == factory.getNumAddressSpaces());
|
||||
assertEquals(PHYSICAL_ADDRESS_SPACES, as.length);
|
||||
assertEquals(PHYSICAL_ADDRESS_SPACES, factory.getNumAddressSpaces());
|
||||
|
||||
for (int i = 0; i < as.length; i++) {
|
||||
Assert.assertEquals(spaceName[i], as[i].getName());
|
||||
Assert.assertEquals(ADDRESS_SPACE_NAMES[i], as[i].getName());
|
||||
Assert.assertTrue(spaces[i] == as[i]);
|
||||
}
|
||||
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Test
|
||||
public void testGetDefaultAddressSpce() {
|
||||
public void testGetDefaultAddressSpace() {
|
||||
AddressSpace defASP = factory.getDefaultAddressSpace();
|
||||
Assert.assertEquals(defASP.getName(), spaces[0].getName());
|
||||
|
||||
@@ -151,6 +194,12 @@ public class AddressFactoryTest extends AbstractGenericTest {
|
||||
|
||||
Assert.assertEquals(addrs[10], factory.getAddress("f000:ffff"));
|
||||
|
||||
Assert.assertEquals(addrs[11], factory.getAddress("unique:0100"));
|
||||
|
||||
Assert.assertEquals(addrs[12], factory.getAddress("const:0200"));
|
||||
|
||||
Assert.assertEquals(addrs[13], factory.getAddress("register:0300"));
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -172,6 +221,10 @@ public class AddressFactoryTest extends AbstractGenericTest {
|
||||
|
||||
addrs[10] = new SegmentedAddress((SegmentedAddressSpace) spaces[3], 0xf000, 0xffff);
|
||||
|
||||
addrs[11] = factory.getAddressSpace("unique").getAddress(0x100);
|
||||
addrs[12] = factory.getAddressSpace("const").getAddress(0x200);
|
||||
addrs[13] = factory.getAddressSpace("register").getAddress(0x300);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user