diff --git a/Ghidra/Features/Base/developer_scripts/BuildResultState.java b/Ghidra/Features/Base/developer_scripts/BuildResultState.java index 2671176d09..ecd3aa0367 100644 --- a/Ghidra/Features/Base/developer_scripts/BuildResultState.java +++ b/Ghidra/Features/Base/developer_scripts/BuildResultState.java @@ -219,8 +219,7 @@ public class BuildResultState extends GhidraScript { // } // } // - Register[] regs = currentProgram.getLanguage().getRegisters(); - List registers = Arrays.asList(regs); + List registers = currentProgram.getLanguage().getRegisters(); try { Register reg = askChoice("Results Query", "Select Register:", registers, null); while (reg != null) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CallDepthChangeInfo.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CallDepthChangeInfo.java index 979d9142f6..2097ce1bf8 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CallDepthChangeInfo.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CallDepthChangeInfo.java @@ -31,7 +31,6 @@ import ghidra.program.util.SymbolicPropogator.Value; import ghidra.util.Msg; import ghidra.util.exception.*; import ghidra.util.task.TaskMonitor; -import ghidra.util.task.TaskMonitorAdapter; /** * CallDepthChangeInfo.java @@ -89,7 +88,7 @@ public class CallDepthChangeInfo { this.program = func.getProgram(); frameReg = program.getCompilerSpec().getStackPointer(); try { - initialize(func, func.getBody(), frameReg, TaskMonitorAdapter.DUMMY_MONITOR); + initialize(func, func.getBody(), frameReg, TaskMonitor.DUMMY); } catch (CancelledException e) { throw new RuntimeException("Unexpected Exception", e); @@ -532,7 +531,7 @@ public class CallDepthChangeInfo { st.push(func.getEntryPoint()); st.push(new Integer(0)); st.push(Boolean.TRUE); - ProcessorContextImpl procContext = new ProcessorContextImpl(trans.getRegisters()); + ProcessorContextImpl procContext = new ProcessorContextImpl(program.getLanguage()); AddressSet undone = new AddressSet(func.getBody()); AddressSet badStackSet = new AddressSet(undone); @@ -903,9 +902,9 @@ public class CallDepthChangeInfo { Stack st = new Stack(); st.push(func.getEntryPoint()); - st.push(new Integer(0)); + st.push(Integer.valueOf(0)); st.push(Boolean.TRUE); - ProcessorContextImpl procContext = new ProcessorContextImpl(trans.getRegisters()); + ProcessorContextImpl procContext = new ProcessorContextImpl(program.getLanguage()); AddressSet undone = new AddressSet(func.getBody()); AddressSet badStackSet = new AddressSet(undone); @@ -955,7 +954,7 @@ public class CallDepthChangeInfo { Address[] flows = instr.getFlows(); for (Address flow2 : flows) { st.push(flow2); - st.push(new Integer(stackPointerDepth)); + st.push(Integer.valueOf(stackPointerDepth)); st.push(stackOK); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/ProgramContextMergeManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/ProgramContextMergeManager.java index bc096a3230..49ea0068d8 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/ProgramContextMergeManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/ProgramContextMergeManager.java @@ -1,6 +1,5 @@ /* ### * 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. @@ -16,6 +15,8 @@ */ package ghidra.app.merge.listing; +import java.util.*; + import ghidra.app.merge.MergeResolver; import ghidra.app.merge.ProgramMultiUserMergeManager; import ghidra.app.merge.tool.ListingMergePanel; @@ -27,9 +28,6 @@ import ghidra.util.Msg; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -import java.util.Arrays; -import java.util.Comparator; - /** * ProgramContextMergeManager merges register value changes * for multi-user program versions. It merges changes for each named register @@ -70,7 +68,7 @@ public class ProgramContextMergeManager implements MergeResolver, ListingMergeCo ProgramContext latestContext; ProgramContext myContext; ProgramContext resultContext; - Register[] registers; + List registers; /** Used to determine differences between the original program and latest program. */ ProgramDiff diffOriginalLatest; @@ -187,21 +185,19 @@ public class ProgramContextMergeManager implements MergeResolver, ListingMergeCo mergePanel.setTopComponent(conflictInfoPanel); } try { - String[] latestNames = latestContext.getRegisterNames(); - String[] myNames = myContext.getRegisterNames(); - Arrays.sort(latestNames); - Arrays.sort(myNames); - if (!Arrays.equals(latestNames, myNames)) { + List latestNames = latestContext.getRegisterNames(); + List myNames = myContext.getRegisterNames(); + if (!latestNames.equals(myNames)) { mergeManager.setStatusText("Program Context Registers don't match between the programs."); cancel(); return; } - Register[] regs = latestContext.getRegisters(); + ArrayList regs = new ArrayList<>(latestContext.getRegisters()); // Sort the registers by size so that largest come first. // This prevents the remove call below from incorrectly clearing // smaller registers that are part of a larger register. - Arrays.sort(regs, new Comparator() { + Collections.sort(regs, new Comparator() { @Override public int compare(Register r1, Register r2) { return r2.getBitLength() - r1.getBitLength(); @@ -211,15 +207,16 @@ public class ProgramContextMergeManager implements MergeResolver, ListingMergeCo int transactionID = resultPgm.startTransaction(getDescription()); boolean commit = false; try { - int numRegs = regs.length; + int numRegs = regs.size(); monitor.initialize(numRegs); // Get the conflicts for each register for (int i = 0; i < numRegs; i++) { - if (regs[i].isProcessorContext()) { + Register reg = regs.get(i); + if (reg.isProcessorContext()) { continue; // context register handle by code unit merge } - String regName = regs[i].getName(); + String regName = reg.getName(); int currentProgressPercentage = (int) (((float) 100 / numRegs) * i); mergeManager.updateProgress(currentProgressPercentage, "Merging register values for " + regName); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/ProcessorStateDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/ProcessorStateDialog.java index c159112dff..e49effacf2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/ProcessorStateDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/ProcessorStateDialog.java @@ -47,9 +47,9 @@ public class ProcessorStateDialog extends DialogComponentProvider { public ProcessorStateDialog(ProgramContext programContext) { super(TITLE, true, false, true, false); this.programContext = programContext; - Register[] contextRegisters = programContext.getProcessorStateRegisters(); + registerList = new ArrayList<>(); - for (Register register : contextRegisters) { + for (Register register : programContext.getContextRegisters()) { if (!register.isBaseRegister()) { registerList.add(register); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/VarnodeLocationCellEditor.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/VarnodeLocationCellEditor.java index 2e6bb3d6df..03947c930c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/VarnodeLocationCellEditor.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/VarnodeLocationCellEditor.java @@ -172,8 +172,8 @@ class VarnodeLocationCellEditor extends AbstractCellEditor implements TableCellE private Component createRegisterCombo(VarnodeInfo varnode) { ProgramContext programContext = program.getProgramContext(); - Register[] contextRegisters = programContext.getRegisters(); - List validItems = new ArrayList<>(Arrays.asList(contextRegisters)); + + List validItems = new ArrayList<>(programContext.getRegisters()); for (Iterator iter = validItems.iterator(); iter.hasNext();) { Register register = iter.next(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/RegisterFieldFactory.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/RegisterFieldFactory.java index 6ebffd1377..6ae3f2f80c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/RegisterFieldFactory.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/RegisterFieldFactory.java @@ -186,7 +186,7 @@ public class RegisterFieldFactory extends FieldFactory { private List getSetRegisters(Function function) { Program program = function.getProgram(); ProgramContext programContext = program.getProgramContext(); - Register[] registers = programContext.getRegisters(); + Register[] registers = programContext.getRegistersWithValues(); Address address = function.getEntryPoint(); List setRegisters = new ArrayList<>(); for (Register register : registers) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/RegisterValuesXmlMgr.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/RegisterValuesXmlMgr.java index 7de94a0792..3633ccc3ab 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/RegisterValuesXmlMgr.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/RegisterValuesXmlMgr.java @@ -1,6 +1,5 @@ /* ### * 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. @@ -16,21 +15,23 @@ */ package ghidra.app.util.xml; -import ghidra.app.util.importer.*; -import ghidra.program.model.address.*; -import ghidra.program.model.lang.*; -import ghidra.program.model.listing.*; -import ghidra.util.*; -import ghidra.util.exception.*; -import ghidra.util.task.*; -import ghidra.util.xml.*; -import ghidra.xml.*; - -import java.io.*; -import java.math.*; +import java.io.IOException; +import java.math.BigInteger; import java.util.*; -import org.xml.sax.*; +import org.xml.sax.SAXParseException; + +import ghidra.app.util.importer.MessageLog; +import ghidra.program.model.address.*; +import ghidra.program.model.lang.Register; +import ghidra.program.model.listing.Program; +import ghidra.program.model.listing.ProgramContext; +import ghidra.util.XmlProgramUtilities; +import ghidra.util.exception.CancelledException; +import ghidra.util.task.TaskMonitor; +import ghidra.util.xml.*; +import ghidra.xml.XmlElement; +import ghidra.xml.XmlPullParser; /** * XML manager for register values. @@ -87,10 +88,11 @@ class RegisterValuesXmlMgr { * Returns list of unique registers which do not overlap any smaller * registers. */ - private Register[] getUniqueRegisters() { + private List getUniqueRegisters() { - Register[] regs = context.getRegisters(); - Arrays.sort(regs, new Comparator() { + ArrayList regs = new ArrayList<>(context.getRegisters()); + Collections.sort(regs, new Comparator() { + @Override public int compare(Register r1, Register r2) { int size1 = r1.getMinimumByteSize(); int size2 = r2.getMinimumByteSize(); @@ -140,7 +142,7 @@ class RegisterValuesXmlMgr { writer.startElement("REGISTER_VALUES"); - Register[] regs = getUniqueRegisters(); + List regs = getUniqueRegisters(); //for (int i = 0; i < regs.length; i++) { //Register reg = regs[i]; @@ -156,8 +158,7 @@ class RegisterValuesXmlMgr { AddressRange range = rangeIter.next(); - for (int i = 0; i < regs.length; i++) { - Register reg = regs[i]; + for (Register reg : regs) { AddressRangeIterator it = context.getRegisterValueAddressRanges(reg, range.getMinAddress(), range.getMaxAddress()); while(it.hasNext()) { monitor.checkCanceled(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiff.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiff.java index 24f1ed4fd1..54d4d928db 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiff.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiff.java @@ -1156,13 +1156,8 @@ public class ProgramDiff { private AddressSet getProgramContextDifferences(AddressSetView addressSet, TaskMonitor monitor) throws ProgramConflictException, CancelledException { AddressSet differences = new AddressSet(); - ProgramContext pc1 = program1.getProgramContext(); - ProgramContext pc2 = program2.getProgramContext(); - String[] names1 = pc1.getRegisterNames(); - String[] names2 = pc2.getRegisterNames(); - Arrays.sort(names1); - Arrays.sort(names2); - if (!Arrays.equals(names1, names2)) { + + if (!ProgramMemoryComparator.sameProgramContextRegisterNames(program1, program2)) { throw new ProgramConflictException( "Program Context Registers don't match between the programs."); } @@ -1171,7 +1166,10 @@ public class ProgramDiff { AddressSet inCommon = pgmMemComp.getAddressesInCommon(); addressSet = (addressSet != null) ? inCommon.intersect(addressSet) : inCommon; - for (String element : names1) { + ProgramContext pc1 = program1.getProgramContext(); + ProgramContext pc2 = program2.getProgramContext(); + + for (String element : pc1.getRegisterNames()) { monitor.checkCanceled(); Register rb1 = pc1.getRegister(element); Register rb2 = pc2.getRegister(element); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiffDetails.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiffDetails.java index a19a196853..ed790f431d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiffDetails.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiffDetails.java @@ -383,9 +383,8 @@ public class ProgramDiffDetails { l1 = p1.getListing(); l2 = p2.getListing(); - Register[] descs1 = p1.getProgramContext().getRegisters(); maxRegisterName = "Register".length(); // default name length. - for (Register element : descs1) { + for (Register element : p1.getProgramContext().getRegisters()) { maxRegisterName = Math.max(maxRegisterName, element.getName().length()); } } @@ -1285,13 +1284,8 @@ public class ProgramDiffDetails { * @throws ConcurrentModificationException if analysis is modifying the program context. */ private void addProgramContextDetails() throws ConcurrentModificationException { - ProgramContext pc1 = p1.getProgramContext(); - ProgramContext pc2 = p2.getProgramContext(); - String[] names1 = pc1.getRegisterNames(); - String[] names2 = pc2.getRegisterNames(); - Arrays.sort(names1); - Arrays.sort(names2); - if (!Arrays.equals(names1, names2)) { + + if (!ProgramMemoryComparator.sameProgramContextRegisterNames(p1, p2)) { addDiffHeader("Program Context"); addText( indent1 + "Program Context Registers don't match between the programs." + newLine); @@ -1299,8 +1293,9 @@ public class ProgramDiffDetails { } // Check all the register's values and output any differences. - Register[] descs1 = pc1.getRegisters(); - for (Register reg1 : descs1) { + ProgramContext pc1 = p1.getProgramContext(); + ProgramContext pc2 = p2.getProgramContext(); + for (Register reg1 : pc1.getRegisters()) { addRegisterDiffDetails(pc1, pc2, reg1); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMemoryComparator.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMemoryComparator.java index 7437d64efb..7b252d1402 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMemoryComparator.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMemoryComparator.java @@ -15,12 +15,13 @@ */ package ghidra.program.util; +import java.util.Arrays; +import java.util.List; + import ghidra.program.model.address.*; import ghidra.program.model.listing.Program; import ghidra.program.model.listing.ProgramContext; -import java.util.Arrays; - /** * ProgramMemoryComparator is a class for comparing two programs and * determining the address differences between them. @@ -120,15 +121,17 @@ public class ProgramMemoryComparator { * @return true if the programs are alike (their language name or address spaces are the same). */ public static boolean similarPrograms(Program p1, Program p2) { - if (p1 == null || p2 == null) + if (p1 == null || p2 == null) { return false; + } if (p1.getLanguageID().equals(p2.getLanguageID())) { return true; } AddressSpace[] spaces1 = p1.getLanguage().getAddressFactory().getAddressSpaces(); AddressSpace[] spaces2 = p2.getLanguage().getAddressFactory().getAddressSpaces(); - if (spaces1.length != spaces2.length) + if (spaces1.length != spaces2.length) { return false; + } Arrays.sort(spaces1); Arrays.sort(spaces2); for (int i=0; i names1 = pc1.getRegisterNames(); + List names2 = pc2.getRegisterNames(); + return names1.equals(names2); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMerge.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMerge.java index fc7c1a24c5..b014b57d12 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMerge.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramMerge.java @@ -239,11 +239,11 @@ public class ProgramMerge implements PropertyVisitor { ProgramContext resultContext = resultProgram.getProgramContext(); ProgramContext originContext = originProgram.getProgramContext(); - Register[] originRegs = originContext.getRegisters(); + ArrayList originRegs = new ArrayList<>(originContext.getRegisters()); // Sort the registers by size so that largest come first. // This prevents the remove call below from incorrectly clearing // smaller registers that are part of a larger register. - Arrays.sort(originRegs, (r1, r2) -> r2.getBitLength() - r1.getBitLength()); + Collections.sort(originRegs, (r1, r2) -> r2.getBitLength() - r1.getBitLength()); AddressRangeIterator originRangeIter = originAddressSet.getAddressRanges(); while (originRangeIter.hasNext() && !monitor.isCancelled()) { AddressRange originRange = originRangeIter.next(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java index 2c141ea0d4..e88dfc8cdf 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java @@ -1389,7 +1389,7 @@ public class VarnodeContext implements ProcessorContext { } @Override - public Register[] getRegisters() { + public List getRegisters() { return offsetContext.getRegisters(); } diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/util/viewer/field/RegisterFieldFactoryTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/util/viewer/field/RegisterFieldFactoryTest.java index fefea8c4eb..7ad3ef5355 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/util/viewer/field/RegisterFieldFactoryTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/util/viewer/field/RegisterFieldFactoryTest.java @@ -15,8 +15,7 @@ */ package ghidra.app.util.viewer.field; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.math.BigInteger; import java.util.*; @@ -106,11 +105,10 @@ public class RegisterFieldFactoryTest extends AbstractGhidraHeadedIntegrationTes } private List getNonContextRegisters(ProgramContext pc) { - Register[] regs = pc.getRegisters(); List nonContextRegs = new ArrayList(); - for (int i = 0; i < regs.length; i++) { - if (!regs[i].isProcessorContext()) { - nonContextRegs.add(regs[i]); + for (Register reg : pc.getRegisters()) { + if (!reg.isProcessorContext()) { + nonContextRegs.add(reg); } } return nonContextRegs; diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/util/ProgramContextTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/util/ProgramContextTest.java index 941b1afad3..ded42540f6 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/util/ProgramContextTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/util/ProgramContextTest.java @@ -58,6 +58,21 @@ public class ProgramContextTest extends AbstractGhidraHeadedIntegrationTest { mem = program.getMemory(); } + @Test + public void testRegisterNameLookup() { + ProgramContext programContext = program.getProgramContext(); + boolean didSomething = false; + for (String regName : programContext.getRegisterNames()) { + Register reg = programContext.getRegister(regName); + assertNotNull(reg); + assertEquals(regName, reg.getName()); + assertTrue(reg == programContext.getRegister(regName.toLowerCase())); + assertTrue(reg == programContext.getRegister(regName.toUpperCase())); + didSomething = true; + } + assertTrue(didSomething); + } + @Test public void testAll() { int id = program.startTransaction("Test"); @@ -73,10 +88,7 @@ public class ProgramContextTest extends AbstractGhidraHeadedIntegrationTest { } ProgramContext programContext = program.getProgramContext(); - Register[] registers = null; - if (programContext != null) { - registers = programContext.getRegisters(); - } + boolean didSomething = false; Address startAddress = start; Address endAddress = getAddress(0x30); @@ -84,7 +96,7 @@ public class ProgramContextTest extends AbstractGhidraHeadedIntegrationTest { // stick a value into each one! BigInteger value = BigInteger.valueOf(255); - for (Register register : registers) { + for (Register register : programContext.getRegisters()) { Register reg = register; if (!reg.isBaseRegister() && reg.isProcessorContext()) { continue; @@ -136,7 +148,9 @@ public class ProgramContextTest extends AbstractGhidraHeadedIntegrationTest { endAddress.getAddressSpace().getMaxAddress()), programContext.getRegisterValueRangeContaining(reg, badAddress)); + didSomething = true; } + assertTrue(didSomething); } finally { program.endTransaction(id, false); diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java index 6674cc9567..2c1d50216b 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java @@ -839,16 +839,13 @@ public class DecompileCallback { return null; } ProgramContext context = program.getProgramContext(); - Register[] regs = context.getRegisters(); - if (regs == null || regs.length == 0) { - return null; - } + StringBuilder stringBuf = new StringBuilder(); stringBuf.append("\n"); - for (Register reg : regs) { + for (Register reg : context.getRegisters()) { if (reg.isProcessorContext()) { continue; } diff --git a/Ghidra/Framework/SoftwareModeling/certification.manifest b/Ghidra/Framework/SoftwareModeling/certification.manifest index 03c810cd8f..d467ee2798 100644 --- a/Ghidra/Framework/SoftwareModeling/certification.manifest +++ b/Ghidra/Framework/SoftwareModeling/certification.manifest @@ -29,7 +29,6 @@ src/main/java/ghidra/program/database/package.html||GHIDRA||||END| src/main/java/ghidra/program/model/address/package.html||GHIDRA||||END| src/main/java/ghidra/program/model/block/package.html||GHIDRA||||END| src/main/java/ghidra/program/model/data/package.html||GHIDRA||||END| -src/main/java/ghidra/program/model/graph/package.html||GHIDRA||||END| src/main/java/ghidra/program/model/lang/package.html||GHIDRA||||END| src/main/java/ghidra/program/model/listing/package.html||GHIDRA||||END| src/main/java/ghidra/program/model/mem/package.html||GHIDRA||||END| diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyDefaultContext.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyDefaultContext.java index 93a8f55dea..cf8a7f6700 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyDefaultContext.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/sem/AssemblyDefaultContext.java @@ -16,6 +16,7 @@ package ghidra.app.plugin.assembler.sleigh.sem; import java.math.BigInteger; +import java.util.List; import ghidra.app.plugin.assembler.sleigh.util.DbgTimer; import ghidra.app.plugin.processors.sleigh.SleighLanguage; @@ -117,7 +118,7 @@ public class AssemblyDefaultContext implements DisassemblerContext, DefaultProgr } @Override - public Register[] getRegisters() { + public List getRegisters() { return lang.getRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighDebugLogger.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighDebugLogger.java index 53f70a3ef6..d397b6df28 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighDebugLogger.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighDebugLogger.java @@ -1276,7 +1276,7 @@ public class SleighDebugLogger { } @Override - public Register[] getRegisters() { + public List getRegisters() { if (originalContext != null) { return originalContext.getRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java index 251be0346c..53b814a611 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java @@ -266,7 +266,7 @@ public class SleighLanguage implements Language { } @Override - public Register[] getContextRegisters() { + public List getContextRegisters() { return getRegisterManager().getContextRegisters(); } @@ -336,12 +336,12 @@ public class SleighLanguage implements Language { } @Override - public Register[] getRegisters() { + public List getRegisters() { return getRegisterManager().getRegisters(); } @Override - public String[] getRegisterNames() { + public List getRegisterNames() { return getRegisterManager().getRegisterNames(); } @@ -1080,11 +1080,8 @@ public class SleighLanguage implements Language { } private void xrefRegisters() { - Register[] regs = getRegisterManager().getRegisters(); - for (Register register : regs) { - if (register.isProcessorContext()) { - contextcache.registerVariable(register); - } + for (Register register : getRegisterManager().getContextRegisters()) { + contextcache.registerVariable(register); } } @@ -1587,7 +1584,7 @@ public class SleighLanguage implements Language { } @Override - public Register[] getSortedVectorRegisters() { + public List getSortedVectorRegisters() { return registerManager.getSortedVectorRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoDisassemblerContext.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoDisassemblerContext.java index dcfc1d529f..a57f7f5c6f 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoDisassemblerContext.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoDisassemblerContext.java @@ -16,6 +16,7 @@ package ghidra.app.util; import java.math.BigInteger; +import java.util.List; import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.model.address.Address; @@ -56,7 +57,7 @@ public class PseudoDisassemblerContext implements DisassemblerContext { } @Override - public Register[] getRegisters() { + public List getRegisters() { return disContext.getRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoInstruction.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoInstruction.java index add5ca057d..600a045f9f 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoInstruction.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/util/PseudoInstruction.java @@ -548,7 +548,7 @@ public class PseudoInstruction extends PseudoCodeUnit implements Instruction, In } @Override - public Register[] getRegisters() { + public List getRegisters() { return procContext.getRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/emulate/EmulateDisassemblerContext.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/emulate/EmulateDisassemblerContext.java index e8e0b2c712..4f843e3c1b 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/emulate/EmulateDisassemblerContext.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/emulate/EmulateDisassemblerContext.java @@ -154,7 +154,7 @@ public class EmulateDisassemblerContext implements DisassemblerContext { } @Override - public Register[] getRegisters() { + public List getRegisters() { throw new UnsupportedOperationException(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/CodeUnitDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/CodeUnitDB.java index 6ef5faf282..dfad2c2cb9 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/CodeUnitDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/CodeUnitDB.java @@ -17,8 +17,7 @@ package ghidra.program.database.code; import java.io.IOException; import java.math.BigInteger; -import java.util.ConcurrentModificationException; -import java.util.Iterator; +import java.util.*; import org.apache.commons.lang3.StringUtils; @@ -753,7 +752,7 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC } @Override - public Register[] getRegisters() { + public List getRegisters() { return programContext.getRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/PrototypeManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/PrototypeManager.java index 0991e62b9d..b0b0bc823b 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/PrototypeManager.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/PrototypeManager.java @@ -17,6 +17,7 @@ package ghidra.program.database.code; import java.io.IOException; import java.math.BigInteger; +import java.util.List; import java.util.StringTokenizer; import db.*; @@ -130,8 +131,9 @@ class PrototypeManager { RecordIterator it = contextTable.iterator(); while (it.hasNext()) { monitor.setProgress(++count); - if (monitor.isCancelled()) + if (monitor.isCancelled()) { throw new IOException("Upgrade Cancelled"); + } Record rec = it.next(); String oldValue = rec.getString(0); rec.setString(0, convertString(oldValue)); @@ -143,8 +145,9 @@ class PrototypeManager { it = tempTable.iterator(); while (it.hasNext()) { monitor.setProgress(++count); - if (monitor.isCancelled()) + if (monitor.isCancelled()) { throw new IOException("Upgrade Cancelled"); + } Record rec = it.next(); contextTable.putRecord(rec); } @@ -187,8 +190,9 @@ class PrototypeManager { RecordIterator it = protoAdapter.getRecords(); while (it.hasNext()) { monitor.setProgress(++count); - if (monitor.isCancelled()) + if (monitor.isCancelled()) { throw new IOException("Upgrade Cancelled"); + } Record rec = it.next(); tempAdapter.createRecord((int) rec.getKey(), rec.getLongValue(ADDR_COL), rec.getBinaryData(BYTES_COL), rec.getBooleanValue(DELAY_COL)); @@ -201,8 +205,9 @@ class PrototypeManager { it = tempAdapter.getRecords(); while (it.hasNext()) { monitor.setProgress(++count); - if (monitor.isCancelled()) + if (monitor.isCancelled()) { throw new IOException("Upgrade Cancelled"); + } Record rec = it.next(); protoAdapter.createRecord((int) rec.getKey(), rec.getLongValue(ADDR_COL), rec.getBinaryData(BYTES_COL), rec.getBooleanValue(DELAY_COL)); @@ -287,19 +292,10 @@ class PrototypeManager { return 0; } -// private boolean shouldSave(BigInteger value, BigInteger defaultValue) { -// if (value == null) { -// return false; -// } -// if (defaultValue == null) { -// return true; -// } -// return !value.equals(defaultValue); -// -// } - /** * Get the prototype with the given ID. + * @param protoID prototype ID + * @return instruction prototype or null if not found */ InstructionPrototype getPrototype(int protoID) { if (protoID < 0) { @@ -449,25 +445,16 @@ class PrototypeManager { this.address = address; } - /** - * @see ghidra.program.model.lang.ProcessorContext#getRegister(java.lang.String) - */ @Override public Register getRegister(String name) { return programContext.getRegister(name); } - /** - * @see ghidra.program.model.lang.ProcessorContext#getRegisters() - */ @Override - public Register[] getRegisters() { + public List getRegisters() { return programContext.getRegisters(); } - /** - * @see ghidra.program.model.lang.ProcessorContext#hasValue(ghidra.program.model.lang.Register) - */ @Override public boolean hasValue(Register register) { return false; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/register/OldProgramContextDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/register/OldProgramContextDB.java index 04775f39b6..0cdd516b43 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/register/OldProgramContextDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/register/OldProgramContextDB.java @@ -49,16 +49,14 @@ public class OldProgramContextDB implements ProgramContext, DefaultProgramContex private DBHandle dbHandle; private ErrorHandler errHandler; - private Register[] registers; + private Language language; private AddressMap addrMap; - private int registerSpaceSize; private Lock lock; /** * maintain values stored in registers for specified addresses and * address ranges using the PropertyMap utilities. */ - private HashMap registersMap; private Map valueMaps; private Register baseContextRegister; protected Map defaultRegisterValueMap; @@ -82,28 +80,12 @@ public class OldProgramContextDB implements ProgramContext, DefaultProgramContex this.errHandler = errHandler; this.lock = lock; this.addrMap = addrMap.getOldAddressMap(); - this.registers = language.getRegisters(); + this.language = language; + defaultRegisterValueMap = new HashMap(); - - registersMap = new HashMap(); valueMaps = new HashMap<>(); - registerSpaceSize = 0; - for (Register register : registers) { - String registerName = register.getName(); - registersMap.put(registerName.toUpperCase(), register); - - int offset = (register.getOffset() & 0xffff); - if (offset + register.getMinimumByteSize() > registerSpaceSize) { - registerSpaceSize = offset + register.getMinimumByteSize(); - } - } - for (Register register : registers) { - if (register.isProcessorContext()) { - baseContextRegister = register.getBaseRegister(); - break; - } - } + baseContextRegister = language.getContextBaseRegister(); if (baseContextRegister == null) { baseContextRegister = new Register("DEFAULT_CONTEXT", "DEFAULT_CONTEXT", @@ -186,28 +168,18 @@ public class OldProgramContextDB implements ProgramContext, DefaultProgramContex } @Override - public Register[] getProcessorStateRegisters() { - List list = new ArrayList(); - for (Register register : registers) { - if (register.isProcessorContext()) { - list.add(register); - } - } - return list.toArray(new Register[list.size()]); + public List getContextRegisters() { + return language.getContextRegisters(); } @Override public Register getRegister(String name) { - return registersMap.get(name.toUpperCase()); + return language.getRegister(name); } @Override - public String[] getRegisterNames() { - List list = new ArrayList(); - for (Register register : registers) { - list.add(register.getName()); - } - return list.toArray(new String[list.size()]); + public List getRegisterNames() { + return language.getRegisterNames(); } @Override @@ -273,8 +245,8 @@ public class OldProgramContextDB implements ProgramContext, DefaultProgramContex } @Override - public Register[] getRegisters() { - return registers; + public List getRegisters() { + return language.getRegisters(); } public long getSigned(Address addr, Register reg) throws UnsupportedOperationException { @@ -446,7 +418,7 @@ public class OldProgramContextDB implements ProgramContext, DefaultProgramContex public Register[] getRegistersWithValues() { if (registersWithValues == null) { List tmp = new ArrayList(); - for (Register register : registers) { + for (Register register : getRegisters()) { AddressRangeIterator it = getRegisterValueAddressRanges(register); if (it.hasNext()) { tmp.add(register); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/register/ProgramRegisterContextDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/register/ProgramRegisterContextDB.java index 3c9316ec4b..4686af2af2 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/register/ProgramRegisterContextDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/register/ProgramRegisterContextDB.java @@ -17,8 +17,7 @@ package ghidra.program.database.register; import java.io.IOException; import java.math.BigInteger; -import java.util.Arrays; -import java.util.HashMap; +import java.util.*; import db.*; import db.util.ErrorHandler; @@ -326,8 +325,8 @@ public class ProgramRegisterContextDB extends AbstractStoredProgramContext imple // Sort the registers by size so that largest come first. // This prevents the remove call below from incorrectly clearing // smaller registers that are part of a larger register. - Register[] registers = language.getRegisters().clone(); - Arrays.sort(registers, (r1, r2) -> r2.getBitLength() - r1.getBitLength()); + List registers = new ArrayList(language.getRegisters()); + Collections.sort(registers, (r1, r2) -> r2.getBitLength() - r1.getBitLength()); // Map all register stores to new registers for (Register register : registers) { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/Disassembler.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/Disassembler.java index ea4406aa8c..a724d43cc6 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/Disassembler.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/Disassembler.java @@ -1727,7 +1727,7 @@ public class Disassembler implements DisassemblerConflictHandler { } @Override - public Register[] getRegisters() { + public List getRegisters() { return langauge.getRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/DisassemblerContextImpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/DisassemblerContextImpl.java index e4ee7c7ee2..d57fd79ccc 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/DisassemblerContextImpl.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/DisassemblerContextImpl.java @@ -566,7 +566,7 @@ public class DisassemblerContextImpl implements DisassemblerContext { } @Override - public Register[] getRegisters() { + public List getRegisters() { return programContext.getRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Language.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Language.java index 9bc96c0192..93b07aac25 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Language.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Language.java @@ -206,21 +206,21 @@ public interface Language { public Register getRegister(AddressSpace addrspc, long offset, int size); /** - * Get the unsorted array of Register objects that this language supports + * Get an unsorted unmodifiable list of Register objects that this language defines * (including context registers). * - * @return the array of processor registers. + * @return unmodifiable list of processor registers. */ - public Register[] getRegisters(); + public List getRegisters(); /** - * Get the unsorted array of register names that this language supports + * Get an alphabetical sorted unmodifiable list of original register names * (including context registers). Names correspond to orignal register * name and not aliases which may be defined. * - * @return the array of processor register names. + * @return alphabetical sorted unmodifiable list of original register names. */ - public String[] getRegisterNames(); + public List getRegisterNames(); /** * Get a register given the name of the register @@ -252,19 +252,19 @@ public interface Language { public Register getProgramCounter(); /** - * Returns context base register or null if one has not been defined by the + * Returns processor context base register or null if one has not been defined by the * language. * @return base context register or null if not defined */ public Register getContextBaseRegister(); /** - * Get the unsorted array of Context Register objects that this language defines + * Get an unsorted unmodifiable list of processor context registers that this language defines * (includes context base register and its context field registers). * - * @return the array of processor registers. + * @return unmodifiable list of processor registers. */ - public Register[] getContextRegisters(); + public List getContextRegisters(); /** * Returns the default memory blocks for this language. @@ -412,9 +412,9 @@ public interface Language { public Exception getManualException(); /** - * Returns the array of vector registers, sorted first by size and then by name. - * @return sorted array of vector registers. + * Returns an unmodifiable list of vector registers, sorted first by size and then by name. + * @return unmodifiable list of vector registers. */ - public Register[] getSortedVectorRegisters(); + public List getSortedVectorRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProcessorContextImpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProcessorContextImpl.java index f3a2668af5..31b64ac877 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProcessorContextImpl.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProcessorContextImpl.java @@ -1,6 +1,5 @@ /* ### * 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. @@ -17,8 +16,7 @@ package ghidra.program.model.lang; import java.math.BigInteger; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * An implementation of processor context which contains the state of all @@ -29,47 +27,41 @@ import java.util.Map; */ public final class ProcessorContextImpl implements ProcessorContext { Map values = new HashMap(); - Register[] registers; - Register baseContextRegister; + Language language; - public ProcessorContextImpl(ProcessorContext context) { - this(context.getRegisters()); - for (Register register : registers) { - if (!register.isBaseRegister()) { - continue; - } - if (register.isProcessorContext()) { - baseContextRegister = register; - } - RegisterValue value = context.getRegisterValue(register); - if (value != null) { - setRegisterValue(value); - } - } - } +// public ProcessorContextImpl(ProcessorContext context) { +// this(context.getRegisters()); +// for (Register register : registers) { +// if (!register.isBaseRegister()) { +// continue; +// } +// if (register.isProcessorContext()) { +// baseContextRegister = register; +// } +// RegisterValue value = context.getRegisterValue(register); +// if (value != null) { +// setRegisterValue(value); +// } +// } +// } - public ProcessorContextImpl(Register[] registers) { - this.registers = registers; + public ProcessorContextImpl(Language language) { + this.language = language; } @Override public Register getBaseContextRegister() { - return baseContextRegister; + return language.getContextBaseRegister(); } @Override public Register getRegister(String name) { - for (Register register : registers) { - if (register.getName().equals(name)) { - return register; - } - } - return null; + return language.getRegister(name); } @Override - public Register[] getRegisters() { - return registers; + public List getRegisters() { + return language.getRegisters(); } @Override diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProcessorContextView.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProcessorContextView.java index b767305967..51ab3a1f38 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProcessorContextView.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProcessorContextView.java @@ -16,6 +16,7 @@ package ghidra.program.model.lang; import java.math.BigInteger; +import java.util.List; /** * Defines the interface for an object containing the state @@ -30,10 +31,10 @@ public interface ProcessorContextView { public Register getBaseContextRegister(); /** - * Returns all the Registers for the processor + * Returns all the Registers for the processor as an unmodifiable list * @return all the Registers for the processor */ - public Register[] getRegisters(); + public List getRegisters(); /** * Get a Register given the name of a register diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProgramProcessorContext.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProgramProcessorContext.java index e45deb560c..a8508d7880 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProgramProcessorContext.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ProgramProcessorContext.java @@ -1,6 +1,5 @@ /* ### * 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. @@ -16,12 +15,13 @@ */ package ghidra.program.model.lang; +import java.math.BigInteger; +import java.util.List; + import ghidra.program.model.address.Address; import ghidra.program.model.listing.ContextChangeException; import ghidra.program.model.listing.ProgramContext; -import java.math.BigInteger; - /** * Implementation for the program processor context interface */ @@ -45,17 +45,11 @@ public class ProgramProcessorContext implements ProcessorContext { return context.getBaseContextRegister(); } - /** - * @see ghidra.program.model.lang.ProcessorContext#getRegisters() - */ @Override - public Register[] getRegisters() { + public List getRegisters() { return context.getRegisters(); } - /** - * @see ghidra.program.model.lang.ProcessorContext#getRegister(java.lang.String) - */ @Override public Register getRegister(String name) { return context.getRegister(name); @@ -71,10 +65,6 @@ public class ProgramProcessorContext implements ProcessorContext { return context.getRegisterValue(register, addr); } - /** - * @throws ContextChangeException - * @see ghidra.program.model.lang.ProcessorContext#setValue(ghidra.program.model.lang.Register, java.math.BigInteger) - */ @Override public void setValue(Register register, BigInteger value) throws ContextChangeException { context.setValue(register, addr, addr, value); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ReadOnlyProcessorContext.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ReadOnlyProcessorContext.java index 9e4c156002..cc75985b54 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ReadOnlyProcessorContext.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/ReadOnlyProcessorContext.java @@ -1,6 +1,5 @@ /* ### * 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. @@ -22,6 +21,7 @@ package ghidra.program.model.lang; */ import java.math.BigInteger; +import java.util.List; public class ReadOnlyProcessorContext implements ProcessorContext { @@ -42,7 +42,7 @@ public class ReadOnlyProcessorContext implements ProcessorContext { } @Override - public Register[] getRegisters() { + public List getRegisters() { return context.getRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterBuilder.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterBuilder.java index 693b185a1c..393b5095a2 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterBuilder.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterBuilder.java @@ -89,11 +89,15 @@ public class RegisterBuilder { return contextAddress; } + /** + * Compute current register collection and instantiate a {@link RegisterManager} + * @return new register manager instance + */ public RegisterManager getRegisterManager() { - return new RegisterManager(computeRegisters(), Collections.unmodifiableMap(registerMap)); + return new RegisterManager(computeRegisters(), registerMap); } - private Register[] computeRegisters() { + private List computeRegisters() { List regList = new LinkedList<>(); List unprocessed = new LinkedList<>(registerList); @@ -115,8 +119,7 @@ public class RegisterBuilder { } bitSize = nextLargerSize; } - - return registerList.toArray(new Register[registerList.size()]); + return registerList; } private Register[] getChildren(Register parent, List regList) { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterManager.java index a91b868670..2b637531c8 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterManager.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterManager.java @@ -22,18 +22,19 @@ import ghidra.program.model.address.OldGenericNamespaceAddress; public class RegisterManager { - Register[] registers; - Map registerNameMap = new HashMap(); // include aliases and case-variations + private List registers; + private Map registerNameMap = new HashMap(); // include aliases and case-variations - String[] registerNames; // excludes aliases - Register[] contextRegisters; - Register contextBaseRegister; + private List registerNames; // alphabetical sorted list, excludes aliases + private List contextRegisters; + private Register contextBaseRegister; - Map sizeMap = new HashMap(); - Map> registerAddressMap = new HashMap>(); + private Map sizeMap = new HashMap(); + private Map> registerAddressMap = + new HashMap>(); - /**Collection of vector registers, sorted first by size and then by offset**/ - private TreeSet sortedVectorRegisters; + /**List of vector registers, sorted first by size and then by offset**/ + private List sortedVectorRegisters; class RegisterSizeKey { Address address; @@ -85,16 +86,16 @@ public class RegisterManager { * @param registerNameMap a complete name-to-register map including all register aliases * and alternate spellings (e.g., case-variations) */ - RegisterManager(Register[] cookedRegisters, Map registerNameMap) { - registers = cookedRegisters; - this.registerNameMap = registerNameMap; + RegisterManager(List cookedRegisters, Map registerNameMap) { + this.registers = Collections.unmodifiableList(cookedRegisters); + this.registerNameMap = Collections.unmodifiableMap(registerNameMap); initialize(); } private void initialize() { List registerNameList = new ArrayList(); List contextRegisterList = new ArrayList(); - List registerList = new ArrayList(Arrays.asList(registers)); + ArrayList registerList = new ArrayList<>(registers); // copy for sorting Collections.sort(registerList, registerSizeComparator); for (Register reg : registerList) { String regName = reg.getName(); @@ -129,8 +130,9 @@ public class RegisterManager { for (Register register : registerList) { sizeMap.put(new RegisterSizeKey(register.getAddress(), 0), register); } - contextRegisters = contextRegisterList.toArray(new Register[contextRegisterList.size()]); - registerNames = registerNameList.toArray(new String[registerNameList.size()]); + contextRegisters = Collections.unmodifiableList(contextRegisterList); + Collections.sort(registerNameList); + registerNames = Collections.unmodifiableList(registerNameList); } private void populateSizeMapBigEndian(Register reg) { @@ -157,18 +159,21 @@ public class RegisterManager { } /** - * Get unsorted array of all processor context registers (include base context register and children) + * Get unsorted unmodifiable list of all processor context registers (include base context register and children) * @return all processor context registers */ - public Register[] getContextRegisters() { + public List getContextRegisters() { return contextRegisters; } /** - * Get unsorted array of all original register names (exludes aliases) - * @return all register names + * Get an alphabetical sorted unmodifiable list of original register names + * (including context registers). Names correspond to orignal register + * name and not aliases which may be defined. + * + * @return alphabetical sorted unmodifiable list of original register names. */ - public String[] getRegisterNames() { + public List getRegisterNames() { return registerNames; } @@ -234,29 +239,30 @@ public class RegisterManager { } /** - * Get all registers. Array returned is not protected and must not be modified - * by caller. - * @return array of all registers defined + * Get all registers as an unsorted unmodifiable list. + * @return unmodifiable list of all registers defined */ - public Register[] getRegisters() { + public List getRegisters() { return registers; } /** - * Get all vector registers indentified by processor specification - * in sorted order based upon address and size. - * @return all vector registers + * Get an unmodifiable list of all vector registers indentified by the processor specification + * in sorted order based upon address and size. + * @return all vector registers as unmodifiable list */ - public Register[] getSortedVectorRegisters() { + public List getSortedVectorRegisters() { if (sortedVectorRegisters == null) { - sortedVectorRegisters = new TreeSet(RegisterManager::compareVectorRegisters); - for (Register reg : getRegisters()) { + ArrayList list = new ArrayList(); + for (Register reg : registers) { if (reg.isVectorRegister()) { - sortedVectorRegisters.add(reg); + list.add(reg); } } + Collections.sort(list, RegisterManager::compareVectorRegisters); + sortedVectorRegisters = Collections.unmodifiableList(list); } - return sortedVectorRegisters.toArray(new Register[0]); + return sortedVectorRegisters; } /** diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterTranslator.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterTranslator.java index f62e31dc5b..4436704d5c 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterTranslator.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterTranslator.java @@ -1,6 +1,5 @@ /* ### * 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. @@ -16,36 +15,33 @@ */ package ghidra.program.model.lang; -import ghidra.program.model.address.Address; - import java.util.*; +import ghidra.program.model.address.Address; + public class RegisterTranslator { private static Comparator registerSizeComparator = new Comparator() { + @Override public int compare(Register r1, Register r2) { // Used for sorting largest to smallest return r2.getBitLength() - r1.getBitLength(); } }; - private Register[] oldRegs; - private Register[] newRegs; + private Language oldLang; + private Language newLang; private HashMap> oldRegisterMap; private HashMap> newRegisterMap; - private HashMap oldRegisterNameMap; - private HashMap newRegisterNameMap; public RegisterTranslator(Language oldLang, Language newLang) { - oldRegs = oldLang.getRegisters(); - newRegs = newLang.getRegisters(); - this.oldRegisterMap = buildOffsetMap(oldRegs); - this.newRegisterMap = buildOffsetMap(newRegs); - oldRegisterNameMap = buildNameMap(oldRegs); - newRegisterNameMap = buildNameMap(newRegs); + this.oldLang = oldLang; + this.newLang = newLang; + this.oldRegisterMap = buildOffsetMap(oldLang.getRegisters()); + this.newRegisterMap = buildOffsetMap(newLang.getRegisters()); } - private HashMap> buildOffsetMap(Register[] registers) { + private HashMap> buildOffsetMap(List registers) { HashMap> offsetMap = new HashMap>(); for (Register register : registers) { Address addr = register.getAddress(); @@ -69,14 +65,6 @@ public class RegisterTranslator { return offsetMap; } - private HashMap buildNameMap(Register[] regs) { - HashMap map = new HashMap(); - for (Register r : regs) { - map.put(r.getName().toUpperCase(), r); - } - return map; - } - public Register getOldRegister(int offset, int size) { List list = oldRegisterMap.get(offset); if (list != null) { @@ -110,15 +98,15 @@ public class RegisterTranslator { } public Register getNewRegister(Register oldReg) { - return newRegisterNameMap.get(oldReg.getName().toUpperCase()); + return newLang.getRegister(oldReg.getName()); } public Register getOldRegister(Register newReg) { - return oldRegisterNameMap.get(newReg.getName().toUpperCase()); + return oldLang.getRegister(newReg.getName()); } - public Register[] getNewRegisters() { - return newRegs; + public List getNewRegisters() { + return newLang.getRegisters(); } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/InstructionStub.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/InstructionStub.java index c7f51c958d..0c4f3855ca 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/InstructionStub.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/InstructionStub.java @@ -340,7 +340,7 @@ public class InstructionStub implements Instruction { } @Override - public Register[] getRegisters() { + public List getRegisters() { throw new UnsupportedOperationException(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/ProgramContext.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/ProgramContext.java index ddf616d7e7..3f27cd10ae 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/ProgramContext.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/ProgramContext.java @@ -15,12 +15,13 @@ */ package ghidra.program.model.listing; +import java.math.BigInteger; +import java.util.List; + import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; import ghidra.program.model.lang.RegisterValue; -import java.math.BigInteger; - /** * Interface to define a processor register context over the address space. */ @@ -34,14 +35,14 @@ public interface ProgramContext { /** * Modify register value to eliminate non-flowing bits - * @param value + * @param value register value to be modified * @return value suitable for flowing */ public RegisterValue getFlowValue(RegisterValue value); /** * Modify register value to only include non-flowing bits - * @param value + * @param value register value to be modified * @return new value or null */ public RegisterValue getNonFlowValue(RegisterValue value); @@ -57,9 +58,9 @@ public interface ProgramContext { /** * Get all the register descriptions defined for this program context. * - * @return array of defined register descriptions + * @return unmodifiable list of defined register descriptions */ - public Register[] getRegisters(); + public List getRegisters(); /** * Returns an array of all registers that at least one value associated with an address. @@ -92,6 +93,8 @@ public interface ProgramContext { * @param start the start address to set values * @param end the end address to set values * @param value the actual values to store at address + * @throws ContextChangeException if failed to modifiy context across specified range + * (e.g., instruction exists). */ public void setRegisterValue(Address start, Address end, RegisterValue value) throws ContextChangeException; @@ -112,6 +115,8 @@ public interface ProgramContext { * @param start the start address. * @param end the end address (inclusive). * @param value the value to assign. A value of null will effective clear any existing values. + * @throws ContextChangeException if failed to modifiy context across specified range + * (e.g., instruction exists). */ public void setValue(Register register, Address start, Address end, BigInteger value) throws ContextChangeException; @@ -130,6 +135,8 @@ public interface ProgramContext { * given range for the given register. Each range returned will have the same value * associated with the register for all addresses in that range. * @param register the register for which to get set value ranges. + * @param start start of address range to search + * @param end end of address range to search * @return An AddressRangeIterator over all address within the given range that have values * for the given register. */ @@ -139,8 +146,8 @@ public interface ProgramContext { /** * Returns the bounding address-range containing addr and the the same RegisterValue throughout. * The range returned may be limited by other value changes associated with register's base-register. - * @param register - * @param addr + * @param register program register + * @param addr program address * @return single register-value address-range containing addr */ public AddressRange getRegisterValueRangeContaining(Register register, Address addr); @@ -159,6 +166,8 @@ public interface ProgramContext { * given range for the given register. Each range returned will have the same default value * associated with the register for all addresses in that range. * @param register the register for which to get default value ranges. + * @param start start of address range to search + * @param end end of address range to search * @return An AddressRangeIterator over all address within the given range that have default values * for the given register. */ @@ -169,20 +178,26 @@ public interface ProgramContext { * Gets the registers for this context that are used for processor context states. * @return all processor context registers */ - public Register[] getProcessorStateRegisters(); + public List getContextRegisters(); /** * Remove (unset) the register values for a given address range. * @param start starting address. * @param end ending adddress. * @param register handle to the register to be set. + * @throws ContextChangeException thrown if context change not permitted over specified + * range (e.g., instructions exist) */ public void remove(Address start, Address end, Register register) throws ContextChangeException; /** - * Returns the list of register names + * Get an alphabetical sorted unmodifiable list of original register names + * (including context registers). Names correspond to orignal register + * name and not aliases which may be defined. + * + * @return alphabetical sorted unmodifiable list of original register names. */ - public String[] getRegisterNames(); + public List getRegisterNames(); /** * Returns true if the given register has the value over the addressSet @@ -224,7 +239,7 @@ public interface ProgramContext { * from the default disassembly context and the context register value stored * at the specified address. Those bits specified by the stored context value * take precedence. - * @param address + * @param address program address * @return disassembly context register value */ public RegisterValue getDisassemblyContext(Address address); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/VarnodeTranslator.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/VarnodeTranslator.java index ac1a42cace..f4240d8b13 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/VarnodeTranslator.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/VarnodeTranslator.java @@ -20,6 +20,8 @@ */ package ghidra.program.model.pcode; +import java.util.List; + import ghidra.program.model.lang.Language; import ghidra.program.model.lang.Register; import ghidra.program.model.listing.Program; @@ -50,8 +52,9 @@ public class VarnodeTranslator { * @return Register or null if node is not a register */ public Register getRegister(Varnode node) { - if (node == null) + if (node == null) { return null; + } return language.getRegister(node.getAddress(), node.getSize()); } @@ -72,9 +75,9 @@ public class VarnodeTranslator { * Get all defined registers for the program this translator was created * with. * - * @return all defined registers + * @return all defined registers as unmodifiable list */ - public Register[] getRegisters() { + public List getRegisters() { return language.getRegisters(); } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/AbstractProgramContext.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/AbstractProgramContext.java index fd96114e20..3817a2c21f 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/AbstractProgramContext.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/AbstractProgramContext.java @@ -16,6 +16,7 @@ package ghidra.program.util; import java.util.Arrays; +import java.util.List; import ghidra.program.model.address.Address; import ghidra.program.model.lang.*; @@ -128,7 +129,7 @@ abstract public class AbstractProgramContext implements ProgramContext, DefaultP } @Override - public final Register[] getProcessorStateRegisters() { + public final List getContextRegisters() { return language.getContextRegisters(); } @@ -138,12 +139,12 @@ abstract public class AbstractProgramContext implements ProgramContext, DefaultP } @Override - public final String[] getRegisterNames() { + public final List getRegisterNames() { return language.getRegisterNames(); } @Override - public final Register[] getRegisters() { + public final List getRegisters() { return language.getRegisters(); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/OldLanguage.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/OldLanguage.java index cb7ad24426..688c0ca6ec 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/OldLanguage.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/OldLanguage.java @@ -120,7 +120,7 @@ class OldLanguage implements Language { } @Override - public Register[] getContextRegisters() { + public List getContextRegisters() { return registerMgr.getContextRegisters(); } @@ -140,12 +140,12 @@ class OldLanguage implements Language { } @Override - public Register[] getRegisters() { + public List getRegisters() { return registerMgr.getRegisters(); } @Override - public String[] getRegisterNames() { + public List getRegisterNames() { return registerMgr.getRegisterNames(); } @@ -747,7 +747,7 @@ class OldLanguage implements Language { } @Override - public Register[] getSortedVectorRegisters() { + public List getSortedVectorRegisters() { throw new UnsupportedOperationException( "Language for upgrade use only (getSortedVectorRegisters)"); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/OldLanguageFactory.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/OldLanguageFactory.java index 1aa64e5e4e..1c9b06ae51 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/OldLanguageFactory.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/OldLanguageFactory.java @@ -270,7 +270,6 @@ public class OldLanguageFactory { private static Element getRegistersElement(Language lang) { - Register[] registers = lang.getRegisters(); Register contextReg = lang.getContextBaseRegister(); Element registersElement = new Element("registers"); if (contextReg != null) { @@ -292,7 +291,7 @@ public class OldLanguageFactory { } registersElement.addContent(ctxElement); } - for (Register reg : registers) { + for (Register reg : lang.getRegisters()) { if (!reg.getBaseRegister().isProcessorContext()) { Element regElement = getRegisterElement(reg); registersElement.addContent(regElement); diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/VectorRegisterPspecTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/VectorRegisterPspecTest.java index 90c7788e46..1e9f786bb3 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/VectorRegisterPspecTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/VectorRegisterPspecTest.java @@ -17,6 +17,8 @@ package ghidra.framework.main; import static org.junit.Assert.*; +import java.util.List; + import org.junit.Test; import generic.test.AbstractGenericTest; @@ -44,19 +46,20 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { public void testPspecParsing_x64() throws Exception { ProgramBuilder pBuilder = new ProgramBuilder("test", ProgramBuilder._X64); testProgram = pBuilder.getProgram(); - Register[] vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); + List vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); String[] intelVectorRegisterNames = getIntelVectorRegisterNames(); - assertEquals(intelVectorRegisterNames.length, vectorRegs.length); + assertEquals(intelVectorRegisterNames.length, vectorRegs.size()); for (int i = 0; i < intelVectorRegisterNames.length; i++) { - assertTrue(vectorRegs[i].isVectorRegister()); - assertEquals(intelVectorRegisterNames[i], vectorRegs[i].getName()); - if (vectorRegs[i].getName().startsWith("Y")) { - assertEquals(YMM_BIT_SIZE, vectorRegs[i].getBitLength()); + Register vectorReg = vectorRegs.get(i); + assertTrue(vectorRegs.get(i).isVectorRegister()); + assertEquals(intelVectorRegisterNames[i], vectorReg.getName()); + if (vectorReg.getName().startsWith("Y")) { + assertEquals(YMM_BIT_SIZE, vectorReg.getBitLength()); } else { - assertEquals(XMM_BIT_SIZE, vectorRegs[i].getBitLength()); + assertEquals(XMM_BIT_SIZE, vectorReg.getBitLength()); } - int[] lanes = vectorRegs[i].getLaneSizes(); + int[] lanes = vectorReg.getLaneSizes(); assertEquals(4, lanes.length); //test lane sizes: should be 1,2,4,8 int laneSize = 1; @@ -64,7 +67,7 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { assertEquals(laneSize, lane); laneSize *= 2; } - assertFalse(vectorRegs[i].isValidLaneSize(3)); + assertFalse(vectorReg.isValidLaneSize(3)); } } @@ -72,19 +75,20 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { public void testPspecParsing_x86() throws Exception { ProgramBuilder pBuilder = new ProgramBuilder("test", ProgramBuilder._X86); testProgram = pBuilder.getProgram(); - Register[] vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); + List vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); String[] intelVectorRegisterNames = getIntelVectorRegisterNames(); - assertEquals(intelVectorRegisterNames.length, vectorRegs.length); + assertEquals(intelVectorRegisterNames.length, vectorRegs.size()); for (int i = 0; i < intelVectorRegisterNames.length; i++) { - assertTrue(vectorRegs[i].isVectorRegister()); - assertEquals(intelVectorRegisterNames[i], vectorRegs[i].getName()); - if (vectorRegs[i].getName().startsWith("Y")) { - assertEquals(YMM_BIT_SIZE, vectorRegs[i].getBitLength()); + Register vectorReg = vectorRegs.get(i); + assertTrue(vectorReg.isVectorRegister()); + assertEquals(intelVectorRegisterNames[i], vectorReg.getName()); + if (vectorReg.getName().startsWith("Y")) { + assertEquals(YMM_BIT_SIZE, vectorReg.getBitLength()); } else { - assertEquals(XMM_BIT_SIZE, vectorRegs[i].getBitLength()); + assertEquals(XMM_BIT_SIZE, vectorReg.getBitLength()); } - int[] lanes = vectorRegs[i].getLaneSizes(); + int[] lanes = vectorReg.getLaneSizes(); assertEquals(4, lanes.length); //test lane sizes: should be 1,2,4,8 int laneSize = 1; @@ -92,7 +96,7 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { assertEquals(laneSize, lane); laneSize *= 2; } - assertFalse(vectorRegs[i].isValidLaneSize(3)); + assertFalse(vectorReg.isValidLaneSize(3)); } } @@ -100,14 +104,15 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { public void testPspecParsing_PPC_32() throws Exception { ProgramBuilder pBuilder = new ProgramBuilder("test", ProgramBuilder._PPC_32); testProgram = pBuilder.getProgram(); - Register[] vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); + List vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); String[] powerPcVectorRegisterNames = getPowerPCVectorRegisterNames(); - assertEquals(powerPcVectorRegisterNames.length, vectorRegs.length); - for (int i = 0; i < vectorRegs.length; i++) { - assertTrue(vectorRegs[i].isVectorRegister()); - assertEquals(powerPcVectorRegisterNames[i], vectorRegs[i].getName()); - assertEquals(VSX_BIT_SIZE, vectorRegs[i].getBitLength()); - int[] lanes = vectorRegs[i].getLaneSizes(); + assertEquals(powerPcVectorRegisterNames.length, vectorRegs.size()); + for (int i = 0; i < powerPcVectorRegisterNames.length; i++) { + Register vectorReg = vectorRegs.get(i); + assertTrue(vectorReg.isVectorRegister()); + assertEquals(powerPcVectorRegisterNames[i], vectorReg.getName()); + assertEquals(VSX_BIT_SIZE, vectorReg.getBitLength()); + int[] lanes = vectorReg.getLaneSizes(); assertEquals(3, lanes.length); //lane sizes should be 1, 2, 4 int size = 1; @@ -115,7 +120,7 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { assertEquals(size, lane); size *= 2; } - assertFalse(vectorRegs[i].isValidLaneSize(5)); + assertFalse(vectorReg.isValidLaneSize(5)); } } @@ -123,14 +128,15 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { public void testPspecParsing_PPC_6432() throws Exception { ProgramBuilder pBuilder = new ProgramBuilder("test", ProgramBuilder._PPC_6432); testProgram = pBuilder.getProgram(); - Register[] vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); + List vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); String[] powerPcVectorRegisterNames = getPowerPCVectorRegisterNames(); - assertEquals(powerPcVectorRegisterNames.length, vectorRegs.length); - for (int i = 0; i < vectorRegs.length; i++) { - assertTrue(vectorRegs[i].isVectorRegister()); - assertEquals(powerPcVectorRegisterNames[i], vectorRegs[i].getName()); - assertEquals(VSX_BIT_SIZE, vectorRegs[i].getBitLength()); - int[] lanes = vectorRegs[i].getLaneSizes(); + assertEquals(powerPcVectorRegisterNames.length, vectorRegs.size()); + for (int i = 0; i < powerPcVectorRegisterNames.length; i++) { + Register vectorReg = vectorRegs.get(i); + assertTrue(vectorReg.isVectorRegister()); + assertEquals(powerPcVectorRegisterNames[i], vectorReg.getName()); + assertEquals(VSX_BIT_SIZE, vectorReg.getBitLength()); + int[] lanes = vectorReg.getLaneSizes(); assertEquals(3, lanes.length); //lane sizes should be 1, 2, 4 int size = 1; @@ -138,7 +144,7 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { assertEquals(size, lane); size *= 2; } - assertFalse(vectorRegs[i].isValidLaneSize(5)); + assertFalse(vectorReg.isValidLaneSize(5)); } } @@ -146,14 +152,15 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { public void testPspecParsing_ARM() throws Exception { ProgramBuilder pBuilder = new ProgramBuilder("test", ProgramBuilder._ARM); testProgram = pBuilder.getProgram(); - Register[] vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); + List vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); String[] armVectorRegisterNames = getArmVectorRegisterNames(); - assertEquals(armVectorRegisterNames.length, vectorRegs.length); - for (int i = 0; i < vectorRegs.length; i++) { - assertTrue(vectorRegs[i].isVectorRegister()); - assertEquals(armVectorRegisterNames[i], vectorRegs[i].getName()); - assertEquals(NEON_BIT_SIZE, vectorRegs[i].getBitLength()); - int[] laneSizes = vectorRegs[i].getLaneSizes(); + assertEquals(armVectorRegisterNames.length, vectorRegs.size()); + for (int i = 0; i < armVectorRegisterNames.length; i++) { + Register vectorReg = vectorRegs.get(i); + assertTrue(vectorReg.isVectorRegister()); + assertEquals(armVectorRegisterNames[i], vectorReg.getName()); + assertEquals(NEON_BIT_SIZE, vectorReg.getBitLength()); + int[] laneSizes = vectorReg.getLaneSizes(); assertEquals(3, laneSizes.length); //lane sizes should be 1, 2, 4 int size = 1; @@ -161,7 +168,7 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { assertEquals(size, laneSize); size *= 2; } - assertFalse(vectorRegs[i].isValidLaneSize(5)); + assertFalse(vectorReg.isValidLaneSize(5)); } } @@ -169,24 +176,25 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { public void testPspecParsing_AARCH64() throws Exception { ProgramBuilder pBuilder = new ProgramBuilder("test", ProgramBuilder._AARCH64); testProgram = pBuilder.getProgram(); - Register[] vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); + List vectorRegs = testProgram.getLanguage().getSortedVectorRegisters(); String[] aarch64VectorRegisterNames = getAarch64VectorRegisterNames(); - assertEquals(aarch64VectorRegisterNames.length, vectorRegs.length); - for (int i = 0; i < vectorRegs.length; i++) { - assertTrue(vectorRegs[i].isVectorRegister()); - assertEquals(aarch64VectorRegisterNames[i], vectorRegs[i].getName()); - switch (vectorRegs[i].getName().substring(0, 1)) { + assertEquals(aarch64VectorRegisterNames.length, vectorRegs.size()); + for (int i = 0; i < aarch64VectorRegisterNames.length; i++) { + Register vectorReg = vectorRegs.get(i); + assertTrue(vectorReg.isVectorRegister()); + assertEquals(aarch64VectorRegisterNames[i], vectorReg.getName()); + switch (vectorReg.getName().substring(0, 1)) { case "z": - assertEquals(SVE_BIT_SIZE, vectorRegs[i].getBitLength()); + assertEquals(SVE_BIT_SIZE, vectorReg.getBitLength()); break; case "q": - assertEquals(NEON_BIT_SIZE, vectorRegs[i].getBitLength()); + assertEquals(NEON_BIT_SIZE, vectorReg.getBitLength()); break; default: throw new IllegalArgumentException( - "bad vector register name: " + vectorRegs[i].getName()); + "bad vector register name: " + vectorReg.getName()); } - int[] laneSizes = vectorRegs[i].getLaneSizes(); + int[] laneSizes = vectorReg.getLaneSizes(); assertEquals(4, laneSizes.length); //sizes should be 1,2,4,8 int size = 1; @@ -194,7 +202,7 @@ public class VectorRegisterPspecTest extends AbstractGenericTest { assertEquals(size, laneSize); size *= 2; } - assertFalse(vectorRegs[i].isValidLaneSize(3)); + assertFalse(vectorReg.isValidLaneSize(3)); } }