Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,5 @@ SLEIGH & P-Code References
--------------------------
Extensive documentation covering SLEIGH and P-Code is available online:

* `SLEIGH, P-Code Introduction <https://htmlpreview.github.io/?https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.0.2_build/GhidraDocs/languages/html/sleigh.html>`_
* `P-Code Reference Manual <https://htmlpreview.github.io/?https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.0.2_build/GhidraDocs/languages/html/pcoderef.html>`_
* `SLEIGH, P-Code Introduction <https://htmlpreview.github.io/?https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.1_build/GhidraDocs/languages/html/sleigh.html>`_
* `P-Code Reference Manual <https://htmlpreview.github.io/?https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.1_build/GhidraDocs/languages/html/pcoderef.html>`_
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pypcode documentation
=====================
pypcode is a machine code disassembly and IR translation library for Python using the
excellent `SLEIGH <https://ghidra.re/courses/languages/html/sleigh.html>`__ library from the `Ghidra <https://ghidra-sre.org/>`__ framework (version 12.0.2).
excellent `SLEIGH <https://ghidra.re/courses/languages/html/sleigh.html>`__ library from the `Ghidra <https://ghidra-sre.org/>`__ framework (version 12.1).

This library was created primarily for use with `angr <http://angr.io>`__, which provides analyses and symbolic
execution of p-code.
Expand Down
1 change: 1 addition & 0 deletions pypcode/processors/68000/data/languages/68000.pspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<processor_spec>
<properties>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.m68kEmulateInstructionStateModifier"/>
<property key="useropLibs" value="m68k,trig"/>
<property key="assemblyRating:68000:BE:32:default" value="PLATINUM"/>
</properties>
<programcounter register="PC"/>
Expand Down
14 changes: 8 additions & 6 deletions pypcode/processors/8051/data/languages/80251.sinc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ define token srcDestByte (8)
drk03 = (0,3)
# constraint bits
d7 = (7,7)
d67 = (6,7)
d57 = (5,7)
d47 = (4,7)
s3 = (3,3)
Expand All @@ -36,6 +37,7 @@ define token srcDestByte2 (8)
drk03_ = (0,3)
# constraint bits
d7_ = (7,7)
d67_ = (6,7)
d57_ = (5,7)
s3_ = (3,3)
s13_ = (1,3)
Expand Down Expand Up @@ -85,13 +87,13 @@ attach variables [ wrj47_d2 ] [
# NOTE: must use constraints DRK, DRKD and DRKS
attach variables [ drk47 drk03 drk47_ drk03_ ] [
DR0 DR4 DR8 DR12 DR16 DR20 DR24 DR28
DPX SPX _ _ _ _ _ _
_ _ _ _ _ _ DPX SPX
];

@define DRK47 "drk47 & (d7=0 | d57=4)" # constraint for using drk47
@define DRK03 "drk03 & (s3=0 | s13=4)" # constraint for using drk03
@define DRK47_ "drk47_ & (d7_=0 | d57_=4)" # constraint for using drk47_
@define DRK47 "drk47 & (d7=0 | d67=3)" # constraint for using drk47
@define DRK03 "drk03 & (s3=0 | s23=3)" # constraint for using drk03
@define DRK47_ "drk47_ & (d7_=0 | d67_=3)" # constraint for using drk47_

AtWRjb: "@"^wrj47 is wrj47 { ptr:3 = zext(wrj47); export *:1 ptr; }
AtWRjw: "@"^wrj47 is wrj47 { ptr:3 = zext(wrj47); export *:2 ptr; }

Expand Down Expand Up @@ -497,7 +499,7 @@ macro pop24(val) {


# MOVH DRk,#data16
:MOVH drk47,Data16x0 is $(GROUP3) & ophi=7 & oplo=14; $(DRK47) & s03=12; Data16x0 { drk47 = (drk47 & 0xffff0000) | (Data16x0 << 16); }
:MOVH drk47,Data16x0 is $(GROUP3) & ophi=7 & oplo=0xa; $(DRK47) & s03=0xc; Data16x0 { drk47 = (drk47 & 0xffff) | (Data16x0 << 16); }

# MOVS WRj,Rm
:MOVZ wrj47,rm03 is $(GROUP3) & ophi=1 & oplo=10; wrj47 & rm03 { wrj47 = sext(rm03); }
Expand Down
114 changes: 83 additions & 31 deletions pypcode/processors/8051/data/languages/8051_main.sinc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ define space BITS type=ram_space size=2;
# EXTERNAL - 0x010000-0x01ffff
# INTERNAL - 0x000000-0x0000ff

@elif defined(MCS51)
@elif defined(MCS51) || defined(CIP51)

@if defined(PTRSIZE)
@else
Expand All @@ -47,12 +47,64 @@ define space BITS type=ram_space size=2;
#
@define SP_SIZE 1

define space RAM type=ram_space size=1;
define space CODE type=ram_space size=$(PTRSIZE) default;
define space INTMEM type=ram_space size=1;
define space EXTMEM type=ram_space size=2;
@if defined(CIP51)
#
# CIP-51 allows up to 256 128-byte pages of these, or 32768 bytes, so two address bytes
# are needed for SFR space.
#
# At execution, SFR page selection uses the 8-bit SFRPAGE SFR to provide the page number,
# which effectively is the upper byte of SFR's full address.
#
# The devices covered in the F12x/13x datasheet only have 5 SFR pages and numbers them 0,
# 1, 2, 3, and F. The datasheet doesn't go into detail about SFRPAGE bits 2 to 6, but
# I suppose that for Ghidra instruction decoding it would suffice to just decode the full
# byte. A custom analyzer or script could check for the use of undefined SFRPAGEs.
#
define space SFR type=ram_space size=2;
@else
#
# Intel MCS-51 devices have a maximum of 128 SFRs and a byte-wide address suffices
#
define space SFR type=ram_space size=1;
@endif
define space BITS type=ram_space size=1;

@if defined(CIP51)
# Per the datasheet https://www.silabs.com/documents/public/data-sheets/C8051F12x-13x.pdf
# (rev 1.4)
# on-chip (internal) flash program/data memory addresses are
# 00000 - 1fbff F120/1/2/3/4/5/6/7, F130/1
# 00000 - 0ffff F132/3
# All of the 12x/13x chips covered by the datasheet have
# on-chip scratchpad (i.e. data only) flash:
# 20000 - 200FF
# So allowing 3 address bytes for CIP51 will cover the entire address range for the
# on-chip (internal) flash
define space IFLASH type=ram_space size=3;
#
# As with Intel's original MCS-51 architecture, CIP-51 "internal" ordinary RAM resides on
# the processor chip and uses single-byte addressing.
#
# The lower half of internal RAM can be accessed either directly (by encoding an 8 bit
# address in the opcode) or indirectly (via an address stored in R0 or R1).
#
# The upper half of internal RAM can be accessed only indirectly, again via R0 or R1.
#
# 00 - 7f directly and indirectly addressable
# 80 - ff indirectly addressable only (via R0 or R1)
#
# In CIP51 chips, addresses in the upper half of the range (that is, 80 - FF), when used
# directly, rather than accessing ordinary RAM get mapped to the chip's special function
# register RAM.
#

define space XRAM type=ram_space size=2;
@endif

@elif defined(MCS80390)

@define PTRSIZE 3
Expand Down Expand Up @@ -117,7 +169,7 @@ define register offset=0x38 size=1 [ R56 DPXL DPH DPL R60 R61 SPH ];
define register offset=0x3A size=2 [ DPTR ];
define register offset=0x38 size=4 [ DPX SPX ];

@elif defined(MCS51) || defined(MCS80390) || defined(MX51)
@elif defined(MCS51) || defined(MCS80390) || defined(MX51) || defined(CIP51)

define register offset=0x00 size=4 [ R0R1R2R3 ];
define register offset=0x01 size=3 [ R1R2R3 ]; # Used as R3R2R1
Expand All @@ -129,7 +181,7 @@ define register offset=0x05 size=3 [ R5R6R7 ];
define register offset=0x0A size=1 [ B ACC ]; # relocated to facilitate AB 16-bit access
define register offset=0x0A size=2 [ AB ];

@if defined(MCS51) || defined(MX51)
@if defined(MCS51) || defined(MX51) || defined(CIP51)
define register offset=0x82 size=2 [ DPTR ];
define register offset=0x82 size=1 [ DPH DPL ]; # relocated to facilitate DPTR 16-bit access
@elif defined(MCS80390)
Expand Down Expand Up @@ -192,7 +244,7 @@ define context contextReg
# GROUP3 - MCS251 instructions in 0x60-0xff range
@define GROUP3 "((srcMode=0 & A5Prefix=1) | (srcMode=1 & A5Prefix=0))"

@elif defined(MCS51) || defined(MCS80390) || defined(MX51)
@elif defined(MCS51) || defined(MCS80390) || defined(MX51) || defined(CIP51)

@define GROUP1 "epsilon"
@define GROUP2 "epsilon"
Expand Down Expand Up @@ -352,7 +404,7 @@ macro push8(val) {
SPX = SPX + 1;
ptr:3 = SPX:3;
*[RAM]:1 ptr = val;
@elif defined(MCS51) || defined(MCS80390)
@elif defined(MCS51) || defined(MCS80390) || defined(CIP51)
SP = SP + 1;
*[INTMEM]:1 SP = val;
@elif defined(MX51)
Expand Down Expand Up @@ -384,16 +436,16 @@ macro push16(val) {
*[RAM]:1 SPX:3 = al;
SPX = SPX + 1;
*[RAM]:1 SPX:3 = ah;
@elif defined(MCS51)

@elif defined(MCS51) || defined(CIP51)
al:1 = val:1;
ah:1 = val(1);

SP = SP + 1;
*[INTMEM]:1 SP = al;
SP = SP + 1;
SP = SP + 1;
*[INTMEM]:1 SP = ah;

@elif defined(MX51)
# dptr push
#ptr:1 = SP + 1;
Expand Down Expand Up @@ -432,7 +484,7 @@ macro pop8(val) {
ptr:3 = SPX:3;
val = *[RAM]:1 ptr;
SPX = SPX - 1;
@elif defined(MCS51) || defined(MCS80390)
@elif defined(MCS51) || defined(MCS80390) || defined(CIP51)
val = *[INTMEM]:1 SP;
SP = SP - 1;
@elif defined(MX51)
Expand Down Expand Up @@ -477,9 +529,9 @@ macro pop16(val) {
SPX = SPX - 1;

val = (zext(ah) << 8) | zext(al);
@elif defined(MCS51)

@elif defined(MCS51) || defined(CIP51)

ah:1 = *[INTMEM]:1 SP;
SP = SP - 1;
al:1 = *[INTMEM]:1 SP;
Expand Down Expand Up @@ -512,7 +564,7 @@ DPTRreg: DPTR is ophi & DPTR { export DPTR; }

@if defined(MCS251)
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:3 = 0xff0000 + zext(DPTR) + zext(ACC); export ptr; }
@elif defined(MCS51)
@elif defined(MCS51) || defined(CIP51)
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:$(PTRSIZE) = zext(DPTR) + zext(ACC); export ptr; }
@elif defined(MCS80390)
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR) + zext(ACC); export ptr; }
Expand All @@ -524,7 +576,7 @@ APC: "@A+PC" is epsilon { tmp:$(PTRSIZE) = inst_next + zext(ACC); expor

@if defined(MCS251)
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = 0x010000 + zext(DPTR); export *:1 ptr; } # 8051 External data address mapped into RAM space
@elif defined(MCS51)
@elif defined(MCS51) || defined(CIP51)
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:2 = DPTR; export *[EXTMEM]:1 ptr; }
@elif defined(MCS80390)
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR); export *[EXTMEM]:1 ptr; }
Expand All @@ -536,13 +588,13 @@ ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR); export *[RAM]:1 ptr; }
Ri: @ri is ri { ptr:3 = zext(ri); export *[RAM]:1 ptr; }
@elif defined(MX51)
Ri: @ri is ri { ptr:3 = zext(ri) + 0x7f0000; export *[RAM]:1 ptr; }
@elif defined(MCS51) || defined(MCS80390)
@elif defined(MCS51) || defined(MCS80390) || defined(CIP51)
Ri: @ri is ri { export *[INTMEM]:1 ri; }
@endif

@if defined(MCS251)
RiX: @ri is ri { ptr:3 = 0x010000 + zext(ri); export *:1 ptr; } # 8051 8-bit External data address mapped into RAM space
@elif defined(MCS51)
@elif defined(MCS51) || defined(CIP51)
RiX: @ri is ri { ptr:2 = zext(ri); export *[EXTMEM]:1 ptr; } # limited to 8-bit external data address (I/O state can be used to produce 16-bit addr)
@elif defined(MCS80390)
RiX: @ri is ri { ptr:3 = zext(ri); export *[EXTMEM]:1 ptr; } # tocheck
Expand All @@ -560,7 +612,7 @@ Data24: "#"data24 is data24 { export *[const]:3 data24; }
Direct: mainreg is bank=0 & mainreg { export *[RAM]:1 mainreg; }
@elif defined(MX51)
Direct: mainreg is bank=0 & mainreg { tmp:3 = mainreg + 0x7f0000; export *[RAM]:1 tmp; }
@elif defined(MCS51) || defined(MCS80390)
@elif defined(MCS51) || defined(MCS80390) || defined(CIP51)
Direct: mainreg is bank=0 & mainreg { export *[INTMEM]:1 mainreg; }
@endif
Direct: direct is bank=1 & direct { export *[SFR]:1 direct; }
Expand All @@ -580,7 +632,7 @@ Direct: DPXL is bank=1 & direct=0x84 & DPXL { export DPXL; }
Direct2: mainreg2 is bank2=0 & mainreg2 { export *[RAM]:1 mainreg2; }
@elif defined(MX51)
Direct2: mainreg2 is bank2=0 & mainreg2 { tmp:3 = mainreg2 + 0x7f0000; export *[RAM]:1 tmp; }
@elif defined(MCS51) || defined(MCS80390)
@elif defined(MCS51) || defined(MCS80390) || defined(CIP51)
Direct2: mainreg2 is bank2=0 & mainreg2 { export *[INTMEM]:1 mainreg2; }
@endif
Direct2: direct2 is bank2=1 & direct2 { export *[SFR]:1 direct2; }
Expand All @@ -601,7 +653,7 @@ BitAddr: bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 6)+sfrb
BitAddr: bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
BitAddr2: "/"bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 6)+sfrbit; ] { export *[BITS]:1 bitaddr; }
BitAddr2: "/"bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
@elif defined(MCS51) || defined(MCS80390) || defined(MX51)
@elif defined(MCS51) || defined(MCS80390) || defined(MX51) || defined(CIP51)
##
##TODO !!! 8051 SFRBITS bit overlay block is probably incorrect since there is not a 1:1 mapping to the SFR space
## While the BitAddr is only used for disassembly markup, and labels come from pspec, the underlying data will
Expand All @@ -622,11 +674,11 @@ BitByteAddr: PSW is bitbank=1 & sfrbyte=0x1A & sfrbit & PSW { export PSW; }
BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { export *[RAM]:1 byteaddr; }
@elif defined(MX51)
BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { tmp:3 = byteaddr + 0x7f0000; export *[RAM]:1 tmp; }
@elif defined(MCS51) || defined(MCS80390)
@elif defined(MCS51) || defined(MCS80390) || defined(CIP51)
BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { export *[INTMEM]:1 byteaddr; }
@endif

@if defined(MCS251) || defined(MX51)
@if defined(MCS251) || defined(MX51) || defined(CIP51)
Addr11: relAddr is aopaddr & adata [ relAddr = (inst_next $and 0xfff800)+(aopaddr*256)+adata; ] { export *:1 relAddr; }
Addr16: addr is addr16 [ addr = (inst_next $and 0xff0000) + addr16; ] { export *:1 addr; }
@elif defined(MCS51)
Expand Down Expand Up @@ -856,21 +908,21 @@ Rel16: relAddr is rel16 [ relAddr=inst_next+rel16; ] { export *:1 relAdd

:PUSH Direct is $(GROUP1) & ophi=12 & oplo=0; Direct { push8(Direct); }

:RET is $(GROUP1) & ophi=2 & oplo=2 {
:RET is $(GROUP1) & ophi=2 & oplo=2 {
@if defined(MCS251) || defined(MX51)
pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3];
@elif defined(MCS51)
pc:2 = 0; pop16(pc); return[pc];
pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3];
@elif defined(MCS51) || defined(CIP51)
pc:2 = 0; pop16(pc); return[pc];
@elif defined(MCS80390)
pc:3 = 0; pop24(pc); return[pc];
@endif
}

:RETI is $(GROUP1) & ophi=3 & oplo=2 {
:RETI is $(GROUP1) & ophi=3 & oplo=2 {
@if defined(MCS251) || defined(MX51)
pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3];
@elif defined(MCS51)
pc:2 = 0; pop16(pc); return[pc];
pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3];
@elif defined(MCS51) || defined(CIP51)
pc:2 = 0; pop16(pc); return[pc];
@elif defined(MCS80390)
pc:3 = 0; pop24(pc); return[pc];
@endif
Expand Down
4 changes: 4 additions & 0 deletions pypcode/processors/8051/data/languages/cip-51.slaspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@define CIP51 ""

@include "8051_main.sinc"

Loading
Loading