Пример #1
0
        private void CalculateMethodParameterSize()
        {
            // Check if already computed
            if (MethodData.ParameterStackSize != 0)
            {
                return;
            }

            int stacksize = 0;

            MethodData.ParameterSizes   = new List <int>(Method.Signature.Parameters.Count);
            MethodData.ParameterOffsets = new List <int>(Method.Signature.Parameters.Count);

            if (Method.HasThis)
            {
                stacksize = TypeLayout.NativePointerSize;
            }

            foreach (var parameter in Method.Signature.Parameters)
            {
                var size = parameter.ParameterType.IsValueType ? TypeLayout.GetTypeSize(parameter.ParameterType) : TypeLayout.NativePointerAlignment;

                MethodData.ParameterSizes.Add(size);
                MethodData.ParameterOffsets.Add(stacksize);

                stacksize += Alignment.AlignUp(size, TypeLayout.NativePointerAlignment);
            }

            MethodData.ParameterStackSize = stacksize;
        }
Пример #2
0
        private int LayoutParameters(int offsetOfFirst)
        {
            int offset = offsetOfFirst;

            foreach (var operand in Parameters)
            {
                int size, alignment;
                Architecture.GetTypeRequirements(TypeLayout, operand.Type, out size, out alignment);

                operand.Offset     = offset;
                operand.IsResolved = true;

                //// adjust split children
                //if (operand.Low != null)
                //{
                //	operand.Low.Offset = offset + (operand.Low.Offset - operand.Offset);
                //	operand.High.Offset = offset + (operand.High.Offset - operand.Offset);
                //}

                size   = Alignment.AlignUp(size, alignment);
                offset = offset + size;
            }

            return(offset);
        }
        /// <summary>
        /// Calculates the remaining space.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="context">The context.</param>
        /// <param name="method">The method.</param>
        /// <param name="operands">The operand stack.</param>
        /// <param name="space">The space.</param>
        /// <param name="scratch">The scratch.</param>
        private void PushOperands(BaseMethodCompiler compiler, MosaTypeLayout typeLayout, Context context, MosaMethod method, List <Operand> operands, int space, Operand scratch)
        {
            Debug.Assert((method.Signature.Parameters.Count + (method.HasThis ? 1 : 0) == operands.Count) ||
                         (method.DeclaringType.IsDelegate && method.Signature.Parameters.Count == operands.Count));

            int offset = method.Signature.Parameters.Count - operands.Count;

            for (int index = operands.Count - 1; index >= 0; index--)
            {
                Operand operand = operands[index];

                MosaType param = (index + offset >= 0) ? method.Signature.Parameters[index + offset].ParameterType : null;

                int size, alignment;

                if (param != null && operand.IsR8 && param.IsR4)
                {
                    architecture.GetTypeRequirements(typeLayout, param, out size, out alignment);
                }
                else
                {
                    architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment);
                }

                size = Alignment.AlignUp(size, alignment);

                space -= size;

                Push(compiler, typeLayout, context, operand, space, size, scratch);
            }
        }
Пример #4
0
        /// <summary>
        /// Requests the calling convention to create an appropriate move instruction to populate the return
        /// value of a method.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="context">The context.</param>
        /// <param name="operand">The operand, that's holding the return value.</param>
        public override void SetReturnValue(BaseMethodCompiler compiler, Context context, Operand operand)
        {
            int size, alignment;

            architecture.GetTypeRequirements(compiler.TypeLayout, operand.Type, out size, out alignment);
            size = Alignment.AlignUp(size, alignment);

            if (operand.IsR4)
            {
                architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, returnFloatingPointRegister), operand);
            }
            else if (operand.IsR8)
            {
                architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, returnFloatingPointRegister), operand);
            }
            else if (operand.IsLong)
            {
                MosaType highType = (operand.IsI8) ? compiler.TypeSystem.BuiltIn.I4 : compiler.TypeSystem.BuiltIn.U4;

                architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(compiler.TypeSystem.BuiltIn.U4, return32BitRegister), operand.Low);
                architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(highType, return64BitRegister), operand.High);
            }
            else if (compiler.StoreOnStack(operand.Type))
            {
                int size2 = compiler.TypeLayout.GetTypeSize(operand.Type);
                var OffsetOfFirstParameterOperand = Operand.CreateConstant(compiler.TypeSystem, OffsetOfFirstParameter);
                architecture.InsertCompoundCopy(compiler, context, compiler.StackFrame, OffsetOfFirstParameterOperand, compiler.StackFrame, operand, size2);
            }
            else
            {
                architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, return32BitRegister), operand);
            }
        }
        private static Result CreateSaveData(FileSystemClient fs, Func <Result> createFunc, ref long requiredSize, long baseSize,
                                             long dataSize, long journalSize)
        {
            Result rc = createFunc();

            if (rc.IsSuccess())
            {
                return(Result.Success);
            }

            if (ResultFs.UsableSpaceNotEnough.Includes(rc))
            {
                Result queryRc = fs.QuerySaveDataTotalSize(out long totalSize, dataSize, journalSize);
                if (queryRc.IsFailure())
                {
                    return(queryRc);
                }

                requiredSize += Alignment.AlignUp(totalSize, 0x4000) + baseSize;
            }
            else if (!ResultFs.PathAlreadyExists.Includes(rc))
            {
                return(rc);
            }

            return(Result.Success);
        }
        /// <summary>
        /// Calculates the stack size for parameters.
        /// </summary>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="operands">The operands.</param>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        protected static int CalculateStackSizeForParameters(MosaTypeLayout typeLayout, BaseArchitecture architecture, List <Operand> operands, MosaMethod method)
        {
            Debug.Assert((method.Signature.Parameters.Count + (method.HasThis ? 1 : 0) == operands.Count) ||
                         (method.DeclaringType.IsDelegate && method.Signature.Parameters.Count == operands.Count), method.FullName);

            int offset = method.Signature.Parameters.Count - operands.Count;
            int result = 0;

            for (int index = operands.Count - 1; index >= 0; index--)
            {
                Operand operand = operands[index];

                int size, alignment;
                architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment);

                var param = (index + offset >= 0) ? method.Signature.Parameters[index + offset] : null;

                if (param != null && operand.IsR8 && param.ParameterType.IsR4)
                {
                    //  adjust for parameter size on stack when method parameter is R4 while the calling variable is R8
                    architecture.GetTypeRequirements(typeLayout, param.ParameterType, out size, out alignment);
                }

                result = (int)Alignment.AlignUp(result, (uint)alignment) + size;
            }

            return(result);
        }
Пример #7
0
        private void ResolveSectionLayout(LinkerSection section, uint fileOffset, ulong virtualAddress)
        {
            section.VirtualAddress = virtualAddress;
            section.FileOffset     = fileOffset;
            section.Size           = 0;

            foreach (var symbol in Symbols)
            {
                if (symbol.IsReplaced)
                {
                    continue;
                }

                if (symbol.SectionKind != section.SectionKind)
                {
                    continue;
                }

                if (symbol.IsResolved)
                {
                    continue;
                }

                //if (symbol.IsExternalSymbol)
                //	continue;

                symbol.SectionOffset  = section.Size;
                symbol.VirtualAddress = section.VirtualAddress + section.Size;
                section.Size         += symbol.Size;
            }

            section.Size       = Alignment.AlignUp(section.Size, SectionAlignment);
            section.IsResolved = true;
        }
Пример #8
0
        private void LayoutObjectsAndSections()
        {
            var virtualAddress = LinkerSettings.BaseAddress;

            // Sort the list --- helpful for debugging
            Symbols.Sort((y, x) => x.Name.CompareTo(y.Name));

            if (FirstSymbol != null)
            {
                Symbols.Remove(FirstSymbol);
                Symbols.Insert(0, FirstSymbol);
            }

            foreach (var section in SectionKinds)
            {
                var size = ResolveSymbolLocation(section, virtualAddress);

                var linkerSection = Sections[(int)section];

                linkerSection.VirtualAddress = virtualAddress;
                linkerSection.Size           = size;

                size = Alignment.AlignUp(size, SectionAlignment);

                virtualAddress += size;
            }
        }
Пример #9
0
        /// <summary>
        /// Creates a new <see cref="AesXtsFile"/> using the provided key.
        /// </summary>
        /// <param name="path">The full path of the file to create.</param>
        /// <param name="size">The initial size of the created file.</param>
        /// <param name="options">Flags to control how the file is created.
        /// Should usually be <see cref="CreateFileOptions.None"/></param>
        /// <param name="key">The 256-bit key containing a 128-bit data key followed by a 128-bit tweak key.</param>
        public Result CreateFile(U8Span path, long size, CreateFileOptions options, byte[] key)
        {
            long containerSize = AesXtsFile.HeaderLength + Alignment.AlignUp(size, 0x10);

            Result rc = BaseFileSystem.CreateFile(path, containerSize, options);

            if (rc.IsFailure())
            {
                return(rc);
            }

            var header = new AesXtsFileHeader(key, size, path.ToString(), KekSource, ValidationKey);

            rc = BaseFileSystem.OpenFile(out IFile baseFile, path, OpenMode.Write);
            if (rc.IsFailure())
            {
                return(rc);
            }

            using (baseFile)
            {
                rc = baseFile.Write(0, header.ToBytes(false));
                if (rc.IsFailure())
                {
                    return(rc);
                }
            }

            return(Result.Success);
        }
Пример #10
0
        private void WriteSection(BinaryWriter writer, Section section)
        {
            if (section.Type == SectionType.Null)
            {
                return;
            }

            section.Offset = Math.Max(BaseFileOffset, Alignment.AlignUp((uint)writer.BaseStream.Length, SectionAlignment));

            if (section.Type == SectionType.NoBits)
            {
                return;
            }

            writer.SetPosition(section.Offset);

            if (section.Emitter != null)
            {
                section.Stream = section.Emitter();
            }

            if (section.Stream != null)
            {
                section.Stream.Position = 0;
                section.Stream.WriteTo(writer.BaseStream);
            }

            section.Size = (uint)section.Stream.Length;
        }
Пример #11
0
        public AesXtsFile(OpenMode mode, IFile baseFile, U8String path, ReadOnlySpan <byte> kekSeed, ReadOnlySpan <byte> verificationKey, int blockSize)
        {
            Mode            = mode;
            BaseFile        = baseFile;
            Path            = path;
            KekSeed         = kekSeed.ToArray();
            VerificationKey = verificationKey.ToArray();
            BlockSize       = blockSize;

            Header = new AesXtsFileHeader(BaseFile);

            baseFile.GetSize(out long fileSize).ThrowIfFailure();

            if (!Header.TryDecryptHeader(Path.ToString(), KekSeed, VerificationKey))
            {
                ThrowHelper.ThrowResult(ResultFs.AesXtsFileHeaderInvalidKeys.Value, "NAX0 key derivation failed.");
            }

            if (HeaderLength + Alignment.AlignUp(Header.Size, 0x10) > fileSize)
            {
                ThrowHelper.ThrowResult(ResultFs.AesXtsFileTooShort.Value, "NAX0 key derivation failed.");
            }

            var fileStorage = new FileStorage2(baseFile);
            var encStorage  = new SubStorage(fileStorage, HeaderLength, fileSize - HeaderLength);

            encStorage.SetResizable(true);

            BaseStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Header.DecryptedKey1, Header.DecryptedKey2, BlockSize, true), 4, true);
        }
Пример #12
0
        /// <summary>
        /// Resolves the method parameters.
        /// </summary>
        /// <param name="method">The method.</param>
        private MethodInfo __ResolveMethodParameters(MosaMethod method)
        {
            if (method.HasOpenGenericParams)
            {
                return(null);
            }

            if (methodData.ContainsKey(method))
            {
                return(null);
            }

            var parameters = method.Signature.Parameters;
            int stacksize  = 0;

            var offsets = new List <int>(parameters.Count + (method.HasThis ? 1 : 0));
            var sizes   = new List <int>(parameters.Count + (method.HasThis ? 1 : 0));

            if (method.HasThis)
            {
                offsets.Add(0);
                sizes.Add(NativePointerSize);

                stacksize = NativePointerSize;                  // already aligned
            }

            foreach (var parameter in parameters)
            {
                var size = parameter.ParameterType.IsValueType ? GetTypeSize(parameter.ParameterType) : NativePointerAlignment;

                offsets.Add(stacksize);
                sizes.Add(size);

                stacksize += Alignment.AlignUp(size, NativePointerAlignment);
            }

            var returnType = method.Signature.ReturnType;
            int returnSize = 0;

            if (!returnType.IsVoid)
            {
                ResolveType(returnType);

                typeSizes.TryGetValue(returnType, out returnSize);
            }

            var methodInfo = new MethodInfo
            {
                ReturnSize         = returnSize,
                ParameterOffsets   = offsets,
                ParameterSizes     = sizes,
                ParameterStackSize = stacksize,
                ReturnInRegister   = !returnType.IsVoid && FitsInRegister(returnType),
                HasThis            = method.HasThis
            };

            methodData.Add(method, methodInfo);

            return(methodInfo);
        }
        /// <summary>
        /// Requests the calling convention to create an appropriate move instruction to populate the return
        /// value of a method.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="context">The context.</param>
        /// <param name="operand">The operand, that's holding the return value.</param>
        public override void SetReturnValue(BaseMethodCompiler compiler, MosaTypeLayout typeLayout, Context context, Operand operand)
        {
            int size, alignment;

            architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment);
            size = Alignment.AlignUp(size, alignment);

            if (operand.IsR4)
            {
                architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, returnFloatingPointRegister), operand);
            }
            else if (operand.IsR8)
            {
                architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, returnFloatingPointRegister), operand);
            }
            else if (operand.IsLong)
            {
                MosaType highType = (operand.IsI8) ? typeLayout.TypeSystem.BuiltIn.I4 : typeLayout.TypeSystem.BuiltIn.U4;

                architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(typeLayout.TypeSystem.BuiltIn.U4, return32BitRegister), operand.Low);
                architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(highType, return64BitRegister), operand.High);
            }
            else if (size == 4 || size == 2 || size == 1)
            {
                architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, return32BitRegister), operand);
            }
            else if (typeLayout.IsCompoundType(operand.Type))
            {
                Operand stackBaseReg = Operand.CreateCPURegister(typeLayout.TypeSystem.BuiltIn.Pointer, architecture.StackFrameRegister);
                architecture.InsertCompoundMoveInstruction(compiler, context, Operand.CreateMemoryAddress(operand.Type, stackBaseReg, OffsetOfFirstParameter), operand, size);
            }
        }
Пример #14
0
        private void Process(Request request)
        {
            lock (sync)
            {
                if (request.Blocks.Count != 0)
                {
                    return;
                }

                requests.Remove(request);

                var data = new byte[request.Size];

                // blocks start/end
                ulong start = Alignment.AlignDown(request.Address, BlockSize);
                ulong end   = Alignment.AlignUp(request.Address + (ulong)request.Size, BlockSize);

                ulong requestStart = request.Address;
                ulong requestEnd   = request.Address + request.Size;

                lock (sync)
                {
                    for (ulong blockStart = start; blockStart < end; blockStart += BlockSize)
                    {
                        ulong blockEnd = blockStart + BlockSize;

                        int blockOffset = 0;
                        int dataOffset  = 0;

                        ulong overlapStart = Math.Max(requestStart, blockStart);
                        ulong overlapEnd   = Math.Min(requestEnd, blockEnd);
                        int   len          = (int)(overlapEnd - overlapStart);

                        if (requestStart > blockStart)
                        {
                            blockOffset = (int)(requestStart - blockStart);
                        }

                        if (blockStart > requestStart)
                        {
                            dataOffset = (int)(blockStart - requestStart);
                        }

                        var block = buffer[blockStart];

                        try
                        {
                            Array.Copy(block, blockOffset, data, dataOffset, len);
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine(e.ToString());
                        }
                    }
                }

                request.OnMemoryRead(request.Address, data);
            }
        }
Пример #15
0
        private bool VerifyPk11Sizes()
        {
            Assert.True(IsDecrypted);

            int pk11Size = Unsafe.SizeOf <Package1Pk11Header>() + GetSectionSize(Package1Section.WarmBoot) +
                           GetSectionSize(Package1Section.Bootloader) + GetSectionSize(Package1Section.SecureMonitor);

            pk11Size = Alignment.AlignUp(pk11Size, 0x10);

            return(pk11Size == Pk11Size);
        }
Пример #16
0
        /// <summary>
        /// Performs a stack layout of all local variables in the list.
        /// </summary>
        /// <param name="locals">The enumerable holding all locals.</param>
        /// <param name="callingConvention">The cc.</param>
        /// <param name="offsetOfFirst">Specifies the offset of the first stack operand in the list.</param>
        /// <param name="isLocalVariable">The direction.</param>
        /// <returns></returns>
        private int LayoutVariables(IList <Operand> locals, BaseCallingConvention callingConvention, int offsetOfFirst, bool isLocalVariable)
        {
            int offset = offsetOfFirst;

            foreach (var operand in locals)
            {
                if (!operand.IsParameter && operand.Uses.Count == 0 && operand.Definitions.Count == 0)
                {
                    bool skip = false;

                    if (operand.Low == null && operand.High == null)
                    {
                        skip = true;
                    }
                    else if (operand.Low.Uses.Count == 0 && operand.Low.Definitions.Count == 0 && operand.High.Uses.Count == 0 && operand.High.Definitions.Count == 0)
                    {
                        skip = true;
                    }

                    if (skip)
                    {
                        operand.Displacement = 0;
                        continue;
                    }
                }

                int size, alignment;
                Architecture.GetTypeRequirements(TypeLayout, operand.Type, out size, out alignment);
                if (isLocalVariable)
                {
                    size   = Alignment.AlignUp(size, alignment);
                    offset = offset - size;
                }

                // adjust split children
                if (operand.Low != null)
                {
                    operand.Low.Displacement  = offset + (operand.Low.Displacement - operand.Displacement);
                    operand.High.Displacement = offset + (operand.High.Displacement - operand.Displacement);
                }

                operand.Displacement = offset;

                if (!isLocalVariable)
                {
                    size   = Alignment.AlignUp(size, alignment);
                    offset = offset + size;
                }
            }

            return(offset);
        }
Пример #17
0
        private void RegisterStandardSections()
        {
            var previous = nullSection;

            foreach (var linkerSection in Linker.Sections)
            {
                if (linkerSection.Size == 0 && linkerSection.SectionKind != SectionKind.BSS)
                {
                    continue;
                }

                var section = new Section()
                {
                    Name        = SectionNames[(int)linkerSection.SectionKind],
                    Address     = linkerSection.VirtualAddress,
                    Size        = Alignment.AlignUp(linkerSection.Size, SectionAlignment),
                    Emitter     = () => { return(WriteLinkerSection(linkerSection.SectionKind)); },
                    SectionKind = linkerSection.SectionKind
                };

                switch (linkerSection.SectionKind)
                {
                case SectionKind.Text:
                    section.Type  = SectionType.ProgBits;
                    section.Flags = SectionAttribute.AllocExecute;
                    break;

                case SectionKind.Data:
                    section.Type  = SectionType.ProgBits;
                    section.Flags = SectionAttribute.Alloc | SectionAttribute.Write;
                    break;

                case SectionKind.ROData:
                    section.Type  = SectionType.ProgBits;
                    section.Flags = SectionAttribute.Alloc;
                    break;

                case SectionKind.BSS:
                    section.Type  = SectionType.NoBits;
                    section.Flags = SectionAttribute.Alloc | SectionAttribute.Write;
                    break;
                }

                section.AddDependency(previous);

                RegisterSection(section);

                previous = section;
            }
        }
Пример #18
0
        public void FsTrim()
        {
            int virtualBlockCount  = Header.MainDataBlockCount;
            int physicalBlockCount = virtualBlockCount + Header.JournalBlockCount;

            int blockMapLength       = virtualBlockCount * MapEntryLength;
            int physicalBitmapLength = Alignment.AlignUp(physicalBlockCount, 32) / 8;
            int virtualBitmapLength  = Alignment.AlignUp(virtualBlockCount, 32) / 8;

            MapStorage.Slice(blockMapLength).Fill(SaveDataFileSystem.TrimFillValue);
            FreeBlocks.Slice(physicalBitmapLength).Fill(SaveDataFileSystem.TrimFillValue);
            ModifiedPhysicalBlocks.Slice(physicalBitmapLength).Fill(SaveDataFileSystem.TrimFillValue);
            ModifiedVirtualBlocks.Slice(virtualBitmapLength).Fill(SaveDataFileSystem.TrimFillValue);
        }
Пример #19
0
        protected static int CalculateStackSizeForParameters(MosaTypeLayout typeLayout, BaseArchitecture architecture, List <Operand> operands)
        {
            // first operand is the call location
            int result = 0;

            foreach (var operand in operands)
            {
                int size, alignment;
                architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment);

                result = Alignment.AlignUp(result, alignment) + size;
            }

            return(result);
        }
        /// <summary>
        /// Calculates the remaining space.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="context">The context.</param>
        /// <param name="operands">The operand stack.</param>
        /// <param name="space">The space.</param>
        /// <param name="scratch">The scratch.</param>
        private void PushOperands(BaseMethodCompiler compiler, MosaTypeLayout typeLayout, Context context, List <Operand> operands, int space, Operand scratch)
        {
            foreach (var operand in operands)
            {
                int size, alignment;

                architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment);

                size = Alignment.AlignUp(size, alignment);

                space -= size;

                Push(compiler, typeLayout, context, operand, space, size, scratch);
            }
        }
Пример #21
0
        private int CalculateReturnSize(Operand result)
        {
            if (result == null)
            {
                return(0);
            }

            var returnType = result.Type;

            if (MosaTypeLayout.IsStoredOnStack(returnType))
            {
                return(Alignment.AlignUp(TypeLayout.GetTypeSize(returnType), NativeAlignment));
            }

            return(0);
        }
Пример #22
0
        private int CalculateReturnSize(Operand result)
        {
            if (result == null)
            {
                return(0);
            }

            var returnType = result.Type;

            if (!MosaTypeLayout.CanFitInRegister(returnType))
            {
                return(Alignment.AlignUp(TypeLayout.GetTypeSize(returnType), NativeAlignment));
            }

            return(0);
        }
Пример #23
0
        private void CalculateMethodParameterSize()
        {
            int stacksize = 0;

            if (Method.HasThis)
            {
                stacksize = TypeLayout.NativePointerSize;
            }

            foreach (var parameter in Method.Signature.Parameters)
            {
                var size = parameter.ParameterType.IsValueType ? TypeLayout.GetTypeSize(parameter.ParameterType) : TypeLayout.NativePointerAlignment;
                stacksize += Alignment.AlignUp(size, TypeLayout.NativePointerAlignment);
            }

            MethodData.ParameterStackSize = stacksize;
        }
Пример #24
0
        /// <summary>
        /// Performs a stack layout of all local variables in the list.
        /// </summary>
        /// <param name="locals">The enumerable holding all locals.</param>
        /// <param name="callingConvention">The cc.</param>
        /// <param name="offsetOfFirst">The offset of first.</param>
        /// <returns></returns>
        private int LayoutVariables(IList <Operand> locals, BaseCallingConvention callingConvention, int offsetOfFirst)
        {
            int offset = offsetOfFirst;

            foreach (var operand in locals)
            {
                int size, alignment;
                Architecture.GetTypeRequirements(TypeLayout, operand.Type, out size, out alignment);

                size   = Alignment.AlignUp(size, alignment);
                offset = offset - size;

                operand.Offset     = offset;
                operand.IsResolved = true;
            }

            return(offset);
        }
Пример #25
0
 /// <summary>
 /// Gets the size of the reference or type.
 /// </summary>
 /// <param name="type">The type.</param>
 /// <param name="aligned">if set to <c>true</c> [aligned].</param>
 /// <returns></returns>
 public int GetReferenceOrTypeSize(MosaType type, bool aligned)
 {
     if (type.IsValueType)
     {
         if (aligned)
         {
             return(Alignment.AlignUp(TypeLayout.GetTypeSize(type), Architecture.NativeAlignment));
         }
         else
         {
             return(TypeLayout.GetTypeSize(type));
         }
     }
     else
     {
         return(Architecture.NativeAlignment);
     }
 }
Пример #26
0
        private void LayoutObjectsAndSections()
        {
            var virtualAddress = LinkerSettings.BaseAddress;

            foreach (var section in SectionKinds)
            {
                var size = ResolveSymbolLocation(section, virtualAddress);

                var linkerSection = Sections[(int)section];

                linkerSection.VirtualAddress = virtualAddress;
                linkerSection.Size           = size;

                size = Alignment.AlignUp(size, SectionAlignment);

                virtualAddress += size;
            }
        }
Пример #27
0
        private void WriteProgramHeader(BinaryWriter writer)
        {
            elfheader.ProgramHeaderOffset = ElfHeader.GetEntrySize(LinkerFormatType);

            writer.SetPosition(elfheader.ProgramHeaderOffset);

            elfheader.ProgramHeaderNumber = 0;

            foreach (var section in sections)
            {
                if (section.SectionKind == SectionKind.Unknown)
                {
                    continue;
                }

                if (section.Size == 0 && section.SectionKind != SectionKind.BSS)
                {
                    continue;
                }

                if (section.Address == 0)
                {
                    continue;
                }

                var programHeader = new ProgramHeader
                {
                    Alignment       = SectionAlignment,
                    FileSize        = Alignment.AlignUp(section.Size, SectionAlignment),
                    MemorySize      = Alignment.AlignUp(section.Size, SectionAlignment),
                    Offset          = section.Offset,
                    VirtualAddress  = section.Address,
                    PhysicalAddress = section.Address,
                    Type            = ProgramHeaderType.Load,
                    Flags           =
                        (section.SectionKind == SectionKind.Text) ? ProgramHeaderFlags.Read | ProgramHeaderFlags.Execute :
                        (section.SectionKind == SectionKind.ROData) ? ProgramHeaderFlags.Read : ProgramHeaderFlags.Read | ProgramHeaderFlags.Write
                };

                programHeader.Write(LinkerFormatType, writer);

                elfheader.ProgramHeaderNumber++;
            }
        }
Пример #28
0
        private void ResolveSectionOffset(Section section)
        {
            if (section.Type == SectionType.NoBits || section.Type == SectionType.Null)
            {
                return;
            }

            if (section.Offset != 0)
            {
                return;
            }

            uint max = 0;

            foreach (var sec in sections)
            {
                max = Math.Max(max, sec.Offset + sec.Size);
            }

            section.Offset = Alignment.AlignUp(max, linker.SectionAlignment);
        }
Пример #29
0
        internal void ResolveLayout(uint fileOffset, ulong virtualAddress)
        {
            VirtualAddress = virtualAddress;
            FileOffset     = fileOffset;

            foreach (var symbol in Symbols)
            {
                if (symbol.IsResolved)
                {
                    continue;
                }

                Size = Alignment.AlignUp(Size, symbol.Alignment);

                symbol.SectionOffset  = Size;
                symbol.VirtualAddress = VirtualAddress + Size;

                Size = Size + symbol.Size;
            }

            IsResolved = true;
        }
Пример #30
0
        /// <summary>
        /// Adds a file to the RomFS.
        /// </summary>
        /// <param name="path">The full path in the RomFS</param>
        /// <param name="file">An <see cref="IFile"/> of the file data to add.</param>
        public void AddFile(string path, IFile file)
        {
            var fileInfo = new RomFileInfo();

            file.GetSize(out long fileSize).ThrowIfFailure();

            fileInfo.Offset = CurrentOffset;
            fileInfo.Length = fileSize;

            IStorage fileStorage = file.AsStorage();

            Sources.Add(fileStorage);

            long newOffset = CurrentOffset + fileSize;

            CurrentOffset = Alignment.AlignUp(newOffset, FileAlignment);

            var padding = new NullStorage(CurrentOffset - newOffset);

            Sources.Add(padding);

            FileTable.AddFile(path, ref fileInfo);
        }