Skip to content

Commit

Permalink
Merge pull request #1306 from ptomin/try-scale-down-index
Browse files Browse the repository at this point in the history
Do not scale array index down if it can't be divided by element size
  • Loading branch information
uxmal authored Dec 8, 2023
2 parents 7728ee1 + 68623ef commit 48b0c03
Show file tree
Hide file tree
Showing 79 changed files with 810 additions and 791 deletions.
41 changes: 24 additions & 17 deletions src/Decompiler/Typing/ComplexExpressionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,14 @@ public Expression VisitArray(ArrayType at)
return expComplex!;
int i = (int)(offset / at.ElementType.Size);
int r = (int)(offset % at.ElementType.Size);
index = ScaleDownIndex(index, at.ElementType.Size);
if (TryScaleDownIndex(index, at.ElementType.Size, out var idx))
{
index = null; // we've consumed the index.
}
dtComplex = at.ElementType;
dtComplexOrig = at.ElementType;
this.expComplex!.DataType = at;
expComplex = CreateArrayAccess(at.ElementType, at, i, index);
index = null; // we've consumed the index.
expComplex = CreateArrayAccess(at.ElementType, at, i, idx);
offset = r;
return dtComplex.Accept(this);
}
Expand Down Expand Up @@ -271,10 +273,9 @@ public Expression VisitPrimitive(PrimitiveType pt)
return CreateUnreferenced(pt, expComplex!);
}
}
else
else if (TryScaleDownIndex(index, pt.Size, out var idx))
{
index = ScaleDownIndex(index, pt.Size);
return CreateArrayAccess(pt, enclosingPtr, offset / pt.Size, index);
return CreateArrayAccess(pt, enclosingPtr, offset / pt.Size, idx);
}
}
return FallbackExpression();
Expand Down Expand Up @@ -308,9 +309,10 @@ public Expression VisitStructure(StructureType str)
--depth;
return exp;
}
else if (index != null && offset == 0)
else if (
index != null && offset == 0 &&
TryScaleDownIndex(index, strSize, out var idx))
{
var idx = ScaleDownIndex(index, strSize);
index = null;
var exp = CreateArrayAccess(str, enclosingPtr, 0, idx);
--depth;
Expand Down Expand Up @@ -480,10 +482,14 @@ private string GlobalFieldName(Field field)
return field.Name;
}

private Expression? ScaleDownIndex(Expression? exp, int elementSize)
private bool TryScaleDownIndex(
Expression? exp, int elementSize, out Expression? index)
{
if (exp == null || elementSize <= 1)
return exp;
{
index = exp;
return true;
}
if (exp is BinaryExpression bin &&
aem.MatchMul(bin) &&
aem.ElementSize!.ToInt32() % elementSize == 0)
Expand All @@ -492,20 +498,21 @@ private string GlobalFieldName(Field field)

var scale = aem.ElementSize!.ToInt32() / elementSize;
if (scale == 1)
return aem.Index;
return new BinaryExpression(
{
index = aem.Index;
return true;
}
index = new BinaryExpression(
Operator.IMul,
bin.DataType,
aem.Index!,
Constant.Int32(scale));
return true;
}
else
{
return new BinaryExpression(
Operator.SDiv,
exp.DataType,
exp,
Constant.Int32(elementSize));
index = null;
return false;
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/UnitTests/Decompiler/Typing/ComplexExpressionBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -544,5 +544,18 @@ public void CEB_ChooseUnionAlternative_dw0004()
var e = ceb.BuildComplex(PrimitiveType.Int32);
Assert.AreEqual("a.point->dw0004", e.ToString());
}

[Test]
public void CEB_PointerToStruct_ArrayField()
{
StructureType str = Struct(
Fld(0, new ArrayType(PrimitiveType.Real64, 4)));
var id = new Identifier("id", PrimitiveType.Ptr32, null);
var index = new Identifier("index", PrimitiveType.Ptr32, null);
CreateTv(id, Ptr32(str), PrimitiveType.Ptr32);
var ceb = CreateBuilder(null, id, m.IMul(index, 8));
var e = ceb.BuildComplex(PrimitiveType.Real64);
Assert.AreEqual("id->a0000[index]", e.ToString());
}
}
}
2 changes: 1 addition & 1 deletion src/tests/Typing/TerAddNonConstantToPointer.exp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ proc1_entry:
l1:
p->w0000 = 4<16>
p->w0004 = 4<16>
p = p + i /16 6<i32>
p = (struct Eq_3 *) ((char *) &p->w0000 + i)
proc1_exit:

// Equivalence classes ////////////
Expand Down
6 changes: 3 additions & 3 deletions subjects/CPM-80/CB80.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions subjects/CPM-80/CB80_code.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions subjects/Elf/ARM/angr-685/RTOSDemo.reko/RTOSDemo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions subjects/Elf/ARM/angr-685/RTOSDemo.reko/RTOSDemo_text.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 48b0c03

Please sign in to comment.