Skip to content

Commit

Permalink
Fix: #1338
Browse files Browse the repository at this point in the history
If Reko can identify which calling convention was used when compiling a procedure, it can sort the parameters in the order prescribed by that calling convention.
  • Loading branch information
uxmal committed Jun 5, 2024
1 parent 52598f1 commit 505ae6a
Show file tree
Hide file tree
Showing 16 changed files with 54 additions and 31 deletions.
4 changes: 1 addition & 3 deletions src/Arch/Arm/AArch32/Arm32CallingConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Reko.Arch.Arm.AArch32
{
Expand All @@ -37,7 +35,7 @@ namespace Reko.Arch.Arm.AArch32
/// </remarks>
public class Arm32CallingConvention : AbstractCallingConvention
{
private RegisterStorage[] argRegs;
private readonly RegisterStorage[] argRegs;

public Arm32CallingConvention() : base("")
{
Expand Down
7 changes: 4 additions & 3 deletions src/Arch/Arm/AArch64/AArch64CallingConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#endregion

using Reko.Core;
using Reko.Core.Expressions;
using Reko.Core.Machine;
using Reko.Core.Types;
using System;
Expand All @@ -31,9 +32,9 @@ namespace Reko.Arch.Arm.AArch64
// Seems identical to the official ARM 64 ABI.
public class AArch64CallingConvention : AbstractCallingConvention
{
private IProcessorArchitecture arch;
private RegisterStorage[] argRegs;
private RegisterStorage[] floatRegs;
private readonly IProcessorArchitecture arch;
private readonly RegisterStorage[] argRegs;
private readonly RegisterStorage[] floatRegs;

public AArch64CallingConvention(IProcessorArchitecture arch) : base("")
{
Expand Down
6 changes: 4 additions & 2 deletions src/Decompiler/Analysis/CallRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
using Reko.Core.Code;
using Reko.Core.Expressions;
using Reko.Core.Lib;
using Reko.Core.Machine;
using Reko.Core.Services;
using Reko.Core.Types;
using Reko.Services;
using System.Collections.Generic;
Expand Down Expand Up @@ -124,7 +126,7 @@ public FunctionType MakeSignature(SsaState ssa, ProcedureFlow flow)
return sig;
}

void ProcessInputStorages(SsaState ssa, ProcedureFlow flow, SignatureBuilder sb)
private void ProcessInputStorages(SsaState ssa, ProcedureFlow flow, SignatureBuilder sb)
{
var frame = ssa.Procedure.Frame;
var mayUseSeqs = flow.BitsUsed.Keys.OfType<SequenceStorage>().ToHashSet();
Expand Down Expand Up @@ -170,7 +172,7 @@ void ProcessInputStorages(SsaState ssa, ProcedureFlow flow, SignatureBuilder sb)
}
}

void ProcessOutputStorages(SsaState ssa, ProcedureFlow flow, SignatureBuilder sb)
private void ProcessOutputStorages(SsaState ssa, ProcedureFlow flow, SignatureBuilder sb)
{
var frame = ssa.Procedure.Frame;
var arch = ssa.Procedure.Architecture;
Expand Down
16 changes: 15 additions & 1 deletion src/Decompiler/Analysis/CallingConventionMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@

namespace Reko.Analysis
{
/// <summary>
/// This class tries to match a given <see cref="FunctionType"/> against well known
/// calling conventions defined by the platform or architecture. If identified,
/// a calling convention can be used to sort the parameters of a procedure in
/// the correct order.
/// </summary>
public class CallingConventionMatcher
{
private readonly IPlatform platform;
Expand All @@ -34,7 +40,15 @@ public CallingConventionMatcher(IPlatform platform)
this.platform = platform;
}


/// <summary>
/// Given a function <paramref name="signature"> and an <see cref="IProcessorArchitecture"/>,
/// discover if the parameters respect a particular calling convention.
/// </summary>
/// <param name="signature">The signature whose calling convention is to be determined.</param>
/// <param name="arch">The processor architecture for the procedure being tested.</param>
/// <returns>An class instance implementing <see cref="ICallingConvention"/> if <paramref name="signature">
/// conforms to a known calling convention, null otherwise.
/// </returns>
public ICallingConvention? DetermineCallingConvention(FunctionType signature, IProcessorArchitecture arch)
{
// Give IPlatform the first chance.
Expand Down
8 changes: 8 additions & 0 deletions src/Decompiler/Analysis/SignatureBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ public void AddInParam(Identifier arg)
parameters.Add(arg);
}

public void SortParameters(ICallingConvention cc)
{
if (cc.InArgumentComparer is not null)
{
parameters.Sort(cc.InArgumentComparer);
}
}

public FunctionType BuildSignature()
{
return FunctionType.Create(ret, parameters.ToArray());
Expand Down
2 changes: 1 addition & 1 deletion src/Environments/AtariTOS/TOSCallingConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace Reko.Environments.AtariTOS
// the first one since it is the system call selector.
public class TOSCallingConvention : AbstractCallingConvention
{
private IProcessorArchitecture arch;
private readonly IProcessorArchitecture arch;

public TOSCallingConvention(IProcessorArchitecture arch) : base("")
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public AlphaCallingConvention(IProcessorArchitecture arch) : base("")
this.fRegs = new[] { "f12", "f13", "f14", "f15" }
.Select(r => arch.GetRegister(r)!)
.ToArray();

}

public override void Generate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
using Reko.Core.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Reko.Environments.SysV.ArchSpecific
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
using Reko.Core.Types;
using System;
using System.Collections.Generic;
using System.Text;

namespace Reko.Environments.SysV.ArchSpecific
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@
using Reko.Core;
using Reko.Core.Expressions;
using Reko.Core.Machine;
using Reko.Core.Serialization;
using Reko.Core.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Reko.Environments.SysV.ArchSpecific
{
Expand Down
6 changes: 2 additions & 4 deletions src/Environments/SysV/ArchSpecific/SparcCallingConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@
*/
#endregion

using System;
using Reko.Core;
using Reko.Core.Serialization;
using Reko.Core.Machine;
using Reko.Core.Types;
using Reko.Core.Expressions;
using System;
using System.Collections.Generic;
using System.Linq;
using Reko.Core.Machine;

namespace Reko.Environments.SysV.ArchSpecific
{
Expand Down
2 changes: 2 additions & 0 deletions src/Environments/SysV/ArchSpecific/X86_64CallingConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public X86_64CallingConvention(IProcessorArchitecture arch) : base("sysv")
this.eax = arch.GetRegister("eax")!;
this.rax = arch.GetRegister("rax")!;
this.rdx = arch.GetRegister("rdx")!;
this.InArgumentComparer = new StorageCollator(iregs.Select(r => r.Domain).ToArray());
this.OutArgumentComparer = new StorageCollator(new[] { rax.Domain, rdx.Domain });
}

public override void Generate(
Expand Down
6 changes: 6 additions & 0 deletions src/Environments/SysV/SysVPlatform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
using Reko.Core.Memory;
using Reko.Core.Rtl;
using Reko.Core.Serialization;
using Reko.Core.Types;
using Reko.Environments.SysV.ArchSpecific;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -60,6 +61,11 @@ public override CParser CreateCParser(TextReader rdr, ParserState? state)
return parser;
}

public override ICallingConvention? DetermineCallingConvention(FunctionType signature, IProcessorArchitecture? arch)
{
return base.DetermineCallingConvention(signature, arch);
}

public override ICallingConvention GetCallingConvention(string? ccName)
{
var cc = archSpecificFactory.CreateCallingConvention(this.Architecture, ccName);
Expand Down
4 changes: 0 additions & 4 deletions src/ImageLoaders/MzExe/Msvc/TypeDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@
using Reko.Core;
using Reko.Core.Memory;
using Reko.Core.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Reko.ImageLoaders.MzExe.Msvc
{
Expand Down
2 changes: 0 additions & 2 deletions src/UnitTests/Mocks/FakeCallingConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

#nullable enable

Expand Down
15 changes: 11 additions & 4 deletions subjects/regression.log

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

0 comments on commit 505ae6a

Please sign in to comment.