Skip to content

Commit

Permalink
v2.9.8
Browse files Browse the repository at this point in the history
  * update to PySide6 (Qt6)
  * add ole2 format
  * update structs subpackage to allow chosen pointer sizes
  * partial update of avr architecture
  • Loading branch information
bdcht committed Jun 14, 2022
1 parent 3f062db commit 69d7296
Show file tree
Hide file tree
Showing 30 changed files with 572 additions and 118 deletions.
9 changes: 8 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ The default Qt stylesheet is inspired by the excellent QDarkStyleSheet_ and
uses most of its icons through the *QResource* API made available
from the generated *rc_icons.py* module::

<pyenv>/lib/python3.<x>/site-packages/PySide2/rcc -g python icons.qrc > rc_icons.py
<pyenv>/lib/python3.<x>/site-packages/PySide6/rcc -g python icons.qrc > rc_icons.py


Licence
Expand All @@ -96,6 +96,13 @@ Please see `LICENSE`_.
Changelog
=========

- `v2.9.8`_

* update to PySide6 (Qt6)
* add ole2 format
* update structs subpackage to allow chosen pointer sizes
* partial update of avr architecture

- `v2.9.7`_

* drop python <3.8 support
Expand Down
23 changes: 13 additions & 10 deletions amoco/arch/avr/asm.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def _pop_(fmap, _l):

def __pc(f):
def pcnpc(i, fmap):
fmap[pc] = fmap[pc] + i.length
fmap[pc] = fmap[pc] + i.length//2
if len(fmap.conds) > 0:
cond = fmap.conds.pop()
m = mapper()
Expand Down Expand Up @@ -97,14 +97,17 @@ def i_BREAK(i, fmap):
fmap[pc] = ext("BREAK", size=pc.size).call(fmap)


@__pc
def i_IN(i, fmap):
r, port = i.operands
fmap[pc] = ext("IN", size=pc.size).call(fmap)

port = port.value
fmap[r] = fmap(mmregs.get(port,top(r.size)))

@__pc
def i_OUT(i, fmap):
port, r = i.operands
fmap[pc] = ext("OUT", size=pc.size).call(fmap)
port = port.value
fmap[mmregs[port]] = fmap(r)


# arithmetic & logic instructions:
Expand Down Expand Up @@ -513,26 +516,26 @@ def i_LPM(i, fmap):
@__pc
def i_BRBC(i, fmap):
b, offset = i.operands
fmap[pc] = fmap(tst(b == bit0, pc + (2 * offset), pc))
fmap[pc] = fmap(tst(b == bit0, pc + (offset), pc))


@__pc
def i_BRBS(i, fmap):
b, offset = i.operands
fmap[pc] = fmap(tst(b == bit1, pc + (2 * offset), pc))
fmap[pc] = fmap(tst(b == bit1, pc + (offset), pc))


@__pc
def i_CALL(i, fmap):
adr = i.operands[0]
_push_(fmap, fmap(pc))
fmap[pc] = fmap(2 * adr)
fmap[pc] = fmap(adr)


@__pc
def i_JMP(i, fmap):
adr = i.operands[0]
fmap[pc] = fmap(2 * adr)
fmap[pc] = fmap(adr)


@__pc
Expand All @@ -550,13 +553,13 @@ def i_RETI(i, fmap):
def i_RCALL(i, fmap):
offset = i.operands[0]
_push_(fmap, fmap(pc))
fmap[pc] = fmap(pc + (2 * offset))
fmap[pc] = fmap(pc + (offset))


@__pc
def i_RJMP(i, fmap):
offset = i.operands[0]
fmap[pc] = fmap(pc + (2 * offset))
fmap[pc] = fmap(pc + (offset))


@__pc
Expand Down
69 changes: 65 additions & 4 deletions amoco/arch/avr/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
R[26] = slc(X, 0, 8, "XL")
R[27] = slc(X, 8, 8, "XH")
Y = reg("Y", 16)
R[28] = slc(X, 0, 8, "YL")
R[29] = slc(X, 8, 8, "YH")
R[28] = slc(Y, 0, 8, "YL")
R[29] = slc(Y, 8, 8, "YH")
Z = reg("Z", 16)
R[30] = slc(X, 0, 8, "ZL")
R[31] = slc(X, 8, 8, "ZH")
R[30] = slc(Z, 0, 8, "ZL")
R[31] = slc(Z, 8, 8, "ZH")

with is_reg_flags:
SREG = reg("SREG", 8)
Expand All @@ -39,6 +39,8 @@

with is_reg_stack:
sp = reg("SP", 16)
spl = slc(sp,0,8,"SPL")
sph = slc(sp,8,8,"SPH")

RAMPX = reg("RAMPX", 8)
RAMPY = reg("RAMPY", 8)
Expand All @@ -47,3 +49,62 @@
EIND = reg("EIND", 8)

registers = R + [sp, pc, SREG]

mmregs = {
0x1e: reg("GPIOR0",8), # General Purpose I/O Register 0
0x1f: reg("EECR",8), # EEPROM control register:[EERE, EEPE, EEMPE, EERIE, EEPM0, EEPM1, -, -]
0x20: reg("EEDR",8), # data readout from the EEPROM @ EEAR
0x21: reg("EEARL",8), # EEPROM address (Low)
0x22: reg("EEARH",8), # EEPROM address (High)
0x2a: reg("GPIOR1",8), # General Purpose I/O Register 1
0x2b: reg("GPIOR2",8), # General Purpose I/O Register 2
0x2c: reg("SPCR",8),
0x2d: reg("SPSR",8),
0x2e: reg("SPDR",8),
0x33: reg("SMCR",8), # Spleep Mode Control Register
0x35: reg("MCUSR",8), # MCU Control Register
0x3d: spl,
0x3e: sph,
0x3f: SREG,
0x61: reg("CLKPR",8), # Clock Prescale
0x64: reg("PRR",8), # Power Reduction
0x66: reg("OSCCAL",8), # Oscillator Calibration
0xc6: reg("UDR0",8),
}

EECR = mmregs[0x1f]
EERE = slc(EECR,0, 1, "EERE") # EEPROM Read Enable
EEPE = slc(EECR,1, 1, "EEPE") # EEPROM Write Enable
EEMPE = slc(EECR,2, 1, "EEMPE") # EEPROM Master Write Enable
EERIE = slc(EECR,3, 1, "EERIE") # enable EEPROM ready interrupt
EEPM0 = slc(EECR,4, 1, "EEPM0") # EEPROM programming mode: 00=EraseWrite 01:EraseOnly
EEPM1 = slc(EECR,5, 1, "EEPM1") # 10=WriteOnly 11:Reserved

vectors = [
ext("RESET",8),
ext("INT0",8),
ext("INT1",8),
ext("PCINT0",8),
ext("PCINT1",8),
ext("PCINT2",8),
ext("WDT",8),
ext("TIMER2_COMPA",8),
ext("TIMER2_COMPB",8),
ext("TIMER2_OVF",8),
ext("TIMER1_CAPT",8),
ext("TIMER1_COMPA",8),
ext("TIMER1_COMPB",8),
ext("TIMER1_OVF",8),
ext("TIMER0_COMPA",8),
ext("TIMER0_COMPB",8),
ext("TIMER0_OVF",8),
ext("SPI_STC",8),
ext("USART_RX",8),
ext("USART_UDRE",8),
ext("USART_TX",8),
ext("ADC",8),
ext("EE_READY",8),
ext("ANALOG_COMP",8),
ext("TWI",8),
ext("SPM_READY",8),
]
24 changes: 22 additions & 2 deletions amoco/arch/avr/formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ def subf(i, L=args):

return subf

def opport(pos):
def port(i, pos=pos):
o = i.operands[pos]
assert o._is_cst
r = mmregs[o.value]
return [(Token.Register,"{0}".format(r))]
return port

def opreg(pos):
def subr(i, pos=pos):
Expand Down Expand Up @@ -79,7 +86,7 @@ def subpc(i, pos=pos):
npc = pc
npc += i.length
offset = i.operands[pos]
tgt = npc + 2 * offset
tgt = npc + offset
return [(Token.Address, "*" + str(tgt))]

return subpc
Expand All @@ -88,11 +95,23 @@ def subpc(i, pos=pos):
def opadr(pos):
def subabs(i, pos=pos):
tgt = i.operands[pos]
tgt = 2 * tgt
return [(Token.Address, "*" + str(tgt))]

return subabs

def format_io(i):
L = []
for o in i.operands:
if o._is_reg:
tt = Token.Register
r = o
elif o._is_cst:
tt = Token.Memory
r = mmregs.get(o.value,top(8))
L.append((tt,"{0}".format(r)))
L.append((Token.Literal,', '))
L.pop()
return L

def format_mem(i):
s = i.misc["mem"]
Expand Down Expand Up @@ -153,6 +172,7 @@ def format_brc(i):
"avr_br": [mnemo, pcrel(0)],
"avr_noops": [mnemo],
"avr_call": [mnemo, opadr(0)],
"avr_io": [mnemo, format_io],
}

AVR_full = Formatter(AVR_full_formats)
Expand Down
19 changes: 7 additions & 12 deletions amoco/arch/tricore/asm.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,9 +836,8 @@ def i_CALL(ins,fmap):
_ea = composer([cst(0,6),FCXO,cst(0,6),FCXS])
new_fcx = fmap(mem(_ea,32))
disp=0
for r in (PCXI,PSW,A[10],A[11],D[8],D[9],D[10],D[11],A[12],A[13],A[14],
A[15],D[12],D[13],D[14],D[15]):
fmap[mem(_ea,32,disp=disp)] = r
for r in env.Upper_Context:
fmap[mem(_ea,32,disp=disp)] = fmap(r)
disp += 4
fmap[PCPN] = fmap(CCPN)
fmap[PIE] = fmap(IE)
Expand All @@ -857,8 +856,7 @@ def i_RET(ins,fmap):
new_pcxi = fmap(mem(_ea,32))
new_psw = fmap(mem(_ea,32,disp=4))
disp=8
for r in (A[10],A[11],D[8],D[9],D[10],D[11],A[12],A[13],A[14],
A[15],D[12],D[13],D[14],D[15]):
for r in env.Upper_Context[2:]:
fmap[r] = fmap(mem(_ea,32,disp=disp))
disp += 4
fmap[mem(_ea,32)] = fmap(FCX)
Expand All @@ -874,8 +872,7 @@ def i_RFE(ins,fmap):
new_pcxi = fmap(mem(_ea,32))
new_psw = fmap(mem(_ea,32,disp=4))
disp=8
for r in (A[10],A[11],D[8],D[9],D[10],D[11],A[12],A[13],A[14],
A[15],D[12],D[13],D[14],D[15]):
for r in env.Upper_Context[2:]:
fmap[r] = fmap(mem(_ea,32,disp=disp))
disp += 4
fmap[mem(_ea,32)] = fmap(FCX)
Expand All @@ -891,8 +888,7 @@ def i_CALLI(ins,fmap):
_ea = composer([cst(0,6),FCXO,cst(0,6),FCXS])
new_fcx = fmap(mem(_ea,32))
disp=0
for r in (PCXI,PSW,A[10],A[11],D[8],D[9],D[10],D[11],A[12],A[13],A[14],
A[15],D[12],D[13],D[14],D[15]):
for r in env.Upper_Context:
fmap[mem(_ea,32,disp=disp)] = r
disp += 4
fmap[PCPN] = fmap(CCPN)
Expand Down Expand Up @@ -1003,9 +999,8 @@ def i_BISR(ins,fmap):
_ea = composer([cst(0,6),FCXO,cst(0,6),FCXS])
new_fcx = fmap(mem(_ea,32))
disp=0
for r in (PCXI,ra,A[2],A[3],D[0],D[1],D[2],D[3],A[4],A[5],A[6],
A[7],D[4],D[5],D[6],D[7]):
fmap[mem(_ea,32,disp=disp)] = r
for r in env.Lower_Context:
fmap[mem(_ea,32,disp=disp)] = fmap(r)
disp += 4
fmap[PCPN] = fmap(CCPN)
fmap[PIE] = fmap(IE)
Expand Down
37 changes: 34 additions & 3 deletions amoco/arch/tricore/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@
# -----------------

ISP = reg("ISP",32) # interrupt stack pointer
SYSCON = reg("SYSCON",32) # system control register

ICR = reg("ICR",32) # interrupt control register
PIPN = slc(ICR,16,8,"ICR.PIPN")
IE = slc(ICR,15,1,"IE")
CCPN = slc(ICR,0,8,"CCPN")
PIPN = slc(ICR,16,8,"ICR.PIPN") # pending interrupt priority number
IE = slc(ICR,15,1,"IE") # global interrupt Enable Bit
CCPN = slc(ICR,0,8,"CCPN") # Current CPU Priority Number

BIV = reg("BIV",32) # base of interrupt vector table register
BTV = reg("BTV",32) # base of trap vector table register
Expand Down Expand Up @@ -90,6 +91,12 @@
def get_current_CSA():
return composer([cst(0,6),PCXO,cst(0,6),PCXS])

Lower_Context = (PCXI, ra, A[2], A[3], D[0], D[1], D[2], D[3],
A[4], A[5], A[6], A[7], D[4], D[5], D[6], D[7])

Upper_Context = (PCXI,PSW,A[10],A[11],D[8],D[9],D[10],D[11],A[12],A[13],A[14],
A[15],D[12],D[13],D[14],D[15])

is_reg_pc(pc)
is_reg_flags(PSW)
is_reg_stack(sp)
Expand All @@ -99,6 +106,30 @@ def get_current_CSA():
CSFR = {
0xfe00: PCXI,
0xfe04: PSW,
0xfe14: SYSCON,
0xfe20: BIV,
0xfe24: BTV,
0xfe28: ISP,
0xfe2c: ICR,
}

addr = 0xff00
for d in D:
CSFR[addr] = d
addr+=4

addr = 0xff80
for a in A:
CSFR[addr] = d
addr+=4

Traps = [ ("VAF", "VAP"), # Class 0: MMU
("PRIV", "MPR", "MPW", "MPX", "MPP", "MPN", "GRWP"), # Class 1: Internal Protection Traps
("IOPC", "UOPC", "OPD", "ALN", "MEM"), # Class 2: Instruction Errors
("FCD", "CDO", "CDU", "FCU", "CSU", "CTYP", "NEST"), # Class 3: Context Management
("PSE", "DSE", "DAE", "PIE", "DIE", "TAE"), # Class 4: System Bus & Periph.
("OVF", "SOVF"), # Class 5: Assertion Traps
("SYS",), # Class 6: System Call,
("NMI",)] # Class 7: Non-Maskable Interrupt

internals = {"trap": None}
3 changes: 3 additions & 0 deletions amoco/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ def __str__(self):

conf = Config()

if ll:=os.getenv("AMOCO_LOG_LEVEL"):
conf.Log.level = ll

from amoco.logger import Log as _LogClass #lgtm [py/unsafe-cyclic-import]

logger = _LogClass(__name__)
Expand Down
16 changes: 14 additions & 2 deletions amoco/sa/ghidra.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import ghidra_bridge

b = ghidra_bridge.GhidraBridge(namespace=__module__.__dict__)
b = ghidra_bridge.GhidraBridge(namespace=locals())

def select_range(begin,end):
setCurrentSelection = ghidra.program.model.address.setCurrentSelection
AddressSet = ghidra.program.model.address.AddressSet
setCurrentSelection(AddressSet(toAddr(begin),toAddr(end)))

Expand Down Expand Up @@ -41,6 +40,19 @@ def create_labels(labels):
a = toAddr(a)
sym.createLabel(a, r, USER_DEFINED)

def getFunctions_XRefd_at_Location(address):
if isinstance(address,int):
address = toAddr(address)
loc = ghidra.program.util.ProgramLocation(currentProgram,address)
F = []
for r in ghidra.app.util.XReferenceUtils.getAllXrefs(loc):
f = getFunctionContaining(r.getFromAddress())
if f is None:
print("no function containing reference %s"%r)
continue
F.append(f)
return set(F)

def get_decompiled(func_name):
func = getGlobalFunctions(func_name)[0]
options = ghidra.app.decompiler.DecompileOptions()
Expand Down
Loading

0 comments on commit 69d7296

Please sign in to comment.