mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-24 13:11:47 +00:00
GP-4569 Pic instruction modifications, analyzer fix for 0 values in
small registers affecting PCLATH, modification of PIC16 analysis defaults
This commit is contained in:
parent
a483c7c971
commit
04972dc810
@ -150,7 +150,13 @@ public class ConstantPropagationAnalyzer extends AbstractAnalyzer {
|
||||
// unless there is a good data type at the location
|
||||
boolean isHarvard = program.getLanguage().getDefaultSpace() != program.getLanguage().getDefaultDataSpace();
|
||||
checkPointerParamRefsOption = program.getDefaultPointerSize() <= 2 || isHarvard;
|
||||
|
||||
checkStoredRefsOption = program.getDefaultPointerSize() > 2 && !isHarvard;
|
||||
|
||||
long size = program.getAddressFactory().getDefaultAddressSpace().getSize();
|
||||
minSpeculativeRefAddress = size * 16;
|
||||
maxSpeculativeRefAddress = size * 8;
|
||||
|
||||
checkParamRefsOption = !(program.getAddressFactory()
|
||||
.getDefaultAddressSpace() instanceof SegmentedAddressSpace);
|
||||
|
||||
@ -570,12 +576,9 @@ public class ConstantPropagationAnalyzer extends AbstractAnalyzer {
|
||||
options.registerOption(MIN_KNOWN_REFADDRESS_OPTION_NAME, minStoreLoadRefAddress, null,
|
||||
MIN_KNOWN_REFADDRESS_OPTION_DESCRIPTION);
|
||||
|
||||
long size = program.getAddressFactory().getDefaultAddressSpace().getSize();
|
||||
minSpeculativeRefAddress = size * 16;
|
||||
options.registerOption(MIN_SPECULATIVE_REFADDRESS_OPTION_NAME, minSpeculativeRefAddress, null,
|
||||
MIN_SPECULATIVE_REFADDRESS_OPTION_DESCRIPTION);
|
||||
|
||||
maxSpeculativeRefAddress = size * 8;
|
||||
options.registerOption(MAX_SPECULATIVE_REFADDRESS_OPTION_NAME, maxSpeculativeRefAddress, null,
|
||||
MAX_SPECULATIVE_REFADDRESS_OPTION_DESCRIPTION);
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ public class VarnodeContext implements ProcessorContext {
|
||||
|
||||
private final int BAD_OFFSET_SPACEID; // address space for offsets from an unknown value;
|
||||
|
||||
static final String SUSPECT_CONST_NAME = "SuspectConst";
|
||||
private final int SUSPECT_OFFSET_SPACEID; // address space for suspect constant values
|
||||
public final Address SUSPECT_ZERO_ADDRESS;
|
||||
|
||||
@ -109,7 +110,7 @@ public class VarnodeContext implements ProcessorContext {
|
||||
/* Suspect constants act like constants, but are in a SuspectConst
|
||||
* address space instead of the constant space.
|
||||
*/
|
||||
SUSPECT_ZERO_ADDRESS = addrFactory.getAddress(getAddressSpace("SuspectConst"), 0);
|
||||
SUSPECT_ZERO_ADDRESS = addrFactory.getAddress(getAddressSpace(SUSPECT_CONST_NAME), 0);
|
||||
SUSPECT_OFFSET_SPACEID = SUSPECT_ZERO_ADDRESS.getAddressSpace().getSpaceID();
|
||||
|
||||
this.programContext = programContext;
|
||||
@ -1754,6 +1755,16 @@ class OffsetAddressFactory extends DefaultAddressFactory {
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
// Borrow JOIN type space for suspect constants
|
||||
// Hack for current storage allows suspect constants to fit in a byte
|
||||
AddressSpace suspectConstspc = new GenericAddressSpace(VarnodeContext.SUSPECT_CONST_NAME, 64,
|
||||
AddressSpace.TYPE_JOIN, 0);
|
||||
addAddressSpace(suspectConstspc);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
throw new AssertException("Duplicate name should not occur.");
|
||||
}
|
||||
try {
|
||||
addAddressSpace(AddressSpace.EXTERNAL_SPACE);
|
||||
}
|
||||
|
@ -11,11 +11,104 @@
|
||||
<set name="SkipNext" val="0"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE">
|
||||
<set name="RP" val="0"/>
|
||||
<set name="RP" val="0x00"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0" last="0x1ff">
|
||||
<tracked_set space="CODE" first="0x0000" last="0x01ff">
|
||||
<set name="PCLATH" val="0"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0200" last="0x03ff">
|
||||
<set name="PCLATH" val="1"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0400" last="0x05ff">
|
||||
<set name="PCLATH" val="2"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0600" last="0x07ff">
|
||||
<set name="PCLATH" val="3"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0800" last="0x09ff">
|
||||
<set name="PCLATH" val="4"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0a00" last="0x0bff">
|
||||
<set name="PCLATH" val="5"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0c00" last="0x0dff">
|
||||
<set name="PCLATH" val="6"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0e00" last="0x0fff">
|
||||
<set name="PCLATH" val="7"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1000" last="0x11ff">
|
||||
<set name="PCLATH" val="8"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1200" last="0x13ff">
|
||||
<set name="PCLATH" val="9"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1400" last="0x15ff">
|
||||
<set name="PCLATH" val="10"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1600" last="0x17ff">
|
||||
<set name="PCLATH" val="11"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1800" last="0x19ff">
|
||||
<set name="PCLATH" val="12"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1a00" last="0x1bff">
|
||||
<set name="PCLATH" val="13"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1c00" last="0x1dff">
|
||||
<set name="PCLATH" val="14"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1e00" last="0x1fff">
|
||||
<set name="PCLATH" val="15"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2000" last="0x21ff">
|
||||
<set name="PCLATH" val="16"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2200" last="0x23ff">
|
||||
<set name="PCLATH" val="17"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2400" last="0x25ff">
|
||||
<set name="PCLATH" val="18"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2600" last="0x27ff">
|
||||
<set name="PCLATH" val="19"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2800" last="0x29ff">
|
||||
<set name="PCLATH" val="20"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2a00" last="0x2bff">
|
||||
<set name="PCLATH" val="21"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2c00" last="0x2dff">
|
||||
<set name="PCLATH" val="22"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2e00" last="0x2fff">
|
||||
<set name="PCLATH" val="23"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3000" last="0x31ff">
|
||||
<set name="PCLATH" val="24"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3200" last="0x33ff">
|
||||
<set name="PCLATH" val="25"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3400" last="0x35ff">
|
||||
<set name="PCLATH" val="26"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3600" last="0x37ff">
|
||||
<set name="PCLATH" val="27"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3800" last="0x39ff">
|
||||
<set name="PCLATH" val="28"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3a00" last="0x3bff">
|
||||
<set name="PCLATH" val="29"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3c00" last="0x3dff">
|
||||
<set name="PCLATH" val="30"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3e00" last="0x3fff">
|
||||
<set name="PCLATH" val="31"/>
|
||||
</tracked_set>
|
||||
</context_data>
|
||||
<volatile outputop="write_sfr" inputop="read_sfr">
|
||||
<range space="DATA" first="0x1" last="0x1"/>
|
||||
|
@ -82,8 +82,6 @@ define DATA offset=0x0000 size=1 [
|
||||
];
|
||||
@elif PROCESSOR == "PIC_16F"
|
||||
define DATA offset=0x0000 size=1 [
|
||||
#PIC16LF1554 INDF0 INDF1 PCL STATUS FSR0L FSR0H FSR1L FSR1H BSR WREG PCLATH INTCON _ _ _ _
|
||||
#PIC16LF1559 INDF0 INDF1 PCL STATUS FSR0L FSR0H FSR1L FSR1H BSR WREG PCLATH INTCON _ _ _ _
|
||||
INDF0 INDF1 PCL STATUS FSR0L FSR0H FSR1L FSR1H BSR WREG PCLATH INTCON _ _ _ _
|
||||
];
|
||||
define DATA offset=0x0004 size=2 [ FSR0 FSR1 ];
|
||||
|
@ -238,13 +238,13 @@ D: "f" is d=1 { }
|
||||
|
||||
# Absolute address generated from k11 and PCLATH<4:3>
|
||||
absAddr11: k11 is k11 {
|
||||
addr:2 = ((zext(PCLATH) & 0x78) << 8) + k11;
|
||||
addr:2 = ((zext(PCLATH) & 0x18) << 8) | k11;
|
||||
export addr;
|
||||
}
|
||||
|
||||
@if PROCESSOR == "PIC_16F"
|
||||
|
||||
# Absolute address generated from k11 and PCLATH<4:3>
|
||||
# Relative address
|
||||
relAddr9: addr is sk9 [ addr = inst_next + sk9; ] {
|
||||
export *[CODE]:2 addr;
|
||||
}
|
||||
@ -327,7 +327,7 @@ trisREG: "7" is l5=7 { local trl:2 = 0x10E; export *[DATA]:1 trl; } #
|
||||
tmp:1 = addr:1;
|
||||
setAddFlags(tmp, W);
|
||||
tmp = tmp + W;
|
||||
addr = (zext(PCLATH) << 8) + zext(tmp);
|
||||
addr = ((zext(PCLATH) & 0x1F) << 8) | zext(tmp);
|
||||
PCL = tmp;
|
||||
setResultFlags(tmp);
|
||||
goto [addr];
|
||||
@ -365,7 +365,7 @@ trisREG: "7" is l5=7 { local trl:2 = 0x10E; export *[DATA]:1 trl; } #
|
||||
$(C) = $(C) | tc;
|
||||
val = val + tmpC;
|
||||
|
||||
addr = (zext(PCLATH) << 8) + zext(val);
|
||||
addr = ((zext(PCLATH) & 0x1F) << 8) | zext(val);
|
||||
PCL = val;
|
||||
setResultFlags(val);
|
||||
goto [addr];
|
||||
@ -799,7 +799,7 @@ srcFSRk: sk6"["fsrk"]" is fsrk & sk6 {
|
||||
}
|
||||
|
||||
:MOVLP imm7 is op7=0x63 & imm7 {
|
||||
PCLATH = imm7;
|
||||
PCLATH = imm7 & 0x1F;
|
||||
}
|
||||
@endif
|
||||
|
||||
@ -831,7 +831,7 @@ srcFSRk: sk6"["fsrk"]" is fsrk & sk6 {
|
||||
# --00 0000 1fff ffff
|
||||
# 0000 0000 1000 0010 -> MOVWF PCL
|
||||
PCL = W;
|
||||
addr:2 = (zext(PCLATH) << 8) + zext(PCL);
|
||||
addr:2 = ((zext(PCLATH) & 0x1F) << 8) | zext(PCL);
|
||||
goto [addr];
|
||||
}
|
||||
|
||||
|
@ -10,9 +10,102 @@
|
||||
<tracked_set space="CODE">
|
||||
<set name="BSR" val="0"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0" last="0x1ff">
|
||||
<tracked_set space="CODE" first="0x0000" last="0x01ff">
|
||||
<set name="PCLATH" val="0"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0200" last="0x03ff">
|
||||
<set name="PCLATH" val="1"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0400" last="0x05ff">
|
||||
<set name="PCLATH" val="2"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0600" last="0x07ff">
|
||||
<set name="PCLATH" val="3"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0800" last="0x09ff">
|
||||
<set name="PCLATH" val="4"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0a00" last="0x0bff">
|
||||
<set name="PCLATH" val="5"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0c00" last="0x0dff">
|
||||
<set name="PCLATH" val="6"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x0e00" last="0x0fff">
|
||||
<set name="PCLATH" val="7"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1000" last="0x11ff">
|
||||
<set name="PCLATH" val="8"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1200" last="0x13ff">
|
||||
<set name="PCLATH" val="9"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1400" last="0x15ff">
|
||||
<set name="PCLATH" val="10"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1600" last="0x17ff">
|
||||
<set name="PCLATH" val="11"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1800" last="0x19ff">
|
||||
<set name="PCLATH" val="12"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1a00" last="0x1bff">
|
||||
<set name="PCLATH" val="13"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1c00" last="0x1dff">
|
||||
<set name="PCLATH" val="14"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x1e00" last="0x1fff">
|
||||
<set name="PCLATH" val="15"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2000" last="0x21ff">
|
||||
<set name="PCLATH" val="16"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2200" last="0x23ff">
|
||||
<set name="PCLATH" val="17"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2400" last="0x25ff">
|
||||
<set name="PCLATH" val="18"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2600" last="0x27ff">
|
||||
<set name="PCLATH" val="19"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2800" last="0x29ff">
|
||||
<set name="PCLATH" val="20"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2a00" last="0x2bff">
|
||||
<set name="PCLATH" val="21"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2c00" last="0x2dff">
|
||||
<set name="PCLATH" val="22"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x2e00" last="0x2fff">
|
||||
<set name="PCLATH" val="23"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3000" last="0x31ff">
|
||||
<set name="PCLATH" val="24"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3200" last="0x33ff">
|
||||
<set name="PCLATH" val="25"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3400" last="0x35ff">
|
||||
<set name="PCLATH" val="26"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3600" last="0x37ff">
|
||||
<set name="PCLATH" val="27"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3800" last="0x39ff">
|
||||
<set name="PCLATH" val="28"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3a00" last="0x3bff">
|
||||
<set name="PCLATH" val="29"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3c00" last="0x3dff">
|
||||
<set name="PCLATH" val="30"/>
|
||||
</tracked_set>
|
||||
<tracked_set space="CODE" first="0x3e00" last="0x3fff">
|
||||
<set name="PCLATH" val="31"/>
|
||||
</tracked_set>
|
||||
</context_data>
|
||||
<volatile outputop="write_sfr" inputop="read_sfr">
|
||||
<range space="DATA" first="0xb" last="0x1f"/>
|
||||
|
@ -53,6 +53,11 @@ public class Pic16Analyzer extends ConstantPropagationAnalyzer {
|
||||
|
||||
@Override
|
||||
public boolean canAnalyze(Program p) {
|
||||
boolean cananalyze = super.canAnalyze(p);
|
||||
|
||||
if (!cananalyze) {
|
||||
return false;
|
||||
}
|
||||
Language lang = p.getLanguage();
|
||||
statusReg = p.getRegister("STATUS");
|
||||
pclathReg = p.getRegister("PCLATH");
|
||||
@ -63,6 +68,10 @@ public class Pic16Analyzer extends ConstantPropagationAnalyzer {
|
||||
rpStatusReg = p.getRegister("RP");
|
||||
irpStatusReg = p.getRegister("IRP");
|
||||
|
||||
// set default analysis options
|
||||
minSpeculativeRefAddress = 4;
|
||||
minStoreLoadRefAddress = 4;
|
||||
|
||||
return lang.getProcessor() == PicProcessor.PROCESSOR_PIC_16 && pclathReg != null;
|
||||
}
|
||||
|
||||
@ -82,25 +91,6 @@ public class Pic16Analyzer extends ConstantPropagationAnalyzer {
|
||||
// use context to fill out addresses on certain instructions
|
||||
ConstantPropagationContextEvaluator eval = new ConstantPropagationContextEvaluator(monitor, trustWriteMemOption) {
|
||||
|
||||
@Override
|
||||
public boolean evaluateReference(VarnodeContext context, Instruction instr, int pcodeop, Address address,
|
||||
int size, DataType dataType, RefType refType) {
|
||||
AddressSpace space = address.getAddressSpace();
|
||||
|
||||
if (address.isExternalAddress()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (space.hasMappedRegisters()) {
|
||||
return true;
|
||||
}
|
||||
boolean isCodeSpace = address.getAddressSpace().getName().equals(CODE_SPACE_NAME);
|
||||
if (refType.isComputed() && refType.isFlow() && isCodeSpace) {
|
||||
return true;
|
||||
}
|
||||
return super.evaluateReference(context, instr, pcodeop, address, size, dataType, refType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean evaluateDestination(VarnodeContext context, Instruction instruction) {
|
||||
FlowType flowType = instruction.getFlowType();
|
||||
@ -111,11 +101,9 @@ public class Pic16Analyzer extends ConstantPropagationAnalyzer {
|
||||
Reference[] refs = instruction.getReferencesFrom();
|
||||
if (refs.length == 1 && refs[0].getReferenceType().isFlow()) {
|
||||
writeContext(refs[0].getToAddress(), context);
|
||||
Address dest = refs[0].getToAddress();
|
||||
disassemblyPoints.addRange(dest, dest);
|
||||
}
|
||||
|
||||
return false;
|
||||
return super.evaluateDestination(context, instruction);
|
||||
}
|
||||
|
||||
private void writeContext(Address dest, VarnodeContext context) {
|
||||
@ -157,11 +145,6 @@ public class Pic16Analyzer extends ConstantPropagationAnalyzer {
|
||||
|
||||
AddressSet result = symEval.flowConstants(flowStart, flowSet, eval, true, monitor);
|
||||
|
||||
if (!disassemblyPoints.isEmpty()) {
|
||||
AutoAnalysisManager mgr = AutoAnalysisManager.getAnalysisManager(program);
|
||||
mgr.disassemble(disassemblyPoints);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user