mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Refactor HighSymbol mutability
This commit is contained in:
parent
616bf82426
commit
e279c5b56a
6 changed files with 69 additions and 144 deletions
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
|||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.data.MutabilitySettingsDefinition;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.listing.VariableStorage;
|
||||
import ghidra.util.exception.AssertException;
|
||||
|
@ -115,13 +116,8 @@ public class DynamicEntry extends SymbolEntry {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVolatile() {
|
||||
return false;
|
||||
public int getMutability() {
|
||||
return MutabilitySettingsDefinition.NORMAL;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
|||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.MutabilitySettingsDefinition;
|
||||
import ghidra.program.model.lang.DynamicVariableStorage;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
|
@ -314,10 +315,14 @@ public class HighSymbol {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return true if the symbol's value is considered read-only (by the decompiler)
|
||||
* Return one of
|
||||
* - MutabilitySettingsDefinition.NORMAL
|
||||
* - MutabilitySettingsDefinition.VOLATILE
|
||||
* - MutabilitySettingsDefinition.CONSTANT
|
||||
* @return the mutability setting
|
||||
*/
|
||||
public boolean isReadOnly() {
|
||||
return entryList[0].isReadOnly();
|
||||
public int getMutability() {
|
||||
return entryList[0].getMutability();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -384,9 +389,11 @@ public class HighSymbol {
|
|||
encoder.writeString(ATTRIB_NAME, name);
|
||||
encoder.writeBool(ATTRIB_TYPELOCK, typelock);
|
||||
encoder.writeBool(ATTRIB_NAMELOCK, namelock);
|
||||
encoder.writeBool(ATTRIB_READONLY, isReadOnly());
|
||||
boolean isVolatile = entryList[0].isVolatile();
|
||||
if (isVolatile) {
|
||||
int mutability = getMutability();
|
||||
if (mutability == MutabilitySettingsDefinition.CONSTANT) {
|
||||
encoder.writeBool(ATTRIB_READONLY, true);
|
||||
}
|
||||
else if (mutability == MutabilitySettingsDefinition.VOLATILE) {
|
||||
encoder.writeBool(ATTRIB_VOLATILE, true);
|
||||
}
|
||||
if (isIsolated()) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package ghidra.program.model.pcode;
|
||||
|
||||
import ghidra.program.model.data.MutabilitySettingsDefinition;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.VariableStorage;
|
||||
|
||||
|
@ -57,21 +58,16 @@ public class MappedDataEntry extends MappedEntry {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
if (data.isWritable()) {
|
||||
return false;
|
||||
public int getMutability() {
|
||||
if (data.isVolatile()) {
|
||||
return MutabilitySettingsDefinition.VOLATILE;
|
||||
}
|
||||
if (data.isConstant()) {
|
||||
return true;
|
||||
return MutabilitySettingsDefinition.CONSTANT;
|
||||
}
|
||||
return super.isReadOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVolatile() {
|
||||
if (data.isVolatile()) {
|
||||
return true;
|
||||
if (data.isWritable()) {
|
||||
return MutabilitySettingsDefinition.NORMAL;
|
||||
}
|
||||
return super.isVolatile();
|
||||
return super.getMutability();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.io.IOException;
|
|||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.AbstractFloatDataType;
|
||||
import ghidra.program.model.data.MutabilitySettingsDefinition;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.listing.VariableStorage;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
|
@ -87,59 +88,44 @@ public class MappedEntry extends SymbolEntry {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
public int getMutability() {
|
||||
Address addr = storage.getMinAddress();
|
||||
return getMutabilityOfAddress(addr, symbol.getProgram());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying mutability setting of an Address based on the Program
|
||||
* configuration and the MemoryBlock. Ignore any overrides of Data at the address.
|
||||
* @param addr is the Address
|
||||
* @param program is the Program containing the Address
|
||||
* @return the mutability
|
||||
*/
|
||||
public static int getMutabilityOfAddress(Address addr, Program program) {
|
||||
if (addr == null) {
|
||||
return false;
|
||||
return MutabilitySettingsDefinition.NORMAL;
|
||||
}
|
||||
if (program.getLanguage().isVolatile(addr)) {
|
||||
return MutabilitySettingsDefinition.VOLATILE;
|
||||
}
|
||||
boolean readonly = false;
|
||||
Program program = symbol.getProgram();
|
||||
MemoryBlock block = program.getMemory().getBlock(addr);
|
||||
if (block != null) {
|
||||
readonly = !block.isWrite();
|
||||
if (block.isVolatile()) {
|
||||
return MutabilitySettingsDefinition.VOLATILE;
|
||||
}
|
||||
// if the block says read-only, check the refs to the variable
|
||||
// if the block says read-only, check the refs to the variable
|
||||
if (readonly) {
|
||||
if (!block.isWrite()) {
|
||||
ReferenceIterator refIter = program.getReferenceManager().getReferencesTo(addr);
|
||||
int count = 0;
|
||||
// boolean foundRead = false;
|
||||
while (refIter.hasNext() && count < 100) {
|
||||
Reference ref = refIter.next();
|
||||
if (ref.getReferenceType().isWrite()) {
|
||||
readonly = false;
|
||||
break;
|
||||
}
|
||||
if (ref.getReferenceType().isRead()) {
|
||||
// foundRead = true;
|
||||
return MutabilitySettingsDefinition.NORMAL;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
// TODO: Don't do override if no read reference found
|
||||
//
|
||||
// if we only have indirect refs to it, don't assume readonly!
|
||||
//if (!foundRead && readonly && count > 1) {
|
||||
// readonly = false;
|
||||
//}
|
||||
// they must be reading it multiple times for some reason
|
||||
// if (readonly && count > 1) {
|
||||
// readonly = false;
|
||||
// }
|
||||
return MutabilitySettingsDefinition.CONSTANT;
|
||||
}
|
||||
}
|
||||
return readonly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVolatile() {
|
||||
Address addr = storage.getMinAddress();
|
||||
if (addr == null) {
|
||||
return false;
|
||||
}
|
||||
Program program = symbol.getProgram();
|
||||
if (program.getLanguage().isVolatile(addr)) {
|
||||
return true;
|
||||
}
|
||||
MemoryBlock block = program.getMemory().getBlock(addr);
|
||||
return (block != null && block.isVolatile());
|
||||
return MutabilitySettingsDefinition.NORMAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,14 +67,13 @@ public abstract class SymbolEntry {
|
|||
public abstract int getSize();
|
||||
|
||||
/**
|
||||
* @return true if the mapped storage is read-only
|
||||
* Return one of
|
||||
* - MutabilitySettingsDefinition.NORMAL
|
||||
* - MutabilitySettingsDefinition.VOLATILE
|
||||
* - MutabilitySettingsDefinition.CONSTANT
|
||||
* @return the mutability setting
|
||||
*/
|
||||
public abstract boolean isReadOnly();
|
||||
|
||||
/**
|
||||
* @return true if the mapped storage is volatile
|
||||
*/
|
||||
public abstract boolean isVolatile();
|
||||
public abstract int getMutability();
|
||||
|
||||
/**
|
||||
* The storage used to hold this Symbol may be used for other purposes at different points in
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue