uxmal / reko

Reko is a binary decompiler.

Home Page:https://uxmal.github.io/reko

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MASTER - M68K switch statement fail

gbody opened this issue · comments

Sample file Link IIgs

BackwardSlicer.cs
public TableExtent? DiscoverTableExtent(Address addrSwitch, RtlTransfer xfer, IEventListener listener)

Following case code evaluates the size of the jump table

0010667E 7000 moveq #$00,d0
00106680 2D40 FE62 move.l d0,-$019E(a6)
00106684 2206 move.l d6,d1
00106686 0481 0000 0050 subi.l #$00000050,d1
0010668C 6B00 05D8 bmi $00106C66

00106690 0C81 0000 0028 cmpi.l #$00000028,d1
00106696 6E00 05CE bgt $00106C66

0010669A D281         add.l d1,d1
0010669C 323B 1806 move.w ($08,pc,d1),d1
001066A0 4EFB 1000 jmp.l ($02,pc,d1.w)


l0010669A:
    d1 = d1 + d1
    CVZNX = cond(d1)
    v87 = Mem0[0x001066A4<p32> + d1:word16]
    v88 = SLICE(d1, word16, 16)
    d1 = SEQ(v88, v87)
    ZN = cond(v87)
    C = false
    V = false
    switch (v89) { l001067C0 l00106C66 l00106C66 l00106C66 l00106C66 l00106C66 l00106C66 l00106C66 l00106C66 l00106C66 l00106C66 l001066F6 l00106C66 l00106C66 l00106C66 l00106C66 l00106C66 l00106C
  •   jumpExpr	{0x001066A2<p32> + CONVERT(Mem0[0x001066A4<p32> + d1 * 2<32>:word16], int16, int32)}	Reko.Core.Expressions.Expression {Reko.Core.Expressions.BinaryExpression}
    
  •   interval	{1[0,28]}	Reko.Core.Lib.StridedInterval
    
  •   index	{d1}	Reko.Core.Expressions.Expression {Reko.Core.Expressions.Identifier}
    

Following case code fails to evaluate the size of the jump table and falls back to indirect call and return

001013FC 206E 000C movea.l $000C(a6),a0
00101400 2007 move.l d7,d0
00101402 E580 asl.l #$02,d0
00101404 2070 0800 movea.l (a0,d0),a0
00101408 1028 0001 move.b $0001(a0),d0
0010140C 0400 0041 subi.b #$41,d0
00101410 6B00 0170 bmi $00101582

00101414 0C00 0017 cmpi.b #$17,d0
00101418 6E00 0168 bgt $00101582

0010141C 7200 moveq #$00,d1
0010141E 1200 move.b d0,d1
00101420 D241 add.w d1,d1
00101422 323B 1006 move.w ($08,pc,d1.w),d1
00101426 4EFB 1000 jmp.l ($02,pc,d1.w)

l0010141C:
    d1 = 0
    ZN = cond(d1)
    C = false
    V = false
    v78 = SLICE(d0, byte, 0)
    v79 = SLICE(d1, word24, 8)
    d1 = SEQ(v79, v78)
    ZN = cond(v78)
    C = false
    V = false
    v80 = SLICE(d1, word16, 0) + SLICE(d1, word16, 0)
    v81 = SLICE(d1, word16, 16)
    d1 = SEQ(v81, v80)
    CVZNX = cond(v80)
    v82 = Mem0[0x0010142A<p32> + CONVERT(SLICE(d1, int16, 0), int16, int32):word16]
    v83 = SLICE(d1, word16, 16)
    d1 = SEQ(v83, v82)
    ZN = cond(v82)
    C = false
    V = false
    call 0x00101428<p32> + CONVERT(SLICE(d1, int16, 0), int16, int32) (retsize: 0;)
    return

``

  •   jumpExpr	{0x00101428<p32> + CONVERT(Mem0[0x0010142A<p32> + CONVERT(SLICE(SEQ(v79, SLICE(d0, byte, 0)), word16, 0) * 2<16>, int16, int32):word16], int16, int32)}	Reko.Core.Expressions.Expression {Reko.Core.Expressions.BinaryExpression}
    
  •   interval	{1[0,17]}	Reko.Core.Lib.StridedInterval
    
  •   index	{SLICE(d0, byte, 0)}	Reko.Core.Expressions.Expression {Reko.Core.Expressions.Slice}
    

Is d1 = SEQ(v79,v78) a special case when d1 is zero (constant) and v79 = SLICE(d1, word24, 8) => SLICE(0, word24, 8)