Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
 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);
     }
 }
Example #4
0
 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);
     }
 }
Example #5
0
 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);
     }
 }
Example #6
0
 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;
     }));
 }
Example #7
0
 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);
     }));
 }
Example #8
0
 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);
     }
 }
Example #9
0
        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;
        }
Example #10
0
        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);
        }
Example #11
0
		public void AllocateAlignedStackOnNonAlignedSegmentTest()
		{
			PartitionRoot = new MemoryPartition(0x000, 0x260);
			PartitionRoot.Allocate(0x100, MemoryPartition.Anchor.High, Alignment: 0x100);
		}
Example #12
0
		public void SetUp()
		{
			PartitionRoot = new MemoryPartition(0x000, 0x100);
		}
Example #13
0
        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}"
                          );
            }
        }
Example #14
0
 public void SetUp()
 {
     PartitionRoot = new MemoryPartition(InjectContext, 0x000, 0x100);
 }