public void ElfLoaderConstructorTest() { var InjectContext = new InjectContext(); InjectContext.SetInstanceType<PspMemory, LazyPspMemory>(); var Memory = InjectContext.GetInstance<PspMemory>(); var MemoryStream = new PspMemoryStream(Memory); var MemoryPartition = new MemoryPartition(InjectContext, PspMemory.MainOffset, PspMemory.MainOffset + PspMemory.MainSize); var ElfLoader = new ElfLoader(); ElfLoader.Load(File.OpenRead("../../../TestInput/minifire.elf"), "minifire.elf"); ElfLoader.AllocateAndWrite(MemoryStream, MemoryPartition); Assert.AreEqual(1, ElfLoader.ProgramHeaders.Length); Assert.AreEqual(3, ElfLoader.SectionHeaders.Length); Assert.AreEqual( "['','.rodata.sceModuleInfo']".Replace('\'', '"'), ElfLoader.SectionHeadersByName.Keys.ToJson() ); //ElfLoader.LoadAllocateMemory(MemoryPartition); //ElfLoader.LoadWriteToMemory(MemoryStream); //var ModuleInfo = ElfLoader.ModuleInfo; var PC = ElfLoader.Header.EntryPoint; //var GP = ModuleInfo.GP; Assert.AreEqual(0x08900008, (int)PC); //Assert.AreEqual(0x00004821, (int)GP); }
private void NormalizePartitions() { bool Normalized; do { Normalized = true; MemoryPartition Previous = null; foreach (var Current in _ChildPartitions) { if (Current.Size == 0) { _ChildPartitions.Remove(Current); Normalized = false; break; } if ((Previous != null) && (Previous.Allocated == false) && (Current.Allocated == false)) { _ChildPartitions.Remove(Previous); _ChildPartitions.Remove(Current); _ChildPartitions.Add(new MemoryPartition( Math.Min(Previous.Low, Current.Low), Math.Max(Previous.High, Current.High), false, ParentPartition: this )); Normalized = false; break; } Previous = Current; } } while (!Normalized); }
public void Dump(MemoryPartition Mark = null, int Level = 0) { Console.Write(new string(' ', Level * 2)); Console.WriteLine( $"MemoryPartition(Low={Low:X}, High={High:X}, Allocated={Allocated}, Size={Size}, Name='{Name}'){((this == Mark) ? " * " : "")}"); foreach (var ChildPartition in ChildPartitions) { ChildPartition.Dump(Level: Level + 1, Mark: Mark); } }
public void Dump(MemoryPartition Mark = null, int Level = 0, TextWriter output = null) { output ??= Console.Out; output.Write(new string(' ', Level * 2)); output.WriteLine( $"MemoryPartition(Low={Low:X}, High={High:X}, Allocated={Allocated}, Size={Size}, Name='{Name}'){(this == Mark ? " * " : "")}"); foreach (var ChildPartition in ChildPartitions) { ChildPartition.Dump(Level: Level + 1, Mark: Mark, output: output); } }
public void Dump(MemoryPartition Mark = null, int Level = 0) { Console.Write(new String(' ', Level * 2)); Console.WriteLine(String.Format( "MemoryPartition(Low={0:X}, High={1:X}, Allocated={2}, Size={3}){4}", Low, High, Allocated, Size, (this == Mark) ? " * " : "" )); foreach (var ChildPartition in ChildPartitions) { ChildPartition.Dump(Level: Level + 1, Mark: Mark); } }
public MemoryPartition(uint Low, uint High, bool Allocated = true, string Name = "<Unknown>", MemoryPartition ParentPartition = null) { if (Low > High) throw (new InvalidOperationException()); this.ParentPartition = ParentPartition; this.Name = Name; this.Low = Low; this.High = High; this.Allocated = Allocated; this._ChildPartitions = new SortedSet<MemoryPartition>(new AnonymousComparer<MemoryPartition>((Left, Right) => { int Result = Left.Low.CompareTo(Right.Low); if (Result == 0) { Result = Left.High.CompareTo(Right.High); } return Result; })); }
public MemoryPartition(InjectContext InjectContext, uint Low, uint High, bool Allocated = true, string Name = "<Unknown>", MemoryPartition ParentPartition = null) { if (Low > High) { throw new InvalidOperationException(); } InjectContext.InjectDependencesTo(this); this.ParentPartition = ParentPartition; this.Name = Name; this.Low = Low; this.High = High; this.Allocated = Allocated; this._ChildPartitions = new SortedSet <MemoryPartition>(new AnonymousComparer <MemoryPartition>( (Left, Right) => { int Result = Left.Low.CompareTo(Right.Low); if (Result == 0) { Result = Left.High.CompareTo(Right.High); } return(Result); })); }
public void Dump(MemoryPartition Mark = null, int Level = 0) { Console.Write(new String(' ', Level * 2)); Console.WriteLine(String.Format( "MemoryPartition(Low={0:X}, High={1:X}, Allocated={2}, Size={3}, Name='{4}'){5}", Low, High, Allocated, Size, Name, (this == Mark) ? " * " : "" )); foreach (var ChildPartition in ChildPartitions) { ChildPartition.Dump(Level: Level + 1, Mark: Mark); } }
public MemoryPartition Allocate(int Size, Anchor AllocateAnchor = Anchor.Low, uint Position = 0, int Alignment = 1, string Name = "<Unknown>") { if (_ChildPartitions.Count == 0) { _ChildPartitions.Add(new MemoryPartition(Low, High, false, ParentPartition: this, Name: Name)); } MemoryPartition OldFreePartition; MemoryPartition NewPartiton; try { var SizeCheck = Size; // As much we will need those space. SizeCheck += (Alignment - 1); var AcceptablePartitions = _ChildPartitions.Where(Partition => !Partition.Allocated && Partition.Size >= SizeCheck); switch (AllocateAnchor) { default: case Anchor.Low: OldFreePartition = AcceptablePartitions.First(); break; case Anchor.High: OldFreePartition = AcceptablePartitions.Last(); break; case Anchor.Set: OldFreePartition = AcceptablePartitions.Where(Partition => (Partition.Low <= Position) && (Partition.High >= Position + Size)).Single(); break; } } catch (InvalidOperationException) { #if false Console.WriteLine(""); Console.WriteLine(""); Root.Dump(this); Console.WriteLine(""); #endif throw (new MemoryPartitionNoMemoryException( String.Format( "Can't allocate Size={0} : AllocateAnchor={1} : Position=0x{2:X}", Size, AllocateAnchor, Position ) )); } if (Alignment > 1) { switch (AllocateAnchor) { default: case Anchor.Low: { var Low = MathUtils.NextAligned(OldFreePartition.Low, Alignment); var High = (uint)(Low + Size); return AllocateLowHigh(Low, High); } case Anchor.High: { var High = MathUtils.PrevAligned(OldFreePartition.High, Alignment); var Low = (uint)(High - Size); //Console.WriteLine("Low: {0:X}, High: {1:X}", Low, High); return AllocateLowHigh(Low, High); } } } _ChildPartitions.Remove(OldFreePartition); switch (AllocateAnchor) { default: case Anchor.Low: _ChildPartitions.Add(NewPartiton = new MemoryPartition(OldFreePartition.Low, (uint)(OldFreePartition.Low + Size), true, ParentPartition: this, Name: Name)); _ChildPartitions.Add(new MemoryPartition((uint)(OldFreePartition.Low + Size), OldFreePartition.High, false, ParentPartition: this, Name: "<Free>")); break; case Anchor.High: _ChildPartitions.Add(NewPartiton = new MemoryPartition(OldFreePartition.Low, (uint)(OldFreePartition.High - Size), true, ParentPartition: this, Name: Name)); _ChildPartitions.Add(new MemoryPartition((uint)(OldFreePartition.High - Size), OldFreePartition.High, false, ParentPartition: this, Name: "<Free>")); break; case Anchor.Set: _ChildPartitions.Add(new MemoryPartition(OldFreePartition.Low, Position, false, ParentPartition: this, Name: "<Free>")); _ChildPartitions.Add(NewPartiton = new MemoryPartition(Position, (uint)(Position + Size), true, ParentPartition: this, Name: Name)); _ChildPartitions.Add(new MemoryPartition((uint)(Position + Size), OldFreePartition.High, false, ParentPartition: this, Name: "<Free>")); break; } NormalizePartitions(); return NewPartiton; }
public MemoryPartition Allocate(int Size, Anchor AllocateAnchor = Anchor.Low, uint Position = 0, int Alignment = 1) { if (_ChildPartitions.Count == 0) { _ChildPartitions.Add(new MemoryPartition(Low, High, false, ParentPartition: this)); } MemoryPartition OldFreePartition; MemoryPartition NewPartiton; try { var SizeCheck = Size; // As much we will need those space. SizeCheck += (Alignment - 1); var AcceptablePartitions = _ChildPartitions.Where(Partition => !Partition.Allocated && Partition.Size >= SizeCheck); switch (AllocateAnchor) { default: case Anchor.Low: OldFreePartition = AcceptablePartitions.First(); break; case Anchor.High: OldFreePartition = AcceptablePartitions.Last(); break; case Anchor.Set: OldFreePartition = AcceptablePartitions.Where(Partition => (Partition.Low <= Position) && (Partition.High >= Position + Size)).Single(); break; } } catch (InvalidOperationException) { #if false Console.WriteLine(""); Console.WriteLine(""); Root.Dump(this); Console.WriteLine(""); #endif throw (new InvalidOperationException( String.Format( "Can't allocate Size={0} : AllocateAnchor={1} : Position=0x{2:X}", Size, AllocateAnchor, Position ) )); } if (Alignment > 1) { switch (AllocateAnchor) { default: case Anchor.Low: { var Low = MathUtils.NextAligned(OldFreePartition.Low, Alignment); var High = (uint)(Low + Size); return(AllocateLowHigh(Low, High)); } case Anchor.High: { var High = MathUtils.PrevAligned(OldFreePartition.High, Alignment); var Low = (uint)(High - Size); //Console.WriteLine("Low: {0:X}, High: {1:X}", Low, High); return(AllocateLowHigh(Low, High)); } } } _ChildPartitions.Remove(OldFreePartition); switch (AllocateAnchor) { default: case Anchor.Low: _ChildPartitions.Add(NewPartiton = new MemoryPartition(OldFreePartition.Low, (uint)(OldFreePartition.Low + Size), true, ParentPartition: this)); _ChildPartitions.Add(new MemoryPartition((uint)(OldFreePartition.Low + Size), OldFreePartition.High, false, ParentPartition: this)); break; case Anchor.High: _ChildPartitions.Add(NewPartiton = new MemoryPartition(OldFreePartition.Low, (uint)(OldFreePartition.High - Size), true, ParentPartition: this)); _ChildPartitions.Add(new MemoryPartition((uint)(OldFreePartition.High - Size), OldFreePartition.High, false, ParentPartition: this)); break; case Anchor.Set: _ChildPartitions.Add(new MemoryPartition(OldFreePartition.Low, Position, false, ParentPartition: this)); _ChildPartitions.Add(NewPartiton = new MemoryPartition(Position, (uint)(Position + Size), true, ParentPartition: this)); _ChildPartitions.Add(new MemoryPartition((uint)(Position + Size), OldFreePartition.High, false, ParentPartition: this)); break; } NormalizePartitions(); return(NewPartiton); }
public void AllocateAlignedStackOnNonAlignedSegmentTest() { PartitionRoot = new MemoryPartition(0x000, 0x260); PartitionRoot.Allocate(0x100, MemoryPartition.Anchor.High, Alignment: 0x100); }
public void SetUp() { PartitionRoot = new MemoryPartition(0x000, 0x100); }
public MemoryPartition Allocate(int Size, Anchor AllocateAnchor = Anchor.Low, uint Position = 0, int Alignment = 1, string Name = "<Unknown>") { try { if (_ChildPartitions.Count == 0) { _ChildPartitions.Add(new MemoryPartition(InjectContext, Low, High, false, ParentPartition: this, Name: Name)); } MemoryPartition OldFreePartition; MemoryPartition NewPartiton; var SizeCheck = Size; // As much we will need those space. SizeCheck += Alignment - 1; var AcceptablePartitions = _ChildPartitions.Where(Partition => !Partition.Allocated && Partition.Size >= SizeCheck); //Console.Error.WriteLine("{0}, {1}", AcceptablePartitions.Count(), AcceptablePartitions.First().Size); switch (AllocateAnchor) { default: case Anchor.Low: OldFreePartition = AcceptablePartitions.First(); break; case Anchor.High: OldFreePartition = AcceptablePartitions.Last(); break; case Anchor.Set: OldFreePartition = AcceptablePartitions.Single(Partition => Partition.Low <= Position && Partition.High >= Position + Size); break; } if (Alignment > 1) { switch (AllocateAnchor) { default: case Anchor.Low: { var Low = MathUtils.NextAligned(OldFreePartition.Low, Alignment); var High = (uint)(Low + Size); return(AllocateLowHigh(Low, High)); } case Anchor.High: { var High = MathUtils.PrevAligned(OldFreePartition.High, Alignment); var Low = (uint)(High - Size); //Console.WriteLine("Low: {0:X}, High: {1:X}", Low, High); return(AllocateLowHigh(Low, High)); } } } _ChildPartitions.Remove(OldFreePartition); switch (AllocateAnchor) { default: case Anchor.Low: _ChildPartitions.Add(NewPartiton = new MemoryPartition(InjectContext, OldFreePartition.Low, (uint)(OldFreePartition.Low + Size), true, ParentPartition: this, Name: Name)); _ChildPartitions.Add(new MemoryPartition(InjectContext, (uint)(OldFreePartition.Low + Size), OldFreePartition.High, false, ParentPartition: this, Name: "<Free>")); break; case Anchor.High: _ChildPartitions.Add(NewPartiton = new MemoryPartition(InjectContext, (uint)(OldFreePartition.High - Size), OldFreePartition.High, true, ParentPartition: this, Name: Name)); _ChildPartitions.Add(new MemoryPartition(InjectContext, OldFreePartition.Low, (uint)(OldFreePartition.High - Size), false, ParentPartition: this, Name: "<Free>")); break; case Anchor.Set: _ChildPartitions.Add(new MemoryPartition(InjectContext, OldFreePartition.Low, Position, false, ParentPartition: this, Name: "<Free>")); _ChildPartitions.Add(NewPartiton = new MemoryPartition(InjectContext, Position, (uint)(Position + Size), true, ParentPartition: this, Name: Name)); _ChildPartitions.Add(new MemoryPartition(InjectContext, (uint)(Position + Size), OldFreePartition.High, false, ParentPartition: this, Name: "<Free>")); break; } NormalizePartitions(); return(NewPartiton); } catch (InvalidOperationException) { #if false Console.WriteLine(""); Console.WriteLine(""); Root.Dump(this); Console.WriteLine(""); #endif throw new MemoryPartitionNoMemoryException( $"Can't allocate Size={Size} : AllocateAnchor={AllocateAnchor} : Position=0x{Position:X}" ); } }
public void SetUp() { PartitionRoot = new MemoryPartition(InjectContext, 0x000, 0x100); }