Candidate release of source code.

This commit is contained in:
Dan 2019-03-26 13:45:32 -04:00
parent db81e6b3b0
commit 79d8f164f8
12449 changed files with 2800756 additions and 16 deletions

View file

@ -0,0 +1,49 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* 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 ghidra.pcodeCPort.slgh_compile.regression;
import java.io.BufferedReader;
import java.io.IOException;
public class PushbackEntireLine {
private final BufferedReader reader;
private String line = null;
public PushbackEntireLine(BufferedReader reader) {
this.reader = reader;
}
public synchronized String readLine() throws IOException {
if (line != null) {
String tmp = line;
line = null;
return tmp;
}
return reader.readLine();
}
public synchronized void putbackLine(String pushedLine) throws IOException {
if (line != null) {
throw new IOException("can only putback one line");
}
line = pushedLine;
}
public void close() throws IOException {
reader.close();
}
}

View file

@ -0,0 +1,272 @@
/* ###
* IP: GHIDRA
* NOTE: The presence of the MIPS and 8051 path flags beg the question: what OTHER languages besides what we know about need these defines?
*
* 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 ghidra.pcodeCPort.slgh_compile.regression;
import static org.junit.Assert.assertTrue;
import java.io.*;
import java.util.*;
import java.util.regex.Pattern;
import org.antlr.runtime.RecognitionException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jdom.JDOMException;
import org.junit.*;
import org.junit.experimental.categories.Category;
import generic.jar.ResourceFile;
import generic.test.AbstractGenericTest;
import generic.test.category.NightlyCategory;
import ghidra.framework.*;
import ghidra.pcodeCPort.slgh_compile.SleighCompileLauncher;
@Category(NightlyCategory.class)
public class SleighCompileRegressionTest extends AbstractGenericTest {
private static final int TOO_MANY_ERRORS = 100;
private Logger log;
@Before
public void setUp() throws Exception {
log = LogManager.getLogger(SleighCompileRegressionTest.class);
}
private boolean allOK = true;
private int currentLangBadCount;
private boolean itsOK(String message, boolean condition) {
if (!condition) {
++currentLangBadCount;
if (currentLangBadCount <= TOO_MANY_ERRORS + 1) {
log.fatal(message);
}
allOK = false;
}
return condition;
}
@Test
public void testExternal() throws Exception {
StringBuffer summary = new StringBuffer();
LoggingInitialization.initializeLoggingSystem();
List<ResourceFile> inputs = getSlaspecFiles();
Iterator<ResourceFile> ii = inputs.iterator();
while (ii.hasNext()) {
ResourceFile inputFile = ii.next();
String inputName = inputFile.getName().replaceFirst("\\.slaspec$", "-");
File targetFile = createTempFile("target-" + inputName, ".sla");
File actualFile = createTempFile("actual-" + inputName, ".sla");
log.info("testing " + inputFile + " (in " + targetFile + " and " + actualFile + ")");
int targetRetval = runTargetCompiler(inputFile, targetFile);
if (itsOK("non-zero target compiler return value", 0 == targetRetval)) {
int actualRetval = runActualCompiler(inputFile.getFile(false), actualFile);
if (itsOK("non-zero actual compiler return value", 0 == actualRetval)) {
currentLangBadCount = 0;
boolean ok = comparesOK(actualFile, targetFile);
if (ok) {
assertTrue("could not delete target output file " + targetFile,
targetFile.delete());
assertTrue("could not delete actual output file " + actualFile,
actualFile.delete());
}
else {
summary.append("Sleigh compile mismatch for: " + inputFile + "\n");
}
}
else {
summary.append("Sleigh(Java) compile failed for: " + inputFile + "\n");
}
}
else {
summary.append("Sleigh(C) compile failed for: " + inputFile + "\n");
}
// printMemory();
}
if (allOK) {
log.info("SUCCESS! Finished all tests.");
}
else {
log.error("FAILURE. Look in the log above for Sleigh ERROR messages\n" + summary);
Assert.fail("Sleigh language errors found");
}
}
private int runTargetCompiler(ResourceFile inputFile, File targetFile)
throws IOException, InterruptedException {
String command = getCppSleighCompilerForArch();
ProcessBuilder processBuilder =
new ProcessBuilder(command, "-DMIPS=../../../../../../ghidra/Ghidra/Processors/MIPS",
"-D8051=../../../../../../ghidra/Ghidra/Processors/8051",
inputFile.getAbsolutePath(), targetFile.getAbsolutePath());
processBuilder.directory(inputFile.getParentFile().getFile(false));
Process process = processBuilder.start();
new IOThread(process.getInputStream()).start();
new IOThread(process.getErrorStream()).start();
int retval = process.waitFor();
return retval;
}
private String getCppSleighCompilerForArch() throws FileNotFoundException {
String exeName;
if (Platform.CURRENT_PLATFORM.getOperatingSystem() == OperatingSystem.WINDOWS) {
exeName = "sleigh.exe";
}
else {
exeName = "sleigh";
}
File file = Application.getOSFile(exeName);
return file.getAbsolutePath();
}
private class IOThread extends Thread {
private BufferedReader shellOutput;
public IOThread(InputStream input) {
shellOutput = new BufferedReader(new InputStreamReader(input));
}
@Override
public void run() {
String line = null;
try {
while ((line = shellOutput.readLine()) != null) {
System.out.println(line);
}
}
catch (Exception e) {
// DO NOT USE LOGGING HERE (class loader)
System.err.println("Unexpected Exception: " + e.getMessage());
e.printStackTrace(System.err);
}
}
}
private int runActualCompiler(File inputFile, File actualFile)
throws JDOMException, IOException, RecognitionException {
return SleighCompileLauncher.runMain(
new String[] { "-DMIPS=../../../../../../ghidra/Ghidra/Processors/MIPS",
"-D8051=../../../../../../ghidra/Ghidra/Processors/8051",
inputFile.getAbsolutePath(), actualFile.getAbsolutePath() },
new HashMap<String, String>());
}
private static final Pattern SPACEMATCH = Pattern.compile("^\\s*<print piece=\" \"/>\\s*$");
private static final Pattern TPLMATCH = Pattern.compile("^\\s*<construct_tpl>\\s*$");
private boolean comparesOK(File actualFile, File targetFile) throws Exception {
boolean ok = true;
PushbackEntireLine actualReader =
new PushbackEntireLine(new BufferedReader(new FileReader(actualFile)));
PushbackEntireLine targetReader =
new PushbackEntireLine(new BufferedReader(new FileReader(targetFile)));
int actualLineNumber = 1;
int targetLineNumber = 1;
while (true) {
try {
if (currentLangBadCount >= 100) {
ok = itsOK("WAY TOO MANY DIFFERENCES, BAILING", false);
break;
}
String actual = actualReader.readLine();
String target = targetReader.readLine();
if (target == null) {
ok &= itsOK("actual has too many lines", actual == null);
break;
}
if (actual == null) {
ok &= itsOK("actual has too few lines", false);
break;
}
boolean actualIsSpace = SPACEMATCH.matcher(actual).find();
boolean targetIsSpace = SPACEMATCH.matcher(target).find();
boolean bothSpace = actualIsSpace && targetIsSpace;
boolean oneIsSpace = actualIsSpace || targetIsSpace;
if (!oneIsSpace) {
ok &= itsOK(
"difference on actual line " + actualLineNumber + ", target line " +
targetLineNumber + ":\nEXPECTED:\n" + target + "\nACTUAL:\n" + actual,
target.equals(actual));
continue;
}
else if (!bothSpace) {
// expected absent trailing space in Java version
if (!TPLMATCH.matcher(actual).find()) {
ok &= itsOK("difference (space!) on actual line " + actualLineNumber +
", target line " + targetLineNumber + ":\nEXPECTED:\n" + target +
"\nACTUAL:\n" + actual, false);
}
}
while (actualIsSpace) {
actual = actualReader.readLine();
++actualLineNumber;
actualIsSpace = actual != null && SPACEMATCH.matcher(actual).find();
}
actualReader.putbackLine(actual);
--actualLineNumber;
while (targetIsSpace) {
target = targetReader.readLine();
++targetLineNumber;
targetIsSpace = target != null && SPACEMATCH.matcher(target).find();
}
targetReader.putbackLine(target);
--targetLineNumber;
}
finally {
++actualLineNumber;
++targetLineNumber;
}
}
actualReader.close();
targetReader.close();
return ok;
}
private List<ResourceFile> getSlaspecFiles() {
List<ResourceFile> allSlaspecFiles =
Application.findFilesByExtensionInApplication(".slaspec");
return allSlaspecFiles;
// Predicate<ResourceFile> predicate = new Predicate<ResourceFile>() {
// @Override
// public boolean accept(ResourceFile t) {
// String absolutePath = t.getAbsolutePath();
// if (absolutePath.contains("<processor you do not want to include>")) {
// return false;
// }
// return true;
// }
// };
//
// return Fx.filter(predicate, allSlaspecFiles);
}
}

View file

@ -0,0 +1,76 @@
/* ###
* 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 ghidra.program.model.data;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.util.Collection;
import org.junit.Test;
import generic.test.AbstractGenericTest;
import ghidra.program.database.data.DataTypeUtilities;
public class DataTypeUtilitiesTest extends AbstractGenericTest {
public DataTypeUtilitiesTest() {
super();
}
@Test
public void testGetContainedDataTypes() {
DataType byteDt = new ByteDataType();
DataType wordDt = new WordDataType();
Structure simpleStruct = new StructureDataType("simpleStruct", 2);
simpleStruct.add(wordDt);
simpleStruct.add(byteDt);
Structure notAsSimpleStruct = new StructureDataType("notAsSimpleStruct", 2);
notAsSimpleStruct.add(simpleStruct);
notAsSimpleStruct.add(byteDt);
Structure selfRefStruct = new StructureDataType("selfRefStruct", 2);
selfRefStruct.add(byteDt);
selfRefStruct.add(new Pointer32DataType(selfRefStruct));
TypeDef typedef = new TypedefDataType("simpleTypedef", simpleStruct);
Structure complexStruct = new StructureDataType("complexStruct", 2);
complexStruct.add(new Pointer32DataType(typedef));
complexStruct.add(notAsSimpleStruct);
complexStruct.add(selfRefStruct);
TypeDef rootDt = new TypedefDataType("root", complexStruct);
Collection<DataType> dts = DataTypeUtilities.getContainedDataTypes(rootDt);
assertEquals(11, dts.size());
}
@Test
public void testGetCPrimitiveType() {
assertEquals(IntegerDataType.dataType, getType("signed int"));
assertEquals(IntegerDataType.dataType, getType(" signed int "));
assertEquals(IntegerDataType.dataType, getType("SIGNED int"));
assertEquals(UnsignedLongLongDataType.dataType, getType("unsigned long long int"));
assertNull(getType("foo bar"));
}
private DataType getType(String typeName) {
return DataTypeUtilities.getCPrimitiveDataType(typeName);
}
}

View file

@ -0,0 +1,496 @@
/* ###
* 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 ghidra.program.model.data;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.io.StringWriter;
import org.junit.*;
import generic.test.AbstractGenericTest;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitorAdapter;
public class DataTypeWriterTest extends AbstractGenericTest {
private static String EOL = System.getProperty("line.separator");
private StringWriter writer;
private DataTypeWriter dtWriter;
public DataTypeWriterTest() {
super();
}
@Before
public void setUp() throws Exception {
writer = new StringWriter();
dtWriter = new DataTypeWriter(null, writer); // uses default data organization
}
@After
public void tearDown() throws Exception {
writer.close();
}
@Test
public void testTypeDef() throws IOException, CancelledException {
TypeDef typedef = new TypedefDataType("BOB", new CharDataType());
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef char BOB;" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testTypeDef2() throws IOException, CancelledException {
TypeDef typedef = new TypedefDataType("unsigned int", new DWordDataType());
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "";
assertEquals(expected, actual);
}
@Test
public void testTypeDef3() throws IOException, CancelledException {
TypeDef typedef = new TypedefDataType("const float", new DWordDataType());
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "";
assertEquals(expected, actual);
}
@Test
public void testTypeDef4() throws IOException, CancelledException {
Structure struct = new StructureDataType("MyBasicStruct", 0);
struct.add(new CharDataType());
struct.add(new ByteDataType());
Pointer pointer1 = PointerDataType.getPointer(struct, 4);
Pointer pointer2 = PointerDataType.getPointer(pointer1, 4);
TypeDef typedef =
new TypedefDataType("static const " + pointer2.getDisplayName(), pointer2);
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "";
assertEquals(expected, actual);
}
@Test
public void testEnum() throws IOException, CancelledException {
Enum enumm = new EnumDataType("myEnum", 1);
enumm.add("A", 0);
enumm.add("B", 1);
enumm.add("C", 2);
enumm.add("D", 3);
enumm.add("E", 4);
dtWriter.write(enumm, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef enum myEnum {" + EOL + " A=0," + EOL + " B=1," + EOL +
" C=2," + EOL + " D=3," + EOL + " E=4" + EOL + "} myEnum;" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testEnum2() throws IOException, CancelledException {
Enum enumm = new EnumDataType("myEnum", 1);
enumm.add("A", 4);
enumm.add("B", 8);
enumm.add("C", 16);
enumm.add("D", 32);
enumm.add("E", 254);
dtWriter.write(enumm, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef enum myEnum {" + EOL + " A=4," + EOL + " B=8," + EOL +
" C=16," + EOL + " D=32," + EOL + " E=254" + EOL + "} myEnum;" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testStructure() throws IOException, CancelledException {
Structure struct = new StructureDataType("MyStruct", 0);
struct.setDescription("this is my structure");
struct.add(new CharDataType(), "myChar", "this is a character");
struct.add(new ByteDataType(), "myByte", "this is a byte");
struct.add(new WordDataType(), "myWord", "this is a word");
struct.add(new DWordDataType(), "myDWord", "this is a dword");
struct.add(new QWordDataType(), "myQWord", "this is a qword");
struct.add(new FloatDataType(), "myFloat", "this is a float");
struct.add(new DoubleDataType(), "myDouble", "this is a double");
struct.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
"this is a float pointer");
struct.setFlexibleArrayComponent(new CharDataType(), "myFlexArray", "this is a flex array");
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef struct MyStruct MyStruct, *PMyStruct;" + EOL + EOL +
"typedef unsigned char byte;" + EOL + "typedef unsigned short word;" + EOL +
"typedef unsigned int dword;" + EOL + "typedef unsigned long long qword;" + EOL +
"struct MyStruct { /* this is my structure */" + EOL +
" char myChar; /* this is a character */" + EOL +
" byte myByte; /* this is a byte */" + EOL +
" word myWord; /* this is a word */" + EOL +
" dword myDWord; /* this is a dword */" + EOL +
" qword myQWord; /* this is a qword */" + EOL +
" float myFloat; /* this is a float */" + EOL +
" double myDouble; /* this is a double */" + EOL +
" float * myFloatPointer; /* this is a float pointer */" + EOL +
" char[0] myFlexArray; /* this is a flex array */" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testStructureBasic() throws IOException, CancelledException {
Structure struct = new StructureDataType("MyBasicStruct", 0);
struct.add(new CharDataType());
struct.add(new ByteDataType());
struct.add(new WordDataType());
struct.add(new DWordDataType());
struct.add(new QWordDataType());
struct.add(new FloatDataType());
struct.add(new DoubleDataType());
struct.add(PointerDataType.getPointer(new FloatDataType(), 4));
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef struct MyBasicStruct MyBasicStruct, *PMyBasicStruct;" + EOL +
EOL + "typedef unsigned char byte;" + EOL + "typedef unsigned short word;" + EOL +
"typedef unsigned int dword;" + EOL + "typedef unsigned long long qword;" + EOL +
"struct MyBasicStruct {" + EOL + " char field_0x0;" + EOL + " byte field_0x1;" +
EOL + " word field_0x2;" + EOL + " dword field_0x4;" + EOL +
" qword field_0x8;" + EOL + " float field_0x10;" + EOL +
" double field_0x14;" + EOL + " float * field_0x1c;" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testStructureInStructure() throws IOException, CancelledException {
Structure innerStructure = new StructureDataType("MyInnerStructure", 0);
innerStructure.setDescription("this is my inner structure");
innerStructure.add(new CharDataType(), "myInnerChar", "this is a inner character");
innerStructure.add(new ByteDataType(), "myInnerByte", "this is a inner byte");
Structure outerStructure = new StructureDataType("MyOuterStructure", 0);
outerStructure.setDescription("this is my outer structure");
outerStructure.add(new FloatDataType(), "myOuterFloat", "this is a outer float");
outerStructure.add(new TypedefDataType("int", new DWordDataType()), "myOuterInt",
"this is a outer int");
outerStructure.add(innerStructure, "myOuterInnerStructure",
"this is a outer inner structure");
outerStructure.add(new CharDataType(), "myOuterChar", "this is a outer character");
dtWriter.write(outerStructure, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef struct MyOuterStructure MyOuterStructure, *PMyOuterStructure;" +
EOL + EOL + "typedef struct MyInnerStructure MyInnerStructure, *PMyInnerStructure;" +
EOL + EOL + "typedef unsigned char byte;" + EOL +
"struct MyInnerStructure { /* this is my inner structure */" + EOL +
" char myInnerChar; /* this is a inner character */" + EOL +
" byte myInnerByte; /* this is a inner byte */" + EOL + "};" + EOL + EOL +
"struct MyOuterStructure { /* this is my outer structure */" + EOL +
" float myOuterFloat; /* this is a outer float */" + EOL +
" int myOuterInt; /* this is a outer int */" + EOL +
" struct MyInnerStructure myOuterInnerStructure; /* this is a outer inner structure */" +
EOL + " char myOuterChar; /* this is a outer character */" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testStructureInUnion() throws IOException, CancelledException {
Structure innerStructure = new StructureDataType("MyInnerStructure", 0);
innerStructure.setDescription("this is my inner structure");
innerStructure.add(new CharDataType(), "myInnerChar", "this is a inner character");
innerStructure.add(new ByteDataType(), "myInnerByte", "this is a inner byte");
Union outerUnion = new UnionDataType("MyOuterUnion");
outerUnion.setDescription("this is my outer union");
outerUnion.add(new FloatDataType(), "myOuterFloat", "this is a outer float");
outerUnion.add(new TypedefDataType("int", new DWordDataType()), "myOuterInt",
"this is a outer int");
outerUnion.add(innerStructure, "myOuterInnerStructure", "this is a outer inner structure");
outerUnion.add(new CharDataType(), "myOuterChar", "this is a outer character");
dtWriter.write(outerUnion, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef union MyOuterUnion MyOuterUnion, *PMyOuterUnion;" + EOL + EOL +
"typedef struct MyInnerStructure MyInnerStructure, *PMyInnerStructure;" + EOL + EOL +
"typedef unsigned char byte;" + EOL +
"struct MyInnerStructure { /* this is my inner structure */" + EOL +
" char myInnerChar; /* this is a inner character */" + EOL +
" byte myInnerByte; /* this is a inner byte */" + EOL + "};" + EOL + EOL +
"union MyOuterUnion { /* this is my outer union */" + EOL +
" float myOuterFloat; /* this is a outer float */" + EOL +
" int myOuterInt; /* this is a outer int */" + EOL +
" struct MyInnerStructure myOuterInnerStructure; /* this is a outer inner structure */" +
EOL + " char myOuterChar; /* this is a outer character */" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testStructureSelfReference() throws IOException, CancelledException {
Structure struct = new StructureDataType("MySelfRefStruct", 0);
struct.add(new WordDataType());
struct.add(PointerDataType.getPointer(struct, 4));
struct.add(new DoubleDataType());
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef struct MySelfRefStruct MySelfRefStruct, *PMySelfRefStruct;" +
EOL + EOL + "typedef unsigned short word;" + EOL + "struct MySelfRefStruct {" + EOL +
" word field_0x0;" + EOL + " struct MySelfRefStruct * field_0x2;" + EOL +
" double field_0x6;" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testUnion() throws IOException, CancelledException {
Union union = new UnionDataType("MyUnion");
union.setDescription("this is my union");
union.add(new CharDataType(), "myChar", "this is a character");
union.add(new ByteDataType(), "myByte", "this is a byte");
union.add(new WordDataType(), "myWord", "this is a word");
union.add(new DWordDataType(), "myDWord", "this is a dword");
union.add(new QWordDataType(), "myQWord", "this is a qword");
union.add(new FloatDataType(), "myFloat", "this is a float");
union.add(new DoubleDataType(), "myDouble", "this is a double");
union.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
"this is a float pointer");
dtWriter.write(union, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef union MyUnion MyUnion, *PMyUnion;" + EOL + EOL +
"typedef unsigned char byte;" + EOL + "typedef unsigned short word;" + EOL +
"typedef unsigned int dword;" + EOL + "typedef unsigned long long qword;" + EOL +
"union MyUnion { /* this is my union */" + EOL +
" char myChar; /* this is a character */" + EOL +
" byte myByte; /* this is a byte */" + EOL +
" word myWord; /* this is a word */" + EOL +
" dword myDWord; /* this is a dword */" + EOL +
" qword myQWord; /* this is a qword */" + EOL +
" float myFloat; /* this is a float */" + EOL +
" double myDouble; /* this is a double */" + EOL +
" float * myFloatPointer; /* this is a float pointer */" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testUnionInUnion() throws IOException, CancelledException {
Union innerUnion = new UnionDataType("MyInnerUnion");
innerUnion.setDescription("this is my inner union");
innerUnion.add(new CharDataType(), "myInnerChar", "this is a inner character");
innerUnion.add(new ByteDataType(), "myInnerByte", "this is a inner byte");
Union outerUnion = new UnionDataType("MyOuterUnion");
outerUnion.setDescription("this is my outer union");
outerUnion.add(new FloatDataType(), "myOuterFloat", "this is a outer float");
outerUnion.add(new TypedefDataType("int", new DWordDataType()), "myOuterInt",
"this is a outer int");
outerUnion.add(innerUnion, "myOuterInnerUnion", "this is a outer inner union");
outerUnion.add(new CharDataType(), "myOuterChar", "this is a outer character");
dtWriter.write(outerUnion, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef union MyOuterUnion MyOuterUnion, *PMyOuterUnion;" + EOL + EOL +
"typedef union MyInnerUnion MyInnerUnion, *PMyInnerUnion;" + EOL + EOL +
"typedef unsigned char byte;" + EOL +
"union MyInnerUnion { /* this is my inner union */" + EOL +
" char myInnerChar; /* this is a inner character */" + EOL +
" byte myInnerByte; /* this is a inner byte */" + EOL + "};" + EOL + EOL +
"union MyOuterUnion { /* this is my outer union */" + EOL +
" float myOuterFloat; /* this is a outer float */" + EOL +
" int myOuterInt; /* this is a outer int */" + EOL +
" union MyInnerUnion myOuterInnerUnion; /* this is a outer inner union */" + EOL +
" char myOuterChar; /* this is a outer character */" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testUnionInStructure() throws IOException, CancelledException {
Union innerUnion = new UnionDataType("MyInnerUnion");
innerUnion.setDescription("this is my inner union");
innerUnion.add(new CharDataType(), "myInnerChar", "this is a inner character");
innerUnion.add(new ByteDataType(), "myInnerByte", "this is a inner byte");
Structure outerStructure = new StructureDataType("MyOuterStructure", 0);
outerStructure.setDescription("this is my outer structure");
outerStructure.add(new FloatDataType(), "myOuterFloat", "this is a outer float");
outerStructure.add(new TypedefDataType("int", new DWordDataType()), "myOuterInt",
"this is a outer int");
outerStructure.add(innerUnion, "myOuterInnerUnion", "this is a outer inner union");
outerStructure.add(new CharDataType(), "myOuterChar", "this is a outer character");
dtWriter.write(outerStructure, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef struct MyOuterStructure MyOuterStructure, *PMyOuterStructure;" +
EOL + EOL + "typedef union MyInnerUnion MyInnerUnion, *PMyInnerUnion;" + EOL + EOL +
"typedef unsigned char byte;" + EOL +
"union MyInnerUnion { /* this is my inner union */" + EOL +
" char myInnerChar; /* this is a inner character */" + EOL +
" byte myInnerByte; /* this is a inner byte */" + EOL + "};" + EOL + EOL +
"struct MyOuterStructure { /* this is my outer structure */" + EOL +
" float myOuterFloat; /* this is a outer float */" + EOL +
" int myOuterInt; /* this is a outer int */" + EOL +
" union MyInnerUnion myOuterInnerUnion; /* this is a outer inner union */" + EOL +
" char myOuterChar; /* this is a outer character */" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testArray() {
//TODO
}
@Test
public void testSizableDynamicInStructure() throws IOException, CancelledException {
Structure struct = new StructureDataType("MyStruct", 0);
struct.setDescription("this is my structure");
struct.add(new QWordDataType(), "myQWord", "this is my qword");
struct.add(new StringDataType(), 10, "myStr", "this is my string");
struct.add(new DoubleDataType(), "myDouble", "this is my double");
struct.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
"this is my float pointer");
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef struct MyStruct MyStruct, *PMyStruct;" + EOL + EOL +
"typedef unsigned long long qword;" + EOL +
"struct MyStruct { /* this is my structure */" + EOL +
" qword myQWord; /* this is my qword */" + EOL +
" char myStr[10]; /* this is my string */" + EOL +
" double myDouble; /* this is my double */" + EOL +
" float * myFloatPointer; /* this is my float pointer */" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testArrayInStructure() throws IOException, CancelledException {
DataType dt = new FloatDataType();
Array array = new ArrayDataType(dt, 300, dt.getLength());
Structure struct = new StructureDataType("MyStruct", 0);
struct.setDescription("this is my structure");
struct.add(new QWordDataType(), "myQWord", "this is my qword");
struct.add(array, "myArray", "this is my array");
struct.add(new DoubleDataType(), "myDouble", "this is my double");
struct.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
"this is my float pointer");
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef struct MyStruct MyStruct, *PMyStruct;" + EOL + EOL +
"typedef unsigned long long qword;" + EOL +
"struct MyStruct { /* this is my structure */" + EOL +
" qword myQWord; /* this is my qword */" + EOL +
" float myArray[300]; /* this is my array */" + EOL +
" double myDouble; /* this is my double */" + EOL +
" float * myFloatPointer; /* this is my float pointer */" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testArrayInUnion() throws IOException, CancelledException {
DataType dt = new FloatDataType();
Array array = new ArrayDataType(dt, 300, dt.getLength());
Union union = new UnionDataType("MyUnion");
union.setDescription("this is my union");
union.add(new QWordDataType(), "myQWord", "this is my qword");
union.add(array, "myArray", "this is my array");
union.add(new DoubleDataType(), "myDouble", "this is my double");
union.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
"this is my float pointer");
dtWriter.write(union, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef union MyUnion MyUnion, *PMyUnion;" + EOL + EOL +
"typedef unsigned long long qword;" + EOL +
"union MyUnion { /* this is my union */" + EOL +
" qword myQWord; /* this is my qword */" + EOL +
" float myArray[300]; /* this is my array */" + EOL +
" double myDouble; /* this is my double */" + EOL +
" float * myFloatPointer; /* this is my float pointer */" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testUnionSelfReference() throws IOException, CancelledException {
Union union = new UnionDataType("MySelfRefUnion");
union.add(new WordDataType());
union.add(PointerDataType.getPointer(union, 4));
union.add(new DoubleDataType());
dtWriter.write(union, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "typedef union MySelfRefUnion MySelfRefUnion, *PMySelfRefUnion;" + EOL +
EOL + "typedef unsigned short word;" + EOL + "union MySelfRefUnion {" + EOL +
" word field0;" + EOL + " union MySelfRefUnion * field1;" + EOL +
" double field2;" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@Test
public void testPointer() throws IOException, CancelledException {
// Only base type is written-out - not pointer
Pointer ptr = PointerDataType.getPointer(null, null);
dtWriter.write(ptr, TaskMonitorAdapter.DUMMY_MONITOR);
String actual = writer.getBuffer().toString();
String expected = "";
assertEquals(expected, actual);
ptr = PointerDataType.getPointer(DataType.DEFAULT, null);
dtWriter.write(ptr, TaskMonitorAdapter.DUMMY_MONITOR);
actual = writer.getBuffer().toString();
expected += "typedef unsigned char undefined;" + EOL + EOL;
assertEquals(expected, actual);
TypeDef typedef = new TypedefDataType("BOB", new CharDataType());
ptr = PointerDataType.getPointer(typedef, null);
dtWriter.write(ptr, TaskMonitorAdapter.DUMMY_MONITOR);
actual = writer.getBuffer().toString();
expected += "typedef char BOB;" + EOL + EOL;
assertEquals(expected, actual);
}
}

View file

@ -0,0 +1,271 @@
/* ###
* 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 ghidra.program.model.data;
import static org.junit.Assert.*;
import java.util.NoSuchElementException;
import org.junit.*;
import generic.test.AbstractGenericTest;
import ghidra.util.task.TaskMonitorAdapter;
/**
* Tests for Enum data types.
*/
public class EnumTest extends AbstractGenericTest {
private DataTypeManager dataMgr;
private int transactionID;
/**
* Constructor for EnumTest.
* @param arg0
*/
public EnumTest() {
super();
}
/*
* @see TestCase#setUp()
*/
@Before
public void setUp() throws Exception {
dataMgr = new StandAloneDataTypeManager("Test");
transactionID = dataMgr.startTransaction("");
}
@After
public void tearDown() {
dataMgr.endTransaction(transactionID, true);
dataMgr.close();
}
@Test
public void testCreateEnum() throws Exception {
Enum enumm = new EnumDataType("Color", 1);
enumm.add("Red", 0);
enumm.add("Green", 1);
enumm.add("Blue", 2);
Category root = dataMgr.getRootCategory();
Category c = root.createCategory("enumms");
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
assertNotNull(enummDT);
assertEquals("Color", enummDT.getName());
assertEquals(0, enummDT.getValue("Red"));
assertEquals(1, enummDT.getValue("Green"));
assertEquals(2, enummDT.getValue("Blue"));
assertEquals(1, enummDT.getLength());
assertEquals(3, enummDT.getCount());
assertTrue(enumm.isEquivalent(enummDT));
assertTrue(enummDT.isEquivalent(enumm));
assertEquals(c.getCategoryPath(), enummDT.getCategoryPath());
assertNotNull(c.getDataType("Color"));
}
@Test
public void testRemoveValue() throws Exception {
Enum enumm = new EnumDataType("Color", 1);
enumm.add("Red", 0);
enumm.add("Green", 1);
enumm.add("Blue", 2);
Category root = dataMgr.getRootCategory();
Category c = root.createCategory("enumms");
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
assertEquals(3, enummDT.getCount());
enummDT.remove("Green");
assertEquals(2, enummDT.getCount());
}
@Test
public void testAddValue() throws Exception {
Enum enumm = new EnumDataType("Color", 1);
enumm.add("Red", 0);
enumm.add("Green", 1);
enumm.add("Blue", 2);
Category root = dataMgr.getRootCategory();
Category c = root.createCategory("enumms");
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
enummDT.add("Purple", 7);
assertEquals(4, enummDT.getCount());
assertEquals(7, enummDT.getValue("Purple"));
}
@Test
public void testEditValue() throws Exception {
Enum enumm = new EnumDataType("Color", 1);
enumm.add("Red", 10);
enumm.add("Green", 15);
enumm.add("Blue", 20);
Category root = dataMgr.getRootCategory();
Category c = root.createCategory("enumms");
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
enummDT.remove("Blue");
assertEquals(2, enummDT.getCount());
enummDT.add("Blue", 30);
assertEquals(30, enummDT.getValue("Blue"));
assertEquals("Blue", enummDT.getName(30));
assertNull(enummDT.getName(20));
}
@Test
public void testCloneRetain() throws Exception {
Enum enumm = new EnumDataType("Color", 1);
enumm.add("Red", 10);
enumm.add("Green", 15);
enumm.add("Blue", 20);
Category root = dataMgr.getRootCategory();
Category c = root.createCategory("enumms");
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
Enum copyDT = (Enum)enummDT.clone(null);
assertNotNull(copyDT);
Enum c2 = (Enum)root.addDataType(copyDT, DataTypeConflictHandler.DEFAULT_HANDLER);
assertNotNull(c2);
assertTrue(copyDT.isEquivalent(c2));
}
@Test
public void testCopyDontRetain() throws Exception {
Enum enumm = new EnumDataType("Color", 1);
enumm.add("Red", 10);
enumm.add("Green", 15);
enumm.add("Blue", 20);
Category root = dataMgr.getRootCategory();
Category c = root.createCategory("enumms");
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
Enum copyDT = (Enum)enummDT.copy(null);
assertNotNull(copyDT);
Enum c2 = (Enum)root.addDataType(copyDT, DataTypeConflictHandler.DEFAULT_HANDLER);
assertNotNull(c2);
assertTrue(copyDT.isEquivalent(c2));
}
@Test
public void testRemoveEnum() throws Exception {
Enum enumm = new EnumDataType("Color", 1);
enumm.add("Red", 10);
enumm.add("Green", 15);
enumm.add("Blue", 20);
Category root = dataMgr.getRootCategory();
Category c = root.createCategory("enumms");
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
assertNotNull(enummDT);
c.remove(enummDT, TaskMonitorAdapter.DUMMY_MONITOR);
assertNull(c.getDataType("Color"));
assertTrue(enummDT.isDeleted());
}
@Test
public void testMoveEnum() throws Exception {
Enum enumm = new EnumDataType("Color", 1);
enumm.add("Red", 10);
enumm.add("Green", 15);
enumm.add("Blue", 20);
Category root = dataMgr.getRootCategory();
Category c = root.createCategory("enumms");
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
root.moveDataType(enummDT, null);
assertNotNull(root.getDataType(enumm.getName()));
assertNull(c.getDataType(enumm.getName()));
}
@Test
public void testResolve() throws Exception {
Enum enumm = new EnumDataType("Color", 1);
enumm.add("Red", 10);
enumm.add("Green", 15);
enumm.add("Blue", 20);
Enum enummDT = (Enum)dataMgr.resolve(enumm, null);
assertNotNull(enummDT);
long id = dataMgr.getResolvedID(enummDT);
assertEquals(enummDT, dataMgr.getDataType(id));
}
@Test
public void testReplace() throws Exception {
Enum enumm = new EnumDataType("Color", 1);
enumm.add("Red", 10);
enumm.add("Green", 15);
enumm.add("Blue", 20);
Category root = dataMgr.getRootCategory();
Category c = root.createCategory("enumms");
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
Enum myEnum = new EnumDataType("my enumm", 1);
myEnum.add("My red", 0);
myEnum.add("My Green", 5);
myEnum.add("My Blue", 25);
myEnum.add("Purple", 10);
enummDT.replaceWith(myEnum);
assertEquals(4, enummDT.getCount());
long[] values = enummDT.getValues();
assertEquals(4, values.length);
assertEquals(0, values[0]);
assertEquals(5, values[1]);
assertEquals(10, values[2]);
assertEquals(25, values[3]);
try {
enummDT.getValue("Red");
Assert.fail("Should have gotten no such element exception!");
} catch (NoSuchElementException e) {
}
}
// private class DomainObjListener implements DomainObjectListener {
// private int count;
//
// /* (non-Javadoc)
// * @see ghidra.framework.model.DomainObjectListener#domainObjectChanged(ghidra.framework.model.DomainObjectChangedEvent)
// */
// public void domainObjectChanged(DomainObjectChangedEvent ev) {
// for (int i=0; i<ev.numRecords(); i++) {
// DomainObjectChangeRecord rec = ev.getChangeRecord(i);
// if (rec.getEventType() == ChangeManager.DOCR_DATA_TYPE_CHANGED) {
// ++count;
// }
// }
// }
// int getCount() {
// return count;
// }
// }
}

View file

@ -0,0 +1,169 @@
/* ###
* 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 ghidra.program.model.data;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.junit.*;
import generic.test.AbstractGenericTest;
public class FileDataTypeManagerTest extends AbstractGenericTest {
private File testArchiveFile;
public FileDataTypeManagerTest() {
super();
}
@Before
public void setUp() throws Exception {
testArchiveFile =
File.createTempFile("TestArchive", ".gdt", new File(getTestDirectoryPath()));
testArchiveFile.delete();
}
@After
public void tearDown() throws Exception {
testArchiveFile.delete();
}
@Test
public void testCreateAndOpenArchive() {
FileDataTypeManager dtMgr = null;
try {
dtMgr = FileDataTypeManager.createFileArchive(testArchiveFile);
assertTrue(dtMgr.isUpdatable());
DataType dt1, dt2;
int txId = dtMgr.startTransaction("Add Types");
try {
dt1 =
dtMgr.addDataType(new TypedefDataType("T1", ByteDataType.dataType), null).clone(
null);
dt2 =
dtMgr.addDataType(new TypedefDataType("T2", ByteDataType.dataType), null).clone(
null);
}
finally {
dtMgr.endTransaction(txId, true);
}
assertTrue(dtMgr.isChanged());
dtMgr.save();
dtMgr.close();
dtMgr = null;
dtMgr = FileDataTypeManager.openFileArchive(testArchiveFile, false);
assertFalse(dtMgr.isUpdatable());
ArrayList<DataType> list = new ArrayList<DataType>();
dtMgr.getAllDataTypes(list);
int size = list.size();
if (size != 3) {
StringBuilder buffy = new StringBuilder();
for (DataType dt : list) {
buffy.append(dt.getName()).append(" - ").append(dt.getDescription()).append(
"\n");
}
Assert.fail("Did not get exptected data types of byte, Typdef and Typedef. Instead found:\n" +
buffy.toString());
}
assertTrue(dt1.isEquivalent(dtMgr.getDataType(CategoryPath.ROOT, "T1")));
assertTrue(dt2.isEquivalent(dtMgr.getDataType(CategoryPath.ROOT, "T2")));
dtMgr.close();
dtMgr = null;
}
catch (IOException e) {
Assert.fail("Unexpected Exception");
}
finally {
if (dtMgr != null) {
dtMgr.close();
}
}
}
@Test
public void testModifyArchive() {
testCreateAndOpenArchive(); // establish archive
for (int i = 0; i < 10; i++) {
FileDataTypeManager dtMgr = null;
try {
dtMgr = FileDataTypeManager.openFileArchive(testArchiveFile, true);
assertTrue("Archive not updateable, i=" + i, dtMgr.isUpdatable());
int txId = dtMgr.startTransaction("Add Type");
try {
dtMgr.addDataType(new TypedefDataType("X" + i, ByteDataType.dataType), null);
}
finally {
dtMgr.endTransaction(txId, true);
}
dtMgr.save();
dtMgr.close();
dtMgr = null;
}
catch (IOException e) {
Assert.fail("Unexpected Exception");
}
finally {
if (dtMgr != null) {
dtMgr.close();
}
}
}
FileDataTypeManager dtMgr = null;
try {
dtMgr = FileDataTypeManager.openFileArchive(testArchiveFile, false);
assertFalse(dtMgr.isUpdatable());
ArrayList<DataType> list = new ArrayList<DataType>();
dtMgr.getAllDataTypes(list);
assertEquals(13, list.size());
dtMgr.close();
dtMgr = null;
}
catch (IOException e) {
Assert.fail("Unexpected Exception");
}
finally {
if (dtMgr != null) {
dtMgr.close();
}
}
}
}

View file

@ -0,0 +1,150 @@
/* ###
* 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 ghidra.program.model.data;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import generic.test.AbstractGenericTest;
import ghidra.program.model.mem.ByteMemBufferImpl;
public class FloatDataTypeTest extends AbstractGenericTest {
/**
* Constructor for LongDoubleDataTypeTest.
* @param arg0
*/
public FloatDataTypeTest() {
super();
}
private byte[] getBytes(long value, int size) {
byte[] bytes = new byte[size];
for (int i = 0; i < size; i++) {
bytes[i] = (byte) value;
value >>= 8;
}
return bytes;
}
@Test
public void testFloat4Extremes() {
int bits = Float.floatToRawIntBits(Float.NaN);
byte[] bytes = getBytes(bits, 4);
Object value =
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(Float.NaN, value);
bits = Float.floatToRawIntBits(Float.POSITIVE_INFINITY);
bytes = getBytes(bits, 4);
value =
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(Float.POSITIVE_INFINITY, value);
bits = Float.floatToRawIntBits(Float.NEGATIVE_INFINITY);
bytes = getBytes(bits, 4);
value =
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(Float.NEGATIVE_INFINITY, value);
bits = Float.floatToRawIntBits(0F);
bytes = getBytes(bits, 4);
value =
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(0F, value);
bits = Float.floatToRawIntBits(1F);
bytes = getBytes(bits, 4);
value =
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(1F, value);
bits = Float.floatToRawIntBits(-1F);
bytes = getBytes(bits, 4);
value =
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(-1F, value);
bits = Float.floatToRawIntBits(555.555F);
bytes = getBytes(bits, 4);
value =
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(555.555F, value);
bits = Float.floatToRawIntBits(-555.555F);
bytes = getBytes(bits, 4);
value =
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(-555.555F, value);
}
@Test
public void testFloat8Extremes() {
long bits = Double.doubleToRawLongBits(Double.NaN);
byte[] bytes = getBytes(bits, 8);
Object value =
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(Double.NaN, value);
bits = Double.doubleToRawLongBits(Double.POSITIVE_INFINITY);
bytes = getBytes(bits, 8);
value =
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(Double.POSITIVE_INFINITY, value);
bits = Double.doubleToRawLongBits(Double.NEGATIVE_INFINITY);
bytes = getBytes(bits, 8);
value =
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(Double.NEGATIVE_INFINITY, value);
bits = Double.doubleToRawLongBits(0D);
bytes = getBytes(bits, 8);
value =
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(0D, value);
bits = Double.doubleToRawLongBits(1D);
bytes = getBytes(bits, 8);
value =
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(1D, value);
bits = Double.doubleToRawLongBits(-1D);
bytes = getBytes(bits, 8);
value =
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(-1D, value);
bits = Double.doubleToRawLongBits(555.555D);
bytes = getBytes(bits, 8);
value =
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(555.555D, value);
bits = Double.doubleToRawLongBits(-555.555D);
bytes = getBytes(bits, 8);
value =
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
assertEquals(-555.555D, value);
}
}

View file

@ -0,0 +1,310 @@
/* ###
* 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 ghidra.program.model.data;
import static org.junit.Assert.*;
import org.junit.*;
import generic.test.AbstractGenericTest;
import ghidra.docking.settings.SettingsImpl;
public class FunctionDefinitionDataTypeTest extends AbstractGenericTest {
private StandAloneDataTypeManager dtm;
private FunctionDefinition functionDt;
private int transactionID;
private FunctionDefinition createFunctionDefinition(String name) {
return (FunctionDefinition) dtm.resolve(new FunctionDefinitionDataType(name), null);
}
/**
* Constructor for FunctionDefinitionDataTypeTest.
*/
public FunctionDefinitionDataTypeTest() {
super();
}
/*
* @see TestCase#setUp()
*/
@Before
public void setUp() throws Exception {
dtm = new StandAloneDataTypeManager("dummyDTM");
transactionID = dtm.startTransaction("");
functionDt = createFunctionDefinition("Test");
}
/*
* @see TestCase#tearDown()
*/
@After
public void tearDown() throws Exception {
dtm.endTransaction(transactionID, true);
dtm.close();
}
@Test
public void testConstructor_WithName() {
FunctionDefinitionDataType impl;
FunctionDefinition fdt;
// name
impl = new FunctionDefinitionDataType("testFunctionDefinition");
assertEquals(impl.getName(), "testFunctionDefinition");
assertNull(impl.getComment());
assertTrue(impl.getReturnType().isEquivalent(DataType.DEFAULT));
assertEquals(impl.getArguments().length, 0);
assertNull(impl.getDataTypeManager());
assertEquals(impl.getMnemonic(new SettingsImpl(impl, null)),
"undefined testFunctionDefinition(void)");
assertEquals(impl.getPathName(), "/testFunctionDefinition");
fdt = (FunctionDefinition) dtm.resolve(impl, null);
assertEquals(fdt.getName(), "testFunctionDefinition");
assertNull(fdt.getComment());
assertTrue(fdt.getReturnType().isEquivalent(DataType.DEFAULT));
assertEquals(fdt.getArguments().length, 0);
String fdtCat = fdt.getCategoryPath().getPath();
String rootCat = CategoryPath.ROOT.getPath();
assertEquals(fdtCat, rootCat);
assertEquals(fdt.getDataTypeManager(), dtm);
assertEquals(fdt.getMnemonic(new SettingsImpl(impl, null)),
"undefined testFunctionDefinition(void)");
assertEquals("/testFunctionDefinition", fdt.getPathName());
}
@Test
public void testConstructor_WithDtmName() throws Exception {
FunctionDefinitionDataType impl;
FunctionDefinition fdt;
// dtm, name
impl = new FunctionDefinitionDataType("testFunctionDefinition");
assertEquals(impl.getName(), "testFunctionDefinition");
assertNull(impl.getComment());
assertTrue(impl.getReturnType().isEquivalent(DataType.DEFAULT));
assertEquals(impl.getArguments().length, 0);
assertEquals(CategoryPath.ROOT, impl.getCategoryPath());
assertEquals(impl.getMnemonic(new SettingsImpl(impl, null)),
"undefined testFunctionDefinition(void)");
assertEquals(impl.getPathName(), "/testFunctionDefinition");
fdt = (FunctionDefinition) dtm.resolve(impl, null);
assertEquals(fdt.getName(), "testFunctionDefinition");
assertNull(fdt.getComment());
assertTrue(fdt.getReturnType().isEquivalent(DataType.DEFAULT));
assertEquals(fdt.getArguments().length, 0);
String fdtCat = fdt.getCategoryPath().getPath();
String rootCat = CategoryPath.ROOT.getPath();
assertEquals(fdtCat, rootCat);
assertEquals(fdt.getDataTypeManager(), dtm);
assertEquals(fdt.getMnemonic(new SettingsImpl(impl, null)),
"undefined testFunctionDefinition(void)");
assertEquals(fdt.getPathName(), "/testFunctionDefinition");
}
@Test
public void testConstructor_WithFuncSig() {
FunctionDefinitionDataType impl;
FunctionDefinition fdt;
FunctionDefinitionDataType sig = new FunctionDefinitionDataType("testFunctionSig");
sig.setReturnType(DataType.VOID);
// sig
impl = new FunctionDefinitionDataType(sig);
assertEquals(impl.getName(), "testFunctionSig");
assertNull(impl.getComment());
assertTrue(impl.getReturnType().isEquivalent(DataType.VOID));
assertEquals(impl.getArguments().length, 0);
assertNull(impl.getDataTypeManager());
assertEquals("void testFunctionSig(void)", impl.getMnemonic(new SettingsImpl(impl, null)));
assertEquals(impl.getPathName(), "/testFunctionSig");
fdt = (FunctionDefinition) dtm.resolve(impl, null);
assertEquals(fdt.getName(), "testFunctionSig");
assertNull(fdt.getComment());
assertTrue(fdt.getReturnType().isEquivalent(DataType.VOID));
assertEquals(fdt.getArguments().length, 0);
String fdtCat = fdt.getCategoryPath().getPath();
String rootCat = CategoryPath.ROOT.getPath();
assertEquals(fdtCat, rootCat);
assertEquals(fdt.getDataTypeManager(), dtm);
assertEquals("void testFunctionSig(void)", fdt.getMnemonic(new SettingsImpl(impl, null)));
assertEquals(fdt.getPathName(), "/testFunctionSig");
}
@Test
public void testConstructor_WithDtmFuncSig() {
FunctionDefinitionDataType impl;
FunctionDefinition fdt;
FunctionDefinitionDataType sig = new FunctionDefinitionDataType("testFunctionSig");
sig.setReturnType(DataType.VOID);
// dtm, sig
impl = new FunctionDefinitionDataType(sig);
assertEquals(impl.getName(), "testFunctionSig");
assertNull(impl.getComment());
assertTrue(impl.getReturnType().isEquivalent(DataType.VOID));
assertEquals(impl.getArguments().length, 0);
assertEquals("void testFunctionSig(void)", impl.getMnemonic(new SettingsImpl(impl, null)));
assertEquals(impl.getPathName(), "/testFunctionSig");
fdt = (FunctionDefinition) dtm.resolve(impl, null);
assertEquals(fdt.getName(), "testFunctionSig");
assertNull(fdt.getComment());
assertTrue(fdt.getReturnType().isEquivalent(DataType.VOID));
assertEquals(fdt.getArguments().length, 0);
String fdtCat = fdt.getCategoryPath().getPath();
String rootCat = CategoryPath.ROOT.getPath();
assertEquals(fdtCat, rootCat);
assertEquals(fdt.getDataTypeManager(), dtm);
assertEquals("void testFunctionSig(void)", fdt.getMnemonic(new SettingsImpl(impl, null)));
assertEquals(fdt.getPathName(), "/testFunctionSig");
}
@Test
public void testConstructor_WithDtmNameFuncSig() {
FunctionDefinitionDataType impl;
FunctionDefinition fdt;
FunctionDefinitionDataType sig = new FunctionDefinitionDataType("testFunctionSig");
sig.setReturnType(DataType.VOID);
// dtm, name, sig
impl = new FunctionDefinitionDataType(CategoryPath.ROOT, "testDtmNameSig", sig);
assertEquals(impl.getName(), "testDtmNameSig");
assertNull(impl.getComment());
assertTrue(impl.getReturnType().isEquivalent(DataType.VOID));
assertEquals(impl.getArguments().length, 0);
assertEquals("void testDtmNameSig(void)", impl.getMnemonic(new SettingsImpl(impl, null)));
assertEquals(impl.getPathName(), "/testDtmNameSig");
fdt = (FunctionDefinition) dtm.resolve(impl, null);
assertEquals(fdt.getName(), "testDtmNameSig");
assertNull(fdt.getComment());
assertTrue(fdt.getReturnType().isEquivalent(DataType.VOID));
assertEquals(fdt.getArguments().length, 0);
String fdtCat = fdt.getCategoryPath().getPath();
String rootCat = CategoryPath.ROOT.getPath();
assertEquals(fdtCat, rootCat);
assertEquals(fdt.getDataTypeManager(), dtm);
assertEquals("void testDtmNameSig(void)", fdt.getMnemonic(new SettingsImpl(impl, null)));
assertEquals(fdt.getPathName(), "/testDtmNameSig");
}
@Test
public void testConstructor_WithFunctionDefDt() {
FunctionDefinitionDataType impl;
FunctionDefinition fdt;
FunctionDefinitionDataType sig = new FunctionDefinitionDataType("testFunctionSig");
sig.setReturnType(DataType.VOID);
FunctionDefinitionDataType functionDefDt = new FunctionDefinitionDataType(sig);
// functionDataTypeImpl
impl = new FunctionDefinitionDataType(functionDefDt);
assertEquals(impl.getName(), "testFunctionSig");
assertNull(impl.getComment());
assertTrue(impl.getReturnType().isEquivalent(DataType.VOID));
assertEquals(impl.getArguments().length, 0);
assertNull(null, impl.getDataTypeManager());
assertEquals("void testFunctionSig(void)", impl.getMnemonic(new SettingsImpl(impl, null)));
assertEquals(impl.getPathName(), "/testFunctionSig");
fdt = (FunctionDefinition) dtm.resolve(impl, null);
assertEquals(fdt.getName(), "testFunctionSig");
assertNull(fdt.getComment());
assertTrue(fdt.getReturnType().isEquivalent(DataType.VOID));
assertEquals(fdt.getArguments().length, 0);
String fdtCat = fdt.getCategoryPath().getPath();
String rootCat = CategoryPath.ROOT.getPath();
assertEquals(fdtCat, rootCat);
assertEquals(fdt.getDataTypeManager(), dtm);
assertEquals("void testFunctionSig(void)", fdt.getMnemonic(new SettingsImpl(impl, null)));
assertEquals(fdt.getPathName(), "/testFunctionSig");
}
@Test
public void testSetArguments() throws Exception {
ParameterDefinition[] parms = functionDt.getArguments();
assertEquals(0, parms.length);
addThreeArguments();
parms = functionDt.getArguments();
assertEquals(3, parms.length);
assertTrue(parms[0].getDataType().isEquivalent(new ByteDataType()));
assertTrue(parms[1].getDataType().isEquivalent(new FloatDataType()));
assertTrue(parms[2].getDataType().isEquivalent(new CharDataType()));
assertEquals(parms[0].getName(), "parm1");
assertEquals(parms[1].getName(), "parm2");
assertEquals(parms[2].getName(), "parm3");
assertEquals(parms[0].getComment(), "this is first parm.");
assertEquals(parms[1].getComment(), "this is second parm.");
assertEquals(parms[2].getComment(), "this is third parm.");
}
private void addThreeArguments() {
ParameterDefinition[] newParms = new ParameterDefinition[3];
newParms[0] =
new ParameterDefinitionImpl("parm1", new ByteDataType(), "this is first parm.");
newParms[1] =
new ParameterDefinitionImpl("parm2", new FloatDataType(), "this is second parm.");
newParms[2] =
new ParameterDefinitionImpl("parm3", new CharDataType(), "this is third parm.");
functionDt.setArguments(newParms);
}
@Test
public void testSetName() throws Exception {
functionDt.setName("printf");
assertEquals(functionDt.getName(), "printf");
}
@Test
public void testSetComment() throws Exception {
functionDt.setComment("My test comment.");
assertEquals(functionDt.getComment(), "My test comment.");
}
@Test
public void testSetReturnType() {
functionDt.setReturnType(new DWordDataType());
assertTrue(functionDt.getReturnType().isEquivalent(new DWordDataType()));
}
@Test
public void testConflictsWithSpecialName() {
String name = "operator[]";
// Create two function definition datatypes with the same name but different signature
FunctionDefinitionDataType impl1 = new FunctionDefinitionDataType(name);
impl1.setReturnType(IntegerDataType.dataType);
impl1.setArguments(new ParameterDefinition[] {
new ParameterDefinitionImpl("x", IntegerDataType.dataType, null) });
FunctionDefinitionDataType impl2 = new FunctionDefinitionDataType(name);
impl2.setReturnType(VoidDataType.dataType);
// Resolve the two function definitions. They should not be equal, and the second
// one should be a conflict
FunctionDefinition fd1 = (FunctionDefinition) dtm.resolve(impl1, null);
FunctionDefinition fd2 = (FunctionDefinition) dtm.resolve(impl2, null);
Assert.assertNotEquals(fd1, fd2);
assertTrue(fd2.getPrototypeString().contains(DataType.CONFLICT_SUFFIX));
// Resolve the second function definition again. It should not have created a new
// function definition.
FunctionDefinition fd3 = (FunctionDefinition) dtm.resolve(impl2, null);
assertEquals(fd2, fd3);
}
}

View file

@ -0,0 +1,969 @@
/* ###
* 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 ghidra.program.model.data;
import static org.junit.Assert.*;
import org.junit.*;
import generic.test.AbstractGTest;
/**
*
*/
public class StructureTest extends AbstractGTest {
private Structure struct;
/**
* @param arg0
*/
public StructureTest() {
super();
}
private Structure createStructure(String name, int length) {
return new StructureDataType(name, length);
}
private Union createUnion(String name) {
return new UnionDataType(name);
}
private TypeDef createTypeDef(DataType dataType) {
return new TypedefDataType(dataType.getName() + "TypeDef", dataType);
}
private Array createArray(DataType dataType, int numElements) {
return new ArrayDataType(dataType, numElements, dataType.getLength());
}
private Pointer createPointer(DataType dataType, int length) {
return new PointerDataType(dataType, length);
}
@Before
public void setUp() throws Exception {
struct = createStructure("TestStruct", 0);
struct.add(new ByteDataType(), "field1", "Comment1");
struct.add(new WordDataType(), null, "Comment2");
struct.add(new DWordDataType(), "field3", null);
struct.add(new ByteDataType(), "field4", "Comment4");
}
@Test
public void testAdd() throws Exception {
assertEquals(8, struct.getLength());
assertEquals(4, struct.getNumComponents());
DataTypeComponent dtc = struct.getComponent(0);
assertEquals(0, dtc.getOffset());
assertEquals(0, dtc.getOrdinal());
assertEquals("field1", dtc.getFieldName());
assertEquals("Comment1", dtc.getComment());
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(1);
assertEquals(1, dtc.getOffset());
assertEquals(1, dtc.getOrdinal());
assertEquals("field_0x1", dtc.getDefaultFieldName());
assertEquals(null, dtc.getFieldName());
assertEquals("Comment2", dtc.getComment());
assertEquals(WordDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(2);
assertEquals(3, dtc.getOffset());
assertEquals(2, dtc.getOrdinal());
assertEquals("field3", dtc.getFieldName());
assertEquals(null, dtc.getComment());
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(3);
assertEquals(7, dtc.getOffset());
assertEquals(3, dtc.getOrdinal());
assertEquals("field4", dtc.getFieldName());
assertEquals("Comment4", dtc.getComment());
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
}
@Test
public void testAdd2() throws Exception {
struct = createStructure("Test", 10);
assertEquals(10, struct.getLength());
assertEquals(10, struct.getNumComponents());
struct.add(new ByteDataType(), "field1", "Comment1");
struct.add(new WordDataType(), null, "Comment2");
struct.add(new DWordDataType(), "field3", null);
struct.add(new ByteDataType(), "field4", "Comment4");
assertEquals(18, struct.getLength());
assertEquals(14, struct.getNumComponents());
DataTypeComponent dtc = struct.getComponent(0);
assertEquals(0, dtc.getOffset());
assertEquals(0, dtc.getOrdinal());
assertEquals("field_0x0", dtc.getDefaultFieldName());
assertNull(dtc.getFieldName());
assertNull(dtc.getComment());
assertEquals(DataType.DEFAULT, dtc.getDataType());
dtc = struct.getComponent(1);
assertEquals(1, dtc.getOffset());
assertEquals(1, dtc.getOrdinal());
assertEquals("field_0x1", dtc.getDefaultFieldName());
assertNull(dtc.getFieldName());
assertEquals(null, dtc.getComment());
assertEquals(DataType.DEFAULT, dtc.getDataType());
dtc = struct.getComponent(10);
assertEquals(10, dtc.getOffset());
assertEquals(10, dtc.getOrdinal());
assertEquals("field1", dtc.getFieldName());
assertEquals("Comment1", dtc.getComment());
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(11);
assertEquals(11, dtc.getOffset());
assertEquals(11, dtc.getOrdinal());
assertEquals("field_0xb", dtc.getDefaultFieldName());
assertNull(dtc.getFieldName());
assertEquals("Comment2", dtc.getComment());
assertEquals(WordDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(12);
assertEquals(13, dtc.getOffset());
assertEquals(12, dtc.getOrdinal());
assertEquals("field3", dtc.getFieldName());
assertEquals(null, dtc.getComment());
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
}
@Test
public void testInsert_beginning() {
struct.insert(0, new FloatDataType());
assertEquals(12, struct.getLength());
assertEquals(5, struct.getNumComponents());
DataTypeComponent dtc = struct.getComponent(0);
assertEquals(0, dtc.getOffset());
assertEquals(0, dtc.getOrdinal());
assertEquals("field_0x0", dtc.getDefaultFieldName());
assertNull(dtc.getFieldName());
assertNull(dtc.getComment());
assertEquals(FloatDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(1);
assertEquals(4, dtc.getOffset());
assertEquals(1, dtc.getOrdinal());
assertEquals("field1", dtc.getFieldName());
assertEquals("Comment1", dtc.getComment());
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(2);
assertEquals(5, dtc.getOffset());
assertEquals(2, dtc.getOrdinal());
assertEquals("field_0x5", dtc.getDefaultFieldName());
assertNull(dtc.getFieldName());
assertEquals("Comment2", dtc.getComment());
assertEquals(WordDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(3);
assertEquals(7, dtc.getOffset());
assertEquals(3, dtc.getOrdinal());
assertEquals("field3", dtc.getFieldName());
assertEquals(null, dtc.getComment());
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(4);
assertEquals(11, dtc.getOffset());
assertEquals(4, dtc.getOrdinal());
assertEquals("field4", dtc.getFieldName());
assertEquals("Comment4", dtc.getComment());
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
}
@Test
public void testInsert_end() {
struct.insert(4, new FloatDataType());
assertEquals(12, struct.getLength());
assertEquals(5, struct.getNumComponents());
DataTypeComponent dtc = struct.getComponent(0);
assertEquals(0, dtc.getOffset());
assertEquals(0, dtc.getOrdinal());
assertEquals("field1", dtc.getFieldName());
assertEquals("Comment1", dtc.getComment());
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(1);
assertEquals(1, dtc.getOffset());
assertEquals(1, dtc.getOrdinal());
assertEquals("field_0x1", dtc.getDefaultFieldName());
assertNull(dtc.getFieldName());
assertEquals("Comment2", dtc.getComment());
assertEquals(WordDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(2);
assertEquals(3, dtc.getOffset());
assertEquals(2, dtc.getOrdinal());
assertEquals("field3", dtc.getFieldName());
assertEquals(null, dtc.getComment());
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(3);
assertEquals(7, dtc.getOffset());
assertEquals(3, dtc.getOrdinal());
assertEquals("field4", dtc.getFieldName());
assertEquals("Comment4", dtc.getComment());
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(4);
assertEquals(8, dtc.getOffset());
assertEquals(4, dtc.getOrdinal());
assertEquals("field_0x8", dtc.getDefaultFieldName());
assertNull(dtc.getFieldName());
assertEquals(null, dtc.getComment());
assertEquals(FloatDataType.class, dtc.getDataType().getClass());
}
@Test
public void testInsert_middle() {
struct.insert(2, new FloatDataType());
assertEquals(12, struct.getLength());
assertEquals(5, struct.getNumComponents());
DataTypeComponent dtc = struct.getComponent(0);
assertEquals(0, dtc.getOffset());
assertEquals(0, dtc.getOrdinal());
assertEquals("field1", dtc.getFieldName());
assertEquals("Comment1", dtc.getComment());
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(1);
assertEquals(1, dtc.getOffset());
assertEquals(1, dtc.getOrdinal());
assertEquals("field_0x1", dtc.getDefaultFieldName());
assertNull(dtc.getFieldName());
assertEquals("Comment2", dtc.getComment());
assertEquals(WordDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(2);
assertEquals(3, dtc.getOffset());
assertEquals(2, dtc.getOrdinal());
assertEquals("field_0x3", dtc.getDefaultFieldName());
assertNull(dtc.getFieldName());
assertNull(dtc.getComment());
assertEquals(FloatDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(3);
assertEquals(7, dtc.getOffset());
assertEquals(3, dtc.getOrdinal());
assertEquals("field3", dtc.getFieldName());
assertEquals(null, dtc.getComment());
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(4);
assertEquals(11, dtc.getOffset());
assertEquals(4, dtc.getOrdinal());
assertEquals("field4", dtc.getFieldName());
assertEquals("Comment4", dtc.getComment());
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
}
@Test
public void testInsertWithEmptySpace() {
struct = createStructure("Test", 100);
struct.insert(40, new ByteDataType());
struct.insert(20, new WordDataType());
struct.insert(10, new FloatDataType());
assertEquals(107, struct.getLength());
assertEquals(103, struct.getNumComponents());
DataTypeComponent[] comps = struct.getDefinedComponents();
assertEquals(3, comps.length);
assertEquals(10, comps[0].getOffset());
assertEquals(10, comps[0].getOrdinal());
assertEquals(FloatDataType.class, comps[0].getDataType().getClass());
assertEquals(24, comps[1].getOffset());
assertEquals(21, comps[1].getOrdinal());
assertEquals(WordDataType.class, comps[1].getDataType().getClass());
assertEquals(46, comps[2].getOffset());
assertEquals(42, comps[2].getOrdinal());
assertEquals(ByteDataType.class, comps[2].getDataType().getClass());
}
// test inserting at offset 0
@Test
public void testInsertAtOffset() {
struct.insertAtOffset(0, new FloatDataType(), 4);
assertEquals(12, struct.getLength());
DataTypeComponent[] comps = struct.getDefinedComponents();
assertEquals(5, comps.length);
assertEquals(0, comps[0].getOffset());
assertEquals(0, comps[0].getOrdinal());
assertEquals(FloatDataType.class, comps[0].getDataType().getClass());
assertEquals(4, comps[1].getOffset());
assertEquals(1, comps[1].getOrdinal());
assertEquals(ByteDataType.class, comps[1].getDataType().getClass());
assertEquals(5, comps[2].getOffset());
assertEquals(2, comps[2].getOrdinal());
assertEquals(WordDataType.class, comps[2].getDataType().getClass());
assertEquals(7, comps[3].getOffset());
assertEquals(3, comps[3].getOrdinal());
assertEquals(DWordDataType.class, comps[3].getDataType().getClass());
}
// test inserting at offset 1
@Test
public void testInsertAtOffset1() {
struct.insertAtOffset(1, new FloatDataType(), 4);
assertEquals(12, struct.getLength());
DataTypeComponent[] comps = struct.getDefinedComponents();
assertEquals(5, comps.length);
assertEquals(0, comps[0].getOffset());
assertEquals(0, comps[0].getOrdinal());
assertEquals(ByteDataType.class, comps[0].getDataType().getClass());
assertEquals(1, comps[1].getOffset());
assertEquals(1, comps[1].getOrdinal());
assertEquals(FloatDataType.class, comps[1].getDataType().getClass());
assertEquals(5, comps[2].getOffset());
assertEquals(2, comps[2].getOrdinal());
assertEquals(WordDataType.class, comps[2].getDataType().getClass());
assertEquals(7, comps[3].getOffset());
assertEquals(3, comps[3].getOrdinal());
assertEquals(DWordDataType.class, comps[3].getDataType().getClass());
}
// test inserting at offset 1
@Test
public void testInsertAtOffset2() {
struct.insertAtOffset(2, new FloatDataType(), 4);
assertEquals(13, struct.getLength());
DataTypeComponent[] comps = struct.getDefinedComponents();
assertEquals(5, comps.length);
assertEquals(0, comps[0].getOffset());
assertEquals(0, comps[0].getOrdinal());
assertEquals(ByteDataType.class, comps[0].getDataType().getClass());
assertEquals(2, comps[1].getOffset());
assertEquals(2, comps[1].getOrdinal());
assertEquals(FloatDataType.class, comps[1].getDataType().getClass());
assertEquals(6, comps[2].getOffset());
assertEquals(3, comps[2].getOrdinal());
assertEquals(WordDataType.class, comps[2].getDataType().getClass());
assertEquals(8, comps[3].getOffset());
assertEquals(4, comps[3].getOrdinal());
assertEquals(DWordDataType.class, comps[3].getDataType().getClass());
}
@Test
public void testInsertAtOffsetPastEnd() {
struct.insertAtOffset(100, new FloatDataType(), 4);
assertEquals(104, struct.getLength());
}
@Test
public void testClearComponent() {
struct.clearComponent(0);
assertEquals(8, struct.getLength());
assertEquals(4, struct.getNumComponents());
DataTypeComponent dtc = struct.getComponent(0);
assertEquals(DataType.DEFAULT, dtc.getDataType());
dtc = struct.getComponent(1);
assertEquals(WordDataType.class, dtc.getDataType().getClass());
}
@Test
public void testClearComponent1() {
struct.clearComponent(1);
assertEquals(8, struct.getLength());
assertEquals(5, struct.getNumComponents());
DataTypeComponent dtc = struct.getComponent(1);
assertEquals(DataType.DEFAULT, dtc.getDataType());
dtc = struct.getComponent(2);
assertEquals(DataType.DEFAULT, dtc.getDataType());
dtc = struct.getComponent(0);
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
dtc = struct.getComponent(3);
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
assertEquals(3, dtc.getOrdinal());
assertEquals(3, dtc.getOffset());
}
@Test
public void testReplace() { // bigger, no space below
try {
struct.replace(0, new QWordDataType(), 8);
Assert.fail();
}
catch (Exception e) {
}
}
@Test
public void testReplace1() { // bigger, space below
struct.insert(1, new QWordDataType());
struct.clearComponent(1);
assertEquals(16, struct.getLength());
assertEquals(12, struct.getNumComponents());
struct.replace(0, new QWordDataType(), 8);
assertEquals(16, struct.getLength());
assertEquals(5, struct.getNumComponents());
DataTypeComponent[] comps = struct.getDefinedComponents();
assertEquals(9, comps[1].getOffset());
assertEquals(2, comps[1].getOrdinal());
}
@Test
public void testReplace2() { // same size
struct.replace(0, new CharDataType(), 1);
assertEquals(8, struct.getLength());
assertEquals(4, struct.getNumComponents());
DataTypeComponent[] comps = struct.getDefinedComponents();
assertEquals(CharDataType.class, comps[0].getDataType().getClass());
assertEquals(1, comps[1].getOffset());
assertEquals(1, comps[1].getOrdinal());
}
@Test
public void testReplace3() { // smaller
struct.replace(1, new CharDataType(), 1);
assertEquals(8, struct.getLength());
assertEquals(5, struct.getNumComponents());
DataTypeComponent[] comps = struct.getDefinedComponents();
assertEquals(CharDataType.class, comps[1].getDataType().getClass());
assertEquals(1, comps[1].getOffset());
assertEquals(1, comps[1].getOrdinal());
assertEquals(3, comps[2].getOffset());
assertEquals(3, comps[2].getOrdinal());
assertEquals(DWordDataType.class, comps[2].getDataType().getClass());
}
@Test
public void testDelete() {
struct.delete(1);
assertEquals(6, struct.getLength());
assertEquals(3, struct.getNumComponents());
DataTypeComponent[] comps = struct.getDefinedComponents();
assertEquals(DWordDataType.class, comps[1].getDataType().getClass());
assertEquals(1, comps[1].getOffset());
}
@Test
public void testDeleteAtOffset() {
struct.deleteAtOffset(2);
assertEquals(6, struct.getLength());
assertEquals(3, struct.getNumComponents());
DataTypeComponent[] comps = struct.getDefinedComponents();
assertEquals(DWordDataType.class, comps[1].getDataType().getClass());
assertEquals(1, comps[1].getOffset());
}
@Test
public void testDeleteAll() {
Structure s = new StructureDataType("test1", 0);
s.add(new ByteDataType());
s.add(new FloatDataType());
struct.add(s);
s.deleteAll();
assertEquals(1, s.getLength());
assertTrue(s.isNotYetDefined());
assertEquals(0, s.getNumComponents());
}
@Test
public void testGetComponents() {
struct = createStructure("Test", 8);
struct.insert(2, new ByteDataType(), 1, "field3", "Comment1");
struct.insert(5, new WordDataType(), 2, null, "Comment2");
struct.insert(7, new DWordDataType(), 4, "field8", null);
assertEquals(15, struct.getLength());
assertEquals(11, struct.getNumComponents());
DataTypeComponent[] dtcs = struct.getComponents();
assertEquals(11, dtcs.length);
int offset = 0;
for (int i = 0; i < 11; i++) {
assertEquals(i, dtcs[i].getOrdinal());
assertEquals(offset, dtcs[i].getOffset());
offset += dtcs[i].getLength();
}
assertEquals(DataType.DEFAULT, dtcs[0].getDataType());
assertEquals(DataType.DEFAULT, dtcs[1].getDataType());
assertEquals(ByteDataType.class, dtcs[2].getDataType().getClass());
assertEquals(DataType.DEFAULT, dtcs[3].getDataType());
assertEquals(DataType.DEFAULT, dtcs[4].getDataType());
assertEquals(WordDataType.class, dtcs[5].getDataType().getClass());
assertEquals(DataType.DEFAULT, dtcs[6].getDataType());
assertEquals(DWordDataType.class, dtcs[7].getDataType().getClass());
assertEquals(DataType.DEFAULT, dtcs[8].getDataType());
assertEquals(DataType.DEFAULT, dtcs[9].getDataType());
assertEquals(DataType.DEFAULT, dtcs[10].getDataType());
}
@Test
public void testGetDefinedComponents() {
struct = createStructure("Test", 8);
struct.insert(2, new ByteDataType(), 1, "field3", "Comment1");
struct.insert(5, new WordDataType(), 2, null, "Comment2");
struct.insert(7, new DWordDataType(), 4, "field8", null);
assertEquals(15, struct.getLength());
assertEquals(11, struct.getNumComponents());
DataTypeComponent[] dtcs = struct.getDefinedComponents();
assertEquals(3, dtcs.length);
assertEquals(ByteDataType.class, dtcs[0].getDataType().getClass());
assertEquals(2, dtcs[0].getOrdinal());
assertEquals(2, dtcs[0].getOffset());
assertEquals(WordDataType.class, dtcs[1].getDataType().getClass());
assertEquals(5, dtcs[1].getOrdinal());
assertEquals(5, dtcs[1].getOffset());
assertEquals(DWordDataType.class, dtcs[2].getDataType().getClass());
assertEquals(7, dtcs[2].getOrdinal());
assertEquals(8, dtcs[2].getOffset());
}
@Test
public void testGetComponentAt() {
DataTypeComponent dtc = struct.getComponentAt(4);
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
assertEquals(2, dtc.getOrdinal());
assertEquals(3, dtc.getOffset());
}
@Test
public void testGetDataTypeAt() {
Structure s1 = createStructure("Test1", 0);
s1.add(new WordDataType());
s1.add(struct);
s1.add(new ByteDataType());
DataTypeComponent dtc = s1.getComponentAt(7);
assertEquals(struct, dtc.getDataType());
dtc = s1.getDataTypeAt(7);
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
}
@Test
public void testReplaceWith() {
assertEquals(8, struct.getLength());
assertEquals(4, struct.getNumComponents());
Structure newStruct = createStructure("Replaced", 8);
newStruct.setDescription("testReplaceWith()");
DataTypeComponent dtc0 = newStruct.insert(2, new ByteDataType(), 1, "field3", "Comment1");
DataTypeComponent dtc1 = newStruct.insert(5, new WordDataType(), 2, null, "Comment2");
DataTypeComponent dtc2 = newStruct.insert(7, new DWordDataType(), 4, "field8", null);
struct.replaceWith(newStruct);
assertEquals(15, struct.getLength());
assertEquals(11, struct.getNumComponents());
DataTypeComponent[] dtcs = struct.getDefinedComponents();
assertEquals(3, dtcs.length);
assertEquals(dtc0, dtcs[0]);
assertEquals(dtc1, dtcs[1]);
assertEquals(dtc2, dtcs[2]);
assertEquals("TestStruct", struct.getName());
assertEquals("", struct.getDescription());
}
/**
* Test that a structure can't ... ???
*/
@Test
public void testCyclingProblem() {
Structure newStruct = createStructure("TestStruct", 80);
newStruct.setDescription("testReplaceWith()");
newStruct.add(new ByteDataType(), "field0", "Comment1");
newStruct.add(struct, "field1", null);
newStruct.add(new WordDataType(), null, "Comment2");
newStruct.add(new DWordDataType(), "field3", null);
try {
struct.add(newStruct);
Assert.fail();
}
catch (IllegalArgumentException e) {
}
try {
struct.insert(0, newStruct);
Assert.fail();
}
catch (IllegalArgumentException e) {
}
try {
struct.replace(0, newStruct, newStruct.getLength());
Assert.fail();
}
catch (IllegalArgumentException e) {
}
}
/**
* Test that a structure can't be added to itself.
*/
@Test
public void testCyclicDependencyProblem1() {
try {
struct.add(struct);
Assert.fail("Shouldn't be able to add a structure to itself.");
}
catch (IllegalArgumentException e) {
// Should get an exception from adding the struct to itself.
}
try {
struct.insert(0, struct);
Assert.fail("Shouldn't be able to insert a structure into itself.");
}
catch (IllegalArgumentException e) {
// Should get an exception from inserting the struct to itself.
}
try {
struct.replace(0, struct, struct.getLength());
Assert.fail(
"Shouldn't be able to replace a structure component with the structure itself.");
}
catch (IllegalArgumentException e) {
// Should get an exception from replacing the struct to itself.
}
}
/**
* Test that a structure array can't be added to the same structure.
*/
@Test
public void testCyclicDependencyProblem2() {
Array array = createArray(struct, 3);
try {
struct.add(array);
Assert.fail("Shouldn't be able to add a structure array to the same structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from adding the struct to itself.
}
try {
struct.insert(0, array);
Assert.fail("Shouldn't be able to insert a structure array into the same structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from inserting the struct to itself.
}
try {
struct.replace(0, array, array.getLength());
Assert.fail(
"Shouldn't be able to replace a structure component with an array of the same structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from replacing the struct to itself.
}
}
/**
* Test that a typedef of a structure can't be added to the structure.
*/
@Test
public void testCyclicDependencyProblem3() {
TypeDef typeDef = createTypeDef(struct);
try {
struct.add(typeDef);
Assert.fail("Shouldn't be able to add a structure typedef to the typedef's structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from adding the struct to itself.
}
try {
struct.insert(0, typeDef);
Assert.fail(
"Shouldn't be able to insert a structure typedef into the typedef's structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from inserting the struct to itself.
}
try {
struct.replace(0, typeDef, typeDef.getLength());
Assert.fail(
"Shouldn't be able to replace a structure component with the structure's typedef.");
}
catch (IllegalArgumentException e) {
// Should get an exception from replacing the struct to itself.
}
}
/**
* Test that a structure can't contain another structure that contains it.
*/
@Test
public void testCyclicDependencyProblem4() {
Structure anotherStruct = createStructure("AnotherStruct", 0);
anotherStruct.add(struct);
try {
struct.add(anotherStruct);
Assert.fail(
"Shouldn't be able to add another structure, which contains this structure, to this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from adding the struct to itself.
}
try {
struct.insert(0, anotherStruct);
Assert.fail(
"Shouldn't be able to insert another structure, which contains this structure, to this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from inserting the struct to itself.
}
try {
struct.replace(0, anotherStruct, anotherStruct.getLength());
Assert.fail(
"Shouldn't be able to replace a structure component with another structure which contains this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from replacing the struct to itself.
}
}
/**
* Test that a structure can't contain another structure that contains a typedef to it.
*/
@Test
public void testCyclicDependencyProblem5() {
Structure anotherStruct = createStructure("AnotherStruct", 0);
TypeDef typeDef = createTypeDef(struct);
anotherStruct.add(typeDef);
try {
struct.add(anotherStruct);
Assert.fail(
"Shouldn't be able to add another structure, which contains a typedef of this structure, to this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from adding the struct to itself.
}
try {
struct.insert(0, anotherStruct);
Assert.fail(
"Shouldn't be able to insert another structure, which contains a typedef of this structure, to this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from inserting the struct to itself.
}
try {
struct.replace(0, anotherStruct, anotherStruct.getLength());
Assert.fail(
"Shouldn't be able to replace a structure component with another structure which contains a typedef of this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from replacing the struct to itself.
}
}
/**
* Test that a structure can't contain a union that contains that structure.
*/
@Test
public void testCyclicDependencyProblem6() {
Union union = createUnion("TestUnion");
union.add(struct);
try {
struct.add(union);
Assert.fail(
"Shouldn't be able to add a union, which contains this structure, to this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from adding the struct to itself.
}
try {
struct.insert(0, union);
Assert.fail(
"Shouldn't be able to insert a union, which contains this structure, to this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from inserting the struct to itself.
}
try {
struct.replace(0, union, union.getLength());
Assert.fail(
"Shouldn't be able to replace a structure component with a union, which contains this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from replacing the struct to itself.
}
}
/**
* Test that a structure can't contain a typedef of a union that contains that structure.
*/
@Test
public void testCyclicDependencyProblem7() {
Union union = createUnion("TestUnion");
union.add(struct);
TypeDef typeDef = createTypeDef(union);
try {
struct.add(typeDef);
Assert.fail(
"Shouldn't be able to add a typedef of a union, which contains this structure, to this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from adding the union typedef to the struct.
}
try {
struct.insert(0, typeDef);
Assert.fail(
"Shouldn't be able to insert a typedef of a union, which contains this structure, to this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from inserting the union typedef to the struct.
}
try {
struct.replace(0, typeDef, typeDef.getLength());
Assert.fail(
"Shouldn't be able to replace a structure component with a typedef of a union, which contains this structure.");
}
catch (IllegalArgumentException e) {
// Should get an exception from replacing the struct component with the union typedef.
}
}
/**
* Test that a structure can contain a pointer in it to the same structure.
*/
@Test
public void testNoCyclicDependencyProblemForStructurePointer() {
Pointer structurePointer = createPointer(struct, 4);
try {
struct.add(structurePointer);
}
catch (IllegalArgumentException e) {
Assert.fail("Should be able to add a structure pointer to the pointer's structure.");
}
try {
struct.insert(0, structurePointer);
}
catch (IllegalArgumentException e) {
Assert.fail(
"Should be able to insert a structure pointer into the pointer's structure.");
}
try {
struct.replace(0, structurePointer, structurePointer.getLength());
}
catch (IllegalArgumentException e) {
Assert.fail(
"Should be able to replace a structure component with the structure's pointer.");
}
}
/**
* Test that a structure can contain a pointer in it to a typedef of the same structure.
*/
@Test
public void testNoCyclicDependencyProblemForTypedefPointer() {
TypeDef typeDef = createTypeDef(struct);
Pointer typedefPointer = createPointer(typeDef, 4);
try {
struct.add(typedefPointer);
}
catch (IllegalArgumentException e) {
Assert.fail(
"Should be able to add a structure typedef pointer to the pointer's structure.");
}
try {
struct.insert(0, typedefPointer);
}
catch (IllegalArgumentException e) {
Assert.fail(
"Should be able to insert a structure typedef pointer into the pointer's structure.");
}
try {
struct.replace(0, typedefPointer, typedefPointer.getLength());
}
catch (IllegalArgumentException e) {
Assert.fail(
"Should be able to replace a structure component with the structure's typedef pointer.");
}
}
/**
* Test that a structure can contain a pointer in it to a typedef of the same structure.
*/
@Test
public void testNoCyclicDependencyProblemForArrayPointer() {
TypeDef typeDef = createTypeDef(struct);
Array array = createArray(typeDef, 5);
Pointer arrayPointer = createPointer(array, 4);
try {
struct.add(arrayPointer);
}
catch (IllegalArgumentException e) {
Assert.fail(
"Should be able to add a structure typedef array pointer to the pointer's structure.");
}
try {
struct.insert(0, arrayPointer);
}
catch (IllegalArgumentException e) {
Assert.fail(
"Should be able to insert a structure typedef arrayointer into the pointer's structure.");
}
try {
struct.replace(0, arrayPointer, arrayPointer.getLength());
}
catch (IllegalArgumentException e) {
Assert.fail(
"Should be able to replace a structure component with the structure's typedef array pointer.");
}
}
}

View file

@ -0,0 +1,448 @@
/* ###
* 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 ghidra.program.model.data;
import static org.junit.Assert.*;
import org.junit.*;
import generic.test.AbstractGenericTest;
/**
*
*/
public class UnionTest extends AbstractGenericTest {
private DataTypeManager dtm;
private Union union;
private int id;
private Union createUnion(String name) {
Union unionDt = new UnionDataType(name);
return (Union)dtm.addDataType(unionDt,DataTypeConflictHandler.DEFAULT_HANDLER);
}
private Structure createStructure(String name, int size) {
return (Structure)dtm.addDataType(new StructureDataType(name, size),DataTypeConflictHandler.DEFAULT_HANDLER);
}
private TypeDef createTypeDef(DataType dataType) {
return new TypedefDataType(dataType.getName()+"TypeDef", dataType);
}
private Array createArray(DataType dataType, int numElements) {
return new ArrayDataType(dataType, numElements, dataType.getLength());
}
private Pointer createPointer(DataType dataType, int length) {
return new PointerDataType(dataType, length);
}
/**
* Constructor for UnionTest.
* @param arg0
*/
public UnionTest() {
super();
}
/*
* @see TestCase#setUp()
*/
@Before
public void setUp() throws Exception {
dtm = new StandAloneDataTypeManager("dummyDTM");
id = dtm.startTransaction("");
union = createUnion("TestUnion");
union.add(new ByteDataType(), "field1", "Comment1");
union.add(new WordDataType(), null, "Comment2");
union.add(new DWordDataType(), "field3", null);
union.add(new ByteDataType(), "field4", "Comment4");
}
/*
* @see TestCase#tearDown()
*/
@After
public void tearDown() throws Exception {
dtm.endTransaction(id, true);
dtm.close();
}
@Test
public void testAdd() throws Exception {
assertEquals(4, union.getLength());
assertEquals(4, union.getNumComponents());
DataTypeComponent[] dtcs = union.getComponents();
assertEquals(4, dtcs.length);
DataTypeComponent dtc = union.getComponent(3);
assertEquals("field4", dtc.getFieldName());
assertEquals("byte", dtc.getDataType().getName());
Structure struct = new StructureDataType("struct_1", 0);
struct.add(new ByteDataType());
struct.add(new StringDataType(), 10);
union.add(struct);
assertEquals(struct.getLength(), union.getLength());
}
@Test
public void testAdd2() {
Structure struct = createStructure("struct_1", 0);
struct.add(new ByteDataType());
struct.add(new StringDataType(), 10);
union.add(struct);
union.delete(4);
assertEquals(4, union.getNumComponents());
assertEquals(4, union.getLength());
}
@Test
public void testGetComponent() {
Structure struct = createStructure("struct_1", 0);
struct.add(new ByteDataType());
struct.add(new StringDataType(), 10);
DataTypeComponent newdtc = union.add(struct, "field5", "comments");
DataTypeComponent dtc = union.getComponent(4);
assertEquals(newdtc, dtc);
assertEquals("field5", dtc.getFieldName());
assertEquals("comments", dtc.getComment());
}
@Test
public void testGetComponents() {
Structure struct = createStructure("struct_1", 0);
struct.add(new ByteDataType());
struct.add(new StringDataType(), 10);
union.add(struct, "field5", "comments");
DataTypeComponent[] dtcs = union.getComponents();
assertEquals(5, dtcs.length);
assertEquals(5, union.getNumComponents());
}
@Test
public void testInsert() {
Structure struct = createStructure("struct_1", 0);
struct.add(new ByteDataType());
struct.add(new StringDataType(), 10);
DataTypeComponent dtc = union.getComponent(2);
assertEquals("field3", dtc.getFieldName());
union.insert(2, struct, struct.getLength(), "field5", "field5 comments");
assertEquals(11, union.getLength());
dtc = union.getComponent(2);
assertEquals("field5", dtc.getFieldName());
}
@Test
public void testGetName() {
assertEquals("TestUnion", union.getName());
}
@Test
public void testCloneRetainIdentity() throws Exception {
Union unionCopy = (Union)union.clone(null);
assertNull(unionCopy.getDataTypeManager());
assertEquals(4, union.getLength());
}
@Test
public void testCopyDontRetain() throws Exception {
Union unionCopy = (Union)union.copy(null);
assertNull(unionCopy.getDataTypeManager());
assertEquals(4, union.getLength());
}
@Test
public void testDelete() throws Exception {
Structure struct = createStructure("struct_1", 0);
struct.add(new ByteDataType());
struct.add(new StringDataType(), 10);
union.add(struct);
assertEquals(11, union.getLength());
union.delete(4);
assertEquals(4, union.getLength());
union.delete(2);
assertEquals(2, union.getLength());
}
@Test
public void testIsPartOf() {
Structure struct = createStructure("struct_1", 0);
struct.add(new ByteDataType());
DataTypeComponent dtc = struct.add(createStructure("mystring", 10));
DataType dt = dtc.getDataType();
DataTypeComponent newdtc = union.add(struct);
assertTrue(union.isPartOf(dt));
Structure newstruct = (Structure)newdtc.getDataType();
Structure s1 = (Structure)newstruct.add(createStructure("s1", 1)).getDataType();
dt = s1.add(new QWordDataType()).getDataType();
assertTrue(union.isPartOf(dt));
}
@Test
public void testReplaceWith() {
assertEquals(4, union.getLength());
assertEquals(4, union.getNumComponents());
Union newUnion = createUnion("Replaced");
newUnion.setDescription("testReplaceWith()");
DataTypeComponent dtc2 = newUnion.insert(0, new DWordDataType(), 4, "field2", null);
DataTypeComponent dtc1 = newUnion.insert(0, new WordDataType(), 2, null, "Comment2");
DataTypeComponent dtc0 = newUnion.insert(0, new ByteDataType(), 1, "field0", "Comment1");
union.replaceWith(newUnion);
assertEquals(4, union.getLength());
assertEquals(3, union.getNumComponents());
DataTypeComponent[] dtcs = union.getComponents();
assertEquals(3, dtcs.length);
assertEquals(dtc0, dtcs[0]);
assertEquals(dtc1, dtcs[1]);
assertEquals(dtc2, dtcs[2]);
assertEquals("TestUnion", union.getName());
assertEquals("testReplaceWith()", union.getDescription());
}
@Test
public void testCyclingProblem() {
Union newUnion = createUnion("Test");
newUnion.setDescription("testReplaceWith()");
newUnion.add(new ByteDataType(), "field0", "Comment1");
newUnion.add(union, "field1", null);
newUnion.add(new WordDataType(), null, "Comment2");
newUnion.add(new DWordDataType(), "field3", null);
try {
union.add(newUnion);
Assert.fail();
} catch (IllegalArgumentException e) {
}
try {
union.insert(0, newUnion);
Assert.fail();
} catch (IllegalArgumentException e) {
}
}
/**
* Test that a structure can't be added to itself.
*/
@Test
public void testCyclicDependencyProblem1() {
try {
union.add(union);
Assert.fail("Shouldn't be able to add a union to itself.");
} catch (IllegalArgumentException e) {
// Should get an exception from adding the union to itself.
}
try {
union.insert(0, union);
Assert.fail("Shouldn't be able to insert a union into itself.");
} catch (IllegalArgumentException e) {
// Should get an exception from inserting the union to itself.
}
}
/**
* Test that a structure array can't be added to the same structure.
*/
@Test
public void testCyclicDependencyProblem2() {
Array array = createArray(union, 3);
try {
union.add(array);
Assert.fail("Shouldn't be able to add a union array to the same union.");
} catch (IllegalArgumentException e) {
// Should get an exception from adding the union to itself.
}
try {
union.insert(0, array);
Assert.fail("Shouldn't be able to insert a union array into the same union.");
} catch (IllegalArgumentException e) {
// Should get an exception from inserting the union to itself.
}
}
/**
* Test that a typedef of a union can't be added to the union.
*/
@Test
public void testCyclicDependencyProblem3() {
TypeDef typeDef = createTypeDef(union);
try {
union.add(typeDef);
Assert.fail("Shouldn't be able to add a union typedef to the typedef's union.");
} catch (IllegalArgumentException e) {
// Should get an exception from adding the union to itself.
}
try {
union.insert(0, typeDef);
Assert.fail("Shouldn't be able to insert a union typedef into the typedef's union.");
} catch (IllegalArgumentException e) {
// Should get an exception from inserting the union to itself.
}
}
/**
* Test that a union can't contain another union that contains it.
*/
@Test
public void testCyclicDependencyProblem4() {
Union anotherUnion = createUnion("AnotherUnion");
anotherUnion.add(union);
try {
union.add(anotherUnion);
Assert.fail("Shouldn't be able to add another union, which contains this union, to this union.");
} catch (IllegalArgumentException e) {
// Should get an exception from adding the union to itself.
}
try {
union.insert(0, anotherUnion);
Assert.fail("Shouldn't be able to insert another union, which contains this union, to this union.");
} catch (IllegalArgumentException e) {
// Should get an exception from inserting the union to itself.
}
}
/**
* Test that a union can't contain another union that contains a typedef to it.
*/
@Test
public void testCyclicDependencyProblem5() {
Union anotherUnion = createUnion("AnotherUnion");
TypeDef typeDef = createTypeDef(union);
anotherUnion.add(typeDef);
try {
union.add(anotherUnion);
Assert.fail("Shouldn't be able to add another union, which contains a typedef of this union, to this union.");
} catch (IllegalArgumentException e) {
// Should get an exception from adding the union to itself.
}
try {
union.insert(0, anotherUnion);
Assert.fail("Shouldn't be able to insert another union, which contains a typedef of this union, to this union.");
} catch (IllegalArgumentException e) {
// Should get an exception from inserting the union to itself.
}
}
/**
* Test that a union can't contain a structure that contains that union.
*/
@Test
public void testCyclicDependencyProblem6() {
Union structure = createUnion("TestStructure");
structure.add(union);
try {
union.add(structure);
Assert.fail("Shouldn't be able to add a structure, which contains this union, to this union.");
} catch (IllegalArgumentException e) {
// Should get an exception from adding the union to itself.
}
try {
union.insert(0, structure);
Assert.fail("Shouldn't be able to insert a structure, which contains this union, to this union.");
} catch (IllegalArgumentException e) {
// Should get an exception from inserting the union to itself.
}
}
/**
* Test that a structure can't contain a typedef of a union that contains that structure.
*/
@Test
public void testCyclicDependencyProblem7() {
Structure structure = createStructure("TestStructure", 0);
structure.add(union);
TypeDef typeDef = createTypeDef(structure);
try {
union.add(typeDef);
Assert.fail("Shouldn't be able to add a typedef of a strucutre, which contains this union, to this union.");
} catch (IllegalArgumentException e) {
// Should get an exception from adding the structure typedef to the union.
}
try {
union.insert(0, typeDef);
Assert.fail("Shouldn't be able to insert a typedef of a structure, which contains this union, to this union.");
} catch (IllegalArgumentException e) {
// Should get an exception from inserting the structure typedef to the union.
}
}
/**
* Test that a structure can contain a pointer in it to the same structure.
*/
@Test
public void testNoCyclicDependencyProblemForStructurePointer() {
Pointer unionPointer = createPointer(union, 4);
try {
union.add(unionPointer);
} catch (IllegalArgumentException e) {
Assert.fail("Should be able to add a union pointer to the pointer's union.");
}
try {
union.insert(0, unionPointer);
} catch (IllegalArgumentException e) {
Assert.fail("Should be able to insert a union pointer into the pointer's union.");
}
}
/**
* Test that a union can contain a pointer in it to a typedef of the same union.
*/
@Test
public void testNoCyclicDependencyProblemForTypedefPointer() {
TypeDef typeDef = createTypeDef(union);
Pointer typedefPointer = createPointer(typeDef, 4);
try {
union.add(typedefPointer);
} catch (IllegalArgumentException e) {
Assert.fail("Should be able to add a union typedef pointer to the pointer's union.");
}
try {
union.insert(0, typedefPointer);
} catch (IllegalArgumentException e) {
Assert.fail("Should be able to insert a union typedef pointer into the pointer's union.");
}
}
/**
* Test that a union can contain a pointer in it to a typedef of the same union.
*/
@Test
public void testNoCyclicDependencyProblemForArrayPointer() {
TypeDef typeDef = createTypeDef(union);
Array array = createArray(typeDef, 5);
Pointer arrayPointer = createPointer(array, 4);
try {
union.add(arrayPointer);
} catch (IllegalArgumentException e) {
Assert.fail("Should be able to add a union typedef array pointer to the pointer's union.");
}
try {
union.insert(0, arrayPointer);
} catch (IllegalArgumentException e) {
Assert.fail("Should be able to insert a union typedef array pointer into the pointer's union.");
}
}
}

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %c{1}: %m%n"/>
</layout>
</appender>
<logger name="ghidra.sleigh.grammar.SleighPreprocessor">
<level value="DEBUG"/>
</logger>
<logger name="slgh_compile.SleighCompile">
<level value="DEBUG"/>
</logger>
<root>
<priority value="TRACE"/>
<appender-ref ref="console"/>
</root>
</log4j:configuration>