mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-1556 - Added support for searching for structure fields by offset
This commit is contained in:
parent
883f5a687a
commit
812ea4fe1e
45 changed files with 1461 additions and 840 deletions
|
@ -38,10 +38,10 @@ public interface Data extends CodeUnit, Settings {
|
|||
|
||||
/**
|
||||
* Get the class used to express the value of this data.
|
||||
*
|
||||
*
|
||||
* <p>NOTE: This determination is made based upon data type and settings only and does not
|
||||
* examine memory bytes which are used to construct the data value object.
|
||||
*
|
||||
*
|
||||
* @return value class or null if a consistent class is not utilized.
|
||||
*/
|
||||
public Class<?> getValueClass();
|
||||
|
@ -216,7 +216,7 @@ public interface Data extends CodeUnit, Settings {
|
|||
* Return the first immediate child component that contains the byte at the given offset. It
|
||||
* is important to note that with certain datatypes there may be more than one component
|
||||
* containing the specified offset (see {@link #getComponentsContaining(int)}).
|
||||
*
|
||||
*
|
||||
* @param offset the amount to add to this data items address to get the address of the
|
||||
* requested data item.
|
||||
* @return first data component containing offset or null
|
||||
|
@ -227,10 +227,10 @@ public interface Data extends CodeUnit, Settings {
|
|||
public Data getComponentAt(int offset);
|
||||
|
||||
/**
|
||||
* RReturn the first immediate child component that contains the byte at the given offset. It
|
||||
* Return the first immediate child component that contains the byte at the given offset. It
|
||||
* is important to note that with certain datatypes there may be more than one component
|
||||
* containing the specified offset (see {@link #getComponentsContaining(int)}).
|
||||
*
|
||||
*
|
||||
* @param offset the amount to add to this data items address to get the
|
||||
* @return first data component containing offset or null address of the requested data item.
|
||||
*/
|
||||
|
|
|
@ -17,13 +17,15 @@
|
|||
|
||||
package ghidra.program.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
|
||||
/**
|
||||
* The <CODE>FieldNameFieldLocation</CODE> class provides specific information
|
||||
* about the Function Name field within a program location.
|
||||
* The <CODE>FieldNameFieldLocation</CODE> class provides specific information about the Function
|
||||
* Name field within a program location.
|
||||
*/
|
||||
public class FieldNameFieldLocation extends CodeUnitLocation {
|
||||
|
||||
|
@ -31,11 +33,11 @@ public class FieldNameFieldLocation extends CodeUnitLocation {
|
|||
|
||||
/**
|
||||
* Construct a new FieldNameFieldLocation.
|
||||
*
|
||||
*
|
||||
* @param program the program of the location
|
||||
* @param addr the address of the codeunit.
|
||||
* @param componentPath if not null, it is the array of indexes that point
|
||||
* to a specific data type inside of another data type
|
||||
* @param addr the address of the code unit
|
||||
* @param componentPath if not null, it is the array of indexes that point to a specific data
|
||||
* type inside of another data type
|
||||
* @param fieldName the field name
|
||||
* @param charOffset the character position within the field name for this location.
|
||||
*/
|
||||
|
@ -48,14 +50,14 @@ public class FieldNameFieldLocation extends CodeUnitLocation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Default constructor needed for restoring
|
||||
* a field name location from XML
|
||||
* Default constructor needed for restoring a field name location from XML
|
||||
*/
|
||||
public FieldNameFieldLocation() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field name of this location.
|
||||
* @return the name.
|
||||
*/
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
|
@ -71,19 +73,19 @@ public class FieldNameFieldLocation extends CodeUnitLocation {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
if (this == obj) {
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
FieldNameFieldLocation other = (FieldNameFieldLocation) obj;
|
||||
if (fieldName == null) {
|
||||
if (other.fieldName != null)
|
||||
return false;
|
||||
}
|
||||
else if (!fieldName.equals(other.fieldName))
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
FieldNameFieldLocation other = (FieldNameFieldLocation) obj;
|
||||
if (!Objects.equals(fieldName, other.fieldName)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,14 +15,16 @@
|
|||
*/
|
||||
package ghidra.program.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.listing.VariableOffset;
|
||||
|
||||
/**
|
||||
* The <CODE>OperandFieldLocation</CODE> class contains specific location information
|
||||
* within the OPERAND field of a CodeUnitLocation object.
|
||||
* The <CODE>OperandFieldLocation</CODE> class contains specific location information within the
|
||||
* OPERAND field of a CodeUnitLocation object.
|
||||
*/
|
||||
public class OperandFieldLocation extends CodeUnitLocation {
|
||||
|
||||
|
@ -32,17 +34,18 @@ public class OperandFieldLocation extends CodeUnitLocation {
|
|||
|
||||
/**
|
||||
* Construct a new OperandFieldLocation object.
|
||||
*
|
||||
* @param program the program of the location
|
||||
* @param addr address of the location; should not be null
|
||||
* @param componentPath array of indexes for each nested data component; the
|
||||
* index is the data component's index within its parent; may be null
|
||||
*
|
||||
* @param program the program of the location.
|
||||
* @param addr address of the location; should not be null.
|
||||
* @param componentPath array of indexes for each nested data component; the index is the data
|
||||
* component's index within its parent; may be null.
|
||||
* @param refAddr the reference 'to' address.
|
||||
* @param rep the String representation of the operand.
|
||||
* @param opIndex the index of the operand at this location.
|
||||
* @param characterOffset the character position from the beginning of the operand.
|
||||
*/
|
||||
public OperandFieldLocation(Program program, Address addr, int[] componentPath,
|
||||
Address refAddr, String rep, int opIndex, int characterOffset) {
|
||||
public OperandFieldLocation(Program program, Address addr, int[] componentPath, Address refAddr,
|
||||
String rep, int opIndex, int characterOffset) {
|
||||
|
||||
super(program, addr, componentPath, refAddr, 0, opIndex, characterOffset);
|
||||
|
||||
|
@ -52,68 +55,63 @@ public class OperandFieldLocation extends CodeUnitLocation {
|
|||
|
||||
/**
|
||||
* Construct a new OperandFieldLocation object.
|
||||
*
|
||||
* @param program the program of the location
|
||||
* @param addr address of the location; should not be null
|
||||
* @param componentPath array of indexes for each nested data component; the
|
||||
* index is the data component's index within its parent; may be null
|
||||
* @param refAddr the "referred to" address if the location is
|
||||
* over a reference; may be null
|
||||
*
|
||||
* @param program the program of the location.
|
||||
* @param addr address of the location; should not be null.
|
||||
* @param componentPath array of indexes for each nested data component; the index is the data
|
||||
* component's index within its parent; may be null .
|
||||
* @param refAddr the "referred to" address if the location is over a reference; may be null.
|
||||
* @param rep the String representation of the operand.
|
||||
* @param opIndex the index indicating the operand the location is on.
|
||||
* @param subOpIndex the index of the Object within the operand, this can
|
||||
* be used to call an instructions getOpObjects() method
|
||||
* @param characterOffset the character position from the beginning of the operand field
|
||||
* @param subOpIndex the index of the Object within the operand, this can be used to call an
|
||||
* instructions getOpObjects() method.
|
||||
* @param characterOffset the character position from the beginning of the operand field.
|
||||
*/
|
||||
public OperandFieldLocation(Program program, Address addr, int[] componentPath,
|
||||
Address refAddr, String rep, int opIndex, int subOpIndex, int characterOffset) {
|
||||
|
||||
public OperandFieldLocation(Program program, Address addr, int[] componentPath, Address refAddr,
|
||||
String rep, int opIndex, int subOpIndex, int characterOffset) {
|
||||
super(program, addr, componentPath, refAddr, 0, opIndex, characterOffset);
|
||||
|
||||
this.rep = rep;
|
||||
this.subOpIndex = subOpIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new OperandFieldLocation object for an instruction operand.
|
||||
*
|
||||
* @param program the program of the location
|
||||
* @param addr address of the location; should not be null
|
||||
* @param variableOffset associated variable offset or null
|
||||
* @param refAddr the "referred to" address if the location is
|
||||
* over a reference; may be null
|
||||
*
|
||||
* @param program the program of the location.
|
||||
* @param addr address of the location; should not be null.
|
||||
* @param variableOffset associated variable offset or null.
|
||||
* @param refAddr the "referred to" address if the location is over a reference; may be null.
|
||||
* @param rep the String representation of the operand.
|
||||
* @param opIndex the index indicating the operand the location is on.
|
||||
* @param subOpIndex the index of the Object within the operand, this can
|
||||
* be used to call an instructions getOpObjects() method
|
||||
* @param characterOffset the character position from the beginning of the operand field
|
||||
* @param subOpIndex the index of the Object within the operand, this can be used to call an
|
||||
* instructions getOpObjects() method.
|
||||
* @param characterOffset the character position from the beginning of the operand field.
|
||||
*/
|
||||
public OperandFieldLocation(Program program, Address addr, VariableOffset variableOffset,
|
||||
Address refAddr, String rep, int opIndex, int subOpIndex, int characterOffset) {
|
||||
|
||||
super(program, addr, null, refAddr, 0, opIndex, characterOffset);
|
||||
|
||||
this.rep = rep;
|
||||
this.subOpIndex = subOpIndex;
|
||||
this.variableOffset = variableOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor needed for restoring
|
||||
* an operand field location from XML.
|
||||
*/
|
||||
* Default constructor needed for restoring an operand field location from XML.
|
||||
*/
|
||||
public OperandFieldLocation() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns VariableOffset object if applicable or null
|
||||
* Returns VariableOffset object if applicable or null.
|
||||
* @return the variable offset.
|
||||
*/
|
||||
public VariableOffset getVariableOffset() {
|
||||
return variableOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the opernand at this location.
|
||||
* Returns a string representation of the operand at this location.
|
||||
* @return the representation.
|
||||
*/
|
||||
public String getOperandRepresentation() {
|
||||
return rep;
|
||||
|
@ -121,6 +119,7 @@ public class OperandFieldLocation extends CodeUnitLocation {
|
|||
|
||||
/**
|
||||
* Returns the index of the operand at this location.
|
||||
* @return the index
|
||||
*/
|
||||
public int getOperandIndex() {
|
||||
return getColumn();
|
||||
|
@ -128,18 +127,15 @@ public class OperandFieldLocation extends CodeUnitLocation {
|
|||
|
||||
/**
|
||||
* Returns the sub operand index at this location.
|
||||
* This index can be used on the instruction.getOpObjects()
|
||||
* to find the actual object (Address, Register, Scalar) the
|
||||
* cursor is over.
|
||||
* <p>
|
||||
* This index can be used on the instruction.getOpObjects() to find the actual object (Address,
|
||||
* Register, Scalar) the cursor is over.
|
||||
* @return 0-n if over a valid OpObject, -1 otherwise
|
||||
*/
|
||||
public int getSubOperandIndex() {
|
||||
return subOpIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String representation of this location.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ", OpRep = " + rep + ", subOpIndex = " + subOpIndex +
|
||||
|
@ -158,27 +154,25 @@ public class OperandFieldLocation extends CodeUnitLocation {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
if (this == obj) {
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
}
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
OperandFieldLocation other = (OperandFieldLocation) obj;
|
||||
if (rep == null) {
|
||||
if (other.rep != null)
|
||||
return false;
|
||||
if (!Objects.equals(rep, other.rep)) {
|
||||
return false;
|
||||
}
|
||||
else if (!rep.equals(other.rep))
|
||||
if (subOpIndex != other.subOpIndex) {
|
||||
return false;
|
||||
if (subOpIndex != other.subOpIndex)
|
||||
return false;
|
||||
if (variableOffset == null) {
|
||||
if (other.variableOffset != null)
|
||||
return false;
|
||||
}
|
||||
else if (!variableOffset.equals(other.variableOffset))
|
||||
if (!Objects.equals(variableOffset, other.variableOffset)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
* Construct a new ProgramLocation for the given address. The address will be adjusted to the
|
||||
* beginning of the {@link CodeUnit code unit} containing that address (if it exists). The
|
||||
* original address can be retrieved using the {@link #getByteAddress()}" method.
|
||||
*
|
||||
*
|
||||
* @param program the program associated with this program location (also used to obtain a
|
||||
* code-unit-aligned address)
|
||||
* @param addr address of the location; cannot be null
|
||||
|
@ -118,7 +118,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
* Construct a new ProgramLocation for the given address. The address will be adjusted to the
|
||||
* beginning of the {@link CodeUnit code unit} containing that address (if it exists). The
|
||||
* original address can be retrieved using the {@link #getByteAddress()} method.
|
||||
*
|
||||
*
|
||||
* @param program the program associated with this program location (also used to obtain a
|
||||
* code-unit-aligned address)
|
||||
* @param addr address for the location
|
||||
|
@ -132,7 +132,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
* Construct a new ProgramLocation for the given address. The address will be adjusted to the
|
||||
* beginning of the {@link CodeUnit code unit} containing that address (if it exists). The
|
||||
* original address can be retrieved using the {@link #getByteAddress()} method.
|
||||
*
|
||||
*
|
||||
* @param program the program associated with this program location (also used to obtain a
|
||||
* code-unit-aligned address)
|
||||
* @param addr address for the location
|
||||
|
@ -150,7 +150,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
* Construct a new ProgramLocation for the given address. The address will be adjusted to the
|
||||
* beginning of the {@link CodeUnit code unit} containing that address (if it exists). The
|
||||
* original address can be retrieved using the {@link #getByteAddress()} method.
|
||||
*
|
||||
*
|
||||
* @param program the program associated with this program location (also used to obtain a
|
||||
* code-unit-aligned address)
|
||||
* @param addr address for the location
|
||||
|
@ -170,6 +170,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
/**
|
||||
* Returns the componentPath for the {@link CodeUnit code unit}. Null will be returned if the
|
||||
* object is an {@link Instruction} or a top-level {@link Data} object.
|
||||
* @return the path.
|
||||
*/
|
||||
public int[] getComponentPath() {
|
||||
return componentPath;
|
||||
|
@ -177,6 +178,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Returns the program associated with this location.
|
||||
* @return the program.
|
||||
*/
|
||||
public Program getProgram() {
|
||||
return program;
|
||||
|
@ -184,11 +186,12 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Returns the address associated with this location.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Note: this may not be the same as the byte address. For example, in a {@link CodeUnit code
|
||||
* unit} location this may be the minimum address of the code unit that contains the byte
|
||||
* address.
|
||||
* @return the address.
|
||||
*/
|
||||
public Address getAddress() {
|
||||
return addr;
|
||||
|
@ -196,6 +199,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Returns the byte level address associated with this location.
|
||||
* @return the byte address.
|
||||
*/
|
||||
public Address getByteAddress() {
|
||||
return byteAddr;
|
||||
|
@ -203,6 +207,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Returns the "referred to" address if the location is over an address in some field.
|
||||
* @return the address.
|
||||
*/
|
||||
public Address getRefAddress() {
|
||||
return refAddr;
|
||||
|
@ -210,7 +215,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Save this program location to the given save state object.
|
||||
*
|
||||
*
|
||||
* @param obj the save state object for saving the location
|
||||
*/
|
||||
public void saveState(SaveState obj) {
|
||||
|
@ -231,7 +236,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Restore this program location using the given program and save state object.
|
||||
*
|
||||
*
|
||||
* @param program1 program to restore from
|
||||
* @param obj the save state to restore from
|
||||
*/
|
||||
|
@ -254,7 +259,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Get the program location for the given program and save state object.
|
||||
*
|
||||
*
|
||||
* @param program the program for the location
|
||||
* @param saveState the state to restore
|
||||
* @return the restored program location
|
||||
|
@ -274,7 +279,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
}
|
||||
// no address, it must be in a removed block; we can't use it
|
||||
}
|
||||
catch (RuntimeException e) { // restoreState may not parse the address if it is no longer valid.
|
||||
catch (RuntimeException e) { // state may not parse the address if it is no longer valid
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
// not sure why we are ignoring this--if you know, then please let everyone else know
|
||||
|
@ -419,7 +424,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
}
|
||||
CodeUnit cu = p.getListing().getCodeUnitContaining(addr);
|
||||
|
||||
// if the codeunit is a data, try and dig down to the lowest subdata containing the address
|
||||
// if the code unit is data, get the lowest sub-data containing the address
|
||||
if (cu instanceof Data) {
|
||||
Data data = (Data) cu;
|
||||
cu = data.getPrimitiveAt((int) addr.subtract(data.getAddress()));
|
||||
|
@ -437,10 +442,10 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if this location represents a valid location in the given program
|
||||
*
|
||||
* Returns true if this location represents a valid location in the given program.
|
||||
*
|
||||
* @param testProgram the program to test if this location is valid.
|
||||
* @return true if this location represents a valid location in the given program
|
||||
* @return true if this location represents a valid location in the given program.
|
||||
*/
|
||||
public boolean isValid(Program testProgram) {
|
||||
return addr == null || testProgram.getAddressFactory().isValidAddress(addr);
|
||||
|
@ -448,7 +453,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Returns the row within the program location.
|
||||
*
|
||||
*
|
||||
* @return the row within the program location.
|
||||
*/
|
||||
public int getRow() {
|
||||
|
@ -456,9 +461,9 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the character offset in the display item at the (row,col)
|
||||
*
|
||||
* @return the character offset in the display item at the (row,col)
|
||||
* Returns the character offset in the display item at the (row,col).
|
||||
*
|
||||
* @return the character offset in the display item at the (row,col).
|
||||
*/
|
||||
public int getCharOffset() {
|
||||
return charOffset;
|
||||
|
@ -467,6 +472,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
/**
|
||||
* Returns the column index of the display piece represented by this location. For most
|
||||
* locations, there is only one display item per row, in which case this value will be 0.
|
||||
* @return the column.
|
||||
*/
|
||||
public int getColumn() {
|
||||
return col;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue