mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 20:29:50 +08:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
@@ -16,7 +16,8 @@
|
|||||||
//Script to graph class hierarchies given metadata found in class structure description that
|
//Script to graph class hierarchies given metadata found in class structure description that
|
||||||
// was applied using the RecoverClassesFromRTTIScript.
|
// was applied using the RecoverClassesFromRTTIScript.
|
||||||
//@category C++
|
//@category C++
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.app.services.GraphDisplayBroker;
|
import ghidra.app.services.GraphDisplayBroker;
|
||||||
@@ -46,7 +47,7 @@ public class GraphClassesScript extends GhidraScript {
|
|||||||
Category category = dataTypeManager.getCategory(dataTypePath);
|
Category category = dataTypeManager.getCategory(dataTypePath);
|
||||||
if (category == null) {
|
if (category == null) {
|
||||||
println(
|
println(
|
||||||
"/ClassDataTypes folder does not exist so there is no class data to process. Please run the ExtractClassInfoFromRTTIScript to generate the necessary information needed to run this script.");
|
"/ClassDataTypes folder does not exist so there is no class data to process. Please run the RecoverClassesFromRTTIScript to generate the necessary information needed to run this script.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +55,11 @@ public class GraphClassesScript extends GhidraScript {
|
|||||||
|
|
||||||
getClassStructures(subCategories);
|
getClassStructures(subCategories);
|
||||||
|
|
||||||
|
if (classStructures.isEmpty()) {
|
||||||
|
println("There were no class structures to process.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AttributedGraph graph = createGraph();
|
AttributedGraph graph = createGraph();
|
||||||
if (graph.getVertexCount() == 0) {
|
if (graph.getVertexCount() == 0) {
|
||||||
println(
|
println(
|
||||||
@@ -93,43 +99,47 @@ public class GraphClassesScript extends GhidraScript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AttributedGraph createGraph() throws CancelledException {
|
/**
|
||||||
|
* Method to create a graph using preconfigured information found in class structure descriptions.
|
||||||
|
* The structure descriptions are created using
|
||||||
|
* {@link RecoveredClassUtils#createParentStringBuffer(RecoveredClass)}
|
||||||
|
* @return the newly created graph
|
||||||
|
*/
|
||||||
|
private AttributedGraph createGraph() throws Exception {
|
||||||
|
|
||||||
AttributedGraph g = new AttributedGraph();
|
AttributedGraph g = new AttributedGraph();
|
||||||
|
|
||||||
Iterator<Structure> classStructuresIterator = classStructures.iterator();
|
for (Structure classStructure : classStructures) {
|
||||||
while (classStructuresIterator.hasNext()) {
|
|
||||||
|
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
|
|
||||||
Structure classStructure = classStructuresIterator.next();
|
|
||||||
|
|
||||||
String description = classStructure.getDescription();
|
String description = classStructure.getDescription();
|
||||||
String mainClassName = getClassName(description);
|
|
||||||
|
|
||||||
if (mainClassName == null) {
|
// parse description for class hierarchy
|
||||||
|
if (!description.startsWith("class")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributedVertex classVertex = g.addVertex(mainClassName);
|
// skip "class " to get overall class
|
||||||
|
description = description.substring(6);
|
||||||
|
String mainClassName = getClassName(description);
|
||||||
|
|
||||||
|
if (mainClassName == null || mainClassName.isBlank()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributedVertex classVertex =
|
||||||
|
g.addVertex(classStructure.getCategoryPath().getPath(), mainClassName);
|
||||||
|
classVertex.setDescription(classStructure.getCategoryPath().getPath());
|
||||||
|
|
||||||
int numParents = 0;
|
int numParents = 0;
|
||||||
while (description.contains(":")) {
|
description = removeClassSubstring(description, mainClassName);
|
||||||
|
|
||||||
|
while (description != null) {
|
||||||
|
|
||||||
numParents++;
|
numParents++;
|
||||||
|
|
||||||
int indexOfColon = description.indexOf(":", 0);
|
String parentName = getClassName(description);
|
||||||
|
|
||||||
description = description.substring(indexOfColon + 1);
|
|
||||||
|
|
||||||
int endOfBlock = description.indexOf(":", 0);
|
|
||||||
if (endOfBlock == -1) {
|
|
||||||
endOfBlock = description.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
String parentName = description.substring(0, endOfBlock);
|
|
||||||
|
|
||||||
description = description.substring(endOfBlock);
|
|
||||||
|
|
||||||
boolean isVirtualParent = false;
|
boolean isVirtualParent = false;
|
||||||
if (parentName.contains("virtual")) {
|
if (parentName.contains("virtual")) {
|
||||||
@@ -139,14 +149,38 @@ public class GraphClassesScript extends GhidraScript {
|
|||||||
parentName = parentName.replace("virtual", "");
|
parentName = parentName.replace("virtual", "");
|
||||||
parentName = parentName.replace(" ", "");
|
parentName = parentName.replace(" ", "");
|
||||||
|
|
||||||
|
// first try to get parent structure from inside child structure
|
||||||
|
Structure parentStructure =
|
||||||
|
getParentStructureFromChildStructure(classStructure, parentName);
|
||||||
|
|
||||||
AttributedVertex parentVertex = g.addVertex(parentName);
|
// if parent structure isn't in child structure then try to get it by name
|
||||||
|
// from the list of class structures - only returns one if unique
|
||||||
|
if (parentStructure == null) {
|
||||||
|
parentStructure = getParentStructureFromClassStructures(parentName);
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributedVertex parentVertex;
|
||||||
|
if (parentStructure == null) {
|
||||||
|
parentVertex = g.addVertex(parentName);
|
||||||
|
parentVertex.setDescription("Couldn't get parent structure " + parentName +
|
||||||
|
" from structure " + classStructure.getName() +
|
||||||
|
" or uniquely from all class structures");
|
||||||
|
println("Couldn't get parent structure " + parentName + " from structure " +
|
||||||
|
classStructure.getName() + " or uniquely from all class structures");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parentVertex =
|
||||||
|
g.addVertex(parentStructure.getCategoryPath().getPath(), parentName);
|
||||||
|
parentVertex.setDescription(parentStructure.getCategoryPath().getPath());
|
||||||
|
}
|
||||||
|
|
||||||
AttributedEdge edge = g.addEdge(parentVertex, classVertex);
|
AttributedEdge edge = g.addEdge(parentVertex, classVertex);
|
||||||
if (isVirtualParent) {
|
if (isVirtualParent) {
|
||||||
edge.setAttribute("Color", "Orange");
|
edge.setAttribute("Color", "Orange");
|
||||||
}
|
}
|
||||||
// else leave it default lime green
|
// else leave it default lime green
|
||||||
|
|
||||||
|
description = removeClassSubstring(description, parentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// no parent = blue vertex
|
// no parent = blue vertex
|
||||||
@@ -166,6 +200,94 @@ public class GraphClassesScript extends GhidraScript {
|
|||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String removeClassSubstring(String string, String substring) {
|
||||||
|
|
||||||
|
int indexofSubstring = string.indexOf(substring);
|
||||||
|
if (indexofSubstring == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexofSubstring + substring.length() >= string.length()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String newString = string.substring(indexofSubstring + substring.length());
|
||||||
|
if (newString.isBlank() || newString.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// should be a space : space and another class name next if gets to here
|
||||||
|
if (newString.length() < 4) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newString.indexOf(" : ") == 0) {
|
||||||
|
return newString.substring(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getIndexOfFirstSingleColon(String string) {
|
||||||
|
|
||||||
|
// replace all :: with something else so can isolate :'s
|
||||||
|
String testString = new String(string);
|
||||||
|
testString = testString.replace("::", "xx");
|
||||||
|
|
||||||
|
return testString.indexOf(":", 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to get the parent structure from within the child structure given the parent name
|
||||||
|
* @param childStructure the child structure
|
||||||
|
* @param parentName the name of the parent structure
|
||||||
|
* @return the parent structure or null if the parent structure is not contained in the child structure
|
||||||
|
* @throws CancelledException if cancelled
|
||||||
|
*/
|
||||||
|
private Structure getParentStructureFromChildStructure(Structure childStructure,
|
||||||
|
String parentName)
|
||||||
|
throws CancelledException {
|
||||||
|
|
||||||
|
DataTypeComponent[] components = childStructure.getComponents();
|
||||||
|
for (DataTypeComponent component : components) {
|
||||||
|
|
||||||
|
monitor.checkCanceled();
|
||||||
|
DataType componentDataType = component.getDataType();
|
||||||
|
if (componentDataType instanceof Structure &&
|
||||||
|
componentDataType.getName().equals(parentName)) {
|
||||||
|
return (Structure) componentDataType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to get the parent structure from the list of class structures
|
||||||
|
* @param parentName the name of the parent
|
||||||
|
* @return the parent structure if there is only one with the given name, else returns null
|
||||||
|
* @throws CancelledException if cancelled
|
||||||
|
*/
|
||||||
|
private Structure getParentStructureFromClassStructures(String parentName)
|
||||||
|
throws CancelledException {
|
||||||
|
|
||||||
|
List<Structure> parentStructures = new ArrayList<Structure>();
|
||||||
|
for (Structure classStructure : classStructures) {
|
||||||
|
monitor.checkCanceled();
|
||||||
|
|
||||||
|
if (classStructure.getName().equals(parentName)) {
|
||||||
|
parentStructures.add(classStructure);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (parentStructures.size() == 1) {
|
||||||
|
return parentStructures.get(0);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void showGraph(AttributedGraph graph) throws Exception {
|
private void showGraph(AttributedGraph graph) throws Exception {
|
||||||
|
|
||||||
GraphDisplay display;
|
GraphDisplay display;
|
||||||
@@ -176,26 +298,20 @@ public class GraphClassesScript extends GhidraScript {
|
|||||||
display.setGraph(graph, "test graph", false, TaskMonitor.DUMMY);
|
display.setGraph(graph, "test graph", false, TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String getClassName(String description) {
|
private String getClassName(String description) {
|
||||||
|
|
||||||
// parse description for class hierarchy
|
int indexOfColon = getIndexOfFirstSingleColon(description);
|
||||||
if (!description.startsWith("class")) {
|
String firstClassName;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip "class " to get overall class
|
|
||||||
description = description.substring(6);
|
|
||||||
int indexOfColon = description.indexOf(":", 0);
|
|
||||||
String mainClassName;
|
|
||||||
if (indexOfColon == -1) {
|
if (indexOfColon == -1) {
|
||||||
mainClassName = description;
|
firstClassName = description;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mainClassName = description.substring(0, indexOfColon - 1);
|
firstClassName = description.substring(0, indexOfColon - 1);
|
||||||
}
|
}
|
||||||
mainClassName = mainClassName.replace(" ", "");
|
firstClassName = firstClassName.replace(" ", "");
|
||||||
|
|
||||||
return mainClassName;
|
return firstClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -115,7 +115,7 @@ public class AddressKeyIteratorTest extends AbstractGhidraHeadedIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIterator0() throws Exception {
|
public void testIterator0() throws Exception {
|
||||||
AddressKeyIterator it = new AddressKeyIterator();
|
AddressKeyIterator it = AddressKeyIterator.EMPTY_ITERATOR;
|
||||||
assertTrue(!it.hasNext());
|
assertTrue(!it.hasNext());
|
||||||
assertTrue(!it.hasPrevious());
|
assertTrue(!it.hasPrevious());
|
||||||
try {
|
try {
|
||||||
@@ -123,12 +123,14 @@ public class AddressKeyIteratorTest extends AbstractGhidraHeadedIntegrationTest
|
|||||||
Assert.fail();
|
Assert.fail();
|
||||||
}
|
}
|
||||||
catch (NoSuchElementException e) {
|
catch (NoSuchElementException e) {
|
||||||
|
// expected
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
it.previous();
|
it.previous();
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
}
|
}
|
||||||
catch (NoSuchElementException e) {
|
catch (NoSuchElementException e) {
|
||||||
|
// expected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||||||
// multiple parents = red vertex
|
// multiple parents = red vertex
|
||||||
// edge between child and parent is orange if child inherits the parent virtually
|
// edge between child and parent is orange if child inherits the parent virtually
|
||||||
// edge between child and parent is lime green if child inherits the parent non-virtually
|
// edge between child and parent is lime green if child inherits the parent non-virtually
|
||||||
private static final boolean GRAPH_CLASS_HIERARCHIES = false;
|
private static final boolean GRAPH_CLASS_HIERARCHIES = true;
|
||||||
|
|
||||||
// show shortened class template names in class structure field names
|
// show shortened class template names in class structure field names
|
||||||
private static final boolean USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS = true;
|
private static final boolean USE_SHORT_TEMPLATE_NAMES_IN_STRUCTURE_FIELDS = true;
|
||||||
@@ -342,7 +342,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||||||
|
|
||||||
RecoveredClass recoveredClass = recoveredClassIterator.next();
|
RecoveredClass recoveredClass = recoveredClassIterator.next();
|
||||||
|
|
||||||
AttributedVertex classVertex = g.addVertex(recoveredClass.getName());
|
AttributedVertex classVertex =
|
||||||
|
g.addVertex(recoveredClass.getClassPath().getPath(), recoveredClass.getName());
|
||||||
|
|
||||||
Map<RecoveredClass, List<RecoveredClass>> classHierarchyMap =
|
Map<RecoveredClass, List<RecoveredClass>> classHierarchyMap =
|
||||||
recoveredClass.getClassHierarchyMap();
|
recoveredClass.getClassHierarchyMap();
|
||||||
@@ -350,6 +351,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||||||
// no parent = blue vertex
|
// no parent = blue vertex
|
||||||
if (classHierarchyMap.isEmpty()) {
|
if (classHierarchyMap.isEmpty()) {
|
||||||
classVertex.setAttribute("Color", "Blue");
|
classVertex.setAttribute("Color", "Blue");
|
||||||
|
classVertex.setDescription(recoveredClass.getClassPath().getPath());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,6 +366,8 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||||||
classVertex.setAttribute("Color", "Red");
|
classVertex.setAttribute("Color", "Red");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
classVertex.setDescription(recoveredClass.getClassPath().getPath());
|
||||||
|
|
||||||
Map<RecoveredClass, Boolean> parentToBaseTypeMap =
|
Map<RecoveredClass, Boolean> parentToBaseTypeMap =
|
||||||
recoveredClass.getParentToBaseTypeMap();
|
recoveredClass.getParentToBaseTypeMap();
|
||||||
|
|
||||||
@@ -372,7 +376,10 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {
|
|||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
RecoveredClass parent = parentIterator.next();
|
RecoveredClass parent = parentIterator.next();
|
||||||
|
|
||||||
AttributedVertex parentVertex = g.addVertex(parent.getName());
|
AttributedVertex parentVertex =
|
||||||
|
g.addVertex(parent.getClassPath().getPath(), parent.getName());
|
||||||
|
|
||||||
|
parentVertex.setDescription(parent.getClassPath().getPath());
|
||||||
|
|
||||||
AttributedEdge edge = g.addEdge(parentVertex, classVertex);
|
AttributedEdge edge = g.addEdge(parentVertex, classVertex);
|
||||||
|
|
||||||
|
|||||||
@@ -3196,9 +3196,15 @@ public class RecoveredClassUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to create a string buffer containing class parents in the corrector order
|
* Method to create a string buffer containing class parents in the correct order. The format
|
||||||
|
* of the parent string is of the format "class <class_name> : <parent1_spec> : <parent2_spec> ...
|
||||||
|
* where parentN_spec = "virtual (only if inherited virtually) <parentN_name>"
|
||||||
|
* Examples:
|
||||||
|
* The class Pet with no parents would be "class Pet"
|
||||||
|
* The class Cat with non-virtual parent Pet would be "class Cat : Pet"
|
||||||
|
* The class A with virtual parent B and non-virtual parent C would be "class A : virtual B : C"
|
||||||
* @param recoveredClass the given class
|
* @param recoveredClass the given class
|
||||||
* @return StringBuffer containing class parents
|
* @return StringBuffer containing class parent description
|
||||||
* @throws CancelledException if cancelled
|
* @throws CancelledException if cancelled
|
||||||
*/
|
*/
|
||||||
public StringBuffer createParentStringBuffer(RecoveredClass recoveredClass)
|
public StringBuffer createParentStringBuffer(RecoveredClass recoveredClass)
|
||||||
@@ -4442,6 +4448,7 @@ public class RecoveredClassUtils {
|
|||||||
recoveredClass.getName(), defaultPointerSize, dataTypeManager);
|
recoveredClass.getName(), defaultPointerSize, dataTypeManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create a description indicating class parentage
|
||||||
classStruct.setDescription(createParentStringBuffer(recoveredClass).toString());
|
classStruct.setDescription(createParentStringBuffer(recoveredClass).toString());
|
||||||
|
|
||||||
classStruct = (Structure) dataTypeManager.addDataType(classStruct,
|
classStruct = (Structure) dataTypeManager.addDataType(classStruct,
|
||||||
|
|||||||
@@ -415,8 +415,9 @@ void PcodeOp::saveXml(ostream &s) const
|
|||||||
else if (vn->getSpace()->getType()==IPTR_CONSTANT) {
|
else if (vn->getSpace()->getType()==IPTR_CONSTANT) {
|
||||||
if ((i==0)&&((code()==CPUI_STORE)||(code()==CPUI_LOAD))) {
|
if ((i==0)&&((code()==CPUI_STORE)||(code()==CPUI_LOAD))) {
|
||||||
AddrSpace *spc = Address::getSpaceFromConst(vn->getAddr());
|
AddrSpace *spc = Address::getSpaceFromConst(vn->getAddr());
|
||||||
s << "<spaceid name=\"";
|
s << "<spaceid";
|
||||||
s << spc->getName() << "\"/>\n";
|
a_v(s,"name",spc->getName());
|
||||||
|
s << "/>\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s << "<addr ref=\"0x" << hex << vn->getCreateIndex() << "\"/>\n";
|
s << "<addr ref=\"0x" << hex << vn->getCreateIndex() << "\"/>\n";
|
||||||
|
|||||||
@@ -259,8 +259,9 @@ void EmitXml::tagField(const char *ptr,syntax_highlight hl,const Datatype *ct,in
|
|||||||
void EmitXml::tagComment(const char *ptr,syntax_highlight hl,
|
void EmitXml::tagComment(const char *ptr,syntax_highlight hl,
|
||||||
const AddrSpace *spc,uintb off) {
|
const AddrSpace *spc,uintb off) {
|
||||||
*s << "<comment " << highlight[(int4)hl];
|
*s << "<comment " << highlight[(int4)hl];
|
||||||
*s << " space=\"" << spc->getName();
|
a_v(*s,"space",spc->getName());
|
||||||
*s << "\" off=\"0x" << hex << off << "\">";
|
a_v_u(*s,"off",off);
|
||||||
|
*s << '>';
|
||||||
xml_escape(*s,ptr);
|
xml_escape(*s,ptr);
|
||||||
*s << "</comment>";
|
*s << "</comment>";
|
||||||
}
|
}
|
||||||
@@ -276,8 +277,9 @@ void EmitXml::tagComment(const char *ptr,syntax_highlight hl,
|
|||||||
void EmitXml::tagLabel(const char *ptr,syntax_highlight hl,
|
void EmitXml::tagLabel(const char *ptr,syntax_highlight hl,
|
||||||
const AddrSpace *spc,uintb off) {
|
const AddrSpace *spc,uintb off) {
|
||||||
*s << "<label " << highlight[(int4)hl];
|
*s << "<label " << highlight[(int4)hl];
|
||||||
*s << " space=\"" << spc->getName();
|
a_v(*s,"space",spc->getName());
|
||||||
*s << "\" off=\"0x" << hex << off << "\">";
|
a_v_u(*s,"off",off);
|
||||||
|
*s << '>';
|
||||||
xml_escape(*s,ptr);
|
xml_escape(*s,ptr);
|
||||||
*s << "</label>";
|
*s << "</label>";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,5 @@ ffffffbfdff7ffffe811ffffffbf6100
|
|||||||
<stringmatch name="Convert #14" min="1" max="1">recv_signed\(-0b1100110011001100\)</stringmatch>
|
<stringmatch name="Convert #14" min="1" max="1">recv_signed\(-0b1100110011001100\)</stringmatch>
|
||||||
<stringmatch name="Convert #15" min="1" max="1">recv_unsigned\(0b1110111011101110\)</stringmatch>
|
<stringmatch name="Convert #15" min="1" max="1">recv_unsigned\(0b1110111011101110\)</stringmatch>
|
||||||
<stringmatch name="Convert #16" min="1" max="1">recv_unsigned\(0b11111111111111111111011111011111\)</stringmatch>
|
<stringmatch name="Convert #16" min="1" max="1">recv_unsigned\(0b11111111111111111111011111011111\)</stringmatch>
|
||||||
<stringmatch name="Convert #17" min="1" max="1">recv_signed\('a'\)</stringmatch>
|
<stringmatch name="Convert #17" min="1" max="1">recv_signed\(L'a'\)</stringmatch>
|
||||||
</decompilertest>
|
</decompilertest>
|
||||||
|
|||||||
+1
-1
@@ -1433,7 +1433,7 @@ public class SleighLanguage implements Language {
|
|||||||
if ((element instanceof OverlayAddressSpace)) {
|
if ((element instanceof OverlayAddressSpace)) {
|
||||||
OverlayAddressSpace ospace = (OverlayAddressSpace) element;
|
OverlayAddressSpace ospace = (OverlayAddressSpace) element;
|
||||||
resBuf.append("<space_overlay");
|
resBuf.append("<space_overlay");
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "name", ospace.getName());
|
SpecXmlUtils.xmlEscapeAttribute(resBuf, "name", ospace.getName());
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "index", ospace.getUnique());
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "index", ospace.getUnique());
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "base",
|
SpecXmlUtils.encodeStringAttribute(resBuf, "base",
|
||||||
ospace.getOverlayedSpace().getName());
|
ospace.getOverlayedSpace().getName());
|
||||||
|
|||||||
+36
-7
@@ -1174,6 +1174,9 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
if (addrSetView == null) {
|
if (addrSetView == null) {
|
||||||
addrSetView = program.getMemory();
|
addrSetView = program.getMemory();
|
||||||
}
|
}
|
||||||
|
else if (addrSetView.isEmpty()) {
|
||||||
|
return CodeUnitIterator.EMPTY_ITERATOR;
|
||||||
|
}
|
||||||
|
|
||||||
if (property.equals(CodeUnit.COMMENT_PROPERTY)) {
|
if (property.equals(CodeUnit.COMMENT_PROPERTY)) {
|
||||||
try {
|
try {
|
||||||
@@ -1219,7 +1222,8 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
/**
|
/**
|
||||||
* Get a forward iterator over code units that have comments of the given type.
|
* Get a forward iterator over code units that have comments of the given type.
|
||||||
* @param commentType comment type defined in CodeUnit
|
* @param commentType comment type defined in CodeUnit
|
||||||
* @param set address set
|
* @param set address set (null for all defined memory)
|
||||||
|
* @return code unit iterator
|
||||||
*/
|
*/
|
||||||
public CodeUnitIterator getCommentCodeUnitIterator(int commentType, AddressSetView set) {
|
public CodeUnitIterator getCommentCodeUnitIterator(int commentType, AddressSetView set) {
|
||||||
CodeUnitIterator it = getCodeUnitIterator(CodeUnit.COMMENT_PROPERTY, set, true);
|
CodeUnitIterator it = getCodeUnitIterator(CodeUnit.COMMENT_PROPERTY, set, true);
|
||||||
@@ -1229,10 +1233,15 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
/**
|
/**
|
||||||
* Get a forward iterator over addresses that have comments of the given type.
|
* Get a forward iterator over addresses that have comments of the given type.
|
||||||
* @param commentType comment type defined in CodeUnit
|
* @param commentType comment type defined in CodeUnit
|
||||||
* @param set address set
|
* @param set address set (null for all defined memory)
|
||||||
|
* @param forward true to iterate in the direction of increasing addresses.
|
||||||
|
* @return address iterator
|
||||||
*/
|
*/
|
||||||
public AddressIterator getCommentAddressIterator(int commentType, AddressSetView set,
|
public AddressIterator getCommentAddressIterator(int commentType, AddressSetView set,
|
||||||
boolean forward) {
|
boolean forward) {
|
||||||
|
if (set != null && set.isEmpty()) {
|
||||||
|
return AddressIterator.EMPTY_ITERATOR;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
AddressKeyIterator keyIter = commentAdapter.getKeys(set, forward);
|
AddressKeyIterator keyIter = commentAdapter.getKeys(set, forward);
|
||||||
AddressIterator addrIter =
|
AddressIterator addrIter =
|
||||||
@@ -1251,6 +1260,9 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
* @param forward true to iterate in the direction of increasing addresses.
|
* @param forward true to iterate in the direction of increasing addresses.
|
||||||
*/
|
*/
|
||||||
public AddressIterator getCommentAddressIterator(AddressSetView addrSet, boolean forward) {
|
public AddressIterator getCommentAddressIterator(AddressSetView addrSet, boolean forward) {
|
||||||
|
if (addrSet != null && addrSet.isEmpty()) {
|
||||||
|
return AddressIterator.EMPTY_ITERATOR;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
AddressKeyIterator keyIter = commentAdapter.getKeys(addrSet, forward);
|
AddressKeyIterator keyIter = commentAdapter.getKeys(addrSet, forward);
|
||||||
return new AddressKeyAddressIterator(keyIter, forward, addrMap, program);
|
return new AddressKeyAddressIterator(keyIter, forward, addrMap, program);
|
||||||
@@ -1632,6 +1644,9 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
searchSet = new AddressSet(
|
searchSet = new AddressSet(
|
||||||
initializedMemoryOnly ? mem.getLoadedAndInitializedAddressSet() : mem);
|
initializedMemoryOnly ? mem.getLoadedAndInitializedAddressSet() : mem);
|
||||||
}
|
}
|
||||||
|
else if (set.isEmpty()) {
|
||||||
|
return set;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
searchSet = new AddressSet(set);
|
searchSet = new AddressSet(set);
|
||||||
searchSet = searchSet.intersect(
|
searchSet = searchSet.intersect(
|
||||||
@@ -1855,13 +1870,19 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
* Returns the next undefined data whose min address falls within the address set
|
* Returns the next undefined data whose min address falls within the address set
|
||||||
* searching in the forward direction {@code (e.g., 0 -> 0xfff).}
|
* searching in the forward direction {@code (e.g., 0 -> 0xfff).}
|
||||||
*
|
*
|
||||||
* @param set the address set to look within.
|
* @param set the address set to look within (required).
|
||||||
* @param monitor the current monitor.
|
* @param monitor the current monitor.
|
||||||
* @return Data the first undefined data within the address set, or null if there is none.
|
* @return Data the first undefined data within the address set, or null if there is none.
|
||||||
*/
|
*/
|
||||||
public Data getFirstUndefinedData(AddressSetView set, TaskMonitor monitor) {
|
public Data getFirstUndefinedData(AddressSetView set, TaskMonitor monitor) {
|
||||||
|
if (set.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
Memory mem = program.getMemory();
|
Memory mem = program.getMemory();
|
||||||
set = mem.intersect(set);
|
set = mem.intersect(set);
|
||||||
|
if (set.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
CodeUnitIterator it = getCodeUnits(set, true);
|
CodeUnitIterator it = getCodeUnits(set, true);
|
||||||
@@ -2172,8 +2193,7 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
private boolean exceedsLimitOn64BitAddressSegments(List<Address> longSegmentAddressList,
|
private boolean exceedsLimitOn64BitAddressSegments(List<Address> longSegmentAddressList,
|
||||||
Address toAddr) {
|
Address toAddr) {
|
||||||
long maskedOffset = toAddr.getOffset() & 0xffffffff00000000L;
|
long maskedOffset = toAddr.getOffset() & 0xffffffff00000000L;
|
||||||
for (int i = 0; i < longSegmentAddressList.size(); i++) {
|
for (Address address : longSegmentAddressList) {
|
||||||
Address address = longSegmentAddressList.get(i);
|
|
||||||
long offset = address.getOffset();
|
long offset = address.getOffset();
|
||||||
if ((offset & 0xffffffff00000000L) == maskedOffset) {
|
if ((offset & 0xffffffff00000000L) == maskedOffset) {
|
||||||
return false;
|
return false;
|
||||||
@@ -2419,6 +2439,7 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
* @param forward if true the iterator returns all codeUnits from the given
|
* @param forward if true the iterator returns all codeUnits from the given
|
||||||
* start address to the end of the program, otherwise it returns all codeUnits
|
* start address to the end of the program, otherwise it returns all codeUnits
|
||||||
* from the given start address to the start of the program.
|
* from the given start address to the start of the program.
|
||||||
|
* @return code unit iterator
|
||||||
*/
|
*/
|
||||||
public CodeUnitIterator getCodeUnits(Address start, boolean forward) {
|
public CodeUnitIterator getCodeUnits(Address start, boolean forward) {
|
||||||
|
|
||||||
@@ -2439,6 +2460,10 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
bounds = program.getAddressFactory().getAddressSet(min, start);
|
bounds = program.getAddressFactory().getAddressSet(min, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddressSet set = mem.intersect(bounds);
|
||||||
|
if (set.isEmpty()) {
|
||||||
|
return CodeUnitIterator.EMPTY_ITERATOR;
|
||||||
|
}
|
||||||
return new CodeUnitRecordIterator(this, getInstructions(start, forward),
|
return new CodeUnitRecordIterator(this, getInstructions(start, forward),
|
||||||
getDefinedData(start, forward), mem.intersect(bounds), forward);
|
getDefinedData(start, forward), mem.intersect(bounds), forward);
|
||||||
}
|
}
|
||||||
@@ -2447,10 +2472,15 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
* Returns an iterator over all codeUnits in the given addressSet. The iterator
|
* Returns an iterator over all codeUnits in the given addressSet. The iterator
|
||||||
* will go from the lowest address to the largest or from the largest to the
|
* will go from the lowest address to the largest or from the largest to the
|
||||||
* lowest depending on the forward parameter.
|
* lowest depending on the forward parameter.
|
||||||
|
* @param set the memory address set over which code units should be iterated (required)
|
||||||
* @param forward determines if the iterator goes from lowest address to highest
|
* @param forward determines if the iterator goes from lowest address to highest
|
||||||
* or the other way around.
|
* or the other way around.
|
||||||
|
* @return code unit iterator
|
||||||
*/
|
*/
|
||||||
public CodeUnitIterator getCodeUnits(AddressSetView set, boolean forward) {
|
public CodeUnitIterator getCodeUnits(AddressSetView set, boolean forward) {
|
||||||
|
if (set.isEmpty()) {
|
||||||
|
return CodeUnitIterator.EMPTY_ITERATOR;
|
||||||
|
}
|
||||||
return new CodeUnitRecordIterator(this, getInstructions(set, forward),
|
return new CodeUnitRecordIterator(this, getInstructions(set, forward),
|
||||||
getDefinedData(set, forward), set, forward);
|
getDefinedData(set, forward), set, forward);
|
||||||
}
|
}
|
||||||
@@ -2677,9 +2707,8 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < addrs.size(); i++) {
|
for (Address addr : addrs) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
Address addr = addrs.get(i);
|
|
||||||
clearCodeUnits(addr, addr, false, monitor);
|
clearCodeUnits(addr, addr, false, monitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -1,6 +1,5 @@
|
|||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,11 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.program.database.code;
|
package ghidra.program.database.code;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combines an Instruction iterator and Data iterator into a codeunit iterator
|
* Combines an Instruction iterator and Data iterator into a codeunit iterator
|
||||||
*/
|
*/
|
||||||
@@ -42,7 +41,7 @@ class CodeUnitRecordIterator implements CodeUnitIterator {
|
|||||||
* @param codeMgr the code managaer
|
* @param codeMgr the code managaer
|
||||||
* @param instIt the instruction iterator
|
* @param instIt the instruction iterator
|
||||||
* @param dataIt the data iterator
|
* @param dataIt the data iterator
|
||||||
* @param set the address set
|
* @param set the address set (required)
|
||||||
* @param forward the iterator direction
|
* @param forward the iterator direction
|
||||||
*/
|
*/
|
||||||
CodeUnitRecordIterator(CodeManager codeMgr, InstructionIterator instIt, DataIterator dataIt,
|
CodeUnitRecordIterator(CodeManager codeMgr, InstructionIterator instIt, DataIterator dataIt,
|
||||||
|
|||||||
+1
-1
@@ -235,7 +235,7 @@ abstract class CommentsDBAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an address key iterator over the given address set in the given direction.
|
* Returns an address key iterator over the given address set in the given direction.
|
||||||
* @param addrSetView the set to iterator over.
|
* @param addrSetView the set to iterator over (null for all defined memory).
|
||||||
* @param forward the direction to iterate.
|
* @param forward the direction to iterate.
|
||||||
*/
|
*/
|
||||||
abstract AddressKeyIterator getKeys(AddressSetView set, boolean forward) throws IOException;
|
abstract AddressKeyIterator getKeys(AddressSetView set, boolean forward) throws IOException;
|
||||||
|
|||||||
+7
-4
@@ -1,6 +1,5 @@
|
|||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,13 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.program.database.map;
|
package ghidra.program.database.map;
|
||||||
|
|
||||||
import ghidra.program.model.address.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import db.*;
|
import db.*;
|
||||||
|
import ghidra.program.model.address.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterator of indexed fields that are addresses. The longs returned are the address longs.
|
* Iterator of indexed fields that are addresses. The longs returned are the address longs.
|
||||||
@@ -95,7 +93,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
|
|||||||
* @param addrMap the address map
|
* @param addrMap the address map
|
||||||
* @param absolute if true, only absolute memory address encodings are considered, otherwise
|
* @param absolute if true, only absolute memory address encodings are considered, otherwise
|
||||||
* only standard/relocatable address encodings are considered.
|
* only standard/relocatable address encodings are considered.
|
||||||
* @param set the set of addresses to iterator over.
|
* @param set the set of addresses to iterator over or null for all addresses.
|
||||||
* @param atStart if true, iterates forward, otherwise iterates backwards.
|
* @param atStart if true, iterates forward, otherwise iterates backwards.
|
||||||
* @throws IOException if a database io error occurs.
|
* @throws IOException if a database io error occurs.
|
||||||
*/
|
*/
|
||||||
@@ -192,6 +190,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.DBLongIterator#hasNext()
|
* @see db.DBLongIterator#hasNext()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean hasNext() throws IOException {
|
public boolean hasNext() throws IOException {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -217,6 +216,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.DBLongIterator#hasPrevious()
|
* @see db.DBLongIterator#hasPrevious()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean hasPrevious() throws IOException {
|
public boolean hasPrevious() throws IOException {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -242,6 +242,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.DBLongIterator#next()
|
* @see db.DBLongIterator#next()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public long next() throws IOException {
|
public long next() throws IOException {
|
||||||
if (hasNext()) {
|
if (hasNext()) {
|
||||||
return ((LongField) it.next()).getLongValue();
|
return ((LongField) it.next()).getLongValue();
|
||||||
@@ -252,6 +253,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.DBLongIterator#previous()
|
* @see db.DBLongIterator#previous()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public long previous() throws IOException {
|
public long previous() throws IOException {
|
||||||
if (hasPrevious()) {
|
if (hasPrevious()) {
|
||||||
return ((LongField) it.previous()).getLongValue();
|
return ((LongField) it.previous()).getLongValue();
|
||||||
@@ -262,6 +264,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.DBLongIterator#delete()
|
* @see db.DBLongIterator#delete()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean delete() throws IOException {
|
public boolean delete() throws IOException {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
return it.delete();
|
return it.delete();
|
||||||
|
|||||||
+1
-1
@@ -93,7 +93,7 @@ public class AddressIndexPrimaryKeyIterator implements DBFieldIterator {
|
|||||||
* @param addrMap the address map
|
* @param addrMap the address map
|
||||||
* @param absolute if true, only absolute memory address encodings are considered, otherwise
|
* @param absolute if true, only absolute memory address encodings are considered, otherwise
|
||||||
* only standard/relocatable address encodings are considered.
|
* only standard/relocatable address encodings are considered.
|
||||||
* @param set the set of addresses to iterator over.
|
* @param set the set of addresses to iterator over or null for all addresses.
|
||||||
* @param atStart if true, iterates forward, otherwise iterates backwards.
|
* @param atStart if true, iterates forward, otherwise iterates backwards.
|
||||||
* @throws IOException if a database io error occurs.
|
* @throws IOException if a database io error occurs.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+3
-4
@@ -1,6 +1,5 @@
|
|||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,15 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.program.database.map;
|
package ghidra.program.database.map;
|
||||||
|
|
||||||
import ghidra.program.model.address.Address;
|
|
||||||
import ghidra.program.model.address.AddressIterator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import db.DBLongIterator;
|
import db.DBLongIterator;
|
||||||
import db.util.ErrorHandler;
|
import db.util.ErrorHandler;
|
||||||
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.address.AddressIterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an AddressKeyIterator or an addressKeyAddressIterator into an AddressIterator
|
* Converts an AddressKeyIterator or an addressKeyAddressIterator into an AddressIterator
|
||||||
@@ -39,6 +37,7 @@ public class AddressKeyAddressIterator implements AddressIterator {
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param keyIter address key iterator, may be null. All long values must decode properly with the specified addrMap.
|
* @param keyIter address key iterator, may be null. All long values must decode properly with the specified addrMap.
|
||||||
|
* @param forward true to iterate in the direction of increasing addresses.
|
||||||
* @param addrMap address map
|
* @param addrMap address map
|
||||||
* @param errHandler IO error handler (may be null)
|
* @param errHandler IO error handler (may be null)
|
||||||
*/
|
*/
|
||||||
|
|||||||
+11
-6
@@ -1,6 +1,5 @@
|
|||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,14 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.program.database.map;
|
package ghidra.program.database.map;
|
||||||
|
|
||||||
import ghidra.program.model.address.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import db.DBLongIterator;
|
import db.DBLongIterator;
|
||||||
import db.Table;
|
import db.Table;
|
||||||
|
import ghidra.program.model.address.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterator of primary keys that are addresses. The longs returned are the address longs.
|
* Iterator of primary keys that are addresses. The longs returned are the address longs.
|
||||||
@@ -31,6 +29,8 @@ import db.Table;
|
|||||||
|
|
||||||
public class AddressKeyIterator implements DBLongIterator {
|
public class AddressKeyIterator implements DBLongIterator {
|
||||||
|
|
||||||
|
public static final AddressKeyIterator EMPTY_ITERATOR = new AddressKeyIterator();
|
||||||
|
|
||||||
private Table table;
|
private Table table;
|
||||||
|
|
||||||
private List<KeyRange> keyRangeList;
|
private List<KeyRange> keyRangeList;
|
||||||
@@ -40,7 +40,7 @@ public class AddressKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* Constructs an empty iterator.
|
* Constructs an empty iterator.
|
||||||
*/
|
*/
|
||||||
public AddressKeyIterator() {
|
private AddressKeyIterator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,7 +96,7 @@ public class AddressKeyIterator implements DBLongIterator {
|
|||||||
* Memory addresses encoded as Absolute are not included.
|
* Memory addresses encoded as Absolute are not included.
|
||||||
* @param table the database table key by addresses
|
* @param table the database table key by addresses
|
||||||
* @param addrMap the address map
|
* @param addrMap the address map
|
||||||
* @param set the address set to iterator over
|
* @param set the address set to iterator over (may be null for all defined memory)
|
||||||
* @param startAddr the address at which to position the iterator, can be null. The exact
|
* @param startAddr the address at which to position the iterator, can be null. The exact
|
||||||
* position of the iterator depends on the before parameter.
|
* position of the iterator depends on the before parameter.
|
||||||
* @param before positions the iterator before the start address,otherwise after
|
* @param before positions the iterator before the start address,otherwise after
|
||||||
@@ -115,7 +115,7 @@ public class AddressKeyIterator implements DBLongIterator {
|
|||||||
* @param addrMap the address map
|
* @param addrMap the address map
|
||||||
* @param absolute if true, only absolute memory address encodings are considered, otherwise
|
* @param absolute if true, only absolute memory address encodings are considered, otherwise
|
||||||
* only standard/relocatable address encodings are considered.
|
* only standard/relocatable address encodings are considered.
|
||||||
* @param set the address set to iterator over
|
* @param set the address set to iterator over or null for all addresses.
|
||||||
* @param startAddr the address at which to position the iterator, can be null. The exact
|
* @param startAddr the address at which to position the iterator, can be null. The exact
|
||||||
* position of the iterator depends on the before parameter.
|
* position of the iterator depends on the before parameter.
|
||||||
* @param before positions the iterator before the start address,otherwise after
|
* @param before positions the iterator before the start address,otherwise after
|
||||||
@@ -180,6 +180,7 @@ public class AddressKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.DBLongIterator#hasNext()
|
* @see db.DBLongIterator#hasNext()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean hasNext() throws IOException {
|
public boolean hasNext() throws IOException {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -203,6 +204,7 @@ public class AddressKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.DBLongIterator#hasPrevious()
|
* @see db.DBLongIterator#hasPrevious()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean hasPrevious() throws IOException {
|
public boolean hasPrevious() throws IOException {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -226,6 +228,7 @@ public class AddressKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.DBLongIterator#next()
|
* @see db.DBLongIterator#next()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public long next() throws IOException {
|
public long next() throws IOException {
|
||||||
if (hasNext()) {
|
if (hasNext()) {
|
||||||
return it.next();
|
return it.next();
|
||||||
@@ -236,6 +239,7 @@ public class AddressKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.DBLongIterator#previous()
|
* @see db.DBLongIterator#previous()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public long previous() throws IOException {
|
public long previous() throws IOException {
|
||||||
if (hasPrevious()) {
|
if (hasPrevious()) {
|
||||||
return it.previous();
|
return it.previous();
|
||||||
@@ -246,6 +250,7 @@ public class AddressKeyIterator implements DBLongIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.DBLongIterator#delete()
|
* @see db.DBLongIterator#delete()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean delete() throws IOException {
|
public boolean delete() throws IOException {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
return it.delete();
|
return it.delete();
|
||||||
|
|||||||
+7
-3
@@ -15,13 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.program.database.map;
|
package ghidra.program.database.map;
|
||||||
|
|
||||||
import ghidra.program.model.address.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import db.*;
|
import db.*;
|
||||||
|
import ghidra.program.model.address.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a RecordIterator over records that are address keyed. Various constructors allow
|
* Returns a RecordIterator over records that are address keyed. Various constructors allow
|
||||||
@@ -116,7 +115,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
|
|||||||
* @param addrMap the address map
|
* @param addrMap the address map
|
||||||
* @param absolute if true, only absolute memory address encodings are considered, otherwise
|
* @param absolute if true, only absolute memory address encodings are considered, otherwise
|
||||||
* only standard/relocatable address encodings are considered.
|
* only standard/relocatable address encodings are considered.
|
||||||
* @param set the address set to iterate over.
|
* @param set the address set to iterate over or null for all addresses
|
||||||
* @param startAddr the address at which to position the iterator. The iterator will be positioned
|
* @param startAddr the address at which to position the iterator. The iterator will be positioned
|
||||||
* either before or after the start address depending on the before parameter. If this parameter
|
* either before or after the start address depending on the before parameter. If this parameter
|
||||||
* is null, then the iterator will start either before the min address or after the max address
|
* is null, then the iterator will start either before the min address or after the max address
|
||||||
@@ -174,6 +173,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.RecordIterator#hasNext()
|
* @see db.RecordIterator#hasNext()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean hasNext() throws IOException {
|
public boolean hasNext() throws IOException {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -197,6 +197,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.RecordIterator#hasPrevious()
|
* @see db.RecordIterator#hasPrevious()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean hasPrevious() throws IOException {
|
public boolean hasPrevious() throws IOException {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -220,6 +221,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.RecordIterator#next()
|
* @see db.RecordIterator#next()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public DBRecord next() throws IOException {
|
public DBRecord next() throws IOException {
|
||||||
if (hasNext()) {
|
if (hasNext()) {
|
||||||
return it.next();
|
return it.next();
|
||||||
@@ -230,6 +232,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.RecordIterator#previous()
|
* @see db.RecordIterator#previous()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public DBRecord previous() throws IOException {
|
public DBRecord previous() throws IOException {
|
||||||
if (hasPrevious()) {
|
if (hasPrevious()) {
|
||||||
return it.previous();
|
return it.previous();
|
||||||
@@ -240,6 +243,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
|
|||||||
/**
|
/**
|
||||||
* @see db.RecordIterator#delete()
|
* @see db.RecordIterator#delete()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean delete() throws IOException {
|
public boolean delete() throws IOException {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
return it.delete();
|
return it.delete();
|
||||||
|
|||||||
+5
-3
@@ -65,7 +65,7 @@ public interface AddressMap {
|
|||||||
/**
|
/**
|
||||||
* Search for addr within the "sorted" keyRangeList and return the index of the
|
* Search for addr within the "sorted" keyRangeList and return the index of the
|
||||||
* keyRange which contains the specified addr.
|
* keyRange which contains the specified addr.
|
||||||
* @param keyRangeList
|
* @param keyRangeList key range list to search
|
||||||
* @param addr address or null
|
* @param addr address or null
|
||||||
* @return index of the keyRange within the keyRangeList which contains addr
|
* @return index of the keyRange within the keyRangeList which contains addr
|
||||||
* if it is contained in the list; otherwise, <code>(-(<i>insertion point</i>) - 1)</code>.
|
* if it is contained in the list; otherwise, <code>(-(<i>insertion point</i>) - 1)</code>.
|
||||||
@@ -100,7 +100,7 @@ public interface AddressMap {
|
|||||||
* Generates a properly ordered list of database key ranges for a
|
* Generates a properly ordered list of database key ranges for a
|
||||||
* a specified address set. If absolute encodings are requested,
|
* a specified address set. If absolute encodings are requested,
|
||||||
* only memory addresses will be included.
|
* only memory addresses will be included.
|
||||||
* @param set address set or null for all real address.
|
* @param set address set or null for all addresses. May not be null if <code>create</code> is true.
|
||||||
* @param create true if a new keys may be generated, otherwise returned
|
* @param create true if a new keys may be generated, otherwise returned
|
||||||
* key-ranges will be limited to those already defined.
|
* key-ranges will be limited to those already defined.
|
||||||
* @return "sorted" list of KeyRange objects
|
* @return "sorted" list of KeyRange objects
|
||||||
@@ -113,12 +113,14 @@ public interface AddressMap {
|
|||||||
* "absoluteEncoding" method. If the program's default address space is segmented (i.e., SegmentedAddressSpace).
|
* "absoluteEncoding" method. If the program's default address space is segmented (i.e., SegmentedAddressSpace).
|
||||||
* the address returned will be always be normalized to defined segmented memory blocks if possible.
|
* the address returned will be always be normalized to defined segmented memory blocks if possible.
|
||||||
* @param value the long value to convert to an address.
|
* @param value the long value to convert to an address.
|
||||||
|
* @return address decoded from long
|
||||||
*/
|
*/
|
||||||
public Address decodeAddress(long value);
|
public Address decodeAddress(long value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the address factory associated with this map.
|
* Returns the address factory associated with this map.
|
||||||
* Null may be returned if map not associated with a specific address factory.
|
* Null may be returned if map not associated with a specific address factory.
|
||||||
|
* @return associated {@link AddressFactory} or null
|
||||||
*/
|
*/
|
||||||
public AddressFactory getAddressFactory();
|
public AddressFactory getAddressFactory();
|
||||||
|
|
||||||
@@ -140,7 +142,7 @@ public interface AddressMap {
|
|||||||
* Generates a properly ordered list of database key ranges for a
|
* Generates a properly ordered list of database key ranges for a
|
||||||
* a specified address set. If absolute encodings are requested,
|
* a specified address set. If absolute encodings are requested,
|
||||||
* only memory addresses will be included.
|
* only memory addresses will be included.
|
||||||
* @param set address set or null for all real address.
|
* @param set address set or null for all addresses. May not be null if <code>create</code> is true.
|
||||||
* @param absolute if true, absolute key encodings are returned, otherwise
|
* @param absolute if true, absolute key encodings are returned, otherwise
|
||||||
* standard/relocatable address key encodings are returned.
|
* standard/relocatable address key encodings are returned.
|
||||||
* @param create true if a new keys may be generated, otherwise returned
|
* @param create true if a new keys may be generated, otherwise returned
|
||||||
|
|||||||
+7
-8
@@ -434,7 +434,7 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an iterator over the long address keys which contain a property value.
|
* Get an iterator over the long address keys which contain a property value.
|
||||||
* @param set
|
* @param set addresses over which to iterate (null indicates all defined memory regions)
|
||||||
* @param atStart true if the iterator should be positioned at the start
|
* @param atStart true if the iterator should be positioned at the start
|
||||||
* of the range
|
* of the range
|
||||||
* @return long address iterator.
|
* @return long address iterator.
|
||||||
@@ -442,9 +442,8 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||||||
*/
|
*/
|
||||||
public AddressKeyIterator getAddressKeyIterator(AddressSetView set, boolean atStart)
|
public AddressKeyIterator getAddressKeyIterator(AddressSetView set, boolean atStart)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
if (propertyTable == null || (set != null && set.isEmpty())) {
|
||||||
if (propertyTable == null) {
|
return AddressKeyIterator.EMPTY_ITERATOR;
|
||||||
return new AddressKeyIterator();
|
|
||||||
}
|
}
|
||||||
if (atStart) {
|
if (atStart) {
|
||||||
return new AddressKeyIterator(propertyTable, addrMap, set, set.getMinAddress(), true);
|
return new AddressKeyIterator(propertyTable, addrMap, set, set.getMinAddress(), true);
|
||||||
@@ -463,7 +462,7 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
if (propertyTable == null) {
|
if (propertyTable == null) {
|
||||||
return new AddressKeyIterator();
|
return AddressKeyIterator.EMPTY_ITERATOR;
|
||||||
}
|
}
|
||||||
return new AddressKeyIterator(propertyTable, addrMap, start, before);
|
return new AddressKeyIterator(propertyTable, addrMap, start, before);
|
||||||
}
|
}
|
||||||
@@ -481,7 +480,7 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
if (propertyTable == null) {
|
if (propertyTable == null) {
|
||||||
return new AddressKeyIterator();
|
return AddressKeyIterator.EMPTY_ITERATOR;
|
||||||
}
|
}
|
||||||
if (atStart) {
|
if (atStart) {
|
||||||
return new AddressKeyIterator(propertyTable, addrMap, start, end, start, true);
|
return new AddressKeyIterator(propertyTable, addrMap, start, end, start, true);
|
||||||
@@ -561,8 +560,8 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AddressIterator getPropertyIterator(AddressSetView asv, boolean forward) {
|
public AddressIterator getPropertyIterator(AddressSetView asv, boolean forward) {
|
||||||
if (propertyTable == null) {
|
if (propertyTable == null || (asv != null && asv.isEmpty())) {
|
||||||
return new EmptyAddressIterator();
|
return AddressIterator.EMPTY_ITERATOR;
|
||||||
}
|
}
|
||||||
AddressKeyIterator keyIter = null;
|
AddressKeyIterator keyIter = null;
|
||||||
try {
|
try {
|
||||||
|
|||||||
+6
@@ -946,6 +946,9 @@ public class ReferenceDBManager implements ReferenceManager, ManagerDB, ErrorHan
|
|||||||
@Override
|
@Override
|
||||||
public AddressIterator getReferenceDestinationIterator(AddressSetView addrSet,
|
public AddressIterator getReferenceDestinationIterator(AddressSetView addrSet,
|
||||||
boolean forward) {
|
boolean forward) {
|
||||||
|
if (addrSet != null && addrSet.isEmpty()) {
|
||||||
|
return AddressIterator.EMPTY_ITERATOR;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return toAdapter.getToIterator(addrSet, forward);
|
return toAdapter.getToIterator(addrSet, forward);
|
||||||
}
|
}
|
||||||
@@ -973,6 +976,9 @@ public class ReferenceDBManager implements ReferenceManager, ManagerDB, ErrorHan
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AddressIterator getReferenceSourceIterator(AddressSetView addrSet, boolean forward) {
|
public AddressIterator getReferenceSourceIterator(AddressSetView addrSet, boolean forward) {
|
||||||
|
if (addrSet != null && addrSet.isEmpty()) {
|
||||||
|
return AddressIterator.EMPTY_ITERATOR;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return fromAdapter.getFromIterator(addrSet, forward);
|
return fromAdapter.getFromIterator(addrSet, forward);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -44,7 +44,7 @@ class AddressSetFilteredSymbolIterator implements SymbolIterator {
|
|||||||
/**
|
/**
|
||||||
* Construct a new AddressSetFilteredSymbolIterator.
|
* Construct a new AddressSetFilteredSymbolIterator.
|
||||||
* @param symbolMgr the symbol manager
|
* @param symbolMgr the symbol manager
|
||||||
* @param set the address set to iterator over.
|
* @param set the address set to iterator over (required).
|
||||||
* @param query the query to use as a filter
|
* @param query the query to use as a filter
|
||||||
* @param forward the direction of the iterator.
|
* @param forward the direction of the iterator.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+6
@@ -1204,6 +1204,9 @@ public class SymbolManager implements SymbolTable, ManagerDB {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SymbolIterator getPrimarySymbolIterator(AddressSetView set, boolean forward) {
|
public SymbolIterator getPrimarySymbolIterator(AddressSetView set, boolean forward) {
|
||||||
|
if (set.isEmpty()) {
|
||||||
|
return SymbolIterator.EMPTY_ITERATOR;
|
||||||
|
}
|
||||||
Query query1 = new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_DATA2_COL, new IntField(1));
|
Query query1 = new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_DATA2_COL, new IntField(1));
|
||||||
Query query2 = new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_TYPE_COL,
|
Query query2 = new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_TYPE_COL,
|
||||||
new ByteField(SymbolType.LABEL.getID()));
|
new ByteField(SymbolType.LABEL.getID()));
|
||||||
@@ -1216,6 +1219,9 @@ public class SymbolManager implements SymbolTable, ManagerDB {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SymbolIterator getSymbols(AddressSetView set, SymbolType type, boolean forward) {
|
public SymbolIterator getSymbols(AddressSetView set, SymbolType type, boolean forward) {
|
||||||
|
if (set.isEmpty()) {
|
||||||
|
return SymbolIterator.EMPTY_ITERATOR;
|
||||||
|
}
|
||||||
Query query =
|
Query query =
|
||||||
new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_TYPE_COL, new ByteField(type.getID()));
|
new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_TYPE_COL, new ByteField(type.getID()));
|
||||||
return new AddressSetFilteredSymbolIterator(this, set, query, forward);
|
return new AddressSetFilteredSymbolIterator(this, set, query, forward);
|
||||||
|
|||||||
+19
-14
@@ -16,6 +16,7 @@
|
|||||||
package ghidra.program.model.address;
|
package ghidra.program.model.address;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import util.CollectionUtils;
|
import util.CollectionUtils;
|
||||||
|
|
||||||
@@ -30,20 +31,24 @@ import util.CollectionUtils;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public interface AddressIterator extends Iterator<Address>, Iterable<Address> {
|
public interface AddressIterator extends Iterator<Address>, Iterable<Address> {
|
||||||
/**
|
|
||||||
* Get the next address.
|
|
||||||
*
|
|
||||||
* @return the next address in the iteration.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Address next();
|
|
||||||
|
|
||||||
/**
|
public static final AddressIterator EMPTY_ITERATOR = new AddressIterator() {
|
||||||
* Checks if there is a next address in the iteration.
|
|
||||||
*
|
@Override
|
||||||
* @return true if there is a next address.
|
public boolean hasNext() {
|
||||||
*/
|
return false;
|
||||||
@Override
|
}
|
||||||
public boolean hasNext();
|
|
||||||
|
@Override
|
||||||
|
public Address next() {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Address> iterator() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-2
@@ -26,14 +26,35 @@ import util.CollectionUtils;
|
|||||||
*/
|
*/
|
||||||
public interface CodeUnitIterator extends Iterator<CodeUnit>, Iterable<CodeUnit> {
|
public interface CodeUnitIterator extends Iterator<CodeUnit>, Iterable<CodeUnit> {
|
||||||
|
|
||||||
|
public static final CodeUnitIterator EMPTY_ITERATOR = new CodeUnitIterator() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodeUnit next() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<CodeUnit> iterator() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the iteration has more elements.
|
* Return true if there is a next CodeUnit.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext();
|
public boolean hasNext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the next code unit in the iteration.
|
* Get the next CodeUnit or null if no more CodeUnits.
|
||||||
|
* <P>NOTE: This deviates from the standard {@link Iterator} interface
|
||||||
|
* by returning null instead of throwing an exception.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CodeUnit next();
|
public CodeUnit next();
|
||||||
|
|||||||
+1
-1
@@ -213,7 +213,7 @@ public interface Listing {
|
|||||||
* addresses are contained in the given address set will be returned by the
|
* addresses are contained in the given address set will be returned by the
|
||||||
* iterator.
|
* iterator.
|
||||||
*
|
*
|
||||||
* @param addrSet the AddressRangeSet to iterate over.
|
* @param addrSet the AddressRangeSet to iterate over (required).
|
||||||
* @param forward true means get iterator in forward direction
|
* @param forward true means get iterator in forward direction
|
||||||
* @return a CodeUnitIterator that is restricted to the give
|
* @return a CodeUnitIterator that is restricted to the give
|
||||||
* AddressRangeSet.
|
* AddressRangeSet.
|
||||||
|
|||||||
+2
-2
@@ -288,7 +288,7 @@ public interface ReferenceManager {
|
|||||||
/**
|
/**
|
||||||
* Returns an iterator over all addresses that are the "From" address in a
|
* Returns an iterator over all addresses that are the "From" address in a
|
||||||
* reference, restricted by the given address set.
|
* reference, restricted by the given address set.
|
||||||
* @param addrSet the set of address to restrict the iterator.
|
* @param addrSet the set of address to restrict the iterator or null for all addresses.
|
||||||
* @param forward true means to iterate in the forward direction
|
* @param forward true means to iterate in the forward direction
|
||||||
*/
|
*/
|
||||||
public AddressIterator getReferenceSourceIterator(AddressSetView addrSet, boolean forward);
|
public AddressIterator getReferenceSourceIterator(AddressSetView addrSet, boolean forward);
|
||||||
@@ -304,7 +304,7 @@ public interface ReferenceManager {
|
|||||||
/**
|
/**
|
||||||
* Returns an iterator over all addresses that are the "To" address in a
|
* Returns an iterator over all addresses that are the "To" address in a
|
||||||
* memory reference, restricted by the given address set.
|
* memory reference, restricted by the given address set.
|
||||||
* @param addrSet the set of address to restrict the iterator.
|
* @param addrSet the set of address to restrict the iterator or null for all addresses.
|
||||||
* @param forward true means to iterate in the forward direction
|
* @param forward true means to iterate in the forward direction
|
||||||
*/
|
*/
|
||||||
public AddressIterator getReferenceDestinationIterator(AddressSetView addrSet, boolean forward);
|
public AddressIterator getReferenceDestinationIterator(AddressSetView addrSet, boolean forward);
|
||||||
|
|||||||
+25
-1
@@ -25,13 +25,37 @@ import util.CollectionUtils;
|
|||||||
* @see CollectionUtils#asIterable
|
* @see CollectionUtils#asIterable
|
||||||
*/
|
*/
|
||||||
public interface SymbolIterator extends Iterator<Symbol>, Iterable<Symbol> {
|
public interface SymbolIterator extends Iterator<Symbol>, Iterable<Symbol> {
|
||||||
|
|
||||||
|
public static final SymbolIterator EMPTY_ITERATOR = new SymbolIterator() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Symbol> iterator() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Symbol next() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if there is a next symbol.
|
* Return true if there is a next symbol.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean hasNext();
|
public boolean hasNext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next symbol.
|
* Get the next symbol or null if no more symbols.
|
||||||
|
* <P>NOTE: This deviates from the standard {@link Iterator} interface
|
||||||
|
* by returning null instead of throwing an exception.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Symbol next();
|
public Symbol next();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -420,7 +420,7 @@ public interface SymbolTable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the symbols of the given type within the given address set.
|
* Returns all the symbols of the given type within the given address set.
|
||||||
* @param set the address set in which to look for symbols of the given type
|
* @param set the address set in which to look for symbols of the given type (required).
|
||||||
* @param type the SymbolType to look for.
|
* @param type the SymbolType to look for.
|
||||||
* @param forward the direction within the addressSet to search
|
* @param forward the direction within the addressSet to search
|
||||||
* @return symbol iterator
|
* @return symbol iterator
|
||||||
@@ -500,7 +500,7 @@ public interface SymbolTable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an iterator over symbols at addresses in the given addressSet
|
* Get an iterator over symbols at addresses in the given addressSet
|
||||||
* @param asv the set of address over which to iterate symbols.
|
* @param asv the set of address over which to iterate symbols (required).
|
||||||
* @param forward true means the iterator is in the forward direction
|
* @param forward true means the iterator is in the forward direction
|
||||||
* @return symbol iterator
|
* @return symbol iterator
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user