Skip to content

Commit

Permalink
Feature: support for CP/M LBR archives
Browse files Browse the repository at this point in the history
Rearchitecting of the ILoader/Loader interface and class.
  • Loading branch information
uxmal committed Nov 28, 2024
1 parent 7dda175 commit 7c75226
Show file tree
Hide file tree
Showing 26 changed files with 13,586 additions and 96 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ TestResults

.vscode/*
!/.vscode/launch.json
!/.vscode/tasks.json
!/.vscode/tasks.json
/src/Benchmarks/BenchmarkDotNet.Artifacts/
1 change: 1 addition & 0 deletions src/Benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Arch\X86\X86.csproj" />
<ProjectReference Include="..\Core\Core.csproj" />

<PackageReference Include="BenchmarkDotNet" Version="0.13.10" />
Expand Down
6 changes: 4 additions & 2 deletions src/Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// See https://aka.ms/new-console-template for more information
using BenchmarkDotNet.Running;
using Benchmarks.Core.Collections;
using Reko.Benchmarks.Arch.X86;

Check failure on line 4 in src/Benchmarks/Program.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The type or namespace name 'Benchmarks' does not exist in the namespace 'Reko' (are you missing an assembly reference?)

Check failure on line 4 in src/Benchmarks/Program.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The type or namespace name 'Benchmarks' does not exist in the namespace 'Reko' (are you missing an assembly reference?)

Check failure on line 4 in src/Benchmarks/Program.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

The type or namespace name 'Benchmarks' does not exist in the namespace 'Reko' (are you missing an assembly reference?)

Check failure on line 4 in src/Benchmarks/Program.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

The type or namespace name 'Benchmarks' does not exist in the namespace 'Reko' (are you missing an assembly reference?)

Check failure on line 4 in src/Benchmarks/Program.cs

View workflow job for this annotation

GitHub Actions / build (macos-13)

The type or namespace name 'Benchmarks' does not exist in the namespace 'Reko' (are you missing an assembly reference?)

Check failure on line 4 in src/Benchmarks/Program.cs

View workflow job for this annotation

GitHub Actions / build (macos-13)

The type or namespace name 'Benchmarks' does not exist in the namespace 'Reko' (are you missing an assembly reference?)

Console.WriteLine("Hello, World!");
var summary = BenchmarkRunner.Run<ConcurrentBTreeDictionaryBenchmarks>();
//var summary = BenchmarkRunner.Run<ConcurrentBTreeDictionaryBenchmarks>();
var summary = BenchmarkRunner.Run<X86DisassemblerBenchmarks>();
summary = BenchmarkRunner.Run<X86RewriterBenchmarks>();
67 changes: 49 additions & 18 deletions src/Core/Loading/ILoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
using Reko.Core.Assemblers;
using Reko.Core.Configuration;
using Reko.Core.Scripts;
using Reko.Core.Serialization;
using System.Collections.Generic;

namespace Reko.Core.Loading
Expand All @@ -42,20 +41,22 @@ public interface ILoader
/// file, loads that. If not, tries to match the file contents to one of the known
/// file formats, or uses an explicity provided <paramref name="loader"/>.
/// </summary>
/// <param name="imageLocation"></param>
/// <param name="loader"></param>
/// <param name="addrLoad"></param>
/// <param name="imageLocation">The <see cref="ImageLocation"/> from which</param>
/// <param name="loader">Optional name of a specific image loader to use.</param>
/// <param name="addrLoad">Optional address at which to load the image.</param>
/// <returns>
/// An <see cref="ILoadedImage"/> instance. In particular, if the
/// file format wasn't recognized an instance of <see cref="Blob"/> is
/// returned.
/// </returns>
ILoadedImage Load(ImageLocation imageLocation, string? loader = null, Address? addrLoad = null);
ILoadedImage Load(
ImageLocation imageLocation,
string? loader = null,
Address? addrLoad = null);

/// <summary>
/// Opens the specified file and reads the contents of the file,
/// starting at file offset <paramref name="offset"/>. No interpretation
/// of the file data is done.
/// Opens the specified file and reads the contents of the file.
/// No interpretation of the file data is done.
/// </summary>
/// <param name="filename">The file system path of the file from which
/// to read the image data.</param>
Expand All @@ -65,8 +66,19 @@ public interface ILoader
byte[] LoadFileBytes(string filename);

/// <summary>
/// Given a executable file image in <param name="bytes">, determines which file
/// format the file has and delegates loading to a specific image loader.
/// Opens an image from the specified location. The image may be located
/// in arbitraritly deeply nested <see cref="IArchive"/>s.
/// </summary>
/// <param name="binLocation"><see cref="ImageLocation"/> describing
/// the location of the requested image.</param>
/// <returns>
/// The loaded image.
/// </returns>
byte[] LoadImageBytes(ImageLocation binLocation);

/// <summary>
/// Given a file image in <param name="bytes">, determines which file
/// format the file has and delegates parsing to a specific image loader.
/// </summary>
/// <param name="imageLocation">The <see cref="ImageLocation"/> from where the
/// image was loaded.</param>
Expand All @@ -79,28 +91,46 @@ public interface ILoader
/// Either a successfully loaded <see cref="ILoadedImage"/>, or a <see cref="Blob"/>
/// if an appropriate image loader could not be determined or loaded.
/// </returns>
//$REVIEW: this method may no longer need to be exposed on this interface.
ILoadedImage LoadBinaryImage(ImageLocation imageLocation, byte[] bytes, string? loader, Address? loadAddress);
ILoadedImage ParseBinaryImage(
ImageLocation imageLocation,
byte[] bytes,
string? loader,
IProcessorArchitecture? arch,
Address? loadAddress);

ILoadedImage ParseBinaryImage(
ImageLocation imageLocation,
byte[] bytes,
LoadDetails loadDetails);

/// <summary>
/// Given a sequence of raw bytes, loads it into memory and applies the
/// <paramref name="details"/> to it. Use this method if the binary has no known file
/// format.
/// Given a sequence of raw bytes, uses the provided <paramref name="details"/> to
/// make sense of it. Use this method if the binary has no known file format.
/// </summary>
/// <param name="image">The raw contents of the file.</param>
/// <param name="loadAddress">The address at which the raw contents are to be loaded.</param>
/// <param name="details">Details about the contents of the file.</param>
/// <returns>A <see cref="Reko.Core.Program"/>.
/// </returns>
Program LoadRawImage(byte[] image, Address? loadAddress, LoadDetails details);
Program ParseRawImage(byte[] image, Address? loadAddress, LoadDetails details);

Program LoadRawImage(LoadDetails raw);

//$TODO: deprecate this method.
Program LoadRawImage(byte[] bytes, LoadDetails raw);

Program AssembleExecutable(ImageLocation asmfileLocation, IAssembler asm, IPlatform platform, Address loadAddress);
Program AssembleExecutable(ImageLocation asmfileLocation, byte[] bytes, IAssembler asm, IPlatform platform, Address loadAddress);
Program AssembleExecutable(
ImageLocation asmfileLocation,
IAssembler asm,
IPlatform platform,
Address loadAddress);

Program AssembleExecutable(
ImageLocation asmfileLocation,
byte[] bytes,
IAssembler asm,
IPlatform platform,
Address loadAddress);

/// <summary>
/// Loads a file containing symbolic, type, or other metadata into a <see cref="Reko.Core.TypeLibrary>"/>.
Expand Down Expand Up @@ -161,6 +191,7 @@ public class LoadDetails

/// <summary>
/// Name of the platform to use. Platform names are found in the
/// Name of the platform to use. Platform names are found in the
/// reko.config file.
/// </summary>
public string? PlatformName;
Expand Down
7 changes: 5 additions & 2 deletions src/Core/Loading/ImageLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
*/
#endregion

using Reko.Core;
using System;
using System.Collections.Generic;

namespace Reko.Core.Loading
{
Expand Down Expand Up @@ -63,6 +61,11 @@ public ImageLoader(IServiceProvider services, ImageLocation imageLocation, byte[
/// <returns>An object implementing the <see cref="ILoadedImage>" /> interface.</returns>
public abstract ILoadedImage Load(Address? addrLoad);

public virtual ILoadedImage Load(Address? addrLoad, IProcessorArchitecture? arch)
{
return Load(addrLoad);
}


public virtual IBinaryFormatter CreateBinaryFormatter(IBinaryImage image)
{
Expand Down
4 changes: 2 additions & 2 deletions src/Core/Serialization/ProjectLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ private Program LoadProgram(ImageLocation projectLocation, DecompilerInput_v5 sI
// use the LoadRawImage path.
var archName = sUser.Processor?.Name;
var platform = sUser.PlatformOptions?.Name;
var bytes = loader.LoadFileBytes(binLocation.FilesystemPath);
program = loader.LoadRawImage(bytes, address, new LoadDetails
var image = loader.LoadImageBytes(binLocation);
program = loader.ParseRawImage(image, address, new LoadDetails
{
Location = binLocation,
LoaderName = sUser.Loader,
Expand Down
Loading

0 comments on commit 7c75226

Please sign in to comment.