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:
emteere 2024-05-14 11:34:14 -04:00
parent a483c7c971
commit 04972dc810
7 changed files with 223 additions and 42 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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"/>

View File

@ -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 ];

View File

@ -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];
}

View File

@ -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"/>

View File

@ -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;
}