Merge remote-tracking branch

'origin/GP-4596_emteere_PR-6466_antoniovazquezblanco_picdefs'
(Closes #6466, Closes #3239)
This commit is contained in:
Ryan Kurtz
2024-07-25 12:56:00 -04:00
8 changed files with 299 additions and 103 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

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -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,20 @@ class OffsetAddressFactory extends DefaultAddressFactory {
}
}
}
try {
// Use JOIN type space for suspect constants, it is used by the decompiler, so can
// be repurposed for this algorithm.
// Hack for current storage allows suspect constants to fit in a byte. The current
// algorithm is sensitive to the space ID value and must be less than 0x7f. Only types that are
// between 0-16 will work correctly because of how the spaceID is calculated based on the space type.
// The spaceID is computed using the type.
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

@@ -14,7 +14,6 @@
<compiler name="default" spec="pic16.cspec" id="default"/>
<external_name tool="IDA-PRO" name="pic16cxx"/>
</language>
<!-- TODO: Need PIC-16F manual and index -->
<language processor="PIC-16"
endian="little"
size="16"

View File

@@ -10,9 +10,105 @@
<tracked_set space="CODE">
<set name="SkipNext" val="0"/>
</tracked_set>
<tracked_set space="CODE" first="0x0" last="0x1ff">
<tracked_set space="CODE">
<set name="RP" val="0x00"/>
</tracked_set>
<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"/>
@@ -40,6 +136,14 @@
<default_symbols>
<symbol name="Reset" address="CODE:0000" entry="true"/>
<symbol name="Interrupt" address="CODE:0004" entry="true"/>
<symbol name="TMR0" address="DATA:01" entry="false"/>
<symbol name="PORTA" address="DATA:05" entry="false"/>
<symbol name="PORTB" address="DATA:06" entry="false"/>
<symbol name="PORTC" address="DATA:07" entry="false"/>
<symbol name="PORTD" address="DATA:08" entry="false"/>
<symbol name="PORTE" address="DATA:09" entry="false"/>
<symbol name="PIR1" address="DATA:0C" entry="false"/>
<symbol name="PIR2" address="DATA:0D" entry="false"/>
<symbol name="TMR1L" address="DATA:0E" entry="false"/>

View File

@@ -2,28 +2,6 @@
# PIC-16 Main Section
# includes constants, memory space and common register space definitions
#
# STATUS bit definitions
@define STATUS_IRP_BIT 7
@define STATUS_RP0_BIT 5
@define STATUS_Z_BIT 2
@define STATUS_DC_BIT 1
@define STATUS_C_BIT 0
# STATUS bit masks used for setting
@define STATUS_IRP_MASK 0x80
@define STATUS_RP_MASK 0x60
@define STATUS_Z_MASK 0x04
@define STATUS_DC_MASK 0x02
@define STATUS_C_MASK 0x01
# STATUS bit masks used for clearing
@define STATUS_IRP_CLEARMASK 0x7F
@define STATUS_RP_CLEARMASK 0x9F
@define STATUS_Z_CLEARMASK 0xFB
@define STATUS_DC_CLEARMASK 0xFD
@define STATUS_C_CLEARMASK 0xFE
define endian=little;
define alignment=2;
@@ -50,18 +28,37 @@ define register offset=0x0002 size=1 [ STKPTR ];
define register offset=0x0003 size=1 [ W SkipNext ];
# Status bit registers (these do not really exist and must get reflected into the STATUS byte register)
@if PROCESSOR == "PIC_16"
define register offset=0x0007 size=1 [ IRP RP ];
@elif PROCESSOR == "PIC_16F"
define register offset=0x0007 size=1 [ IRP RP ];
@endif
@define C "STATUS[0,1]"
@define DC "STATUS[1,1]"
@define Z "STATUS[2,1]"
@define PD "STATUS[3,1]"
@define TO "STATUS[4,1]"
@define PA0 "STATUS[5,1]"
@define RP "STATUS[5,2]"
@define IRP "STATUS[7,1]"
# STATUS bit definitions
@define STATUS_IRP_BIT 7
@define STATUS_RP_BIT 5
@define STATUS_Z_BIT 2
@define STATUS_DC_BIT 1
@define STATUS_C_BIT 0
# STATUS bit masks used for setting
@define STATUS_IRP_MASK 0x80
@define STATUS_RP_MASK 0x60
@define STATUS_Z_MASK 0x04
@define STATUS_DC_MASK 0x02
@define STATUS_C_MASK 0x01
# STATUS bit masks used for clearing
@define STATUS_IRP_CLEARMASK 0x7F
@define STATUS_RP_CLEARMASK 0x9F
@define STATUS_Z_CLEARMASK 0xFB
@define STATUS_DC_CLEARMASK 0xFD
@define STATUS_C_CLEARMASK 0xFE
#
# WARNING! - Reflection of these DATA-based registers with the corresponding register
@@ -80,16 +77,13 @@ define register offset=0x0007 size=1 [ IRP RP ];
#
@if PROCESSOR == "PIC_16"
define DATA offset=0x0000 size=1 [
INDF TMR0 PCL STATUS FSR PORTA PORTB PORTC PORTD PORTE PCLATH INTCON PIR1 PIR2 TMR1L TMR1H
INDF _ PCL STATUS FSR _ _ _ _ _ PCLATH INTCON _ _ _ _
];
@elif PROCESSOR == "PIC_16F"
define DATA offset=0x0000 size=1 [
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 ];
@endif
# Additional Data Bank data registers are defined in the .PSPEC file.

View File

@@ -25,7 +25,6 @@ define token instr16(16)
uf7 = (4,6)
fsr = (2,2)
fsrk = (6,6)
fregCore = (0,3)
k5 = (0,4)
k6 = (0,5)
k7 = (0,6)
@@ -44,15 +43,7 @@ define context contextreg
;
@if PROCESSOR == "PIC_16"
attach variables [ fregCore ] [
INDF TMR0 PCL STATUS FSR PORTA PORTB PORTC PORTD PORTE PCLATH INTCON _ _ _ _
];
@elif PROCESSOR == "PIC_16F"
attach variables [ fregCore ] [
INDF0 INDF1 PCL STATUS FSR0L FSR0H FSR1L FSR1H BSR W PCLATH INTCON _ _ _ _
];
@if PROCESSOR == "PIC_16F"
attach names [IntConBits] [ IOCIF INTF TMR0IF IOCIE INTE TMR0IE PEIE GIE ];
@@ -178,31 +169,45 @@ srcREG: fv is uf7=0x7 & lf7 [fv = 0x70 + lf7; ] {
export *[DATA]:1 addr;
}
# The registers listed here are explicitly defined as registers in sleigh.
# There are other registers but they are named in the .pspec file.
# The reason this is done is to have cross references created to certain registers, and to have
# only the registers that must be accessed directly in sleigh (e.g. PCL, FSR) defined in sleigh.
# Register explicitly defined in sleigh will not have xref's created to them.
# Registers named only in the .pspec file will have xref's to them in most cases.
#
# Also, these registers ignore RP, or BSR which allow more registers to be in a different register bank.
#
# PIC16 : INDF _ PCL STATUS FSR _ _ _ _ _ PCLATH INTCON _ _ _ _
# PIC16F: INDF0 INDF1 PCL STATUS FSR0L FSR0H FSR1L FSR1H BSR W PCLATH INTCON _ _ _ _
# File register index (f7=0): INDF use implies indirect data access using FSR value and IRP bit in STATUS reg
@if PROCESSOR == "PIC_16"
srcREG: fregCore is f7=0 & fregCore {
srcREG: INDF is f7=0 & INDF {
addr:2 = (zext(IRP) << 8) + zext(FSR);
export *[DATA]:1 addr;
}
srcREG: fregCore is f7=1 & fregCore {
rpval:2 = zext(RP == 1) + zext(RP == 2);
addr:2 = (zext(rpval) << 7) + 1;
export *[DATA]:1 addr;
srcREG: lf7 is f7=1 & lf7 {
rpval:2 = zext(RP == 1) + zext(RP == 3);
addr:2 = (zext(rpval) << 7) + 1;
export *[DATA]:1 addr;
}
@elif PROCESSOR == "PIC_16F"
srcREG: fregCore is f7=0 & fregCore {
srcREG: INDF0 is f7=0 & INDF0 {
addr:2 = FSR0;
export *[DATA]:1 addr;
}
srcREG: fregCore is f7=1 & fregCore {
srcREG: INDF1 is f7=1 & INDF1 {
addr:2 = FSR1;
export *[DATA]:1 addr;
}
@endif
# Special File Registers always mapped to Bank-0
srcREG: fregCore is f7=0x02 & fregCore {
srcREG: PCL is f7=0x02 & PCL {
# PCL and PCLATH must be latched
addr:2 = inst_start >> 1; # Compensate for CODE wordsize
PCL = addr:1;
@@ -210,17 +215,19 @@ srcREG: fregCore is f7=0x02 & fregCore {
export PCL;
}
srcREG: fregCore is f7=0x03 & fregCore { export fregCore; }
srcREG: fregCore is f7=0x04 & fregCore { export fregCore; }
@if PROCESSOR == "PIC_16F"
srcREG: fregCore is f7=0x05 & fregCore { export fregCore; }
srcREG: fregCore is f7=0x06 & fregCore { export fregCore; }
srcREG: fregCore is f7=0x07 & fregCore { export fregCore; }
srcREG: fregCore is f7=0x08 & fregCore { export fregCore; }
srcREG: fregCore is f7=0x09 & fregCore { export fregCore; }
srcREG: STATUS is f7=0x03 & STATUS { export STATUS; }
@if PROCESSOR == "PIC_16"
srcREG: FSR is f7=0x04 & FSR { export FSR; }
@elif PROCESSOR == "PIC_16F"
srcREG: FSR0L is f7=0x04 & FSR0L { export FSR0L; }
srcREG: FSR0H is f7=0x05 & FSR0H { export FSR0H; }
srcREG: FSR1L is f7=0x06 & FSR1L { export FSR1L; }
srcREG: FSR1H is f7=0x07 & FSR1H { export FSR1H; }
srcREG: BSR is f7=0x08 & BSR { export BSR; }
srcREG: W is f7=0x09 & W { export W; }
@endif
srcREG: fregCore is f7=0x0a & fregCore { export fregCore; }
srcREG: fregCore is f7=0x0b & fregCore { export fregCore; }
srcREG: PCLATH is f7=0x0a & PCLATH { export PCLATH; }
srcREG: INTCON is f7=0x0b & INTCON { export INTCON; }
# Destination register (either srcREG or W)
@@ -230,7 +237,7 @@ destREG: "0" is d=0 { export W; }
destREG: "1" is d=1 & f7 & srcREG { export srcREG; }
# Destination register: Special File Registers always mapped to Bank-0
destREG: "1" is d=1 & f7=0x02 & fregCore { export fregCore; } # PCL (special behavior reqd)
destREG: "1" is d=1 & f7=0x02 { export PCL; } # PCL (special behavior reqd)
# Destination operand representation (w: W register is destination; f: specified srcREG is destination)
D: "w" is d=0 { }
@@ -238,13 +245,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 +334,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 +372,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 +806,7 @@ srcFSRk: sk6"["fsrk"]" is fsrk & sk6 {
}
:MOVLP imm7 is op7=0x63 & imm7 {
PCLATH = imm7;
PCLATH = imm7 & 0x1F;
}
@endif
@@ -831,7 +838,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,9 @@ public class Pic16Analyzer extends ConstantPropagationAnalyzer {
@Override
public boolean canAnalyze(Program p) {
if (!super.canAnalyze(p)) {
return false;
}
Language lang = p.getLanguage();
statusReg = p.getRegister("STATUS");
pclathReg = p.getRegister("PCLATH");
@@ -63,6 +66,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 +89,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 +99,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 +143,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;
}